mudlet-2.1/COMPILE0000644000175000017500000000433211624306130013167 0ustar csmallcsmallCompiling Mudlet 2.0 --------------------- Use the Qt-4.6-SDK package from ftp://ftp.trolltech.com/qtsdk/ or http://qt.nokia.com It comes with a binary distribution of the libs a ready made compiler for windows (mingw) (NOTE GNU/Linux: If you experience instability or weird behaviour of Mudlet link against the SDK libs instead of your distro's qt libs.) 1. DEPENDENCIES: ================ required libs to compile Mudlet: - Qt >=4.4 (included in the SDK) - liblua-5.1 - libpcre-7.8 or later - yajl-1.0 (you can also use yajl-2.0 if you change make config file src/src.pro and include lua_yajl.c instead of lua_yajl1.c) - hunspell - boost (www.boost.org) - zlib.1.2.3 - Open GL libs + Qt OpenGL module see Qt OpenGL docs for more info - zzlib (http://zziplib.sourceforge.net) - luazip (Lua unzip module) http://www.keplerproject.org/luazip/ - Lua File System (LFS) - rex_pcre (Lua pcre interface) - Lua sql (Lua module for SQL) (NOTE: GNU/Linux: You'll always need the "dev" versions of the required libs if you use packages of your distro.) additional packages that should be present on your system to get the full feature set of Mudlet: (NOTE: Mudlet checks if these pacakges are available at runtime and can do without them if they cannot be found in the Lua path of your system. Check Mudlet's startup messages when connecting to see if Mudlet can find these extra packages.)) - luasql (http://www.keplerproject.org/luasql/) - lrexlib (http://lrexlib.luaforge.net/) NOTE: You only need to compile the pcre module. The other modules of this lib are not used. - sqlite3 2. COMPILING: ============= Use qmake. You can adjust the paths to the dependencies in the project file mudlet/src/src.pro - simply look at the top of the file and adjust the paths you find to your own system. This is easy. If compile breaks with an error your paths are not correct. After having adjusted src.pro: make clean qmake-qt4 (NOTE: On most systems there is qmake and qmake-qt4 qmake relates to the old qt version 3 qmake.) make make install Note: If you run into compiler problems then edit the file mudlet/src/src.pro in order to change the INCLUDE and/or LIBS part of the make file and set the correct path on your system. Good Luck. mudlet-2.1/COPYING0000644000175000017500000004313111513237311013210 0ustar csmallcsmall GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. mudlet-2.1/Doxyfile0000644000175000017500000002577211513237311013676 0ustar csmallcsmall# Doxyfile 1.5.5-KDevelop #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = mudlet PROJECT_NUMBER = 0.1 OUTPUT_DIRECTORY = CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = /home/heiko/ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES TYPEDEF_HIDES_STRUCT = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = NO SHOW_FILES = YES SHOW_NAMESPACES = YES FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = /home/heiko/mudlet INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.py \ *.f90 \ *.f \ *.vhd \ *.vhdl \ *.C \ *.CC \ *.C++ \ *.II \ *.I++ \ *.H \ *.HH \ *.H++ \ *.CS \ *.PHP \ *.PHP3 \ *.M \ *.MM \ *.PY \ *.F90 \ *.F \ *.VHD \ *.VHDL \ *.C \ *.H \ *.tlh \ *.diff \ *.patch \ *.moc \ *.xpm \ *.dox RECURSIVE = yes EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXCLUDE_SYMBOLS = EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = NO INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO REFERENCES_LINK_SOURCE = YES USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project HTML_DYNAMIC_SECTIONS = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NONE TREEVIEW_WIDTH = 250 FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = YES LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = yes XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = mudlet.tag ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES MSCGEN_PATH = HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO DOT_FONTNAME = FreeSans DOT_FONTPATH = CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = YES DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO mudlet-2.1/README0000644000175000017500000000005211513237311013030 0ustar csmallcsmallSee COMPILE for compilation instructions. mudlet-2.1/mudlet.desktop0000644000175000017500000000040311513237311015035 0ustar csmallcsmall[Desktop Entry] Version=1.0 Encoding=UTF-8 Name=Mudlet X-AppInstall-Package=mudlet GenericName=Mud Client Comment=Play online text-based games (MUDs) Exec=mudlet Terminal=false Type=Application Icon=mudlet Categories=Game;AdventureGame;RolePlaying;ActionGame mudlet-2.1/mudlet.png0000644000175000017500000000700511513237311014155 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDAThŚ[p]yZ{,ɖ, 5IIքI[&[:}kJgLZC&60tLC1ld7ɺXҹׇź,huZ{QU.4n H·zr%ޙ9u|H?ZP;̸/bo-^^5/ _-5.IлyhiQ ^D<‰?,UUW_ }MZWƣ.T^q"UiUk??%w ?S}k)~R9txnI庘:2wDyU_{إb1:J`v#38[r*AuUZ4lKnoez8=457sץxoJ`px\},}{u0Mi4`ȵ)pvӇys8ȅ?c{]6ޟM_g8@Sg8z%p!eE) oklUfh2VePw^'V#7y {tNo2ƓM;1KQYmT xؾa³lj&;K7GwjL א)t7֊4T#fa[ڽgϳJ]0Tгsڻ~įx WA*7875j67A19;⿪T/f˴w7r-"ʛM;eK;6>տ`9VMt;]2E! 8"&6J;X߷H;t}RE_MR0hizJd ̃7 k*A'bƔ>]Ҿ*[2JM[43[ WQ73JkGP\olfl[M |ٔάI,АN\8A560߮.R Ns6C'GnR)#UfR¦U N7NS(<<  ԪX]|N@3\ sifk3@)qT*Ť"8jl {^ a0 B0uEDL@XB%:l-V Z8U`:b%)~-" æ(Xc7*/Q.GQH-P_"TAD FmB`1Z—+!N8]>SGNC"pqᴎt舢iUP`+dy?:܅ |6| 6ؘD9%,(| 4iB"Jy` rCehϭ)ᅫ;RuhӍb9++>hb %:/3U.D8utMc*>|CbZe5be Z,:bK ŪOQZ:sSM`bpoTG5rxhh($ >b`bǂ$$jj P0GQQ΍t8+4kR\"Q;Q(8>UP2bkl F,V<&Xfv/ˉȑ*C=+,TZ䷿},42Nߺ-:Ogn}1UXgwͤ cwzzo(ν XRu9X(-fGm^G>_-[,r=1Λ& ۷E/ b걠hfLG:cd]w":nݼꦵ.#pژrcfuz3$!*FBlAGqK cMW' @!\{ر#Q]!ӮzHI9|{VꇙNGˉ4RF1X QԂt)%-ލYs8?]H=$ >+kߗLH\VHU 1]$+RPUɷǧ2Q͸OOY\@`%YLqvl[SŅyt- ψ!,K`@rWiBL:AJƌh-F`/#ҍ#Ok8U[d\T;o _ٙű͛֎ildS) lh]fܹ'fhƏNNη_1^J4 b>n~"/E 6"hgB>w%ۛbQq8x#.3yDYRPF]cK8WDH.Y>:/=zjXIENDB`mudlet-2.1/mudlet.svg0000644000175000017500000046432011513237311014177 0ustar csmallcsmall image/svg+xml Breathe Icon Team Breathe Icon Set template Jakub Steiner, Cory Kontros mudlet-2.1/src/0000755000175000017500000000000012076170616012753 5ustar csmallcsmallmudlet-2.1/src/Mudlet_splashscreen_main0000755000175000017500000021651511513237311017712 0ustar csmallcsmallPNG  IHDRBi!isRGBbKGD pHYs B(xtIME *;? IDATxidu%vbɥ2kzA7@440I I4CD)͌d2}>?H?AȌ66gd&hD赪*r~>EFҵEfݕk[˹_x} __ץo|qx= P1~̔OO}) "P_JPU#@%0U몊Ng S;dT" fr @JP5 ;CHv1#P@( @@|2<z?i( FS]R 0/@|uĎK_CGM@ ߏi|ͥqY+dX;U=!\3߳!(QY t=+xXև?T?3vȗJS#F%pLzEq}a$y"1ARGgӟr^u1"4c3UM"Kd?gh)T=Bd뀙o:=!BKC T Tm3>r<ꥵ2_yBu~/(SuyJ(h ÚC~2ȑ|Ϲ:rlSF(~~ILɋ!pol-m;9@P8R`߼){Q  C5**+rJA7u)kS&˭b` $m+mU81}6kǩHeMinۭo  Ephsj]Q&^/X "`6RY:0AS\m% suf}`M<@ZKlL/?Z4'qB$A4"gAC&6#4tm#"Zblm7x{D3*ySHMPU8CTBC-h)@${ }6ٖh()&u?|Q@$A5?o ; 0BG>s5@]ۭ镵y^FH%D;tq#p@mA8lu)Bq&X Pn~ t ]̡DO5bF tǘvFhP Jl%ZZEg%#{*6OvA1ƶ#:8\1s%C5U*1H n!uzPE4A`- ud 7 F#~͞1>Z@°x+ ֿݦ}dFߕNp_L DS^&m/\kf]K?K$uO[Tͺ'9]'?C њ=+W7G.j ?GC9T?4牭Sj\ѫTem8D\dedhj Rj0kk&\5?ZJF-[RrΜ5i?[(M5|\j\g}ꥅ|Dz=ͳcV]K:@?=BKYLx @C^ERC58C쏪^K1@uW X ?!*.V"KCKQj=  )@ӕ@QQa9LIW>v3Zk3(<\Īеeb*CLJ>Oa@&oG>~`kDHd9B}RWD=h)&׳jdi5S]ǁC^Ab9M t!?YU{[bb 2z6;OuuHyM).Ơi᳙m[^oaE!Ȫku=M$  iUħxoH)>WWրKU7{; 9ѽId:u_ɒ>,^,cܫ;DˑjB8ht% 5W7%!geH5AT& /(aC).i_"ɴT#ukhͭO]ǽnϧI R܇ZcVEz6HF)W=>/xR&Ui(>@tKCcgmcJM Rz.Դ4mk0<8?){WO֦d~"8-V^_> 8chETp4RS_Բ790J@Q4:}Hy /pB[fC=,oŴSl$gms j+qsR]RΰYR6'}\8lRw qqAJ@eN܄]uz}!|Z{ Z*żRHLDqqFScQ.}gk~yyT  k@T]Z @ɍ}c7I\SKKa at8mf&SxH׳[)ӼQ8!jZ9NK_'1lNqdyM6=_OJX`1/f5_b#6xEYJ%⬢Q U$ڽ3 ԧ@*[;<"AD9w۶&}Wt 1x)j2OCSã`%ЀAd6K'[K*fLZjf;?ΐ O{.[l}21-IN~ M)$uvygQ$A5&8ond"sܶ[%gVĶ0M̞y׼c(+Аm@"p"E<]ٚ0zzM #X%T)-K)HM(qU L^\hĭ(,BrU90Rχg1`֕V4DXM͟+)w?E2ZpP#4 (Z ;*6$≥_GUk ikpYHeIRpޫ"dCՀ5 bAh¦Q QRf3 l-߈xے R2MsrxL :9AO+wIYGt<@8\`nl2gWy #ZKYΜCB{k~dӴo;@[AH b7K CnHԠ . "H2JAc{}AaMA g޽TiWzEM]Ƨu4E=3b,Zn, `fTP,,jblLLz) 'wͱuEqݿf^?l}:x֟]_)J*DmUFp(JՁHM{xdZ0lT_= S oDB:`^e lD2yAF$󱎱}f[񸎮,w$I⛡Xyer]H\RRH=xQz9hl20[T\ Pд泻a\zN@f^=D${Z ?X@(q 樈 Ҙ>ؑagِWlJJS¢YR-b 4W.6SǛE90OT]3!"*o(RJp6Mh6n l9T>cx419zw7%˟͏:wu2E B/Շz>y), $K~#<@RQ) ƀZQc7Rr }ʯ9r+R#0AV1!q nKťfr,-5X{򻔲Ki]RrY@4aKRv+`#gNV|w0j7жOB1D{U(V%“R[u E\_0Q$Vg'QYl E *uкiMU%ڊ&_lZ%ZjA:th m8x?Fۈ1ݑo, հva6u2`׵ķ %ET3pē=t'7!A* x M00=PxW2 <*i<VIc?&ۈ$,;@h' v9#{Xs8 Kwy`T-8Bt$30UcUfP*T.L{I8Bm;Fck@tI  p9vfj$+DBcI =q`8"Z$M>'t귰x55`|?Sg]* >&oM\x7{װbÿ70|`$AI ]Z@!IBqW*O6C!7+UZI!aE|LGr[} a #ϗ\U B5- <.x/-@)I&cs>BU`O! % Z@ՈL!Nn~M3 ocl]|k!sz_eSiAB^H1zVdgvFy~|>+,G{`0phAԠVwDeȄ#Dc< 5,<*nRV1j=eDPZ1Q5k5L!@᱀cppY ~2ϓZ39è}]nwX@ >TtcvGo,u.Y׼[ j;< BKЄN!|$`[^x  |0}5.vڒQ RT)>'&%k@iʽq("T^r yC^ ևisu.-SFH+EKۤBrȫc0GIY٥@-c'.ūbk$ror`xr'U˗y"v/.(KV1:w 7o];`CLos*$@SgoZGw#)g9(SP-4u)bo{OGJ^ 7wv))'YB2 DE[V?V'{t[Ӭ;AJY zj Pg)D^kz[h{U<pگOxn&.2覞s4͡em _)I!#m;?_e4/lL ZE]h D#s:aSr3uD*Z}_ϒ|\8nEs~>G\7<!>FX~NW(*}XC:)u`"^Ҫ/nKRc0<Nш }_bq"=x<3G? E#;ױwgu~ ޾IørU IhǻH=$4FA) :&^xůXw XBJ ͊+r=[DĜ.Dh&f@I#Cr4$hPxU"VӤ6Yri|]gC^=N<&LcK`f4_x:nګװ˥| ۻBSK&)2!4@ U\zC8hI Q8D%O,MѺ*jt;VMfq99z`P R hsϼPk NG?Rf(Ie@(OFl b ] 9͐}Lii-,%"n0Y QOŨ> g3λhK_^C}ى9:4&&P;y?KW_D;j[3pnk۷n╫4[Z1(܎p˿?cL%l4VYH-84Ț;A-pcT#m9L J?NG.RQQto5~D LjʆzϨVrB[DfLJ=k+!!%UEU?*Tz8:MWT9u2\+((elU߳k: u lomyRד;[O\Z6D 1hBn &yw[z J6Zg' IDATU&.$Ƣc geE"+##=mފՋ4EC"v3OU4 .`&Q+xue~CS*>1QR2]"r8!h$t%i/ $U7Н@:fs0xw?.^U wɝKdrFUn+&W))Pq̚#ՎǧS4MU^ C"`EPB*[\|Ņ]t'ػ7%d%gM#Q)5PՔ`o sXJb Wa2d9ݿIʽ@ *9xꘛo*TͿ`9 &rC IIs!4 n56n rn8 WS@O,Uc/ |< ~1+ ƺꂋ1E #1\P\v:\:=!|,jZRjYt|yi,>|w/xkxx/*ؾn;cx\T@ Ff?[ʣJWrg7.)wSxDϊkB—~*϶m\M\M!n}/x6Z'$OCBC&(1HrAR&)[_(gQ"PSnr6`<'S*"rǓ{>iI!D!e r VkQ9Q+Sj& NƟ,G?ef77abZ5;qAt\LwQM32gy%fAsQYJ2 W,R™6i {AR8Qk/ځT+GYN`OTD+9̬+6:kG}E3K$/)Ȅmg`ܸ(WsNk!k/_?E<M}ۗ8Vg*6[9&ͭF#k\+oCZ%Bm)S?(0>NfU|͊ o tf+Gگpg;f%^54qS7_Zqbp09!;X qQ2U6:;og+bG[jBZ}QZ k^>>twԢk'\5vywΜ8 PFnN(Eu'48_i-Y]eUY0jb+Rh!hJedufY&!O9)eG 6/}LTzXr՟Csm563Uρf˚Äm"*I VOX@wenIDMâÀ q韢~ Wm;e@OzLfn<,eTe/r_* x1ȖahڝR ʔ+3KO- 2דɥ}N':vVvi=XIJ)uϥ>%]ɾMg' z I F!3,Hk8Bl=2ZTpu@%F/כy:nTWd#9WDO-"4PB ,>FcL6wp?xR_ =Z8ma~CC3,1RݩHM%3'% 6z&zc,ֵ><٪Rb7˪2*q^0I1پo??8E{ ^tv@sN"1Bkb;jRSKP5N\4N%4jgNNnu9a9M\TFNeg%f"A$}$fn+`jHRcjgDxJfW AdS^r(30ugGd4:)E~Q9" .|,n.j)yWknOW&9!&@ c:xv m%2YCIrNտ*D<DV`F#PhW)6vܻ<çHMWD[Wpr *OhCZ G9%5a𵂂4l eC6\Oօ`jfDeXpR}x"^yq!;89[h&3 %9z `Ӡ sALӺI%{& &U@sDRbTvǛRݫR-Bqk7 [0Є4ڰ2)_QAjts$RuMmƀ{d_ۼ~BW50,Xj?BdqӟF.[ȶ-w,"4Gw fov_@6Z:oq ?3*s0ܷ}]\`<jl$T1nlgH-@< 9V׆_ʱxؿcɟ 0:3c+Kj~YHݺES28(Y=ĢCA6z", kk*|*̌ysNz0gG9Xu9bh1F01tku{BTP?K[}L@WiI 9HL]hݝC7qoc祯ItTqwFB{KФXau)6`$Aa|taq%'CW YK@Xߣ災'H$l\Vծ..e%zkh4&6/{~<=T'b{l4v/4HU7~`d=siF~xvMW((\EA<D\FSrSv}箾n|ΛMA[%I,Ą(uzqsфq%!pOZ %Y |-LK_UaC M5Z_If.RHLJ<)KqpPĘu; %%HLΟƣKdͱ!4p[/T6`GJ^1oќ-< ( 揼FL`\VtǛ@(at-,Ax~{Rx]Ys8(>.L^}MzہҠ .![дoa~n0h6ul]w6JFOE=~f_bY`rÓ|"1}!lS D`ki{. v7Lw,a@bVn ;&1 :sSj 04Xa5~O  ųS$28-Ky6c{@/>) \n #^Il X+H%|oؕErJ炝#6b⫸t3f{ tRoV̚)N 헠&kۑp8:3پۚ!olF#,p{/a`ngو' Txl~1h+Bѥyऋ,>/*@vRcuWٟcv/쾅f|lV4!j6@*6zɢNhLu̽VѠQRa0שfHEv1$[œA< fB?ϖ,7PҢvErSfhjCp%? _ L.f1-Q}h>@"H]BD2JT~`("hPj9H"X !eI4F ]joA0IZyV#%Ew)ʗ [^yRR=pXwnU]Lmߠ1j7]M޺p$u~:F]IkXs-Gv!A) p us -0>mhx|V鉊UTvtc@H $܎o`tC|h@{roxL@EUfu+Qg`8}$U50UE)$b *3b+~, X{gT%ƘJ|Sƙ!%+UA)o8pOopO7}:RmnoF1PD~ LP\yAJ_EwOch CSM['4`D&la箙o3Au.kVU}KY&)0vMlc`a,<Z&D{%IXwxb%js85Kf2DoZW#*soȱ5'7-4&63k ቴ9D!$'k%,nsݼD]q̝IUG؄Mp2uG7I-hZkSQ) o[;Dt_p{ fM"&A 1 $KCQ C [Of71$l"&4iglA.cʓ>G"H[v^o[GBW9= }#h00R|H=U")Uo]P2/|05I|Bl,/|6Lo΄+.MtHP4O]T^͗DY`8jUPuxiZ*ЈR\S8"p2`\)@Mzzۘs] DfD }C6NW=mW^wF@L )IΦ$:1_ -LJ!>l3b7us#Jbxؼfa!/YlN CGmRn^`ɣ$҃abլC2blkM$@t<F ?MPn9v6=E!, 1[>Ƞgy8uq00u( 0 SH)pz xf*` :e'B98Sz aef32L4ٍͮg3OsVɑgkGVCEz JH6-Q[`תU$@"pȦXEDhPӌ&l=6'\nxh^$ kz"<]&"=J`8={(ZBl0J@% H $1M7ʦ!PZ'EV }= R'K R@xw19- IDATlҹ\VBLYX$t`$p7eňMvY1@]v/O3@0ں$V`a[S"p~HrϬ>:3 &KYzݝѝhzKph0F;2#ub;&&p`Puޭ/ !u }*@*(Ͽx뇈Ky9 Rг Ĵoufn@hؼf vd_[CzⅇS>i2OHd\,l@!Og(&D 5q@g!TRppCgK,n2G'v+:hX%"bt%v9Q%''|R@CRZ R갈%D ڡm7  fg uǮ!wr_e+Q(_q{;?tC>0rR,11!E ~@:d0 tbԄ"v=`bf!7똞\HI!{2{N)rCV\j@  B;fhG;7m 1bF@PZEL%c:AREh0Wūjd.[j׹F{ `n On{"40>k붣-4Ew%Ȩ/x!5[(F[NуQO[ hڿYUqt)sVъ@[lv1uhw #v+_B%pD48wPkdIa[~RA׼.0MpΘXLоM4o| _}荆KKh_:߱Mw,>]: h' x2)m,9 G#l\›h6."!Ha58Ks風U㔔؃t3xZ&_-_Zg 4ۯi|Li1k b~{Ayİ<2˂y Uglp OY6@+!I4,9# .T#г3A%ݻscPi[0~_;a<:jvM V}zfIKHK-)!K .d}q. pksFlV^90?JWE)J$tAG=yEq/!Mkۮ}E4_?ÿ߃zݏ 'slL e`t AaɅݹj|BѰ"B3V,` 7KL&aѿJ7~x " ;oCpgG\V # n;+ͨwhZ({O$4RD&& M±D;Q@09fGpxAJ3("FրgZ[zJH!BKͶ`"dqvJp=9}bJehr%;Nwrq}Εa2_p{;.дmYKr(1y$ &ē=̮)c3ޟp8[`Aa?о‹^xw~|mo_5,a{.cnz]/GRE#ဠA!*]ܿvXJޛ G?3.\i1%?3vzHYmeY =ZH{R0껪ΡzO3 l y1/L?&HxyiJHUJ$'H:PԊL0x=f `3m\tŢ1mħ/cgrBm lVE6+!Bgr+(RشC:H6$0MG#8baft ,c_}&`mE{kMAUƁ RqtIfH5qfl9"+X#yDG14BN5}ND͝k_DBh4V q E D8A03B{/Sm/8>pg.T b{2ɇ?y^x832tF*VhOc˿^AbQ( pQk)m!69Fb*~ori6.'.Dw6ղE >/"dfzq;Ϩe:ގꁓUD[= I6r0l'm|@]XM]MAPZ?cm9tA0KD|",6OW=qCEvL ѱ27K H;Ps.U&^ ~ƹk?~Gᘵ;?C'%{vs3 Cz7+ =JGk!D]2auqV6t~4)$D[|`CT;KXgA1ygGA=ISGK\"mS5z{.ND}@LLA35h8)}B@scf=w4ڬM3D;B (al^0uJD/W%=`NSդ9h%jdpeqr˿㟊F2%x]Muڛ7k|g9?[kpq.ſý_|+NY){f/#2:,")4Р^5dqs||38g[/b&I}/D?A6Ds9\g4ηЍ#mGNu1 /ͺ\"k -rlI(y"EYfim#\=^fS :d,z|&z]P`4"5u=KZ/bٿF1qY5]$/uӸVrm%y<.{/"}ji|i ܺjwi)Qn4C/IRNxXp|swZC}̮?j>>&1&(L k"mQ-ES>{=kH[ =w23kY{ҶivBZ d8COL>AmšQZnPU;_Üڧw7ۻosbc&QE]d~O>t[{4s`X tFMY 1iQ&[~ B=f_j{ \g>{ /=}kxi.CA6އ޻jx/vxN0hse85 %M&+]%Ps& ض\0T>t܀$ *"Ӆ$B۷fBr~"7JJi ]zWQ!@x}'fŝ;_=)˵{]_62o6muf$ }zK^GT xP }@E9f|n[~H"Vۄf7ݙd6q/e-UcDW3v^tR /ESs&O4_?x M22-^S1pRiGNl*gho&~a^Ӻh2VoIqsI$¸bqYAےV1t~TG(숲\27OzN&.Jh2įe8R_>1!c:DrXA&y~BܒIۣЊۘ^6ٶe =0)ڕք(.A{O7emxoINaD wfb\Eԟoz(_3Mi+O#iVZ8L}Ӧ5 4(̶Bީd3o.}jՠ-F WycR{wpgo1|/ $Ǯs(kڭ};E`NN%~9fyfRc_ /) ј[_qX\Ǫ`\{6@h`·耴;~2;kl~ubvtf)L5{Y2I7C/]@aGbMݐյǣu$ßKW!Սhtkͤ EK$[ {xv<K ׊]czIӳq!%:9/qRY!;(_!n>c{bk5ewBco3ظp5:? X7oc42Z"T nV'HZEhWrў`8DMƛc4(WYoPaаdTa.Gɂ#IJ!%> "]+&4&u[l͞{f ̉6 IA%7sX]zDқ }rR﨟m $:z8}L9!P<5zO:1ކҕAiz ?d-6{j&_\'4AZoswƘw4/Us_Xs6Mׯa\ 0$)#"ĦE$CH>Fll rgQڲDאӾ&SvQ[(\OrdŏtڌHv#6zHj'Y *96IX̮y]? CWI,Y6+ďe~Q;VXK1g퐝H IDATe'Ulr/]oм bhW`l{!zXABfpte TQa:(5g)l<}[<VMTT !/4nkWm6;4uERa4b29Pˇ߸0%>oZFӠNN<9[I-<BBu c ĶbM9 nrIA{;ߤy]\UU'k8}HưbYծ*w_c7z͘%Cե~ 1U4sRUwR=i9u2cΞ)M;7I~ k7!j*^?\9%0q )1"KѰ,I֦5kDL\G0{'~X&)/ z⾠d |[UF<Ϋ~ psaُ3i:n\}g?kv*85?z`ԗ,M"}!%bM} &c%Y6#on* ɪ"$ Tz2eutQd&tHq,+:w:<:%l_6稇t֬hSv_hӛFՖ JjAm{M^*fo0e89j V:˘-r?fU}Cz_aa/&`wcϞfbed"-$kbVTNGC >*P#]y-~c"(P7pMf\Yu)eIPdhY`mX K$i2~*5#TIfGG0ˆIup~riy<ʵ\kwK T+̆^tY a:p[8T3xmfz7laGW݃2¨4$A="S@u6/0M*:}HKAhiS3K?0~TA=7αܧ$Un]խ"ŔH Kdcvb+%c$YRfh08+zKB"dxY/a2 r/c=+4{$$D<R@h WPQCBhAdhMMfT.Uuډ9Ji#0^ t}msE&x|x xi"df5.<4mOzg6/Ef;oĞ]HS/\q4(1+4,f%AM[!Sx5r߬о0!XÚw|C4GV2ͨHh@@BDmBW>٢ M{h2API)o3= h|L#tB&SH"gxQBS1U*{viEi.+?Wy/xr8%/Aٽ '`mJ@L&-۵u8kZ\]Dՙb a`PWsToG ;k*J%v[bΩ#4d!,4INSQ잃i;OcXy$.SHRK[\kmrÂ87eodldb?1{|$lRpXJ+W0 g)dh5䀚0|6^D1ټ$c:ƨyΠGaE| _1STnÙVi.Vg>9^_f &ۯ.[_@\Zx(l_dE荣 Aar{/ S"VB r>Π-6ދ5E\gpt^D)B`!CaBMz]<@fY=dL)pfSD1t(ELJE{ sIqmfu'NERXV f(KpI%]z&#]16=L5#}\%~j~%$~~PKK?`.rS?u5K)ٍܾn g_f09-& $ʹ;YV+3KsV4 yDO*42R~+; D]1t"(%tո}cdǑME?-%g;O$)O'Uy+y]c|5Kc/5H;%AU*֗~ ܛ+*<{2? v;7ƙ@a !ID' 5j$1nyѿ\HyS#Jr3& &;wjv]eq{I T{o9mB%Xl$I!Uj]*MM#4Tm0At1lT.uuXY `0ԋ۩e 6x[^wk#$ Oc\-62RBTɽGQ)qoX-I. Wq*874Q8E`Inuj.R?%Ijqk4v9M`<#?s ~^~g7X1 s e7YB'l+F8R8so_Ӿ5Mកq8w$VWP%2E9-h$NJe5m߮3+R^&>X7xW,WA}+EOLi{QmJbj{oĀg7߻ʓ4M|5>Ph} q|V <(S2F]YJ,xz})>~woy v\S>HRwѠ1>Y>EzkOS7I8R3AŸ#冘o5i:}g}֦+TgmD9|XNX)h$"\E$t6M{ 0* 1.Gh*ƊJT8:qS5%r ηBPi|f11Z7*f&6US҃^I@1l΅'խˀrܹETKygØ=@!q //ozj2b >x:s})f2?x`U -*GxjGRZA}9"]0%T S Vϣb[]3iNgI`iWۇJد#}ɱ^ȉ78 }CIefyEfs)ƟY? ;~kx;f8+^%3E.n aR6*}Uya8bOƓ/+Lƣ=8q? UP<&t"R̪TF#{7og knE1in_gBժ\UX&1IhA_FeRHù|;\19{T{;ܹ;o_GUF[O1l"d$s'Ij!{z1TZ?~O?_ߘGt.:XMUPgx.Y:t*2b R`RW1I)F%zM<_c0L!IDE<KT)ʊ5)\`y&(@vY Pf^6KiЦuScLa}Ɠ bЋ]7&N׸'[p7o|F[}JlӤH4;uu)nD-jO^ h5ʲȥRa*ϡH1Y^[fqeb@90<7Tpr*Z|]#8 FZz2i0T=9RUCx !m8;J{aVFE=c“Iw{eTPVgy_c]"AKK7.I({s| >rtOY8gʯs~kM43ђoS{w*0Y%i=;߳z۩'9(lCKOb&[i$]&E1HeuR\G'6z&`YLzLmHܽ5 7dc>?455uU1(b BXٸ8w]ojl]zKQ/پ{le0ZL1U{ *jzμCuuc?W~9eIBo>~_GX` gξWL:^Í(SYt ĀUػ-LY]p&CTpOk۝I4r@]Q"z/Bӽ[M%0 RbQrݯ@%Ƭ1vɜIi7(pˢYv*u"0ppV z`Wf3/k~ɥw͵ne^Rj`8e VΤ%KOk[Qaٱ6m&DܟvɁВ"~(1{ 2N[;[1zxo;=`hl?\}n eڽ(WX[BYb b"*PZmbI@P3<4=/ IOU%s#SLW\\=GƷ=wlmxF>~z=z,½7ny6'C֧p(I*sMºv+vjRw9 S :+ #6ǚ2B/ ZaWȲy}BA/g\+]ZKh1vKЙG,=u3=xhkT,xtC"bTնݪC$E9?"FqgFYXFkŔS6ӝ~z=|߇xi;;L%n3LysW>+F-=f!ar@l9`1X18A` 1on x5嘲Q &YatK$dw՜#&Nt_ b Db ԃ ]pSF/*]J3 Ei<*/ML8m>:,  iZGmxƔ[a:)Kvf5ߙr >S]:ޭo?pni<\8cRИ[l{AkQ@/s1M3aL)6&AhOl&tNާO5TnEE: o[X7 L4gE,>bBlʌ/"rL<r糗bQ k+CpXW1Y‹?_lw%+FTheSk3?sOB=PLwo&$ n28Ό`h&qq爽 " û^9{!ֵ¦hr!ւ薅K~).ޅAFHX0n hߗ[v7E(F٢-)?c08O兮8 n if1mdE_ W ۯlՌff~ntWkB鹞ȋ-I@𐌔̯w[#$a8JqGe, X78JD|D/r n+I6nf Nw5gr x$xU]/-J={ey;P-)cBldD#BnK&[G7s>u Nt^~4M,SʕlH) IDAT{oJ.lc43:fF0Xԋ+P ѹ(u=~~D x}B=zq :{W 󭆠= /~&AjnT6BN `XFZN [Og:eٽ 6zԸ)4RZٹ hMZI"M2Ffm>sΕ¥oGx74GL^&Xw%ͦLS]&DRFl15s_JyRn#,gsx=UZlz*Nzx>άXNO6WJ.+2ӆD rNA ٢.!ؼ4I.r-Z:l onv?qEuXR$ >IHnΥm<{g7D9K󷒻f_dd*-zkK\UuY+X;( ,44 f٢^^3fBX^{(a.ppyGɋ6 2`>{#J9sJ[*+eLۖڊG9b5a" J` ]BeJ ɳ%L%|&NKV,mwo6g,yD~v%  #Mm%i66 #_gegRRZ3K%TiPSs;N9mkAw`p%WѣUkDhO04 >#!BpnpLsdp9ew|6ռaxn`1܁!=A<*{Mc{z0Zǘ{rGvB)* =}fbES{PC|Zk*RӤR׷X<n8{ly_!u3cDmu6$=v n_yPLfIt/FܣMbIHg)[A ֍ߞ.-xb˯X`βU[#%e`Hti6G}st|HY @ԂDdj)7 ˙rfP RuJSLz=U6+dZ*_Qi_h H!/P$ ٫- v<=a f7 l p^^Xg}L"m^%ȴ6z#XwIX{;zEh*ۆ1nsoWFh\2N͑FavqGy#ն0(8x*KWq㠁:ȶ,%B;M샒]ehc:hmbh;v^C/s\1ywB,Vr/M$IKyzv'ɧ1iqh Ԭ*SKPt)4Xӹ}E9y@RRŒ&Jo"A~qmD(6ĸƁX̓,ggU7[HŎǒKeU(g3sB U\p(,r3 kUef,[|̨BO@ @eEnvQգQm"KQaFI7pz /`ؗ!XiFb~ m6;C|iKBGY:2 yN"}ً*8ew5ĩ([1V8Fq:HSZ„ź3jVe{Qŝ >F={\Ь !fQSiij eZ^8ޞxikvNŵ eIF6s$kTFMjb @[{ZC3EcKw\Z6[l[bھFvK UMХ"r}ӵSfyj?;EX! apPғȷ&9}i%Bʺ@Ja"HwFi-qC7 |),&ζF%?)pPK I D n do֗Eic9{s$Ya`lpA% PFi%@\p1OjmP=߶`+;{٣J-43 "7 @8<\z@SoQ5X*!-<葘Z&iCP+1'0#+hԠ5Y+`?8"  jfMj" ki5&IMp1Nh< 7cEu`;J-Tl`$$p \|M Cp.8CFy0МQq}s=F_`S/QkT9 AAk^xC [wb"wrhum{-jcu ~)a=r=:CK>Z(% d!n 2b,4gSZ!=&EJ#@]w1iDN# U! ] 5Y` %ΤYNoV?D | LU}ni H cIdh5y$*O> mE-u_%* AIװvF\<=KSuZ=f㳾! e.KTu^(;2I^`\T m9T-yoæ~cB{ۿɅI0XaD|M "sL:Rׇg!Q,лu;[h<XgHRb o3StvzJXgj": AɃ* PB%Ȇ55N`.mz B#I 9 X# KiY!0ry~ M{iŞ^c'_pk*6m"$߄Fl42>EuTr{: |4rhHFi dv0V ?y(eD!ݖ # 4֌dY`E\y u wzA G5f (c_cё-F#i a^c_ %ߠkZBV5*=8=]}Ǧ`[줆CUsZC!uM2#3n:BS{,tMRP[w=v^!LnT٠}1֗q]|5֫f3qؔnCt]$.Љ$':L Ӯ-`pDA k)"X+)Yj I3ܪ^  ܵ-48dml ZTuAq [NDtC.62\igrH8#2֍-Փat(z ф.|@inPsTtF =N-6=6 ](hCf}7 e"KI ʢi\_e'o2`O!S&F c!1w˱M,wbTDmt)_f. *ܮ<_t)X f͚b6쭵$i7SVxx𰆹r , :>Jd[` wclŅR9DڢhU/i0zx'+9>5!m 'ZbG2[.Y˴Ue``x ua1[,A!nVx#W` [9B<#tpMo5<(lGS.PdiqYX8-lqJ[PlCyoR-v}995elm}^19',>zpX$RaEa\ nx@\@ OMY? C2 $LT$i ߏ.؃O um89 "9ԝY#|!qd.pӞق!aAc>EA&aXKdn@ u*CaLd-94aqN/' " :~~p5N&/GbB6 1TG94^ 4ZbXlQ \b9vB_3Co 22Rw8K'7:Q%ñM^*0UG{NCHP3NDdl< d$@SXqM4rsp-|:ћ&wEȶi֠o؂LLu &f IDAT4*n+G /sPWGPiuDUp*f5qh\ j 3xp,cPE:,4D c~t?r1`&_z-bV~ه {85 ca]De‰ߐ)!֗3C%6c7:4^*5 Tnn@T P?(l. 9:?*G}HE 5'H=(XMlf)SDF;}@aOC/nR>miF6-jX`5 z jmb]z8ZSl̷Hk*~N*GۗWa9SQPꔅ'H\bO3H98򰯸oF;8B>kc?nH : 5f&+΢V 7k汿V8%OGCpXt< R=q9{<;PsaD)a\Գ;imA 4ͷx ϖDaK*ل'1>:XkfR4tx$VCIuP_2%+LC"X')KKEaqmHOS |(픁[Ti̖&'fe}XnXUW(xJ=3Hd)8kLw Β7s☶H=8poh` 8BA ^,vDp U[-ESp.2>=T[ PnMI}F QA(kfHgĤ+O~h@:^ݤ{ *&(3Ď#r·iJIiɣ4BE\A؛w&Tg]#.vG<ߖ؆XF}jұKp;b lf#7 -< Y#f#ػCl᠈^A ~OCnB, r e[zM2G9d9U>ON4^8wI @ռh/A{Ħ6: aqJn6dr04>4 z# UL&%zk;:]S M}{(jRH2^.clri= تeSoeYkLlI0^4F;TgPC̈́r4F0"T>P3$Abl5P.xIGq2E=smq9r](hzژ(f@CV8av\XB8o–.p,64:1aCpEg´9_GddڷfϠ30Aϗi|4#;$pPXيՙq0dA% r CҰݚͩ 2Z`Vna^"4p HQڔhfFP|~4`m[45n'He&2] ƞmx%F1\&?8c ~!͙d7mR ǧب@GN>C>X` d`Ha_]s<3 xAB ~B$Rji#p9Ǝp*c!zpc? éd8%t: "Phepiu`bjŤE՞znQg0 3[AIGwe|s1crte& b b}VJzr=ԙM$F>훝qM&~'9V|f{ms)tΜUOX{1DgNMcK04N?6D4]tȔlo?$,12 .\t?,du @1jw@q*ђeeĎ۰8/'ڂW=ZJJrvㄴ\s&"TQ;Q EWk? iՅlQM'+jI]wMV.AS}G9Vz:΢qѳBQg~.h0zWUD22&y7 y>Ɠ h,<㵆}֘vS J:zfG@1OtM"(gf#bxGeS7( uF GGm8%,`Y(W絼fnr_[l /ޥJJQʀ r(M!DVJq_k`؏đgM:3Gx[`/ɴE U0x^pm[r%2&]fBYྫPv0 8'#WJzw>(]y:0l= ?B85tyjɬS)uUvw3t!\pKcB ,آ׸m-pN6Lݛi-E!P2F +یaϬX{1E"LT>㼍n& mk,z'eʻxniJg&ՇAL855}>V8f+> `CqXC0M AqLS̋y`Am݆gia˾W[Mp$}a@XX)P*pW@b*I1h9%2ٵį+NkG&^!:HJ `9i985(8",oFOGM~SKǐ~b|!pց5~&".ڱ::%bA'8>z mq>(5<,:ŖTdemi m/qWkpIdQcE%MK[bMPoCmcC/'Pԁ0~NYw1WgѼ 5\(N?Avd;89kVJVi\(FQrh #t Enm-$bեa^\ KM8YMpc!7{3{ñSaW_^|Ob\&0x^~@N~=0'r_[A1 GBe ިqTeJ3`NRAS5` K6X l00K\56fZ\ AΤԯY|jP @B} PDl0dTH>JOOԉԣA[HDBY-Μ>v9N/lPS%73X]n sy=sןau뫛dOiSz5; Snk|_}G0h lQ{Եԟ - `yy2B]4c]"gEҠpMg&Xr .41,[k`T\ [ldh05DdVO,7eQ]p{( 0t~y?'*H"AzrK왬YC/y.[pN,A2 rXէ` ۏ!M}??~/?onq{; -+u@Qŧ%觛TQ"c Chjbp<ubw *Xqk.p ę@JX UcP _M-4p8/}4_p7~[nkŪij}tC| XzH u!$A2,Lэ(\]ǟǟN>׿'ϿB lʳ˩:vPWc_XCٟw#[4[c8>g )ݞqD;L1e ,ĸT`1 #0%KZ!U>BQ@&wCp {ݢzN %Fa b5:t"{:fi^8LRH}K|OgnlikNx.q;~}%ĶgFr M,PT/N;p"pM~a(v7o~|l׍Rc) Q4Շ$Р.>8(k$;[::t"P\BUм9\)J֨7_%N sŵ(\+7;`cTêHeQ4 n, xe߽m<{ yT[4H 5`ݰU~ { (`MS`s,/+MѸ$hcK|q{} 2wl~Lr08Ga=NY:uTI{ܖ‰7J3L!T+؋"6b"PW0)4{K+:TefL\KcPȲi/ M7{-Ed` [DXb?{aAф"zWxnV*2(d[ ?FXajF QD7ud4/&臏IĴ["8 gGcH}sD;)IkC@`mEkX^~rcZs\Ip0s7˿@Q]_5=H ÷ &Q'$Qp"nxVJƇ#8h+(EY%d6x,lnuf΃2k[-pcVX(&`lAh'X 6/'}X?I>"\b!d~ [[1ڑ0;>lVy3{Fw.-߹0\*'΃P;w(z$-TdI\3{ΤɎȩƇ#qAG;:z?mDhpcfy_>K%Y7 / Ii 6sA!"Xlq&*gG ԊꓷU!&~4DU#ѹNlffZ?_Cݖ?Zܾwq32:33fK5O> e@}y,1fe~)* 1K*pi+Wf_A'mtqH03 0eK丽Z:.2ϳBI* vJ c G\LzxUKFH r@0wsK'+W8-%GfIxPȀ%7=p4\1S| !< Q,_r@99pkNJ&G8`<BDzDtg)lϴdKkTbexa/WXEEEh J f. -x24(zHf{(g@9`ك|@k >4'x"['btt IDATh峴 b,K\ /K^`i dab4qpȇDv91%D}Zχ~]9'f9cɠ8>?Kb7l |m7*XŒ+\nTba e06@\?+MOAk?~MadzɔCp2fS4g/78}qi`[Bš?]p7 !8 ke-Sbm`(XҔk\aA*ca`B_nLztwIW(=*eiO|W2g:;:anO釗<2&s(7n |yw@(҄9Z]h '5uTO9@Xb.#rJNyXłJQWxa/qiVDI%,{h/(WK!N$M,;HQv8ՆgV}FힱPcN,>$jWY8x0SP|j T,+k ss%U(Ȣ4L&XVgM#+mL^O?Y⣓+aP`IV\K, %(LC:a{@ʉM;Q"0& f#W@.CJ6`Z;hKqF>dC+hϪ8pBynu@]jvg* >[VkYZeGgć͜JTX,T+\׸*|IL?CFuvsjHSIvSc<੏}BR`y L`k@a5 fw/R}@rd@NY aaAi XS ^C /W_bt|9YĢD;YF֕"W"I=oCІw8 ' ;kh@{ \~_޽5+S': %?}qOgsf\_  JX-qc/AqKPPK >1=vK@v* |;YJ9F }1}9ޮif1~-Lq\56<S\CZ'>;Ap(K7ϏxȞgfԁa`E Ƃ+\Rk‡Td[6]PޜKJ&ɸPHmfC%Hrvg3>H͋ md͘aB[ Ѯ#W 2˜^7X%Pmh8-]a UuBQ\cGPs[BK`kI ̵`!iG8> 0DzfFb@+p%+|T(D!uY>tS5 "i]:#cub!TF漝[]ьPy2-ÜyϩyĻI bj 5p@eL]oO|s {sW\-T5oA\&G"oů;l|  㕯C%ȾfttJs1xP9tOba ygGs<7Xp ,>BS>-RWAJ=r(Š=;҆ʣFazX1jF3buo cJ0az'q cN.w!~`s9vo<3Tq{"jp-(xz)oR@%& *ޫ pUf7.}.63e!ǯAqRS<:6SRK%*6XWć>7XqJc`yO[չp'I-a5?oіL'Rul^R:zkgrck4U9ăpIF du-@;x Z달ɀȂ!0a~ɓ%KcWO+jR xj''^(}(>6t> )k^' <3kTx cBQX6>FZGۚBn"T;6T kC哿=X8YR?YC 0BPt{wo͗B  Y( :}swZ.ҨԎ+}8Lŧ8 XX,-p7`A*0dR3z!RkmR{**t߁DE(Y0hL2 =`1;Rt cw~ʣAT@nJ)% %(ȇ8q:\nO$#hɛR%ٺNE. 5 e@25N/˔r&kISo@B ?^ԏUD_0Ik0jvPAY8@o9mn!=#q( O`bf(0׼~X}-`  6ἧ3]8up,TN,2âtÙ'{0h&"{~\`쯆Z(Tvp-m=r+Wٛl66SRÅW~{t qfY^{s{4ܓGI8{b:G xea*cC8JyD6ғ %tUa7T>E7N ߎp2әvFL%.o~ 6T07u̷@ݷ cJ`%ƾKb@#$2q5ٿXV\#R0cSC@7Ocȁ2Ě1Qn%*.`k %-s~'ogaj{(ʧ)TtpmY[ O'^/hlt60v٠0 60‹OɣM[P֟Gl}נ. k;@mݠfe!-c-PPp+|T>'%J(``xa7ISHT?⺤ ݐˌUn<2,WbdK#;_<}½6݊'rIji =*ݏYl|V/Z;i0 #3=(0 /2X 3sT㹹BImxgP͢^E6FDl)0<BG2ʁQ;<yB-.6G;۞2ke<%W=SOfmOwV1ǏO04Pa4 Rd(xk|`oX_C` +PC-aQB]0`(g`8l{o42Sȏ)<ɱG F̘&Wm~Wa~fV=v|'O uGASb(Ƞ KSڬ>d8<>9  BC@ͺvS`8DQ(q`Grn=Y$LNɠ ʝhw [~Qi߉ S=pғ"qڬe gxƗxiP0ַR*\l0\KPq" M B=vx7A(fD XPK~x oF  ,R _ENÌr 1 ] 6uJ90u0TYcU0a qwҊ_ZA|dPBT17^>X,@TkK.%ƧKd},BBxNI 6]MgMK(}Y.0xi0l0NϼX}әdD!dC?}4֡SL Jub1,(>`@$ (Wl ~P~ ,qMl8ĸ0+[0ȏtC]0L;÷|d.x= Ta$0.潮squl,[98 '[f S:, z/ 68y?H0lu34=#0y<@O-y3W39(903H`d.l`P?@ϾfO =-N;K K paVxa^S/o ixe%Pcߎ:G '(]SاiA}иM-{]ނaP<*c^Q~\k~) Iܣx0-yaޑ:3vv65ﷻ50UpAҾD.xC[>czA+^ʮ{Ha0M84̈́ΩI: %Y\k7B:Oa7ܿ\:p m~89$ gm֘MG$c@S74\Ϫ_`lkK읓ZNGb"¼Uq?[}W(MdNTW^s6?*|܁#ʁQyҗ-)aMCs y 'MDQo7,2\|F Luي=KV>:n`&)M!:\ \b+(/?Mq X8V+i>qߗաOϯ㺬hL JbGv` `c4 S4N 43Rh5"FzZzDFdd2;Oːڵې {3M]UE6US/$>^IrpA{&Lc֙8OD_f(tp ƫ%b,‡Au3XSݓs!\Ok.״ŦaPHɔl#[R{!frʴ##.ŠKY*Idˁg.//c vU4nqf '[vPl<ĈB" G#yz ' IT(v >?~4Ū-KU}L9 6/AIK^ಸ⏗$|fN8(ΌB t/{',woahߋp(w{{0!X5%%wf&؁Ė@扷{plh4DXkqoL 4ϱ_t554;{nu}ϮlS ~sc^P!p t*ЌkA-!iĿoәPx?:ɬ%)l9Q[P &l9*HQ(;_ޑ}P/‰@Сz/pvt'x2Jk. ?~ͧBs08bCYS*_?G{,"$-,Q ߅Y~72XÐҬø=&8,.w?`e% 4 >{W㓏>:a~B@YRzGi ppsulYDaG繕{-:5KtLFЈQԶ'-,Q4N!"P ϿۍBJO֢2]`i-pٟ D"1W72ɀTCe[jvIZ,T}M7v'K]w|ufr\po66`zJH /؀qWYb.]ݝ[nwowN:Ygkŧݙ7y͛$<"n::l>xrJո YHSyƩ <$gl֝rn[TgV`|.X>-/JyN+*p! }i` nƉ4ƃi0lx4ui f /pqQ1ݐREa8SL8\BkrX(/DL@fz*(%W?$ոȬT4k*5J; σ)p67Ҍ\ ,E. tǬip1DmEOREN\s=,H`rNv"%TN( yzH(dxr.=p,BdP3+d>*;TCG{ʛ& Fy)M N‛ua{0Ș;c"'OsIy ĎqN 5Ax*¯Rq!:&I=fH\Kޔmm^Xb T@(J'4Dz=@z< a]ٙn!38ak S eW 8Sa7N:(; j&O4vb'*r_qI,gC,#(RB/U>1 Ҟ^̶%$@R/#jސ`V`d`X\0?taɭ)LqEUU<dh]KmSA!M'Qi5ńW~V4\#H"aƉ>:vb?xCXN;6|z wF8jFN1 6š@Pưp2dX9Na" I$'lbVGF::'CB .@ӌ/DMM(lY]C!B œ3nO8Ca ՠ_hWi Bg27%q$@"9R~] &"M4,ļsDoÒوLDxI s!7ƔqYҀ>r^nR 7G\;J$ A,fNPϠXN?nJKE(uX&Eh !B12X辂Kɯ'YcE1*SsT%0o~}1=JuE]G+X6` B!@ %g$膄KɀIk2!=Q X(B.Ju%ABZZ:ـGas[vf<<QV.&*!4DգJ|4)R"iPFuLz I%@ B}};F V^ ?56c K!ޤM8Q=\ͺ)c#Ԯ13h(q ;V;.]?E,)wP9S„t:xhӏI KArim$R %o2,AY`֙EHOu&[^N#e`h9>Z+Z+ ƔҶA"q]b-ө*`s xqxTdcsduhnjÙL@^^lvB^Jn#QUӂj@٠I5A{XU#*XK=Yh7< AʅĠ80<B \>PNL! %r^h!"`' 2% JdPˆ @  GIx@r(b4fQ" cS'sGLN-I<egj^As"';,cE9v  ]س&6\f LPVțwڈv bvrBSb4c^o㑚ck'h |E*8a(8V8}Hn)qxdP`jBUU=f.pحo2WUU8G*0|@_G) υCS3&&}"&Rn%@x^JژpjOe']pΘCσw<=J XdQ$9, bXUߌ{#tm';(K'P<웆2/>q8*IdSy4mđ= ?Z. 2CpCT<2H Asa@ Vi)%ʼnѣn$voޏ`洉< ǙnQkAmL#Y8ըMe(|GMXԣ\׌_f !3Sاi11nTaDi8~0[}h+=[cԨH=Wjh*9 Q_>a%QEP(vPӆÓJո}~9` k>" !" " "9t)(9j QVH U^J S>Pl  N `L8c N [dQ4bm Ĭñ=ʼnX7o^OVV%͉HtF!zՂՅRwp]x\]HIq#Fۍ(3NCIo})_9T|(ρ p) L8"ˈO^d60 EGBD#.:ဩM>ҎccmddcHA OGvV*v(n8zERp?0),W} „wN8Aʫ(|Dt+k̀]ppڐAZ GrHR]<r :ck&" J`FO0@*ro (0]:A x|D‰9N`g6ksĢ.S!0*-bH7 TW !qQcvR2 ngӁIؒ*&N݉{>'A]i*7*XdQ5!`ZSV톔 Ǚdc,i&P,hB ^$2TQ>TAëlo YC,./QxjAFA#U n;_QHGyA40"*R0j)[AA" c坵(`GƊ_D5+e} Q )K/U^zF!JCeJ UaxFZLPǭ b^"E"!TTiTt 0%h6T\0ٽkE4/RPE ĔqHp:D Q0Y,Hãrw1Ddz>;x*RzyI&ً0hCwp*Q߫dBhzeUQW!4|4ߨL1lTP7Qۡb)Y2CPRO֕D!a,FC7N K|R5Rk4-}Jg|Y5 8$OVEdFDJ<safz/CjUE%V(Q^PQB8-D!-R)/Psx%#E')Qk^cNx9FΑVtq )7 mBdVo5aT8@.G5R!4% 5ٿjT[zV-d/KiDRrWa,bCAªW@ظ#FnVHuf.Ëj X!Mn T@J)%%z;N*I`%>Č&"HLJ`OFXV槣ZF,QCog4ztPгiށ@0 PM+,/R#_ , NcQ%]뵣ZTatww*LBy ڨ nbYEK|0oc-Ͱ"%;R)!*_\L.fWElA{@hC eEc65o}:o"6,<9dÝOnFƀSVZdQg &o}=o@bPu:S ̝?a|K|-_O^.<}3b8i,JVC5 iϻ#%/L{WX$㹔X "J)|%+WfRX, \͟qW]wVv߶:z3wPxbOJlNZʛ ·~ëbEO E|Wwu^Q-Q/۾>GqڏQ@ z;|(ߴ"o L0}5, :3!M%ٳ>Z :j+&]w9SZ]>!߸?Q{?X(voij-ö_0@hA6|󗿢dH$1?)y:J{ +o9]Es%(۸ ߽HJCݘo<5%B73 #>r)u͙k&2+)=0JlS7.WEO>i\('] 3L945U\X? NNAA>]BrOJ;.gj5, L~Qi#SX_Octs7%B8]dlN'wuݲ5{aKOM p>a9{jai&\5Pj*=-Ͽ۴[~ea:f`|VtD1h,=3Umg\0dXIEO͏@7GzykIIK\0/z !o*>$/][EX"Ew{ܘvͺƿ<}JQ1.8I%`Dha2ou:M9;QF(\-O\ETS.dgv )T nPݧQ.MF}MkXcwT#%9#@^sO8m;U%\ylSaۄE _S3jV 4!Y['M@߶ 6X'O8 K;𷶡}v.vÉ~8+IhaS7u@1qYDL+:b.r$mIDATIt6XrYÆZrn9yž}}%J\KeZfDѯ7=rgb3KPc@5lة!WR8Qs#Sl15-gʣmtAX}+l^vJ+E c<Ps8.@ymUa Õ 0 ,>pgeZžN6jc 9bv@ڨ{TlSYNYhcۿt9zO^`Me74*G01vg\u1N h'[vsPς;Arپ1Ǘی-Jo{ ;Æa [r={&7rk'iUbcԬq83( j8;9nH(H+3tCKqU4&''mJ;q2FP-K<!rDݿ43c`\=e_o{WÕUW U {oÝeGZ>on;[?*o?\(vԌm/~`{_ |̺.xrs dB<)2QFo4y?.dՎw݇mbzGoc SIT5YZ+_HCc%kj͸t}9g5, **Qc/6nB}qq?gh#丨&OQqbu@5)]yj @hgɕ~hlWk[>`,\sFt԰lQj> omr8;Q$QhB`V(` X{5 W/FɲMXqWXŐp0d$F4W;>eI5ֽբ%P ohò G ˥ `Kq6m;pQLEsU ZLGLL,2gZ\نe-SPm֝i>wXWׯхmh*..2\O힃@8Ȱl f m_1r<[fy|X 9wu. ^Q\ְ!2oJlP6ޚs ,0a)TDFQ&&Qtn"Kջ >to1%/>hUF?[PaX:P+'^$-JW3:m uOPGbzaTlƠ~1km7~(E2)Yvg0lk,rA(Ya[!_vpGl_ M0 Ova?hMeuMyrrFko1_?wb{Bz:Ѩ? >ҸޡiO^N6.a{7hkj+3Lkea[;bN݀Ǝ6`1(\̅+3M\9m4D;vZwRE8mbzf~1*qEjq1òo;uD`'//ja 7kAsE52lru1p^aw oN/B1✳tAV"G6'tȚfa3X&& 6KbV+u9b)fbs㍥9wvV3m[+3|u |Mmm܌+.TszA] _#:{*F=Έȝ@e䩤ڽfKEb/;:B(~ Ǭlۑ'ni~~bS(߼ c/S3-ݰ5jf6|]$fjm0m+ `S:'wN*"H^i.#k8Ơ*g{'M&^ g`._c WG!/j5%-G|:HsaKtuc隍6FJ٣7x]:?!>==&l9*?pt7քK,Z~D,YdFզ)Oszb^^ /\dZGZ~E<>yUui4iFSYUDgaFmڴM_ Ecmv̛[;]QfI b䗽KWEנ>Q7lg^7b9g&!,^!Z4lϰÐ<;3Gl8|U*߁}&TفcQ̝Qߵ8coDsWҸ<ѿjw9ZkjI(?e<@pgM'[?z_|5,89əS 'VkMnjCFrb9 -Y{ :^)GkzrG+϶xWC̀+ս׻ˢᎨmߟC̄C{W' 2lcӯ•5x}!;zc}a0bYSdQ\@{ES˷4,E9]nò @gEsZL[m1!G7n;RR07{햬Mm1݅݇6 szݓ6g};Y~!__x/cTn/S}P _`֕wΚw],[hٳ`OvMMU&r_o$Jz$Eޏ!O܌C>8; 'qmq)޼6%O߃ϕfiןE1G kB}*P{"~ȲߣrٔӁ9܈7^izr;P}7拱;EK5Nmx|[T| fҒG65* a8IJ}6|'XQ߫y?!=cJY񓏞Eĕo ÄSv7pJ2y# p1[_8Rs]qǏo+3o)ذ ql  d뗽L&qs wnvU3.;\p2κ6k%J5$ʇƷ6!ˆ'o?R<`Ƃ`X %`l,x.>B( aO.Ccfp5xQŋbBz \χ091DžU;T "(39y= MI"ܹ;nT}[[^/jtԇ"LCB 1/Z>yc|cn/`㳯?QԗCcI3 7'AcXdDqa2#ba_c,IDHB޵&^5:`vN9%߷d ?m>]Θ"474"%+x gY@hEY@h-" 3YdQo'K"",-" -$","-]uarq|Ϲaz;q'}|}e 5kÏwC3r~%֮so?{ }0R\{CعX  fϻ sκ T'Gc`Ó>G((Z[_DM7^hY}nzmE+m$D=Ϟ%8Q[ׄt|ڈE5#T-{epų:,.X'LHڽz^ q_.>܎̙= +>e~W8{Vd"''>|O]~-}GZ}fw9~妆FuuͮYx\.W>/~W]P H.S`)/]ƽF (.opyhpX# ŜnƋ/$7dH?Ricϻ);w?O:G{w C`Y} Oɰc\VV\'~?mpcp:'_$xc^2$Xsjh֙ϻt\VMo1y`g?Tulq期6.t>6}O],~WQ]ӀW_~ ÀRQ(ζ ֤|{Qopy^[s /ߟw]c'w=^Boߘ<0PmFO:Tるmbzx_|#yS[~]ں&_x++6Δ4|@]rs2;/1IG\xvm@='}m3zCN6Ӧ z-N2;;>?p#& Î3᝷ -Ɇ3?+<_c"NNL\?SH(==x8 L0HK`QT7"!-[?>N8͢$zL{f8Ϛ<۝XKZ h" !7X6&[â^@l/O'6kTkŢS]dE d/E';3#QlˮsR`-|| 8|a'B!VtjdTy$BqZ0]b*BWl!v9QJqMw^eu!I;(Z $duYt"zCOoQk4AБM\NIENDB`mudlet-2.1/src/dlgTriggerPatternEdit.cpp0000644000175000017500000000304411513237311017705 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "dlgTriggerPatternEdit.h" dlgTriggerPatternEdit::dlgTriggerPatternEdit(QWidget * pF) : QWidget(pF) { // init generated dialog setupUi(this); } mudlet-2.1/src/XMLexport.h0000644000175000017500000000635711647202526015040 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn ( KoehnHeiko@googlemail.com ) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef XML_EXPORT_H #define XML_EXPORT_H #include #include "Host.h" class XMLexport : public QXmlStreamWriter { public: XMLexport( Host * ); XMLexport( Host *, bool ); XMLexport( TTrigger * ); XMLexport( TTimer * ); XMLexport( TAlias * ); XMLexport( TAction * ); XMLexport( TScript * ); XMLexport( TKey * ); bool writeHost( Host * ); bool writeTrigger( TTrigger * ); bool writeTimer( TTimer * ); bool writeAlias( TAlias * ); bool writeAction( TAction * ); bool writeScript( TScript * ); bool writeKey( TKey * ); bool writeModuleXML( QIODevice * device, QString moduleName); bool exportHost( Host * ); bool exportHost( QIODevice * ); bool exportGenericPackage( QIODevice * device ); bool writeGenericPackage( Host * pT ); bool exportTrigger( QIODevice * ); bool exportTimer( QIODevice * ); bool exportAlias( QIODevice * ); bool exportAction( QIODevice * ); bool exportScript( QIODevice * ); bool exportKey( QIODevice * ); bool exportTrigger( TTrigger * ); bool exportTimer( TTimer * ); bool exportAlias( TAlias * ); bool exportAction( TAction * ); bool exportScript( TScript * ); bool exportKey( TKey * ); private: Host * mpHost; TTrigger * mpTrigger; TTimer * mpTimer; TAlias * mpAlias; TAction * mpAction; TScript * mpScript; TKey * mpKey; QString mType; }; #endif // XML_EXPORT_H mudlet-2.1/src/FontManager.cpp0000644000175000017500000000467311513237311015661 0ustar csmallcsmall/* * FontManager.cpp * * Copyright 2009 Vadim Peretokin * * Add your name to the copyright notice above if you do any work with * this file. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ #include "FontManager.h" #include "TDebug.h" #include #include #include void FontManager::addFonts() { // load all font files we see. I'd also like to load files with mime type of "application/x-font-ttf" but Qt lacks a function to check for them QDir dir = QDir::homePath() + "/.config/mudlet/"; if (!dir.exists()) return; // load all fonts in the 'fonts' folder loadFonts(dir.absolutePath()); // load all fonts in the subfolders of 'font' foreach(QString fontfolder, dir.entryList(QDir::Dirs | QDir::Readable | QDir::NoDotAndDotDot)) { loadFonts(dir.absolutePath() + "/" + fontfolder); } } // loads all of the fonts in the given folder void FontManager::loadFonts(QString folder) { // Check what happens with this: "Adding application fonts on Unix/X11 platforms without fontconfig is currently not supported." QStringList filters; filters << "*.ttf" << "*.otf"; QDir dir = folder; dir.setNameFilters(filters); foreach(QString fontfile, dir.entryList(QDir::Files | QDir::Readable | QDir::NoDotAndDotDot)) { if (QFontDatabase::addApplicationFont(dir.absolutePath() + "/" + fontfile) == -1) std::cout << "Couldn't load the font in the file " << dir.absolutePath().toUtf8(). data() << "/" << fontfile.toUtf8().data() << std::endl; else std::cout << "Loaded the font the file " << fontfile.toUtf8().data() << std::endl; } } mudlet-2.1/src/TTreeWidgetItem.h0000644000175000017500000000615111513237311016124 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TTREE_WIDGET_ITEM_H #define TTREE_WIDGET_ITEM_H #include #include class TTreeWidget; class TTreeWidgetItem : public QTreeWidgetItem { //Q_OBJECT public: TTreeWidgetItem( TTreeWidgetItem * parent, const QStringList & strings, int type = QTreeWidgetItem::UserType ); TTreeWidgetItem( int type = QTreeWidgetItem::UserType ); TTreeWidgetItem( const QStringList & strings, int type = QTreeWidgetItem::UserType ); TTreeWidgetItem( TTreeWidget * parent, int type = QTreeWidgetItem::UserType ); TTreeWidgetItem( TTreeWidget * parent, const QStringList & strings, int type = QTreeWidgetItem::UserType ); TTreeWidgetItem( TTreeWidget * parent, TTreeWidgetItem * preceding, int type = QTreeWidgetItem::UserType ); TTreeWidgetItem( TTreeWidgetItem * parent, int type = QTreeWidgetItem::UserType ); TTreeWidgetItem( TTreeWidgetItem * parent, TTreeWidgetItem * preceding, int type = QTreeWidgetItem::UserType ); TTreeWidgetItem( const TTreeWidgetItem & other ); void addChildren( const QList & children ); void addChildren( const QList & children ); void removeChild( QTreeWidgetItem * child ); TTreeWidgetItem * takeChild ( int index ); void addChild( QTreeWidgetItem * child ); //Qt::ItemFlags flags(const QModelIndex &index) const; //bool removeRows(int row, int count, const QModelIndex &parent); Qt::DropActions supportedDropActions() const; //void dragEnterEvent( QDragEnterEvent * event ); //void dragMoveEvent( QDragMoveEvent * event ); //void dropEvent( QDropEvent * event ); //void startDrag( Qt::DropActions supportedActions ); //signals: //public slots: }; #endif mudlet-2.1/src/TFlipButton.h0000644000175000017500000000201711513237311015325 0ustar csmallcsmall#ifndef TFLIPBUTTON_H #define TFLIPBUTTON_H #include "TToolBar.h" #include "TEasyButtonBar.h" #include #include class TAction; class Host; class TToolBar; class TEasyButtonBar; class TFlipButton : public QPushButton { public: TFlipButton( TToolBar *, TAction *, int, Host * ); TFlipButton( TEasyButtonBar *, TAction *, int, Host * ); TFlipButton( const QString & text, QWidget* parent = 0); TFlipButton( const QIcon & icon, const QString & text, QWidget * parent = 0 ); Qt::Orientation orientation() const; void setOrientation( Qt::Orientation orientation ); bool mirrored() const; void setMirrored( bool mirrored ); QSize sizeHint() const; QSize minimumSizeHint() const; protected: void paintEvent( QPaintEvent * event ); public: QStyleOptionButton getStyleOption() const; void init(); Qt::Orientation mOrientation; bool mMirrored; TAction * mpTAction; int mID; Host * mpHost; }; #endif mudlet-2.1/src/mac_src.pro.user0000644000175000017500000005732311624306130016061 0ustar csmallcsmall ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings true false System false false 4 true 1 true false true 0 8 true 1 true true true false ProjectExplorer.Project.Target.0 Desktop Desktop Qt4ProjectManager.Target.DesktopTarget 1 0 0 ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-32bit. qmake QtProjectManager.QMakeBuildStep false false Make Qt4ProjectManager.MakeStep false 2 Build ProjectExplorer.BuildSteps.Build Make Qt4ProjectManager.MakeStep true clean 1 Bereinigen ProjectExplorer.BuildSteps.Clean 2 false Qt aus PATH Debug Qt4ProjectManager.Qt4BuildConfiguration 2 /Users/heikokoehn/mdev/mudlet/mac_src-build-desktop 2 ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-32bit. true ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-32bit. qmake QtProjectManager.QMakeBuildStep false false Make Qt4ProjectManager.MakeStep false -j2 2 Build ProjectExplorer.BuildSteps.Build Make Qt4ProjectManager.MakeStep true clean 1 Bereinigen ProjectExplorer.BuildSteps.Clean 2 false Qt aus PATH Release Qt4ProjectManager.Qt4BuildConfiguration 0 /Users/heikokoehn/mdev/mudlet/mac_src-build-desktop 2 ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-32bit. false ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-32bit. qmake QtProjectManager.QMakeBuildStep false false Make Qt4ProjectManager.MakeStep false 2 Build ProjectExplorer.BuildSteps.Build Make Qt4ProjectManager.MakeStep true clean 1 Bereinigen ProjectExplorer.BuildSteps.Clean 2 false static-qt-4.7 Debug Qt4ProjectManager.Qt4BuildConfiguration 2 /Users/heikokoehn/mdev/mudlet/mac_src-build-desktop 4 ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-32bit. true ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-32bit. qmake QtProjectManager.QMakeBuildStep false false Make Qt4ProjectManager.MakeStep false 2 Build ProjectExplorer.BuildSteps.Build Make Qt4ProjectManager.MakeStep true clean 1 Bereinigen ProjectExplorer.BuildSteps.Clean 2 false static-qt-4.7 Release Qt4ProjectManager.Qt4BuildConfiguration 0 /Users/heikokoehn/mdev/mudlet/mac_src-build-desktop 4 ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-macos-generic-mach_o-32bit. true 4 0 Deployment ProjectExplorer.BuildSteps.Deploy 1 Kein Deployment ProjectExplorer.DefaultDeployConfiguration 1 true 25 true valgrind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 mac_src Qt4ProjectManager.Qt4RunConfiguration 2 mac_src.pro false false /Users/heikokoehn/mdev/mudlet/src/mudlet.app/Contents/MacOS 3768 true false 1 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.EnvironmentId {77560ccf-b504-4704-a5c4-663fbe9262cd} ProjectExplorer.Project.Updater.FileVersion 9 mudlet-2.1/src/dlgAliasMainArea.cpp0000644000175000017500000000302511513237311016564 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "dlgAliasMainArea.h" dlgAliasMainArea::dlgAliasMainArea(QWidget * pF) : QWidget(pF) { // init generated dialog setupUi(this); } mudlet-2.1/src/TConsole.h0000644000175000017500000002723112020507607014650 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn (KoehnHeiko@googlemail.com) * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TCONSOLE_H #define TCONSOLE_H //#include #include #include #include #include #include //#include "ui_console.h" //#include #include #include "ctelnet.h" #include "TCommandLine.h" #include #include #include #include "TBuffer.h" #include "Host.h" #include "TLabel.h" class Host; class mudlet; class TTextEdit; class TBuffer; class TLabel; class TSplitter; class dlgNotepad; class TFontSpecsLogger { public: TFontSpecsLogger(){ reset(); } QString getFontWeight() { if(bold) { return QString("bold"); } else return QString("normal"); } QString getFontStyle(){ return (italics) ? QString("italics") : QString("normal");} QString getFontDecoration(){ return (underline) ? QString("underline") : QString("normal");} void reset() { bold = false; italics = false; underline = false; m_bgColorHasChanged = false; m_fgColorHasChanged = false; } void bg_color_change(){ m_bgColorHasChanged=true; } void fg_color_change(){ m_fgColorHasChanged=true; } QColor fgColor; QColor fgColorLight; QColor bgColor; bool m_bgColorHasChanged; bool m_fgColorHasChanged; bool bold; bool italics; bool underline; }; class TConsole : public QWidget { Q_OBJECT public: TConsole( Host *, bool isDebugConsole, QWidget * parent=0 ); void reset(); void resetMainConsole(); void echoUserWindow( QString & ); Host * getHost() { return mpHost; } TCommandLine * mpCommandLine; void replace( QString ); void insertHTML( QString ); void insertText( QString ); void insertText( QString, QPoint ); void insertLink( QString, QStringList &, QStringList &, QPoint, bool customFormat=false ); void insertLink( QString, QStringList &, QStringList &, bool customFormat=false ); void echoLink( QString & text, QStringList & func, QStringList & hint, bool customFormat=false ); void setLabelStyleSheet( std::string & buf, std::string & sh ); void copy(); void cut(); void paste(); void appendBuffer(); void appendBuffer( TBuffer ); int getButtonState(); void closeEvent( QCloseEvent *event ); void resizeEvent( QResizeEvent * event ); void pasteWindow( TBuffer ); void setUserWindow(); QStringList getLines( int from, int to ); int getLineNumber(); int getLineCount(); bool deleteLine( int ); std::list getFgColor( std::string & buf ); std::list getBgColor( std::string & buf ); void luaWrapLine( std::string & buf, int line ); int getColumnNumber(); void createMapper( int, int, int, int ); void loadRawFile( std::string ); void setWrapAt( int pos ){ mWrapAt = pos; buffer.setWrapAt( pos ); } void setIndentCount( int count ){ mIndentCount = count; buffer.setWrapIndent( count ); } void echo( QString & ); bool moveCursor( int x, int y ); int select( QString, int numOfMatch = 1 ); void deselect(); bool selectSection( int, int ); void skipLine(); void setFgColor( int, int, int ); void setBgColor( int, int, int ); void changeColors(); TConsole * createBuffer( QString & name ); void scrollDown( int lines ); void scrollUp( int lines ); void print( QString &, int, int, int, int, int, int ); void print( QString & msg ); void print( const char * ); void printDebug( QColor &, QColor &, QString & ); void printSystemMessage( QString & msg ); void printOnDisplay( std::string & ); void printCommand( QString & ); bool hasSelection(); void moveCursorEnd(); int getLastLineNumber(); void refresh(); TLabel * createLabel( QString & name, int x, int y, int width, int height, bool fillBackground ); TConsole * createMiniConsole( QString & name, int x, int y, int width, int height ); bool createButton( QString & name, int x, int y, int width, int height, bool fillBackground ); bool showWindow( QString & name ); bool hideWindow( QString & name ); bool printWindow( QString & name, QString & text ); bool setBackgroundImage( QString & name, QString & path ); bool setBackgroundColor( QString & name, int r, int g, int b, int alpha ); QString getCurrentLine( std::string & ); void selectCurrentLine( std::string & ); bool setMiniConsoleFontSize( std::string &, int ); void setBold( bool ); void setLink( QString & linkText, QStringList & linkFunction, QStringList & linkHint ); void setItalics( bool ); void setUnderline( bool ); void finalize(); void runTriggers( int ); void showStatistics(); void showEvent( QShowEvent * event ); void hideEvent( QHideEvent * event ); void echoConsole( QString & msg ); void setConsoleBgColor( int, int, int ); void setConsoleFgColor( int, int, int ); std::list _getFgColor(); std::list _getBgColor(); void _luaWrapLine( int ); QString getCurrentLine(); void selectCurrentLine(); bool saveMap(QString location); bool loadMap(QString location); QString logger_translate( QString & ); void logger_set_text_properties( QString ); QString assemble_html_font_specs(); QSize getMainWindowSize() const; // Returns the size of the main buffer area (excluding the command line and toolbars). Host * mpHost; TBuffer buffer; static const QString cmLuaLineVariable; TTextEdit * console; TTextEdit * console2; int currentFgColorProperty; QToolButton * emergencyStop; bool isUserScrollBack; QWidget * layer; QWidget * layerCommandLine; QWidget * layerEdit; TFontSpecsLogger m_LoggerfontSpecs; QColor mBgColor; int mButtonState; TBuffer mClipboard; QColor mCommandBgColor; QColor mCommandFgColor; QString mConsoleName; QString mCurrentLine; int mDeletedLines; QFont mDisplayFont; int mEngineCursor; QColor mFgColor; TChar mFormatBasic; TChar mFormatSystemMessage; int mIndentCount; bool mIsDebugConsole; bool mIsHighColorMode; bool mIsSubConsole; std::map mLabelMap; QFile mLogFile; QString mLogFileName; QTextStream mLogStream; bool mLogToLogFile; int mMainFrameBottomHeight; int mMainFrameLeftWidth; int mMainFrameRightWidth; int mMainFrameTopHeight; int mOldX; int mOldY; TChar mFormatCurrent; QString mFormatSequenceRest; bool mHighColorModeBackground; bool mHighColorModeForeground; QWidget * mpBaseVFrame; QWidget * mpTopToolBar; QWidget * mpBaseHFrame; QWidget * mpLeftToolBar; QWidget * mpMainFrame; QWidget * mpRightToolBar; QWidget * mpMainDisplay; dlgMapper * mpMapper; dlgNotepad * mpNotePad; QScrollBar * mpScrollBar; QTime mProcessingTime; bool mRecordReplay; QFile mReplayFile; QDataStream mReplayStream; TChar mStandardFormat; QList mSubConsoleList; std::map mSubConsoleMap; QColor mSystemMessageBgColor; QColor mSystemMessageFgColor; bool mTriggerEngineMode; bool mUserConsole; QPoint mUserCursor; bool mWaitingForHighColorCode; bool mWindowIsHidden; int mWrapAt; QLineEdit * networkLatency; QPoint P_begin; QPoint P_end; QString profile_name; TSplitter * splitter; int mLastBufferLogLine; bool mIsPromptLine; QToolButton * logButton; bool mUserAgreedToCloseConsole; QLineEdit * mpBufferSearchBox; QToolButton * mpBufferSearchUp; QToolButton * mpBufferSearchDown; int mCurrentSearchResult; QList mSearchResults; QString mSearchQuery; signals: public slots: void slot_searchBufferUp(); void slot_searchBufferDown(); void slot_toggleReplayRecording(); void slot_stop_all_triggers( bool ); void slot_toggleLogging(); }; #endif mudlet-2.1/src/mudlet.cpp0000644000175000017500000022540612076170616014762 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn (KoehnHeiko@googlemail.com) * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "mudlet.h" #include "TConsole.h" #include #include #include #include #include #include "ctelnet.h" #include "dlgConnectionProfiles.h" #include "dlgTriggerEditor.h" #include "dlgPackageExporter.h" #include "dlgAboutDialog.h" #include "TCommandLine.h" #include "EAction.h" #include "dlgProfilePreferences.h" #include "TDebug.h" #include "XMLimport.h" #include "EAction.h" #include "TTextEdit.h" #include "dlgNotepad.h" //#ifdef Q_CC_GNU #include "dlgIRC.h" //#endif //#define NDEBUG #include using namespace std; bool TConsoleMonitor::eventFilter(QObject *obj, QEvent *event) { if( event->type() == QEvent::Close ) { mudlet::debugMode = false; return QObject::eventFilter(obj,event); } else { return QObject::eventFilter(obj, event); } } TConsole * mudlet::mpDebugConsole = 0; QMainWindow * mudlet::mpDebugArea = 0; bool mudlet::debugMode = false; mudlet * mudlet::_self = 0; mudlet * mudlet::self() { if( ! _self ) { _self = new mudlet; } return _self; } mudlet::mudlet() : QMainWindow() , mShowMenuBar( false ) , mShowToolbar( true ) , mWindowMinimized( false ) , mReplaySpeed( 1 ) , mIsGoingDown( false ) , mpCurrentActiveHost( 0 ) , actionReplaySpeedDown( 0 ) , actionReplaySpeedUp( 0 ) , mpIRC( 0 ) , mpMusicBox1(Phonon::createPlayer(Phonon::MusicCategory) ) , mpMusicBox2(Phonon::createPlayer(Phonon::MusicCategory) ) , mpMusicBox3(Phonon::createPlayer(Phonon::MusicCategory) ) , mpMusicBox4(Phonon::createPlayer(Phonon::MusicCategory) ) #ifdef Q_OS_LINUX , version( "Mudlet 2.1" ) #endif #ifdef Q_OS_MAC , version( "Mudlet 2.1" ) #endif #ifdef Q_OS_WIN , version( "Mudlet 2.1" ) #endif { setupUi(this); setUnifiedTitleAndToolBarOnMac( true ); setContentsMargins(0,0,0,0); mudlet::debugMode = false; setAttribute( Qt::WA_DeleteOnClose ); QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding); setWindowTitle(version); setWindowIcon(QIcon(":/icons/mudlet_main_16px.png")); mpMainToolBar = new QToolBar( this ); addToolBar( mpMainToolBar ); //restoreBar = menuBar()->addMenu( "" ); mpMainToolBar->setMovable( false ); addToolBarBreak(); QWidget * frame = new QWidget( this ); frame->setFocusPolicy( Qt::NoFocus ); setCentralWidget( frame ); mpTabBar = new QTabBar( frame ); mpTabBar->setMaximumHeight(30); mpTabBar->setFocusPolicy( Qt::NoFocus ); #if QT_VERSION >= 0x040500 mpTabBar->setTabsClosable ( true ); connect( mpTabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(slot_close_profile_requested(int))); #endif connect( mpTabBar, SIGNAL(currentChanged(int)), this, SLOT(slot_tab_changed(int))); QVBoxLayout * layoutTopLevel = new QVBoxLayout(frame); layoutTopLevel->setContentsMargins(0,0,0,0); layoutTopLevel->setContentsMargins(0,0,0,0); layoutTopLevel->addWidget( mpTabBar ); mainPane = new QWidget( frame ); QPalette mainPalette; //mainPalette.setColor( QPalette::Text, QColor(100,255,100) ); //mainPalette.setColor( QPalette::Highlight, QColor(55,55,255) ); //mainPalette.setColor( QPalette::Window, QColor(250,150,0,50) ); mainPane->setPalette( mainPalette ); mainPane->setAutoFillBackground(true); mainPane->setFocusPolicy( Qt::NoFocus ); layoutTopLevel->addWidget( mainPane ); QHBoxLayout * layout = new QHBoxLayout( mainPane ); layout->setContentsMargins(0,0,0,0); layout->setContentsMargins(0,0,0,0); //layout->addWidget(mainPane); mainPane->setContentsMargins(0,0,0,0); mainPane->setSizePolicy( sizePolicy ); mainPane->setFocusPolicy( Qt::NoFocus ); QFile file_autolog( QDir::homePath()+"/.config/mudlet/autolog" ); if( file_autolog.exists() ) { mAutolog = true; } else { mAutolog = false; } QFile file_use_smallscreen( QDir::homePath()+"/.config/mudlet/mudlet_option_use_smallscreen" ); if( file_use_smallscreen.exists() ) { mpMainToolBar->setIconSize(QSize(16,16)); } else { mpMainToolBar->setIconSize(QSize(32,32)); mpMainToolBar->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); } //restoreBar = new QMenu( this ); QAction * actionConnect = new QAction(QIcon(":/icons/preferences-web-browser-cache.png"), tr("Connect"), this); actionConnect->setStatusTip(tr("Connect To Server")); mpMainToolBar->addAction( actionConnect ); QAction * actionTriggers = new QAction(QIcon(":/icons/tools-wizard.png"), tr("Triggers"), this); actionTriggers->setStatusTip(tr("Show Triggers")); mpMainToolBar->addAction( actionTriggers ); QAction * actionAlias = new QAction(QIcon(":/icons/system-users.png"), tr("Aliases"), this); actionAlias->setStatusTip(tr("Show Aliases")); actionAlias->setEnabled( true ); mpMainToolBar->addAction( actionAlias ); QAction * actionTimers = new QAction(QIcon(":/icons/chronometer.png"), tr("Timers"), this); actionTimers->setStatusTip(tr("Show Timers")); mpMainToolBar->addAction( actionTimers ); QAction * actionButtons = new QAction(QIcon(":/icons/bookmarks.png"), tr("Buttons"), this); actionButtons->setStatusTip(tr("Show Easy Buttons")); mpMainToolBar->addAction( actionButtons ); QAction * actionScripts = new QAction(QIcon(":/icons/document-properties.png"), tr("Scripts"), this); actionScripts->setEnabled( true ); actionScripts->setStatusTip(tr("Show Scripts")); mpMainToolBar->addAction( actionScripts ); QAction * actionKeys = new QAction(QIcon(":/icons/preferences-desktop-keyboard.png"), tr("Keys"), this); actionKeys->setStatusTip(tr("Options")); actionKeys->setEnabled( true ); mpMainToolBar->addAction( actionKeys ); QAction * actionIRC = new QAction(QIcon(":/icons/internet-telephony.png"), tr("Help Chat"), this); actionIRC->setStatusTip(tr("help chat on IRC")); mpMainToolBar->addAction( actionIRC ); QAction * actionMapper = new QAction(QIcon(":/icons/applications-internet.png"), tr("Map"), this); actionMapper->setStatusTip(tr("show map")); mpMainToolBar->addAction( actionMapper ); QAction * actionHelp = new QAction(QIcon(":/icons/help-hint.png"), tr("Manual"), this); actionHelp->setStatusTip(tr("Browse Reference Material and Documentation")); mpMainToolBar->addAction( actionHelp ); QAction * actionOptions = new QAction(QIcon(":/icons/configure.png"), tr("Settings"), this); actionOptions->setStatusTip(tr("Settings, Options and Preferences")); mpMainToolBar->addAction( actionOptions ); QAction * actionNotes = new QAction(QIcon(":/icons/applications-accessories.png"), tr("Notepad"), this); actionNotes->setStatusTip(tr("take notes")); mpMainToolBar->addAction( actionNotes ); QAction * actionPackageM = new QAction(QIcon(":/icons/utilities-file-archiver.png"), tr("Package Manager"), this); actionPackageM->setStatusTip(tr("Package Manager")); mpMainToolBar->addAction( actionPackageM ); // QAction * menuActionPackageM = new QAction("Package Manager", this); // menuActionPackageM->setStatusTip(tr("Package Manager")); // connect(menuActionPackageM, SIGNAL(triggered()), this, SLOT(slot_package_manager())); // QMenu * _miscMenu = new QMenu("Misc", this); // _miscMenu->addAction(menuActionPackageM); // menuBar()->addMenu(_miscMenu); QAction * actionReplay = new QAction(QIcon(":/icons/media-optical.png"), tr("Replay"), this); actionNotes->setStatusTip(tr("load replay")); mpMainToolBar->addAction( actionReplay ); actionReconnect = new QAction(QIcon(":/icons/system-restart.png"), tr("Reconnect"), this); actionNotes->setStatusTip(tr("reconnect")); mpMainToolBar->addAction( actionReconnect ); QAction * actionMultiView = new QAction(QIcon(":/icons/view-split-left-right.png"), tr("MultiView"), this); actionMultiView->setStatusTip(tr("MultiView")); mpMainToolBar->addAction( actionMultiView ); QAction * actionStopAllTriggers = new QAction(QIcon(":/icons/edit-bomb.png"), tr("Stop All Triggers"), this); actionStopAllTriggers->setStatusTip(tr("stop all triggers, alias, actions, timers and scripts")); //mpMainToolBar->addAction( actionStopAllTriggers ); /* QAction * actionProfileBackup = new QAction(QIcon(":/icons/utilities-file-archiver.png"), tr("Backup Profile"), this); actionProfileBackup->setStatusTip(tr("Backup Profile")); mpMainToolBar->addAction( actionProfileBackup );*/ QAction * actionAbout = new QAction(QIcon(":/icons/mudlet_main_32px.png"), tr("About"), this); actionAbout->setStatusTip(tr("About")); mpMainToolBar->addAction( actionAbout ); QAction * actionCloseProfile = new QAction(QIcon(":/icons/window-close.png"), tr("Close"), this); actionScripts->setEnabled( true ); actionScripts->setStatusTip(tr("close connection")); //mpMainToolBar->addAction( actionCloseProfile ); disableToolbarButtons(); mpDebugArea = new QMainWindow(0); HostManager::self()->addHost("default_host", "", "","" ); mpDefaultHost = HostManager::self()->getHost(QString("default_host")); mpDebugConsole = new TConsole( mpDefaultHost, true ); mpDebugConsole->setWindowTitle("Central Debug Console"); mpDebugConsole->setSizePolicy( sizePolicy ); mpDebugConsole->setWrapAt(100); mpDebugArea->setCentralWidget( mpDebugConsole ); TConsoleMonitor * consoleCloser = new TConsoleMonitor; mpDebugArea->installEventFilter(consoleCloser); QSize generalRule( qApp->desktop()->size() ); generalRule -= QSize( 30, 30 ); mpDebugArea->resize( QSize( 800, 600 ).boundedTo( generalRule ) ); mpDebugArea->hide(); QFont mainFont; if( file_use_smallscreen.exists() ) { mainFont = QFont("Bitstream Vera Sans Mono", 8, QFont::Courier); showFullScreen(); QAction * actionFullScreeniew = new QAction(QIcon(":/icons/dialog-cancel.png"), tr("Toggle Full Screen View"), this); actionFullScreeniew->setStatusTip(tr("Toggle Full Screen View")); mpMainToolBar->addAction( actionFullScreeniew ); connect(actionFullScreeniew, SIGNAL(triggered()), this, SLOT(toggleFullScreenView())); } else { mainFont = QFont("Bitstream Vera Sans Mono", 8, QFont::Courier); } QFont mdiFont = QFont("Bitstream Vera Sans Mono", 6, QFont::Courier); setFont( mainFont ); mainPane->setFont( mainFont ); mpTabBar->setFont( mdiFont ); QIcon noIcon; mainPane->show(); connect(actionConnect, SIGNAL(triggered()), this, SLOT(connectToServer())); connect(actionHelp, SIGNAL(triggered()), this, SLOT(show_help_dialog())); connect(actionTriggers, SIGNAL(triggered()), this, SLOT(show_trigger_dialog())); connect(actionTimers, SIGNAL(triggered()), this, SLOT(show_timer_dialog())); connect(actionAlias, SIGNAL(triggered()), this, SLOT(show_alias_dialog())); connect(actionScripts, SIGNAL(triggered()), this, SLOT(show_script_dialog())); connect(actionKeys, SIGNAL(triggered()),this,SLOT(show_key_dialog())); connect(actionButtons, SIGNAL(triggered()), this, SLOT(show_action_dialog())); connect(actionOptions, SIGNAL(triggered()), this, SLOT(show_options_dialog())); connect(actionAbout, SIGNAL(triggered()), this, SLOT(slot_show_about_dialog())); connect(actionMultiView, SIGNAL(triggered()), this, SLOT(slot_multi_view())); connect(actionCloseProfile, SIGNAL(triggered()), this, SLOT(slot_close_profile())); connect(actionReconnect, SIGNAL(triggered()), this, SLOT(slot_reconnect())); connect(actionReplay, SIGNAL(triggered()), this, SLOT(slot_replay())); connect(actionNotes, SIGNAL(triggered()), this, SLOT(slot_notes())); connect(actionMapper, SIGNAL(triggered()), this, SLOT(slot_mapper())); connect(actionIRC, SIGNAL(triggered()), this, SLOT(slot_irc())); connect(actionPackageM, SIGNAL(triggered()), this, SLOT(slot_package_manager())); QAction * mactionConnect = new QAction(tr("Connect"), this); QAction * mactionTriggers = new QAction(tr("Triggers"), this); QAction * mactionAlias = new QAction(tr("Aliases"), this); QAction * mactionTimers = new QAction(tr("Timers"), this); QAction * mactionButtons = new QAction(tr("Actions"), this); QAction * mactionScripts = new QAction(tr("Scripts"), this); QAction * mactionKeys = new QAction(tr("Keys"), this); QAction * mactionMapper = new QAction(tr("Map"), this); QAction * mactionHelp = new QAction(tr("Help"), this); QAction * mactionOptions = new QAction(tr("Preferences"), this); QAction * mactionMultiView = new QAction(tr("MultiView"), this); QAction * mactionAbout = new QAction(tr("About"), this); QAction * mactionCloseProfile = new QAction(tr("Close"), this); connect(mactionConnect, SIGNAL(triggered()), this, SLOT(connectToServer())); connect(dactionConnect, SIGNAL(triggered()), this, SLOT(connectToServer())); connect(dactionReconnect, SIGNAL(triggered()), this, SLOT(slot_reconnect())); connect(dactionDisconnect, SIGNAL(triggered()), this, SLOT(slot_disconnect())); connect(dactionNotepad, SIGNAL(triggered()), this, SLOT(slot_notes())); connect(dactionReplay, SIGNAL(triggered()), this, SLOT(slot_replay())); connect(mactionHelp, SIGNAL(triggered()), this, SLOT(show_help_dialog())); connect(dactionHelp, SIGNAL(triggered()), this, SLOT(show_help_dialog())); connect(dactionVideo, SIGNAL(triggered()), this, SLOT(slot_show_help_dialog_video())); connect(dactionForum, SIGNAL(triggered()), this, SLOT(slot_show_help_dialog_forum())); connect(dactionIRC, SIGNAL(triggered()), this, SLOT(slot_irc())); connect(actionLive_Help_Chat, SIGNAL(triggered()), this, SLOT(slot_irc())); connect(actionShow_Map, SIGNAL(triggered()), this, SLOT(slot_mapper())); connect(dactionDownload, SIGNAL(triggered()), this, SLOT(slot_show_help_dialog_download())); connect(actionPackage_manager, SIGNAL(triggered()), this, SLOT(slot_package_manager())); connect(actionPackage_Exporter, SIGNAL(triggered()), this, SLOT(slot_package_exporter())); connect(actionModule_manager, SIGNAL(triggered()), this, SLOT(slot_module_manager())); connect(dactionMultiView, SIGNAL(triggered()), this, SLOT(slot_multi_view())); connect(mactionTriggers, SIGNAL(triggered()), this, SLOT(show_trigger_dialog())); connect(dactionScriptEditor, SIGNAL(triggered()), this, SLOT(show_trigger_dialog())); connect(mactionMapper, SIGNAL(triggered()), this, SLOT(slot_mapper())); connect(mactionTimers, SIGNAL(triggered()), this, SLOT(show_timer_dialog())); connect(mactionAlias, SIGNAL(triggered()), this, SLOT(show_alias_dialog())); connect(mactionScripts, SIGNAL(triggered()), this, SLOT(show_script_dialog())); connect(mactionKeys, SIGNAL(triggered()),this,SLOT(show_key_dialog())); connect(mactionButtons, SIGNAL(triggered()), this, SLOT(show_action_dialog())); connect(mactionOptions, SIGNAL(triggered()), this, SLOT(show_options_dialog())); connect(dactionOptions, SIGNAL(triggered()), this, SLOT(show_options_dialog())); connect(mactionAbout, SIGNAL(triggered()), this, SLOT(slot_show_about_dialog())); connect(dactionAbout, SIGNAL(triggered()), this, SLOT(slot_show_about_dialog())); connect(mactionMultiView, SIGNAL(triggered()), this, SLOT(slot_multi_view())); connect(mactionCloseProfile, SIGNAL(triggered()), this, SLOT(slot_close_profile())); /* QMenu * menu; menuBar()->addAction(mactionConnect); menuBar()->addAction(mactionTriggers); menuBar()->addAction(mactionTimers); menuBar()->addAction(mactionAlias); menuBar()->addAction(mactionScripts); menuBar()->addAction(mactionKeys); menuBar()->addAction(mactionButtons); menuBar()->addAction(mactionOptions); menuBar()->addAction(mactionAbout); menuBar()->addAction(mactionHelp);*/ readSettings(); QTimer * timerAutologin = new QTimer( this ); timerAutologin->setSingleShot( true ); connect(timerAutologin, SIGNAL(timeout()), this, SLOT(startAutoLogin())); timerAutologin->start( 1000 ); //qApp->setStyleSheet("QMainWindow::separator{border: 0px;width: 0px; height: 0px; padding: 0px;} QMainWindow::separator:hover {background: red;}"); } void mudlet::layoutModules(){ Host * pH = getActiveHost(); QMapIterator it (pH->mInstalledModules); QStringList sl; // The following seems like a non-intuitive operator // overload but that is how they do it... sl << "Module Name" << "Priority" << "Save & Sync?" << "Module Location"; moduleTable->setHorizontalHeaderLabels(sl); moduleTable->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); moduleTable->verticalHeader()->hide(); moduleTable->setShowGrid(true); //order modules by priority and then alphabetically QMap mOrder; while( it.hasNext() ){ it.next(); int priority = pH->mModulePriorities[it.key()]; if (mOrder.contains(priority)) mOrder[priority].append(it.key()); else mOrder[priority] = QStringList(it.key()); } QMapIterator it2 (mOrder); while(it2.hasNext()){ it2.next(); QStringList pModules = it2.value(); pModules.sort(); for(int i=0;irowCount(); moduleTable->insertRow(row); QTableWidgetItem *masterModule = new QTableWidgetItem (); QTableWidgetItem *itemEntry = new QTableWidgetItem (); QTableWidgetItem *itemLocation = new QTableWidgetItem (); QTableWidgetItem *itemPriority = new QTableWidgetItem (); masterModule->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable); QStringList moduleInfo = pH->mInstalledModules[pModules[i]]; if (moduleInfo[1].toInt()){ masterModule->setCheckState(Qt::Checked);//Qt::Checked); masterModule->setText("sync"); } else{ masterModule->setCheckState(Qt::Unchecked);//Qt::Checked); masterModule->setText("don't sync"); } masterModule->setToolTip(QString("Checking this box will cause the module to be saved & resync'd across all open sessions.")); if (moduleInfo[0].endsWith(".zip") || moduleInfo[0].endsWith(".mpackage")){ masterModule->setCheckState(Qt::Unchecked); masterModule->setFlags(Qt::NoItemFlags); masterModule->setText("don't sync"); moduleInfo[1] = "0"; masterModule->setToolTip(QString("mpackage and zip packages are currently unabled to be synced across packages.")); } QString moduleName = pModules[i]; itemEntry->setText(moduleName); itemEntry->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); itemLocation->setText(moduleInfo[0]); //itemPriority->setText(QString::number(pH->mModulePriorities[moduleName])); //moduleTable->setItem(row, 0, masterModule); itemLocation->setToolTip(moduleInfo[0]); // show the full path in a tooltip, in case it doesn't fit in the table itemLocation->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); // disallow editing of module path, because that is not saved itemPriority->setData(Qt::EditRole, pH->mModulePriorities[moduleName]); moduleTable->setItem(row, 0, itemEntry); moduleTable->setItem(row, 1, itemPriority); moduleTable->setItem(row, 2, masterModule); moduleTable->setItem(row, 3, itemLocation); } } moduleTable->resizeColumnsToContents(); //moduleTable->sortItems(1, Qt::AscendingOrder); } void mudlet::slot_module_manager(){ Host * pH = getActiveHost(); if( ! pH ) return; QUiLoader loader; QFile file(":/ui/module_manager.ui"); file.open(QFile::ReadOnly); QDialog * d = dynamic_cast(loader.load(&file, this)); file.close(); if( ! d ) return; moduleTable = d->findChild("moduleTable"); moduleUninstallButton = d->findChild("uninstallButton"); moduleInstallButton = d->findChild("installButton"); moduleHelpButton = d->findChild("helpButton"); if( !moduleTable || !moduleUninstallButton || !moduleHelpButton) return; layoutModules(); connect(moduleUninstallButton, SIGNAL(clicked()), this, SLOT(slot_uninstall_module())); connect(moduleInstallButton, SIGNAL(clicked()), this, SLOT(slot_install_module())); connect(moduleHelpButton, SIGNAL(clicked()), this, SLOT(slot_help_module())); connect(moduleTable, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(slot_module_clicked(QTableWidgetItem*))); connect(moduleTable, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(slot_module_changed(QTableWidgetItem*))); d->setWindowTitle("Module Manager"); d->show(); d->raise(); } bool mudlet::openWebPage(QString path){ if (path.isEmpty() || path.isNull()) return false; QUrl url(path,QUrl::TolerantMode); if (!url.isValid()) return false; return QDesktopServices::openUrl(url); } void mudlet::slot_help_module(){ Host * pH = getActiveHost(); if (!pH) return; int cRow = moduleTable->currentRow(); QTableWidgetItem * pI = moduleTable->item(cRow, 0); if (!pI) return; if (pH->moduleHelp[pI->text()].contains("helpURL") && !pH->moduleHelp[pI->text()]["helpURL"].isEmpty()){ if (!openWebPage(pH->moduleHelp[pI->text()]["helpURL"])){ //failed first open, try for a module related path QTableWidgetItem * item = moduleTable->item(cRow,3); QString itemPath = item->text(); QStringList path = itemPath.split(QDir::separator()); path.pop_back(); path.append(QDir::separator()); path.append(pH->moduleHelp[pI->text()]["helpURL"]); QString path2 = path.join(""); if (!openWebPage(path2)) moduleHelpButton->setDisabled(true); } } } void mudlet::slot_module_clicked(QTableWidgetItem* pItem){ int i = pItem->row(); Host * pH = getActiveHost(); QTableWidgetItem * entry = moduleTable->item(i,0); QTableWidgetItem * checkStatus = moduleTable->item(i,2); QTableWidgetItem * itemPriority = moduleTable->item(i,1); QTableWidgetItem * itemPath = moduleTable->item(i,3); qDebug()<text(); if (!entry || !checkStatus || !itemPriority || !pH->mInstalledModules.contains(entry->text())){ moduleHelpButton->setDisabled(true); checkStatus->setCheckState(Qt::Unchecked); checkStatus->setFlags(Qt::NoItemFlags); return; } if (pH->moduleHelp.contains(entry->text())) moduleHelpButton->setDisabled((!pH->moduleHelp[entry->text()].contains("helpURL") || pH->moduleHelp[entry->text()]["helpURL"].isEmpty())); else moduleHelpButton->setDisabled(true); if (itemPath->text().endsWith(".zip") || itemPath->text().endsWith(".mpackage")){ checkStatus->setCheckState(Qt::Unchecked); checkStatus->setFlags(Qt::NoItemFlags); checkStatus->setText("don't sync"); } } void mudlet::slot_module_changed(QTableWidgetItem* pItem){ int i = pItem->row(); Host * pH = getActiveHost(); QStringList moduleStringList; QTableWidgetItem * entry = moduleTable->item(i,0); QTableWidgetItem * checkStatus = moduleTable->item(i,2); QTableWidgetItem * itemPriority = moduleTable->item(i,1); if (!entry || !checkStatus || !itemPriority || !pH->mInstalledModules.contains(entry->text())) return; moduleStringList = pH->mInstalledModules[entry->text()]; if (checkStatus->checkState() == Qt::Unchecked){ moduleStringList[1] = "0"; checkStatus->setText("don't sync"); } if (checkStatus->checkState() == Qt::Checked){ moduleStringList[1] = "1"; checkStatus->setText("sync"); } pH->mInstalledModules[entry->text()] = moduleStringList; pH->mModulePriorities[entry->text()] = itemPriority->text().toInt(); } void mudlet::slot_install_module() { QString fileName = QFileDialog::getOpenFileName(this, tr("Load Mudlet Module"), QDir::currentPath()); if( fileName.isEmpty() ) return; QFile file(fileName); if( ! file.open(QFile::ReadOnly | QFile::Text) ) { QMessageBox::warning(this, tr("Load Mudlet Module:"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } Host * pH = getActiveHost(); if( ! pH ) return; pH->installPackage( fileName, 1); //moduleTable->clearContents(); for (int i=moduleTable->rowCount()-1; i >= 0; --i) moduleTable->removeRow(i); layoutModules(); } void mudlet::slot_uninstall_module() { Host * pH = getActiveHost(); if( ! pH ) return; int cRow = moduleTable->currentRow(); QTableWidgetItem * pI = moduleTable->item(cRow, 0); if( pI ) pH->uninstallPackage( pI->text(), 1); for (int i=moduleTable->rowCount()-1; i >= 0; --i) moduleTable->removeRow(i); layoutModules(); } void mudlet::slot_package_manager() { Host * pH = getActiveHost(); if( ! pH ) return; QUiLoader loader; QFile file(":/ui/package_manager.ui"); file.open(QFile::ReadOnly); QDialog * d = dynamic_cast(loader.load(&file, this)); file.close(); if( ! d ) return; packageList = d->findChild("packageList"); uninstallButton = d->findChild("uninstallButton"); installButton = d->findChild("installButton"); if( ! packageList || ! uninstallButton ) return; packageList->addItems( pH->mInstalledPackages ); connect(uninstallButton, SIGNAL(clicked()), this, SLOT(slot_uninstall_package())); connect(installButton, SIGNAL(clicked()), this, SLOT(slot_install_package())); d->setWindowTitle("Package Manager"); d->show(); d->raise(); } void mudlet::slot_install_package() { QString fileName = QFileDialog::getOpenFileName(this, tr("Import Mudlet Package"), QDir::currentPath()); if( fileName.isEmpty() ) return; QFile file(fileName); if( ! file.open(QFile::ReadOnly | QFile::Text) ) { QMessageBox::warning(this, tr("Import Mudlet Package:"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } Host * pH = getActiveHost(); if( ! pH ) return; pH->installPackage( fileName, 0); packageList->clear(); packageList->addItems( pH->mInstalledPackages ); } void mudlet::showUnzipProgress( QString txt ) { Host * pH = getActiveHost(); if( ! pH ) return; pH->showUnpackingProgress( txt ); } void mudlet::slot_uninstall_package() { Host * pH = getActiveHost(); if( ! pH ) return; QListWidgetItem * pI = packageList->currentItem(); if( pI ) pH->uninstallPackage( pI->text(), 0); packageList->clear(); packageList->addItems( pH->mInstalledPackages ); } void mudlet::slot_package_exporter(){ Host * pH = getActiveHost(); if( ! pH ) return; dlgPackageExporter *d = new dlgPackageExporter(this, pH); d->show(); } void mudlet::slot_close_profile_requested( int tab ) { QString name = mpTabBar->tabText( tab ); Host * pH = HostManager::self()->getHost( name ); if( ! pH ) return; if( ! pH->mpConsole->close() ) return; else pH->mpConsole->mUserAgreedToCloseConsole = true; pH->stopAllTriggers(); pH->mpEditorDialog->close(); mConsoleMap[pH]->close(); if( mTabMap.contains( pH->getName() ) ) { mpTabBar->removeTab( tab ); mConsoleMap.remove( pH ); HostManager::self()->deleteHost( pH->getName() ); mTabMap.remove( pH->getName() ); } // hide the tab bar if we only have 1 or no tabs available. saves screen space. if( mConsoleMap.size() > 1 ) { mpTabBar->show(); } else mpTabBar->hide(); } void mudlet::slot_close_profile() { if( mpCurrentActiveHost ) { if( mConsoleMap.contains( mpCurrentActiveHost ) ) { QString name = mpCurrentActiveHost->getName(); Host * pH = mpCurrentActiveHost; mpCurrentActiveHost->mpEditorDialog->close(); mConsoleMap[mpCurrentActiveHost]->close(); if( mTabMap.contains( pH->getName() ) ) { mpTabBar->removeTab( mpTabBar->currentIndex() ); mConsoleMap.remove( pH ); HostManager::self()->deleteHost( pH->getName() ); mTabMap.remove( pH->getName() ); } if( !mpCurrentActiveHost ) disableToolbarButtons(); } } } void mudlet::slot_tab_changed( int tabID ) { if( ( ! mTabMap.contains( mpTabBar->tabText( tabID ) ) ) && ( tabID != -1 ) ) { mpCurrentActiveHost = 0; return; } if( mConsoleMap.contains( mpCurrentActiveHost ) ) { mpCurrentActiveHost->mpConsole->hide(); QString host = mpTabBar->tabText( tabID ); if( mTabMap.contains( host ) ) { mpCurrentActiveHost = mTabMap[host]->mpHost; } else { mpCurrentActiveHost = 0; return; } } else { if( mTabMap.size() > 0 ) { mpCurrentActiveHost = mTabMap.begin().value()->mpHost; } else { mpCurrentActiveHost = 0; return; } } if( ! mpCurrentActiveHost || mConsoleMap.contains( mpCurrentActiveHost ) ) { if( ! mpCurrentActiveHost ) return; mpCurrentActiveHost->mpConsole->show(); mpCurrentActiveHost->mpConsole->repaint(); mpCurrentActiveHost->mpConsole->refresh(); mpCurrentActiveHost->mpConsole->mpCommandLine->repaint(); mpCurrentActiveHost->mpConsole->mpCommandLine->setFocus(); mpCurrentActiveHost->mpConsole->show(); int x = mpCurrentActiveHost->mpConsole->width(); int y = mpCurrentActiveHost->mpConsole->height(); QSize s = QSize(x,y); QResizeEvent event(s, s); QApplication::sendEvent( mpCurrentActiveHost->mpConsole, &event); } else { mpCurrentActiveHost = 0; return; } // update the window title for the currently selected profile setWindowTitle(mpCurrentActiveHost->getName() + " - " + version); } void mudlet::addConsoleForNewHost( Host * pH ) { if( mConsoleMap.contains( pH ) ) return; pH->mLogStatus = mAutolog; TConsole * pConsole = new TConsole( pH, false ); if( ! pConsole ) return; pH->mpConsole = pConsole; pConsole->setWindowTitle( pH->getName() ); mConsoleMap[pH] = pConsole; int newTabID = mpTabBar->addTab( pH->getName() ); mTabMap[pH->getName()] = pConsole; if( mConsoleMap.size() > 1 ) { mpTabBar->show(); } else mpTabBar->hide(); //update the main window title when we spawn a new tab setWindowTitle(pH->getName() + " - " + version); mainPane->layout()->addWidget( pConsole ); if( mpCurrentActiveHost ) mpCurrentActiveHost->mpConsole->hide(); mpCurrentActiveHost = pH; if( pH->mLogStatus ) pConsole->logButton->click(); pConsole->show(); connect( pConsole->emergencyStop, SIGNAL(pressed()), this , SLOT(slot_stopAllTriggers())); dlgTriggerEditor * pEditor = new dlgTriggerEditor( pH ); pH->mpEditorDialog = pEditor; pEditor->fillout_form(); pH->getActionUnit()->updateToolbar(); QMap miniConsoleMap; mHostConsoleMap[mpCurrentActiveHost] = miniConsoleMap; QMap labelMap; mHostLabelMap[mpCurrentActiveHost] = labelMap; mpCurrentActiveHost->mpConsole->show(); mpCurrentActiveHost->mpConsole->repaint(); mpCurrentActiveHost->mpConsole->refresh(); mpCurrentActiveHost->mpConsole->mpCommandLine->repaint(); mpCurrentActiveHost->mpConsole->mpCommandLine->setFocus(); mpCurrentActiveHost->mpConsole->show(); mpTabBar->setCurrentIndex( newTabID ); int x = mpCurrentActiveHost->mpConsole->width(); int y = mpCurrentActiveHost->mpConsole->height(); QSize s = QSize(x,y); QResizeEvent event(s, s); QApplication::sendEvent( mpCurrentActiveHost->mpConsole, &event); } void mudlet::slot_timer_fires() { QTimer * pQT = (QTimer*)sender(); if( ! pQT ) return; if( mTimerMap.contains( pQT ) ) { TTimer * pTT = mTimerMap[pQT]; pTT->execute(); if( pTT->checkRestart() ) { pTT->start(); } } else { qDebug()<<"MUDLET CRITICAL ERROR: Timer not registered!"; } } void mudlet::unregisterTimer( QTimer * pQT ) { //qDebug()<<"removing QTIMER"< AFTER size="<actions()[1]->setEnabled( false ); mpMainToolBar->actions()[2]->setEnabled( false ); mpMainToolBar->actions()[3]->setEnabled( false ); mpMainToolBar->actions()[4]->setEnabled( false ); mpMainToolBar->actions()[5]->setEnabled( false ); mpMainToolBar->actions()[6]->setEnabled( false ); mpMainToolBar->actions()[8]->setEnabled( false ); mpMainToolBar->actions()[9]->setEnabled( false ); mpMainToolBar->actions()[10]->setEnabled( false ); mpMainToolBar->actions()[11]->setEnabled( false ); mpMainToolBar->actions()[12]->setEnabled( false ); } void mudlet::enableToolbarButtons() { mpMainToolBar->actions()[1]->setEnabled( true ); mpMainToolBar->actions()[2]->setEnabled( true ); mpMainToolBar->actions()[3]->setEnabled( true ); mpMainToolBar->actions()[4]->setEnabled( true ); mpMainToolBar->actions()[5]->setEnabled( true ); mpMainToolBar->actions()[6]->setEnabled( true ); mpMainToolBar->actions()[8]->setEnabled( true ); mpMainToolBar->actions()[9]->setEnabled( true ); mpMainToolBar->actions()[10]->setEnabled( true ); mpMainToolBar->actions()[11]->setEnabled( true ); mpMainToolBar->actions()[12]->setEnabled( true ); } bool mudlet::openWindow( Host * pHost, QString & name ) { if( ! dockWindowMap.contains( name ) ) { QDockWidget * pD = new QDockWidget; pD->setContentsMargins(0,0,0,0); pD->setFeatures( QDockWidget::AllDockWidgetFeatures ); pD->setWindowTitle( name ); dockWindowMap[name] = pD; TConsole * pC = new TConsole( pHost, false ); pC->setContentsMargins(0,0,0,0); pD->setWidget( pC ); pC->show(); pC->layerCommandLine->hide(); pC->mpScrollBar->hide(); pC->setUserWindow(); QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; dockWindowConsoleMap[name] = pC; addDockWidget(Qt::RightDockWidgetArea, pD); return true; } else return false; } bool mudlet::createMiniConsole( Host * pHost, QString & name, int x, int y, int width, int height ) { if( ! pHost ) return false; if( ! pHost->mpConsole ) return false; QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( ! dockWindowConsoleMap.contains( name ) ) { TConsole * pC = pHost->mpConsole->createMiniConsole( name, x, y, width, height ); pC->mConsoleName = name; if( pC ) { dockWindowConsoleMap[name] = pC; return true; } } return false; } bool mudlet::createLabel( Host * pHost, QString & name, int x, int y, int width, int height, bool fillBg ) { if( ! pHost ) return false; if( ! pHost->mpConsole ) return false; QMap & labelMap = mHostLabelMap[pHost]; if( ! labelMap.contains( name ) ) { TLabel * pL = pHost->mpConsole->createLabel( name, x, y, width, height, fillBg ); if( pL ) { labelMap[name] = pL; return true; } } return false; } bool mudlet::createBuffer( Host * pHost, QString & name ) { if( ! pHost ) return false; if( ! pHost->mpConsole ) return false; QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( ! dockWindowConsoleMap.contains( name ) ) { TConsole * pC = pHost->mpConsole->createBuffer( name ); pC->mConsoleName = name; if( pC ) { dockWindowConsoleMap[name] = pC; return true; } } return false; } bool mudlet::setBackgroundColor( Host * pHost, QString & name, int r, int g, int b, int alpha ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->setConsoleBgColor(r,g,b); return true; } else { QMap & labelMap = mHostLabelMap[pHost]; if( labelMap.contains( name ) ) { QPalette mainPalette; mainPalette.setColor( QPalette::Window, QColor(r, g, b, alpha) ); labelMap[name]->setPalette( mainPalette ); return true; } } return false; } bool mudlet::setBackgroundImage( Host * pHost, QString & name, QString & path ) { QMap & labelMap = mHostLabelMap[pHost]; if( labelMap.contains( name ) ) { if( QDir::homePath().contains('\\') ) { path.replace('/', "\\"); } else path.replace('\\', "/"); QPixmap bgPixmap( path ); labelMap[name]->setPixmap( bgPixmap ); return true; } else return false; } bool mudlet::setTextFormat( Host * pHost, QString & name, int r1, int g1, int b1, int r2, int g2, int b2, bool bold, bool underline, bool italics ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { TConsole * pC = dockWindowConsoleMap[name]; pC->mFormatCurrent.bgR = r1; pC->mFormatCurrent.bgG = g1; pC->mFormatCurrent.bgB = b1; pC->mFormatCurrent.fgR = r2; pC->mFormatCurrent.fgG = g2; pC->mFormatCurrent.fgB = b2; pC->mFormatCurrent.bold = bold; pC->mFormatCurrent.underline = underline; pC->mFormatCurrent.italics = italics; return true; } else return false; } void mudlet::showEvent( QShowEvent * event ) { mWindowMinimized = false; QMainWindow::showEvent( event ); } void mudlet::hideEvent( QHideEvent * event ) { mWindowMinimized = true; QMainWindow::hideEvent( event ); } bool mudlet::clearWindow( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->buffer.clear(); dockWindowConsoleMap[name]->console->update(); return true; } else return false; } bool mudlet::showWindow( Host * pHost, QString & name ) { // check labels first as they are shown/hidden more often QMap & labelMap = mHostLabelMap[pHost]; if( labelMap.contains( name ) ) { labelMap[name]->show(); return true; } QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->console->show(); dockWindowConsoleMap[name]->console->forceUpdate(); return true; } return false; } bool mudlet::paste( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->paste(); return true; } else return false; } bool mudlet::hideWindow( Host * pHost, QString & name ) { // check labels first as they are shown/hidden more often QMap & labelMap = mHostLabelMap[pHost]; if( labelMap.contains( name ) ) { labelMap[name]->hide(); return true; } QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->console->hide(); dockWindowConsoleMap[name]->console->forceUpdate(); return true; } return false; } bool mudlet::resizeWindow( Host * pHost, QString & name, int x1, int y1 ) { QMap & labelMap = mHostLabelMap[pHost]; if( labelMap.contains( name ) ) { labelMap[name]->resize( x1, y1 ); return true; } QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->resize( x1, y1 ); return true; } return false; } bool mudlet::setConsoleBufferSize( Host * pHost, QString & name, int x1, int y1 ) { if( name == "main" ) { pHost->mpConsole->buffer.setBufferSize( x1, y1 ); return true; } QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { (dockWindowConsoleMap[name]->buffer).setBufferSize( x1, y1 ); return true; } else return false; } bool mudlet::resetFormat( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->reset(); return true; } else return false; } bool mudlet::moveWindow( Host * pHost, QString & name, int x1, int y1 ) { QMap & labelMap = mHostLabelMap[pHost]; if( labelMap.contains( name ) ) { labelMap[name]->move( x1, y1 ); return true; } QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->move( x1, y1 ); dockWindowConsoleMap[name]->mOldX = x1; dockWindowConsoleMap[name]->mOldY = y1; return true; } return false; } bool mudlet::closeWindow( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->console->close(); return true; } else return false; } bool mudlet::setLabelClickCallback( Host * pHost, QString & name, QString & func, TEvent * pA ) { QMap & labelMap = mHostLabelMap[pHost]; if( labelMap.contains( name ) ) { labelMap[name]->setScript( pHost, func, pA ); return true; } else return false; } bool mudlet::setLabelOnEnter( Host * pHost, QString & name, QString & func, TEvent * pA ) { QMap & labelMap = mHostLabelMap[pHost]; if( labelMap.contains( name ) ) { labelMap[name]->setEnter( pHost, func, pA ); return true; } else return false; } bool mudlet::setLabelOnLeave( Host * pHost, QString & name, QString & func, TEvent * pA ) { QMap & labelMap = mHostLabelMap[pHost]; if( labelMap.contains( name ) ) { labelMap[name]->setLeave( pHost, func, pA ); return true; } else return false; } int mudlet::getLastLineNumber( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowMap.contains( name ) ) { return dockWindowConsoleMap[name]->getLastLineNumber(); } else { TDebug(QColor(Qt::white),QColor(Qt::red))<<"ERROR: window doesnt exit\n" >> 0; } return -1; } bool mudlet::moveCursorEnd( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->moveCursorEnd(); return true; } else return false; } bool mudlet::moveCursor( Host * pHost, QString & name, int x, int y ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { return dockWindowConsoleMap[name]->moveCursor( x, y ); } else return false; } void mudlet::deleteLine( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->skipLine(); } } void mudlet::insertText( Host * pHost, QString & name, QString text ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->insertText( text ); } } void mudlet::insertLink( Host * pHost, QString & name, QString text, QStringList & func, QStringList & hint, bool customFormat ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->insertLink( text, func, hint, customFormat ); } } void mudlet::replace( Host * pHost, QString & name, QString text ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->replace( text ); } } void mudlet::setLink( Host * pHost, QString & name, QString & linkText, QStringList & linkFunction, QStringList & linkHint ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { TConsole * pC = dockWindowConsoleMap[name]; pC->setLink( linkText, linkFunction, linkHint ); } } void mudlet::setBold( Host * pHost, QString & name, bool b ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { TConsole * pC = dockWindowConsoleMap[name]; pC->setBold( b ); } } void mudlet::setItalics( Host * pHost, QString & name, bool b ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { TConsole * pC = dockWindowConsoleMap[name]; pC->setItalics( b ); } } void mudlet::setUnderline( Host * pHost, QString & name, bool b ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { TConsole * pC = dockWindowConsoleMap[name]; pC->setUnderline( b ); } } void mudlet::setFgColor( Host * pHost, QString & name, int r, int g, int b ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { TConsole * pC = dockWindowConsoleMap[name]; pC->setFgColor( r, g, b ); } } void mudlet::setBgColor( Host * pHost, QString & name, int r, int g, int b ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { TConsole * pC = dockWindowConsoleMap[name]; pC->setBgColor( r, g, b ); } } int mudlet::selectString( Host * pHost, QString & name, QString text, int num ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { TConsole * pC = dockWindowConsoleMap[name]; return pC->select( text, num ); } else return -1; } int mudlet::selectSection( Host * pHost, QString & name, int f, int t ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { TConsole * pC = dockWindowConsoleMap[name]; return pC->selectSection( f, t ); } else return -1; } void mudlet::deselect( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { TConsole * pC = dockWindowConsoleMap[name]; pC->deselect(); } } bool mudlet::setWindowWrap( Host * pHost, QString & name, int & wrap ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; QString wn = name; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[wn]->setWrapAt( wrap ); return true; } else return false; } bool mudlet::setWindowWrapIndent( Host * pHost, QString & name, int & wrap ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; QString wn = name; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[wn]->setIndentCount( wrap ); return true; } else return false; } bool mudlet::echoWindow( Host * pHost, QString & name, QString & text ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; QString t = text; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->echoUserWindow( t ); return true; } QMap & labelMap = mHostLabelMap[pHost]; if( labelMap.contains( name ) ) { labelMap[name]->setText( t ); return true; } else return false; } bool mudlet::echoLink( Host * pHost, QString & name, QString & text, QStringList & func, QStringList & hint, bool customFormat ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; QString t = text; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->echoLink( text, func, hint, customFormat ); return true; } else return false; } bool mudlet::copy( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->copy(); return true; } else return false; } bool mudlet::pasteWindow( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->pasteWindow( mConsoleMap[pHost]->mClipboard ); return true; } else return false; } bool mudlet::appendBuffer( Host * pHost, QString & name ) { QMap & dockWindowConsoleMap = mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( name ) ) { dockWindowConsoleMap[name]->appendBuffer( mConsoleMap[pHost]->mClipboard ); return true; } else return false; } void mudlet::slot_userToolBar_hovered( QAction* pA ) { QStringList sL; if( pA->menu() ) { pA->menu()->exec(); } } void mudlet::slot_userToolBar_orientation_changed( Qt::Orientation dir ) { } Host * mudlet::getActiveHost() { if( mConsoleMap.contains( mpCurrentActiveHost ) ) { return mpCurrentActiveHost; } else return 0; } void mudlet::addSubWindow( TConsole* pConsole ) { mainPane->layout()->addWidget( pConsole ); pConsole->show();//NOTE: this is important for Apple OSX otherwise the console isnt displayed } void mudlet::closeEvent(QCloseEvent *event) { foreach( TConsole * pC, mConsoleMap ) { if( ! pC->close() ) { event->ignore(); return; } else pC->mUserAgreedToCloseConsole = true; } writeSettings(); goingDown(); if( mpDebugConsole ) { mpDebugConsole->close(); } foreach( TConsole * pC, mConsoleMap ) { if( pC->mpHost->getName() != "default_host" ) { // close script-editor if( pC->mpHost->mpEditorDialog ) { pC->mpHost->mpEditorDialog->setAttribute( Qt::WA_DeleteOnClose ); pC->mpHost->mpEditorDialog->close(); } if( pC->mpHost->mpNotePad ) { //qDebug()<<"saving notepad"; pC->mpHost->mpNotePad->save(); pC->mpHost->mpNotePad->setAttribute( Qt::WA_DeleteOnClose ); pC->mpHost->mpNotePad->close(); } // close console pC->close(); } } event->accept(); qApp->quit(); } void mudlet::readSettings() { QSettings settings("Mudlet", "Mudlet 1.0"); QPoint pos = settings.value("pos", QPoint(0, 0)).toPoint(); QSize size = settings.value("size", QSize(750, 550)).toSize(); mMainIconSize = settings.value("mainiconsize",QVariant(3)).toInt(); mTEFolderIconSize = settings.value("tefoldericonsize", QVariant(3)).toInt(); mShowMenuBar = settings.value("showMenuBar",QVariant(0)).toBool(); mShowToolbar = settings.value("showToolbar",QVariant(0)).toBool(); resize( size ); move( pos ); setIcoSize( mMainIconSize ); if( mShowMenuBar ) MenuBar->show(); else MenuBar->hide(); if( mShowToolbar || ! mShowMenuBar ) { mpMainToolBar->show(); } else { if( mShowMenuBar ) { mpMainToolBar->hide(); } else mpMainToolBar->show(); } if( settings.value("maximized", false).toBool() ) { showMaximized(); } } void mudlet::setIcoSize( int s ) { mpMainToolBar->setIconSize(QSize(s*8,s*8)); if( mMainIconSize > 2 ) mpMainToolBar->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); else mpMainToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly ); if( mShowMenuBar ) menuBar()->show(); else menuBar()->hide(); } void mudlet::writeSettings() { QSettings settings("Mudlet", "Mudlet 1.0"); settings.setValue("pos", pos()); settings.setValue("size", size()); settings.setValue("mainiconsize", mMainIconSize); settings.setValue("tefoldericonsize",mTEFolderIconSize); settings.setValue("showMenuBar", mShowMenuBar ); settings.setValue("showToolbar", mShowToolbar ); settings.setValue("maximized", isMaximized()); } void mudlet::connectToServer() { dlgConnectionProfiles * pDlg = new dlgConnectionProfiles(this); connect (pDlg, SIGNAL (signal_establish_connection( QString, int )), this, SLOT (slot_connection_dlg_finnished(QString, int))); pDlg->fillout_form(); pDlg->exec(); enableToolbarButtons(); } void mudlet::show_trigger_dialog() { Host * pHost = getActiveHost(); if( ! pHost ) return; dlgTriggerEditor * pEditor = pHost->mpEditorDialog; if( ! pEditor ) return; pEditor->slot_show_triggers(); pEditor->raise(); pEditor->show(); } void mudlet::show_alias_dialog() { Host * pHost = getActiveHost(); if( ! pHost ) return; dlgTriggerEditor * pEditor = pHost->mpEditorDialog; if( ! pEditor ) return; pEditor->slot_show_aliases(); pEditor->raise(); pEditor->show(); } void mudlet::show_timer_dialog() { Host * pHost = getActiveHost(); if( ! pHost ) return; dlgTriggerEditor * pEditor = pHost->mpEditorDialog; if( ! pEditor ) return; pEditor->slot_show_timers(); pEditor->raise(); pEditor->show(); } void mudlet::show_script_dialog() { Host * pHost = getActiveHost(); if( ! pHost ) return; dlgTriggerEditor * pEditor = pHost->mpEditorDialog; if( ! pEditor ) return; pEditor->slot_show_scripts(); pEditor->raise(); pEditor->show(); } void mudlet::show_key_dialog() { Host * pHost = getActiveHost(); if( ! pHost ) return; dlgTriggerEditor * pEditor = pHost->mpEditorDialog; if( ! pEditor ) return; pEditor->slot_show_keys(); pEditor->raise(); pEditor->show(); } void mudlet::show_action_dialog() { Host * pHost = getActiveHost(); if( ! pHost ) return; dlgTriggerEditor * pEditor = pHost->mpEditorDialog; if( ! pEditor ) return; pEditor->slot_show_actions(); pEditor->raise(); pEditor->show(); } void mudlet::show_options_dialog() { Host * pHost = getActiveHost(); if( ! pHost ) return; dlgProfilePreferences * pDlg = new dlgProfilePreferences( this, pHost ); connect(actionReconnect, SIGNAL(triggered()), pDlg->need_reconnect_for_gmcp, SLOT(hide())); connect(dactionReconnect, SIGNAL(triggered()), pDlg->need_reconnect_for_gmcp, SLOT(hide())); connect(actionReconnect, SIGNAL(triggered()), pDlg->need_reconnect_for_specialoption, SLOT(hide())); connect(dactionReconnect, SIGNAL(triggered()), pDlg->need_reconnect_for_specialoption, SLOT(hide())); if( ! pDlg ) return; pDlg->show(); } void mudlet::show_help_dialog() { QString p = qApp->applicationDirPath(); p.append("/Mudlet_API_Reference_HTML.html"); QDesktopServices::openUrl(QUrl::fromLocalFile(p));//("file://./Mudlet_API_Reference_HTML.html"));//"http://mudlet.sourceforge.net/wordpress/?page_id=40")); } void mudlet::slot_show_help_dialog_video() { QDesktopServices::openUrl(QUrl("http://www.mudlet.org/media/")); } void mudlet::slot_show_help_dialog_forum() { QDesktopServices::openUrl(QUrl("http://forums.mudlet.org/")); } void mudlet::slot_show_help_dialog_irc() { QDesktopServices::openUrl(QUrl("http://webchat.freenode.net/?channels=mudlet")); } #include "dlgMapper.h" void mudlet::slot_mapper() { Host * pHost = getActiveHost(); if( ! pHost ) return; if( pHost->mpMap->mpMapper ) { pHost->mpMap->mpMapper->setVisible( ! pHost->mpMap->mpMapper->isVisible() ); return; } QDockWidget * pDock = new QDockWidget("Mudlet Mapper"); pHost->mpMap->mpMapper = new dlgMapper( pDock, pHost, pHost->mpMap );//FIXME: mpHost definieren pHost->mpMap->mpM = pHost->mpMap->mpMapper->glWidget; pDock->setWidget( pHost->mpMap->mpMapper ); if( pHost->mpMap->rooms.size() < 1 ) { pHost->mpMap->restore(""); pHost->mpMap->init( pHost ); pHost->mpMap->mpMapper->mp2dMap->init(); pHost->mpMap->mpMapper->show(); } else { if( pHost->mpMap->mpMapper ) { pHost->mpMap->mpMapper->show(); } } addDockWidget(Qt::RightDockWidgetArea, pDock); check_for_mappingscript(); TEvent mapOpenEvent; mapOpenEvent.mArgumentList.append( "mapOpenEvent" ); mapOpenEvent.mArgumentTypeList.append(ARGUMENT_TYPE_STRING); pHost->raiseEvent( & mapOpenEvent ); } void mudlet::check_for_mappingscript() { Host * pHost = getActiveHost(); if( ! pHost ) return; if (!pHost->check_for_mappingscript()) { QUiLoader loader; QFile file(":/ui/lacking_mapper_script.ui"); file.open(QFile::ReadOnly); QDialog *dialog = dynamic_cast(loader.load(&file, this)); file.close(); connect(dialog, SIGNAL(accepted()), this, SLOT(slot_open_mappingscripts_page())); dialog->show(); dialog->raise(); dialog->activateWindow(); } } void mudlet::slot_open_mappingscripts_page() { QDesktopServices::openUrl(QUrl("http://forums.mudlet.org/search.php?keywords=mapping+script&terms=all&author=&sc=1&sf=titleonly&sr=topics&sk=t&sd=d&st=0&ch=400&t=0&submit=Search")); } void mudlet::slot_show_help_dialog_download() { QDesktopServices::openUrl(QUrl("http://sourceforge.net/projects/mudlet/files/")); } void mudlet::slot_show_about_dialog() { dlgAboutDialog * pDlg = new dlgAboutDialog( this ); pDlg->raise(); pDlg->show(); } #include void mudlet::slot_notes() { Host * pHost = getActiveHost(); if( ! pHost ) return; dlgNotepad * pNotes = pHost->mpNotePad; if( ! pNotes ) { pHost->mpNotePad = new dlgNotepad( pHost ); pNotes = pHost->mpNotePad; QTextCharFormat format; format.setFont( pHost->mDisplayFont ); pNotes->notesEdit->setCurrentCharFormat( format ); pNotes->restore(); pNotes->setWindowTitle( pHost->getName()+" notes" ); } pNotes->raise(); pNotes->show(); } void mudlet::slot_irc() { //#ifdef Q_CC_GNU if( ! mpIRC ) { mpIRC = new dlgIRC(); mpIRC->setWindowTitle( "Mudlet live IRC Help Channel #mudlet-help on irc.freenode.net" ); mpIRC->resize(660,380); } mpIRC->raise(); mpIRC->show(); //#endif } void mudlet::slot_reconnect() { Host * pHost = getActiveHost(); if( ! pHost ) return; pHost->mTelnet.connectIt( pHost->getUrl(), pHost->getPort() ); } void mudlet::slot_disconnect() { Host * pHost = getActiveHost(); if( ! pHost ) return; pHost->mTelnet.disconnect(); } void mudlet::slot_replay() { Host * pHost = getActiveHost(); if( ! pHost ) return; QString home = QDir::homePath() + "/.config/mudlet/profiles/"; home.append( pHost->getName() ); home.append( "/log/" ); QString fileName = QFileDialog::getOpenFileName(this, tr("Select Replay"), home, tr("*.dat")); if( fileName.isEmpty() ) return; QFile file(fileName); if( ! file.open(QFile::ReadOnly | QFile::Text) ) { QMessageBox::warning(this, tr("Select Replay"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } //QString directoryLogFile = QDir::homePath()+"/.config/mudlet/profiles/"+profile_name+"/log"; //QString fileName = directoryLogFile + "/"+QString(n.c_str()); pHost->mTelnet.loadReplay( fileName ); } void mudlet::printSystemMessage( Host * pH, QString & s ) { mConsoleMap[pH]->printSystemMessage( s ); } void mudlet::print( Host * pH, QString & s ) { mConsoleMap[pH]->print( s ); } QString mudlet::readProfileData( QString profile, QString item ) { QFile file( QDir::homePath()+"/.config/mudlet/profiles/"+profile+"/"+item ); file.open( QIODevice::ReadOnly ); if( ! file.exists() ) return ""; QDataStream ifs( & file ); QString ret; ifs >> ret; file.close(); return ret; } // this slot is called via a timer in the constructor of mudlet::mudlet() void mudlet::startAutoLogin() { QStringList hostList = QDir(QDir::homePath()+"/.config/mudlet/profiles").entryList(QDir::Dirs, QDir::Name); hostList.removeAll("."); hostList.removeAll(".."); for( int i = 0; i< hostList.size(); i++ ) { QString item = "autologin"; QString val = readProfileData( hostList[i], item ); if( val.toInt() == Qt::Checked ) { doAutoLogin( hostList[i] ); } } } /* QString mudlet::readProfileData( QString profile, QString item ) { QFile file( QDir::homePath()+"/.config/mudlet/profiles/"+profile+"/"+item ); file.open( QIODevice::ReadOnly ); QDataStream ifs( & file ); QString ret; ifs >> ret; file.close(); return ret; }*/ void mudlet::doAutoLogin( QString & profile_name ) { if( profile_name.size() < 1 ) return; Host * pOH = HostManager::self()->getHost( profile_name ); if( pOH ) { pOH->mTelnet.connectIt( pOH->getUrl(), pOH->getPort() ); return; } // load an old profile if there is any HostManager::self()->addHost( profile_name, "", "", "" ); Host * pHost = HostManager::self()->getHost( profile_name ); if( ! pHost ) return; QString folder = QDir::homePath()+"/.config/mudlet/profiles/"+profile_name+"/current/"; QDir dir( folder ); dir.setSorting(QDir::Time); QStringList entries = dir.entryList( QDir::Files, QDir::Time ); //for( int i=0;i 0 ) { QFile file(folder+"/"+entries[0]); file.open(QFile::ReadOnly | QFile::Text); XMLimport importer( pHost ); qDebug()<<"[LOADING PROFILE]:"<setLogin( val1 ); QString pass = "password"; QString val2 = readProfileData( profile_name, pass ); pHost->setPass( val2 ); slot_connection_dlg_finnished( profile_name, 0 ); enableToolbarButtons(); } /* QList hostList = HostManager::self()->getHostList(); for( int i=0; igetHost( hostList[i] ); QString profile = pH->getName(); if( profile.size() < 1 ) { HostManager::self()->deleteHost( profile ); continue; } QString item = "autologin"; QString val = readProfileData( profile, item ); if( val.toInt() == Qt::Checked ) { qDebug()<<"----> Host:"<getName()<<" URL:"<getUrl()<<"Login:"<getLogin(); addConsoleForNewHost( pH ); pH->connectToServer(); } else { // remove Hosts that don't have autologin defined from HostPool qDebug() << "----> [ EXPIRED ] " << profile.toLatin1().data() << " Host ist no longer an autoloader. Due to user decision."; HostManager::self()->deleteHost( profile ); } } if( hostList.size() < 1 ) qDebug() << "----> [ OK ] nothing to be done (no autologin profiles defined)"; else qDebug() << "----> [ OK ] autologin finished"; qDebug()<<"[ AUTOLOGIN END ] currently loaded hosts after removal of non-autoloaders:"<getHostList(); }*/ /////////////////////////////////////////////////////////////////////////////// // these two callbacks are called from cTelnet::handleConnectedToServer() void mudlet::slot_send_login() { if( tempHostQueue.isEmpty() ) return; Host * pHost = tempHostQueue.dequeue(); QString login = pHost->getLogin(); pHost->sendRaw( login ); } void mudlet::slot_send_pass() { if( tempHostQueue.isEmpty() ) return; Host * pHost = tempHostQueue.dequeue(); QString pass = pHost->getPass(); pHost->sendRaw( pass ); } ////////////////////////////////////////////////////////////////////////////// void mudlet::processEventLoopHack() { QTimer::singleShot(1, this, SLOT(processEventLoopHack_timerRun())); } void mudlet::processEventLoopHack_timerRun() { Host * pH = getActiveHost(); if( !pH ) return; pH->mpConsole->refresh(); } void mudlet::slot_connection_dlg_finnished( QString profile, int historyVersion ) { Host * pHost = HostManager::self()->getHost( profile ); if( ! pHost ) return; pHost->mIsProfileLoadingSequence = true; addConsoleForNewHost( pHost ); pHost->mBlockScriptCompile = false; pHost->mLuaInterpreter.loadGlobal(); pHost->getScriptUnit()->compileAll(); pHost->mIsProfileLoadingSequence = false; //do modules here qDebug()<<"loading modules now"; //QMapIterator it (pHost->mInstalledModules); QMapIterator it (pHost->mModulePriorities); QMap moduleOrder; while( it.hasNext() ){ it.next(); QStringList moduleEntry = moduleOrder[it.value()]; moduleEntry << it.key(); moduleOrder[it.value()] = moduleEntry; /*QStringList entry = it.value(); pHost->installPackage(entry[0],1); qDebug()<mInstalledModules[it.key()] = entry;*/ } QMapIterator it2 (moduleOrder); while (it2.hasNext()){ it2.next(); QStringList modules = it2.value(); for (int i=0;imInstalledModules[modules[i]]; pHost->installPackage(entry[0],1); qDebug()<mInstalledModules[modules[i]] = entry; } } // install default packages for( int i=0; i< packagesToInstallList.size(); i++ ) { pHost->installPackage( packagesToInstallList[i], 0 ); } packagesToInstallList.clear(); TEvent event; event.mArgumentList.append( "sysLoadEvent" ); event.mArgumentTypeList.append(ARGUMENT_TYPE_STRING); pHost->raiseEvent( & event ); //NOTE: this is a potential problem if users connect by hand quickly // and one host has a slower response time as the other one, but // the worst that can happen is that they have to login manually. tempHostQueue.enqueue( pHost ); tempHostQueue.enqueue( pHost ); pHost->connectToServer(); } void mudlet::slot_multi_view() { QMapIterator it( mConsoleMap ); while( it.hasNext() ) { it.next(); it.value()->show(); } } void mudlet::slot_stopAllTriggers() { /* foreach( TConsole * pC, mConsoleMap ) { pC->mpHost->stopAllTriggers(); }*/ } mudlet::~mudlet() { } void mudlet::toggleFullScreenView() { if( isFullScreen() ) showNormal(); else showFullScreen(); } QLabel * replaySpeedDisplay = 0; QLabel * replayTime = 0; QAction * actionSpeedDisplay = 0; QAction * actionReplayTime = 0; QToolBar * replayToolBar = 0; const QString timeFormat = "hh:mm:ss"; QTimer * replayTimer = 0; void mudlet::replayStart() { if( ! mpMainToolBar ) return; replayToolBar = new QToolBar( this ); mReplaySpeed = 1; replayTime = new QLabel( this ); actionReplayTime = replayToolBar->addWidget( replayTime ); actionReplaySpeedUp = new QAction(QIcon(":/icons/export.png"), tr("faster"), this); actionReplaySpeedUp->setStatusTip(tr("Replay Speed Up")); replayToolBar->addAction( actionReplaySpeedUp ); actionReplaySpeedDown = new QAction(QIcon(":/icons/port.png"), tr("slower"), this); actionReplaySpeedDown->setStatusTip(tr("Replay Speed Down")); replayToolBar->addAction( actionReplaySpeedDown ); replaySpeedDisplay = new QLabel( this ); actionSpeedDisplay = replayToolBar->addWidget( replaySpeedDisplay ); connect(actionReplaySpeedUp, SIGNAL(triggered()), this, SLOT(slot_replaySpeedUp())); connect(actionReplaySpeedDown, SIGNAL(triggered()), this, SLOT(slot_replaySpeedDown())); QString txt = "speed:"; txt.append( QString::number( mReplaySpeed ) ); txt.append("X"); replaySpeedDisplay->setText(txt); QString txt2 = "Time:"; txt2.append( mReplayTime.toString( timeFormat ) ); txt2.append(""); replayTime->setText( txt2 ); replaySpeedDisplay->show(); replayTime->show(); insertToolBar( mpMainToolBar, replayToolBar ); replayToolBar->show(); replayTimer = new QTimer( this ); replayTimer->setInterval(1000); replayTimer->setSingleShot( false ); connect( replayTimer, SIGNAL( timeout() ), this, SLOT(slot_replayTimeChanged())); replayTimer->start(); } void mudlet::slot_replayTimeChanged() { QString txt2 = "Time:"; txt2.append( mReplayTime.toString( timeFormat ) ); txt2.append(""); replayTime->setText( txt2 ); } void mudlet::replayOver() { if( ! mpMainToolBar ) return; if( ! replayToolBar ) return; if( actionReplaySpeedUp ) { disconnect(actionReplaySpeedUp, SIGNAL(triggered()), this, SLOT(slot_replaySpeedUp())); disconnect(actionReplaySpeedDown, SIGNAL(triggered()), this, SLOT(slot_replaySpeedDown())); replayToolBar->removeAction( actionReplaySpeedUp ); replayToolBar->removeAction( actionReplaySpeedDown ); replayToolBar->removeAction( actionSpeedDisplay ); removeToolBar( replayToolBar ); actionReplaySpeedUp = 0; actionReplaySpeedDown = 0; actionSpeedDisplay = 0; actionReplayTime = 0; replayToolBar = 0; } } void mudlet::slot_replaySpeedUp() { mReplaySpeed = mReplaySpeed * 2; QString txt = "speed:"; txt.append( QString::number( mReplaySpeed ) ); txt.append("X"); replaySpeedDisplay->setText(txt); replaySpeedDisplay->show(); } void mudlet::slot_replaySpeedDown() { mReplaySpeed = mReplaySpeed / 2; if( mReplaySpeed < 1 ) mReplaySpeed = 1; QString txt = "speed:"; txt.append( QString::number( mReplaySpeed ) ); txt.append("X"); replaySpeedDisplay->setText(txt); replaySpeedDisplay->show(); } void mudlet::playSound( QString s ) { if( mpMusicBox1->remainingTime() == 0 ) { mpMusicBox1->setCurrentSource( s ); mpMusicBox1->play(); } else if( mpMusicBox2->remainingTime() == 0 ) { mpMusicBox2->setCurrentSource( s ); mpMusicBox2->play(); } else if( mpMusicBox3->remainingTime() == 0 ) { mpMusicBox3->setCurrentSource( s ); mpMusicBox3->play(); } else { mpMusicBox4->clear(); mpMusicBox4->setCurrentSource( s ); mpMusicBox4->play(); } } mudlet-2.1/src/TCommandLine.h0000644000175000017500000000722011624306130015425 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TCOMMANDLINE_H #define TCOMMANDLINE_H #include #include #include //#include "ui_console.h" //#include #include #include "ctelnet.h" #include "TCommandLine.h" #include "Host.h" #include #include class TConsole; class KeyUnit; class Host; class TConsole; class TCommandLine : public QPlainTextEdit//QLineEdit { Q_OBJECT public: TCommandLine( Host *, TConsole *, QWidget * ); // void keyPressEvent(QKeyEvent *event); void focusInEvent ( QFocusEvent * ); void focusOutEvent ( QFocusEvent * ); QPalette mRegularPalette; private: QString mLastCompletion; void handleAutoCompletion(); void spellCheck(); void handleTabCompletion( bool direction ); void historyUp(QKeyEvent *event); void historyDown(QKeyEvent *event); bool event(QEvent *event); void enterCommand(QKeyEvent *event); void adjustHeight(); void mousePressEvent( QMouseEvent * event ); int mHistoryBuffer; QStringList mHistoryList; QMap mHistoryMap; bool mAutoCompletion; bool mTabCompletion; Host * mpHost; int mTabCompletionCount; int mAutoCompletionCount; QString mTabCompletionTyped; QString mAutoCompletionTyped; bool mUserKeptOnTyping; QPalette mTabCompletionPalette; QPalette mAutoCompletionPalette; KeyUnit * mpKeyUnit; TConsole * mpConsole; QString mSelectedText; int mSelectionStart; QString mTabCompletionOld; Hunhandle * mpHunspell; QPoint mPopupPosition; int mHunspellSuggestionNumber; char ** mpHunspellSuggestionList; signals: void textChanged ( const QString & ); public slots: void slot_textChanged(const QString &); void slot_sendCommand(const char * pS); void slot_popupMenu(); }; #endif mudlet-2.1/src/TRoom.h0000644000175000017500000000413612076170616014170 0ustar csmallcsmall#ifndef TROOM_H #define TROOM_H #include #include #include #define DIR_NORTH 1 #define DIR_NORTHEAST 2 #define DIR_NORTHWEST 3 #define DIR_EAST 4 #define DIR_WEST 5 #define DIR_SOUTH 6 #define DIR_SOUTHEAST 7 #define DIR_SOUTHWEST 8 #define DIR_UP 9 #define DIR_DOWN 10 #define DIR_IN 11 #define DIR_OUT 12 class TRoom { public: TRoom(); bool hasExit( int ); void setWeight( int ); void setExitLock( int, bool ); void setSpecialExitLock(int to, QString cmd, bool doLock); bool hasExitLock(int to); bool hasSpecialExitLock( int, QString ); void removeSpecialExit( int to, QString cmd ); void addSpecialExit( int to, QString cmd ); void setExitWeight( QString cmd, int weight ); void setDoor( QString cmd, int doorStatus );//0=no door, 1=open door, 2=closed, 3=locked int hasExitStub(int direction); void setExitStub(int direction, int status); void calcRoomDimensions(); int id; int area; int x; int y; int z; int north; int northeast; int east; int southeast; int south; int southwest; int west; int northwest; int up; int down; int in; int out; int environment; int weight; bool isLocked; qreal min_x; qreal min_y; qreal max_x; qreal max_y; qint8 c; QString name; QVector3D v; QMultiMap other; // es knnen mehrere exits zum gleichen raum verlaufen //verbotene exits werden mit 0 geprefixed, offene mit 1 QList exitStubs; //contains a list of: exittype (according to defined values above) QMap userData; QList exitLocks; QMap > customLines; QMap > customLinesColor; QMap customLinesStyle; QMap customLinesArrow; bool highlight; QColor highlightColor; QColor highlightColor2; float highlightRadius; bool rendered; QMap doors; //0=no door 1=open 2=closed 3=locked QMap exitWeights; }; #endif // TROOM_H mudlet-2.1/src/dlgScriptsMainArea.h0000644000175000017500000000327611513237311016637 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef dlg_scriptsmainarea_h #define dlg_scriptsmainarea_h #include "ui_scripts_main_area.h" #include class dlgScriptsMainArea : public QWidget , public Ui::scripts_main_area { Q_OBJECT public: dlgScriptsMainArea(QWidget*); signals: public slots: }; #endif mudlet-2.1/src/TForkedProcess.h0000644000175000017500000000423611513237311016015 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2009 by Benjamin Lerman * * mudlet@ambre.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef FORKED_PROCESS_H #define FORKED_PROCESS_H #include "TLuaInterpreter.h" #include extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" } class TLuaInterpreter; class TForkedProcess : public QProcess { Q_OBJECT public: virtual ~TForkedProcess(); static int startProcess( TLuaInterpreter *, lua_State *); private: TForkedProcess( TLuaInterpreter *, lua_State * ); int callBackFunctionRef; TLuaInterpreter *interpreter; bool running; static int closeInputOfProcess ( lua_State * L ); static int isProcessRunning ( lua_State * L ); static int sendMessage( lua_State * L ); private slots: void slotReceivedData(); void slotFinish(); }; #endif mudlet-2.1/src/mudlet_documentation.html0000755000175000017500001147637711513237311020110 0ustar csmallcsmall Mudlet Manual

Introduction

Welcome to Mudlet, a modern MUD client for GNU/Linux, Windows and Mac OSX that offers all the tools to get the most out of your gaming experience.

Throughout this document we hope to familiarize you with the basic aspects of Mudlet, from the interface to its very powerful and feature rich scripting backend The main focus in the development of Mudlet has been efficiency and performance, but we also try to make it as easily accessible as possible. However, keep in mind that this is a complex piece of software with a large set of tools that does require some deeper understanding of the underlying principles. To use Mudlet in any meaningful way, you have to take a closer look at the technical section in this manual.

If you are not familiar with using modern MUD clients in general you should also take a look at the general introduction to MUD clients section at the beginning of this manual. You are welcome to ask questions on the forum of our website. If you find a bug, please let us know.

Note Everything is centered around the central Lua scripting unit. Everything shares the same variables & functions and everything is accessible from anywhere.

Quick Start

To connect to the MUD of your choice, click on Connect. !

  • Create a new profile by clicking on Add New Profile.

  • Specify the host and the port of the MUD (This information is usually found on the MUD’s homepage).

  • Now just click Connect to play!

1. General Introduction to Modern MUD Clients

1.1 Mudlets automation features

Mudlet offers a vast array of standard features to automate or otherwise improve your gaming experience. These include, but are not limited to:

  • Aliases – user-defined text input, which is converted into a different, usually longer input before being sent to the MUD, e.g. ggget gold from ground;put gold in 2.bag.

  • Keybindings – also known as hotkeys, allow executing certain user-defined commands by simultaneously pressing a specific combination of keys, e.g. CTRL+Hsend say Hello Miyuki! to the MUD or plays La Marseillaise

  • Triggers – execute user-defined commands upon receiving specific out from the MUD, e.g. MUD sends You see Elyssa standing here. → send poke Elyssa to the MUD.

  • Timers – delay the execution of a command or execute it after a specified period of time, e.g. throw gauntlet to Eric-wait 3 seconds-exclaim Let us end this here!

  • Variables – allow the user to store text or numbers for easier use inside scripts.

  • Events – allow the user to make triggers for specific events like when Mudlet has connected to the MUD, or even user-defined events to use in complex system making.

Scripting allows the user to create automation utilities (triggers, aliases) with the Lua scripting language. The possibilities of what can be achieved by using this technique are, practically speaking, endless - ranging from teaching the client how to heal your character in combat for you to creating a fully automated robot (known as `bot`s) that will completely take over the control for your character (especially useful for completing repetitive, rudimentary tasks).

1.2 Automation and MUD rules

Effectively speaking, it is possible to create an AI (Artificial Intelligence) that does everything you can do in a MUD. Even more so, the program will be able outperform you in almost every routine operation. The difficulty of creating such a program depends on the task it has to perform: gathering loot being very easy, walking through a dungeon and leveling you character being moderately easy and socially interacting with other real people being outrageously difficult (see A.L.I.C.E.). In the end of the day, you’re teaching your client to process information and act the way you consider best suited. Because scripting is so powerful, it can give you a competitive advantage that some people consider it unfair or even cheating. As of the moment of this writing (2 November 2008), this sort of automation can be best observed in commercial massively-multiplayer online role-playing games (MMORPG), known as gold-farming or power-leveling. The basic idea is creating a system that will raise your character to the maximum level and gather in-game currency in the process, both of which can be effectively exchanged for real-world currency. The spread of the above aspects can have much more far reaching consequences than just being unfair, such as inflation, loss of balance in terms of game-mechanics or, ultimately, a complete crash of in-game economy. For more information see the paper "Simple Economics of Real-Money Trading in Online Games" by Jun-Sok Huhh of the Seoul National University. For these, and various other, reasons the administrators and owners of the corresponding virtual worlds can forbid the usage of automation tools. A failure to comply can result in suspension or deletion of the user’s character or account for future denial of service. By including scripting support in Mudlet, we effectively give you the ability to create and utilize AI tool-kits, however, we do not endorse or promote the usage of these systems if it’s prohibited in your MUD. Keep in mind that by cheating you can lessen the quality of gameplay for both, your fellow players and yourself.

1.3 Basic scripting

The following part of the guide is written for new beginners in scripting. If you’re coming over from zMud or cMud, you may move on to section two.

1.4 Variables - basics

Variables are containers for data. In Lua, they can store numbers or words. You can use variables to store important information like how much gold do you have, or have them remember things for you.

The syntax for making a variable remember a number is the following:

variable = number

Or to make it remember some text:

For example, here we’ll set the myhealth variable to number 1345, and the myname variable to Bob:

You can also do basic maths easily, for example:

To concatenate strings together, you can use the .. expression:

1.5 How to send text to the mud

To send a command to the MUD, you can use the send() function. Data inside the quotes is sent to the MUD.

For example, the following code sends the command to eat bread:

If you’d like to include variables in the send command, you need to prefix and suffix them with two dots outside the quotes, like this:

send("My name is " .. full_name .. ". What's yours?")

1.6 How to echo text to yourself

To echo (show text to yourself) you can use the echo() or the insertText() function. For example, the following code will display Time to eat dinner! on your screen:

echo("Time to eat dinner")

If you’d like to include variables in your echo, you concatenate the value of your variable to the text:

my_gold = 5
echo("I have " .. my_gold .. " pieces of gold!")

1.7 Aliases

The aliases are the most basic way of automating the gameplay - you can use aliases to shorten the amount of typing you do. For example:

Example - Brew’o'Matic 6000

You’re walking around the epic dungeon of the Unholy Firedragon of Westersand, gathering roots in order to brew a potion and thus restore the growth of hair on Farmer Benedict’s bald head. Once you see a root, you need to:

open the bag of tools
get the sickle of damnation from the bag of tools
cut the root of hair-growth
clean the sickle of damnation of deadly root acid
put the sickle of damnation in the bag of tools
close the bag of tools
open the magical bag of storing
take the root
put the root into the magical bag of storing
close the magical of storing

and once you’re done, do the exact same thing nine more times… trice a day.

Alternatively, you just create an alias that would do this all with a single command - for example, quest.

1.8 Making a simple alias

To get started, go click on the Aliases button in Mudlet, and then on the Add one. This will make a blank alias for you, which we’ll now fill in.

The Alias name field is optional - it’s mainly used for the alias listing that you see on the left as an easy way to distinguish all of the aliases. You can just name our alias test for now. The Pattern field is where you put your regex pattern to describe on what command that you are typing in the command line, your new alias will spring into action. Let’s say, we want our new alias to send the command "say hello" whenever we type "sh". The regex pattern would be "^sh$". Then we put "say hello" into the substitution field. After you have saved and activated your new alias "test", whenever you type "sh" Mudlet will not send "sh", but "say hello" instead. We call this substitution process alias expansion.

Mudlet uses Perl regular expression aliases. Regexes are a special way of matching patterns of words. For the beginners it is enough to think of them as a general way to specify the words itself and their placement within the line. For basic alias it is enough to know that the character ^ symbolizes the beginning of the line and the character $ symbolizes the end of the line. If you want to make an alias "tw" that sends the command "take weapon", you don’t have to care about placement or pattern matching in general. All you need to do is fill "tw" in the field called "Regex" and type "take weapon" in the field called "substitution". Then you need to save the new alias by clicking on the "Save" icon in the top middle. The symbol for unsaved items disappears and makes way for a little blue checkbox. If this box is checked the alias is active. If the blue box is empty, the alias is deactivated and will not work unless you press the "activate" toggle padlock icon. Now you are ready to go. Type "tw" in the command line and press the enter key. Mudlet will send "take weapon" to the MUD. Alias as basically, a feature to save you a bit of typing - much like buttons which will be described in detail in section two of the manual. To learn more about more complex aliases have a look at section 2 of the manual.

1.9 Simple Triggers

Triggers are an automation feature offered in all MUD clients. They help you respond quicker a particular situation and generally make things more convenient for you since you need to do less manual work as your triggers will do the hard work for you often times. This helps you concentrate more on the important aspects of the game and lessen stress. The way a trigger works is simple: You define some text that you want to trigger some action. This is called the trigger pattern. When the trigger "sees" this text in the MUD output, it’ll run the commands you’ve told it to. Example: Whenever you see a bunny, you want to attack it. You type "bunny" in the data field titled "add to list" and then either press the enter key or click on the little + icon next to the input line to add this word to the list of texts this trigger fires on. Now you type "kill bunny" in the field called "send plain text". Then click on the save icon to save the trigger and activate your new trigger (= blue checkbox icon in front of the trigger name in the trigger tree on the right side is checked). When the trigger is active each time the word "bunny" will appear in the MUD output, your trigger will issue the command "kill bunny" automatically as long as it is active. When you want to stop hunting bunnies, you can simply select the bunny trigger and then click on the padlock icon to deactivate the trigger. The trigger will stop firing until you re-enable it again via the padlock icon. If you lock a group of triggers or an entire trigger branch, all triggers in this branch will be locked until you remove the lock again. The locking starts from the root of the tree down to the end. As soon as a lock is met the trigger engine will skip the locked branch. Locking and unlocking branches is one of the most common actions you have to take care of when playing. You turn on your defensive triggers when engaging into a battle and you turn them off afterwards, or you turn on your harvesting triggers only when you are going to harvest.

Tip Beginners should use Mudlets automated highlight triggers in the beginning to highlight the text that has been triggered on to get the hang of the different trigger and pattern types. Click on the "highlight trigger" option and pick a foreground and a background color that you like to highlight your trigger with. When the trigger matches it automatically highlights its pattern. This is the most used form of triggers in mudding as it is a quick way of highlighting words that are important to you at the moment. You don’t have to know anything about scripting, regular expressions etc. to use highlight triggers. Just type in the word you like to be highlighted, select appropriate colors, save the new trigger and activate it.
1.10 Matching one unknown

You can also set up a trigger to gather the scimitars, gold or whatever the skeletons could carry around with them. Since we do not know what the loot is, we will need to set up a trigger to match the line and take whatever was dropped. Examples:

The skeleton drops ring.
The skeleton drops gold.
The skeleton drops scimitar.

The skeleton drops_ is the generic segment of the line, the loot itself varies. Thus, we need to tell the client to take_ whatever the skeleton dropped. We do this by setting up a so-called regular expression:

Perl Style Regular Expression: The skeleton drops (.*)\.
Script: send("take " .. matches[2])

The expression (.*) matches any characters that the client receives between The skeleton drops_ (NB: notice the blank at the end) and the full-stop. matches[2] simply transfers the first matched text fitting the search criteria into the output (matches[1] contains the entire matched text, matches[2] contains the first capture group. More on this in section two of the manual).

1.11 Matching multiple unknowns

Now, let’s try making a trigger that would gather the loot from anybody:

Perl Style Regular Expression: (.*) drops (.*).
Script:
send("take " .. matches[3])

In this case, any time somebody, or something, drops something else, or someone else, the client will pick it up. Note that we used matches[3] instead of matches[2] this time, in order to pick up the second match. If we used matches[2], we’d end up picking up the skeleton’s corpse.

1.12 Matching known variants

If you’re playing a MUD in English, you’ll notice that these triggers probably won’t work due to English syntax. Compare:

The skeleton drops apple.
The skeleton drops an apple.

Chances are that you’ll see the later a little more often. If we used our old RegEx, the output would look something like this.

INPUT: The skeleton drops an apple.
OUTPUT: take an apple

Most MUDs can’t handle determiners, such as articles (i.e. a, an, the) or quantifiers (e.g. five, some, each), in user-input. To match this line we could either create multiple triggers matching every possible article or a regular expression filtering out these words:

Perl Style Regular Expression: (.*) drops (a|an|the|some|a couple of|a few|) (.*).
Script:
send("take " .. matches[4])

Once again, note that we’re using the third match (matches[4]) this time. NOTE: Certain other languages, with a morphology richer than that of English, might require a somewhat different approach. If you’re stuck, and your MUD-administrators don’t prohibit the use of triggers, try asking on the corresponding world’s forums.

For more information, see the chapter Regular Expressions.

1.13 explain basic regex characters (^, $, (\w+), (\d+) and .*) and how to use them properly.

Retrieving wildcards from triggers

Wildcards from triggers are stored in the matches[] table. The first wildcard goes into matches[1], second into matches[2], and so on, for however many wildcards do you have in your trigger.

For example, you’d like to say out loud how much gold did you pick up from a slain monster. The message that you get when you pick up the gold is the following:

You pick up 16 gold.

A trigger that matches this pattern could be the following:

Perl Style Regular Expression: You pick up (\d+) gold

And in your code, the variables matches[2] will contain the amount of gold you picked up (in this case, 16). So now to say out loud how much gold did you loot, you can do the following:

Script: echo("I got " .. matches[2] .. " gold!")
More advanced example

Here’s an example by Heiko, which makes you talk like Yoda:

Perl Style Regular Expression: ^say (\w+) *(\w*) .*?(.*)
Script:  send( "say "..matches[4].." "..matches[2].." "..matches[3] )

What it does here is save the first word, the second word and then the rest of the text into wildcards. It then says rest of the text first, then the first word and then the second word.

1.14 How to highlight words

To highlight something in the MUD output, make a trigger and use the "highlight trigger" option to highlight the matched trigger pattern.

Optionally, you can also make use of the bg() and fg() functions in scripting to highlight.

1.15 Keybindings

Keybindings, or hotkeys, are in many respects very similar to aliases, however, instead of typing in what you want to be done, you simply hit a key (or combination of keys) and let the Mudlet do the work.

HOTKEY: F1
command on button down: sip earl gray

HOTKEY: F2
command on button down: sip ceylon mint

Now you just have to listen, or rather read, carefully and hit either F1 or F2 to claim that prize.

Another practical use for keybindings would be creating a so-called "targeting system", which is especially useful for grinding down armies of pumpkin-men in MUDs without auto-attack. See the Variables chapter for further details.

1.16 Timers

Timers, as the name suggests, can be used to execute a specific command at a certain time, after a certain time or once every so often.

Main Manual

Multi Session Gaming

Mudlet lets you play several simultaneous MUD sessions. However, currently we have the restriction that you cannot use the same profile twice. Consequently, if you want to play three characters on the same MUD at the same time, you need to make 3 profiles with 3 different names e.g. ernie@avalon.de, bert@avalon.de etc.

Split Screen

Mudlet has a split screen. If you scroll up in the MUD text screen (or any other mini console window), the screen will split in two parts. The lower part will follow the MUD output while the upper part will stay focused on your scrolling. This way you can read easier through old passages without missing what is going on at the moment.

Split screen can be activated via the scroll bar, page up / page down keys or the mouse wheel. Scrolling back to the end will close the split screen automatically. A click on the middle mouse button will close the split screen immediately as well as pressing control+return on the keyboard. The size of the 2 parts of the split screen can be modified by dragging the separator bar in the middle with the mouse. Split screen usage is necessary when selecting text in order to copy it to trigger editor e.g. when making triggers. If you don’t use split screen when selecting text, new arriving text will upset your selection.

Command Line Auto-Completion, Tab-Completion and Command History

Mudlets command line is especially designed for MUD and MUSH playing. It aims at reducing the amount of typing by using autocompletion and tab completion schemes that are optimized for typical MUD playing situations. The command line offers tab completion (TAB key with or without shift) and autocompletion (cursor up and cursor down keys).

  1. Tab completion searches the last 100 lines in the MUD output buffer for words matching the word that you are currently typing. This is useful if you have to type complicated long names. You only have to type the first letters and then press the tab key until the proposal is what you want.

  2. Autocompletion tries to match your current typing with your command history. Example: If you typed the same command a while ago, you only have to start typing the first couple of letters and then press the cursor up key until the proposal matches the command that you want to use.

  3. Command History: If you haven’t started to type anything yet, you can browse through your command history with the cursor up and cursor down keys. However, if you have started typing pressing cursor up will result in a shot at autocompletion.

  4. ESC:To get out of autocompletion you can press the ESC key any time. After pressing ESC the entire text gets selected and you can overwrite it or get back into command history mode.

Logging Output to text or HTML Log Files

Press on the little button with the blue folder with the green arrow icon on the lower right side of the command line to turn on plain text logging. Click again to stop logging. This will inform you about the file name and path of the log file. If you want to log in color you can chose to log to files in html format, but note that due to the nature of HTML, these log files tend to get very large quickly.

Log files can be found at the mudlet home directory in your profile directory. To get the path to your mudlet home directory you can run a script like this one:

echo( getMudletHomeDir() .. "\n" )

Log files are stored in "<mudletHomeDir>/logs". Each profile has its own <mudletHomeDir> path. Log files have a similar naming convention to the autosaved profiles: date#time.txt or date#time.html

Exporting and Importing Profiles or Packages

Mudlet supports XML packages that can be imported and exported while playing. You can find a package section on the forum at http://mudlet.sourceforge.net where you can download demo packages or ready made packages for your MUD or upload your own packages to share your work with other players. A package can contain anything ranging from a single trigger to hundreds of button groups, trigger groups aliases - in other words, entire "systems".

Importing Packages

To import a package, open the script editor and click the import icon, select your xml package file and import it. Package files might be compressed to save space. If the file is compressed, you’ll need to uncompress it before importing it. The imported package will be stored permanently in your profile when you safe the profile. If you don’t like the imported package, delete its components manually or simply don’t save the profile. Then the new content will be lost on restart. Good packages will be organized in such a way that they will be easy to update or remove.

Packages are nothing else, but profiles - or parts of profiles that can be exchanged, imported and exported between your own profiles and between different players. From a technical perspective a package and a profile xml file are the same thing.

Exporting Packages

Exporting items or groups is also easy. Select your item or a group containing many items or subgroups and then click on the "Export" button. You’ll be prompted for a file name and that’s it. Package file names should end with ".xml" to make import easier for users on all platforms. You can send your cool trigger, buttons, timers etc. to your friends or use them in another profile of yours. Exporting your good stuff is strongly recommended as it makes MUDding more enjoyable for everybody. Share your knowledge and help others! Mudlet stores your saved profiles as XML files in your home directory under "<mudletHomeDir>/current". To get <mudletHomeDir> run a script like this:

echo( getMudletHomeDir() .. "\n" )

To export your entire profile e. g. to make a backup on a flash drive, use the "save profile as" button. You can export packages of a trigger branch, alias branch, function key, scripts etc. by clicking on a folder in the tree of the particular item in question and then click on the export icon. You’ll be asked to give a filename for your package. You can export arbitrarily complex structures by moving them into a folder that e.g. is named after the package you’d like to make.

Sharing your System with others - Making complex Packages

If you have written a nice set of triggers, buttons, scripts etc. or maybe even a fully fledged "system" of some sort and you want to share it with others, you can make a nice packages that other people can import with a single mouse click. The recommended procedure to make a large package that contains groups of all sorts of items e.g. trigger groups, individual triggers, scripts, buttons, aliases etc., is to export the entire profile with "save profile as". Then create a new empty profile e.g. with your package name. Don’t give a server or port name in the connection dialog and "connect". Mudlet will load the new empty profile although you are offline. Open the script editor and import your previously exported profile and then delete all items that are not part of the package that you are making. Finally, make a folder (group) that is named after your package name and version number e.g. "Johnny’s curing system 12-3-2009" and move all respective items into this folder and repeat the same procedure for all triggers/aliases/scripts etc.. This will make it much easier for other people to import your package and stay updated if you release a newer version. Then save your profile and use the "save profile as" button to create your package.

Using Variables in Mudlet

Using Variables in Mudlet

One of the major design goals in Mudlet was to integrate scripts and variables into triggers/aliases/buttons etc. as seamlessly as possible. The usage of variables in Mudlet is distinctly different from the other major clients, as native Lua scripting has been integrated into Mudlet from the ground up. As scripts are so closely intertwined with the core of Mudlet, variables do not need any special treatment as in other clients i.e. there is no need for code such as:

totalKills = getVariable("killedMonsters") + getVariable("killedVillains")
echo( "kills=" .. totalKills )

In Mudlet, the above code translates into:

totalKills = killedMonsters + killedVillains
echo( "kills=" .. totalKills )

If you define a variable in any given script in Mudlet, be it a trigger, a button, an alias key, an event handler, a free function, etc. It can be used from within any context without any special getVariable() type of function or any special variable symbols, such as @myVar etc.. In Mudlet all variables are native Lua variables. Each session (= profile/connection tab) runs in its own dedicated Lua interpreter. Consequently, all scripts of a profile are compiled into the same Lua interpreter and thus their code runs in the same variable space. All scripts from another simultaneously opened profile will not interfere because each profile uses its own Lua interpreter.

Note Everything shares the same variables & functions.

To give you an example: Let’s make a little trigger that counts how many monsters you have killed. Each time you have made a new kill, the trigger matches on the kill message and runs a little script that increases the amount of kills by one each time the trigger fires - in other words, each time you kill a monster and the kill message is sent from the MUD. For the kill counter we declare a variable and call it myKills. This variable is going to hold the number of kills we’ve made so far. The script will look like this:

myKills = myKills + 1

Then we add a little alias, a button or a keybindings that executes another little script that prints your current kill statistics on the screen. The attached script would look like this:

echo( "I have killed " .. myKills .. " monsters today." )

Let’s get back to our example. The trigger script expects myKills to be a number so you have to initialze the variable myKills to 0 before running the script for the first time. The best place to initialize variables is in script script outside of a function definition as this code is executed when the session is loaded or if you compile the script again after you have edited it. To do this click on the "Scripts" icon and select the standard script "My Global Variable Definitions". If you are using an older version of Mudlet or a profile that doesn’t have this script item, simply click on the "Add" icon and make your own script. You can call it whatever you want to. Add following code to initialize your new variable myKills to a number and set its value to 0:

myKills = 0

Whenever you edit this script, it will be recompiled and the code will be run as it is not part of a function definition. This is the major difference between trigger-scripts, alias-scripts etc. and script-scripts. Script-scripts can contain an unlimited amount of function definitions and also free code i. e. code outside of a function definition - code that is not enclosed by function xyz() …. end. On saving the script the script gets compiled and the free code is run instantly. All other item scripts, i. e. trigger-scripts etc., secretly define a function name for the script and thus the script is not free code, but function code. When a trigger fires Mudlet calls this invisible function name to run the script e.g. trigger738(), button82(), alias8(). This means that if you define variables inside a trigger script the variable will not be defined before the trigger runs for the first time. However, if you define this variable as free code in a script-script the definition becomes available immediately on script save. Now, whenever you add new variables to your variable definition script, the script gets run and your old variables will be reinitialized and reset to 0. This will be no big problem in most cases as you won’t work on your systems while really playing in most cases. To solve this problem you have two options:

First option: Add a script group (a folder) and add a new script item for each variable you define. This way, editing a variable definition will only reset the edited variable and none of the others that are defined in different scripts. This has the added advantage that you have a nice graphical overview of your defined variables.

Note Organize your variables

Second option (more advanced): Change the variable initialization to only initialize the variable if it hasn’t been initialized before, thus keeping the values of previously defined variables. This would look like this:

if myKills == nil then    -- this code initializes the variable myKills to the number 0 if it hasn't been initialed before
    myKills = 0
end

In Lua all undefined variables are initialized to the value nil. The value nil is not the same thing as the number 0 or the empty string "". What it means is that a variable that has the value nil has not been declared yet and does not exist. If a variable does not exist, it cannot be used as its value is undefined at this point. Consequently, increasing the value of nil by one is impossible as the variable doesn’t exist yet and will lead to a Lua error. The above script simply checks if the variable myKills has been defined yet and if it hasn’t, it will declare the variable and set its value to 0. === Lists Having variables that hold a single value is the most important usage of variables, but very often you’ll like to define variables that hold a list of values e. g. a list of your enemies, a list the items you are currently carrying etc.. To define a variable to be a list you need to declare it to be a Lua table. Let’s declare the variable myEnemies as a list containing the names of your enemies:

You can now add new enemies to this list by calling the Lua function listAdd( listName, item ) e.g.

listAdd( myEnemies, "Tom" )
listAdd( myEnemies, "Jim" )

To print the contents of your enemy list on the screen you can run this script

listPrint( myEnemies )

Now let’s make a little alias that adds a new name to your enemy list when you type "add enemy " followed by the name of the enemy e. g. "add enemy Peter" Open the alias editor by clicking on the alias icon. Click on the "Add" icon to add a new alias. Choose any name you like for your alias e.g. "add new enemy" and then define following pattern for the alias: ^add enemy (.*) Then add this little script in the script editor below:

listAdd( myEnemies, matches[2] )
echo( "Added a new enemy:" .. matches[2] .. "\n" )

Save the alias and try. Alias are explained in detail below. Another way to declare a list is to define its values directly.

myEnemies = { "Peter", "Jim", "Carl", "John" }

To remove an item from the list you can use the function listRemove( listName, item ). === Saving Variable Values to Disc Having statistics scripts that last as long as the session lasts is a nice thing, but it makes more sense to write the variables to disc and reload them when you play the next time. To do this you have to save your variables. Mudlet has 2 ways to implement variable persistence. First, you can tell Mudlet to save all of your variables on exit automatically and ask Mudlet to automatically restore them when the session gets reloaded the next time you play on this profile. Second, you can take care of saving your variables yourself and reloading them yourself. This gives you more control and will be the preferred solution in bigger systems.

To be continued …

Input Triggers - Mudlets Alias Engine

Important QUICKSTART: Here is a video tutorial on how to do basic aliases in Mudlet: http://blip.tv/file/2288749

Alias are triggers that operate on user input. Mudlet uses hierarchically ordered powerful Perl regex expression alias. We have explicitly chosen not to offer multi condition alias, alias chains or the same trigger types the trigger engine offers because this would be way over the top and is simply not needed for alias expansion - although it should be noted that the processes are closely related, except that aliases, i.e. input triggers, operate on a different data stream, namely the user input stream, whereas triggers operate on the MUD output data stream. The only real difference between output triggers and input triggers is that input triggers can change the input stream they work on, whereas output triggers cannot change the stream itself - output triggers can change what is printed on the screen as a result of the stream, but they cannot change the stream itself. This is a fundamental difference and a deeper understanding is key to getting to grips with Mudlets alias engine. When you enter a command on the keyboard and press enter or return, the text that you have typed in the command line will be forwarded to the alias unit, i. e. the input trigger unit, in form of the Lua variable command. This variable will be matched against all active alias in the hierarchy unless access to an alias branch is locked by the user or by a script. If an input trigger matches, it will intercept the user command and the original command will be ignored. Upon a match the clear text command is being send as a command to the MUD in replacement of the original command, if a clear text command has been specified by the user and the attached alias script is being executed. However, the initial command that the user has typed in the command line will not be sent unless you do this as part of your script. Consequently, if you want your input trigger to send a command to the MUD, you’ll either have to specify a clear text command for simple cases or send commands via the attached alias script e.g. send("kill monster"). You may argue that you feel that it is unnecessary work to be forced to send a command replacement yourself, but this very fact makes our alias system way more powerful because it gives you complete control about what is happening. Why is this so? The initial user command is being held in the Lua variable command. When this value changes within the alias unit processing chain, the initial user input that the input triggers work on can be rewritten and changed in the process. Consequently, you can substitute the user input step by step - or alias by alias - without that anything happens as far as sending commands is being concerned unless you explicitly decide to do so.

Note .

The example in the diagram above shows 2 matching aliases, but only one of them sends commands to the MUD - and only if the player is healthy enough to attack the opponent. The other alias that matched the user input (enemy) choses a fitting opponent and sets the variable enemy accordingly, otherwise it issues a warning that attacking one of the available enemies would be too dangerous.

For an input trigger to match the command text the same rules as explained above in the trigger section apply. However, to simplify matters there is only one alias type. As alias are not performance critical we could reduce the amount of trigger types to just Perl regex as this type can do it all and performance is no issue with alias as the amount of data is much less. Even if you type like a madman you’ll never get close to sending the same amount of text to the MUD than the amount of text the MUD sends back to you.

What does it mean that a regex is true or "matched"? A trigger or an alias fires - or executes its commands/script - when the text matches the pattern of the trigger or alias. In most cases this means that the text contains the trigger/alias pattern. If the regex pattern is reen then a text "The green house" will match because "reen" is contained in the text. More complex regex patterns can also hold information on where in the text a certain pattern must occur in order to match. ^tj only matches when the letters "tj" occur at the beginning of the text. Consequently, a text like "go tj" would not match. Regex patterns can also capture data like numbers, sequences of letters, words etc. at certain positions in the text. This is very useful for MUD related scripting and this is why it is explained below.

Let’s get back to alias. We start with a simple example.

We want Mudlet to send "put weapon in bag" whenever we type "pwb". Consequently, the pattern is pwb and as the task is so simple it’s enough to enter "put weapon in bag" in the send field. Then we click on save to save the changes and activate the alias by clicking on the padlock icon. Then we leave the trigger editor and test our new alias. After typing "pwb" and pressing return Mudlet will send the command "put weapon in bag" to the MUD.

Let’s move on to a more complicated example that is needed very often.

We want our script to automatically put the weapon in the correct bag as we have many bags and many weapons. The pattern stays the same. ^pwb The ^ at the beginning of the line means that the command starts with pwd and no other letter in front of this. If we define our pattern more clearly, the pattern will match less often. Without the ^ the alias will match and the alias script will always be run whenever there is the sequence of letters "pwd" in your commands. This may not always be what you want. This is why it’s usually a good idea to make the pattern definition as exact as needed by being less general. The more general the pattern, the more often it will match.

Back to our task: The pattern is ^pwb. Let’s assume that we have defined 2 variables in some other script. The variable "weapon" is the weapon we use and the variable "bag" is the name of the bag. NOTE: In Mudlet global variables can be accessed anywhere from within Mudlet scripts - no matter if they have been defined in a trigger script, in an alias script or in a key or button script. As soon as it’s been defined it somewhere it is usable. To make sure that a variable is local only, i. e. cannot be referenced from other scripts, you have to use the keyword local in front of your variable definition. Back to our alias: Pattern is:[,#b0e0e6]^pwb Script is:

send( "put " .. weapon .. " in " .. bag )

Depending on the values of our variables Weapon and bag the command "pwd" will be substituted with an appropriate command. To set your weapon and bag variables we use 2 more aliases: Alias to set the weapon: uw (\w)+ Script:

weapon = matches[2];
send( "wield " .. weapon )

To set our bag variable: Pattern:[,#b0e0e6]^set bag (.*)

bag = matches[2]

Now let’s go back to our initial problem. We want an alias to put our current weapon into our current bag. But what happens if we are in the middle of a fight and absolutely need to sip a healing potions because we are close to death and cannot take the risk that the bag may be too full to take the weapon? We want to upgrade out little alias to take into account that the bag may be full and chose an empty bag instead. To do this we set up a trigger that detects messages that indicate that the attempt to put the weapon in the bag failed. In this trigger we execute this little bag-is-full-detection-trigger Trigger Pattern: (type substring) "Your bag is full." script:

bagIsFull = true;

This detection trigger will set the variable bagIsFull to true as soon as it sees the message "Your bag is full.". Then you know that you have to use your spare bag to take the weapon.

Now we have the tools to write an improved version of our little alias script:

if bagIsFull then
    send( "put " .. weapon .. " in " .. spareBag )
else
    send( "put " .. weapon .. " in " .. bag )
end

The next example is one of the most common aliases a tell alias: Pattern:[,#b0e0e6]^tj (.*) Script:

send( "tell Jane " .. matches[2]

Sadly, Jane is your fiancée and the one thing she is a vegetarian and absolutely hates all words that relate to meat. Luckily, you know enough about aliases by now to make her believe that you’d never ever even think about meat. So you head to your global function script (any script item will do as long as you define your variables outside of your function definitions. See the scripts chapter below for more information. In your script "my global functions" you add a Lua table containing a list of all of all words that a vegetarian might hate. For example:

happyJaneTable = { "meat", "burger", "steak", "hamburger", "chickenburger" }

Now you can upgrade your tell-jane script to automatically search our tell for all words that Jane might not like. In case such a word is found we substitute the entire tell with "How is the weather?".

for key, value in ipairs( happyJaneTable ) do     -- looking at each element of the list
    badWord = happyJaneTable[key]                 -- check out the Lua table chapter below for more info
    begin, end = string.find( command, badWord )  -- begin holds the start position of the word, end* the end-position
    if begin ~= nil then                          -- we have found a bad word
        send( "tell Jane How is the weather?" )
        return
    end
end

Mudlets Trigger Engine

Unlike alias that define patterns that match on user input, triggers define patterns that match on MUD output. In other words, triggers react to text that has been sent by the MUD, whereas alias react to user commands that have been typed into the command line.

Simple Trigger Matching

Note .script editor screenshot
Important QUICKSTART: Here is a simple video tutorial on how to make basic triggers in Mudlet: http://blip.tv/file/2288760

To begin with, click on the "Add" button to create a new trigger. Then put the text pattern that you’d like to trigger on into the trigger conditions table on the right side of the screen above the script editor. Afterwards, chose the correct pattern type of your trigger pattern in the drop down list on the right side of the trigger pattern i.e. in the second column of the trigger pattern table. If you define multiple patterns in the same trigger, your trigger will run whenever any one of these patterns matches unless you chose the AND-trigger option, in which case the trigger will only fire if all patterns match within a specified amount of lines from the MUD. For more advanced information on AND and OR trigger see the corresponding AND/OR trigger section below. The next step is to define what should happen when the trigger matches. Usually, this will be done by a Lua script in the Lua editor below the table with the pattern list. In the beginning, you can simply chose the "highlight trigger" option to make your trigger highlight the text that it has triggered on or send a clear text command to the MUD whenever the trigger fires until you have learned enough Lua to more meaningful scripts. Clear text command can be defined in the "send plain text" input box next to the trigger name above the pattern table. Finally, you need to save the new trigger and then activate it with the padlock icon button. By default, new triggers are deactivated and thus will do nothing unless you explicitly activate them. Activated triggers show a green tick in the little blue box on the left side of the trigger name in the trigger tree on the left side of the script editor dialog. There is three ways to save your changes. 1. click on the save icon 2. adding a new trigger 3. clicking on another trigger item. Triggers that have not been saved yet cannot be activated. If you see a bug icon instead of an activation box, there is some error that prevents to activate your trigger. Check the error message above the pattern table.

Simple Highlighter Triggers

Tip Beginners should use Mudlets automated highlight triggers in the beginning to get the hang of the different trigger and pattern types quicker. Click on the "highlight trigger" option and pick a foreground and a background color. When the trigger matches it automatically highlights its pattern. This is the most used form of triggers in mudding as it is a quick way of highlighting words that are important to you at the moment. This helps you spot things at a single glance instead of reading the entire text. You don’t have to know anything about scripting, regular expressions etc. to use highlight triggers. Just type in the word you like to be highlighted, select appropriate colors, save the new trigger and activate it.

More advanced users will often want to do custom highlighting from within scripts. This is how it works: If you want to highlight the word "pond" in the above example you have to add the following little Lua script to the script editor on the lower right side of the Script Editor window:

selectString( "pond", 1 )
fg( "red " )
bg( "blue" )
resetFormat()

"AND" and "OR" Condition Triggers

AND -Triggers execute their respective command or script only if all conditions in their respective conditions expression list are fulfilled. OR-Triggers execute when any one of their conditions is true. To make OR-Triggers you simply have to add a few conditions to the conditions list e.g. in our example: "pond", "frog", "Plop". The trigger will now also execute on lines like this: "A frog is green" or "You hear a loud Plop!" However, it will not execute on "With a loud plop the frog dived into the water." because "plop" in the line is in lower case letters and your condition specified a "P" in upper case. The simplest form of AND-Triggers in Mudlet are Trigger Chains or Filter Chains, whatever you’d like to call it.

Trigger Chains & Filter Chains

"Chains" and "filters" are different trigger group entities in Mudlet and serve completely different ends.

Chains

A chain is defined in Mudlet by making a trigger group and adding a trigger pattern to the group. A group without a pattern is a simple trigger group that serves no other purposes than adding structure to your trigger system in order to organize your triggers better. Such a normal trigger group will always grant access to its children unless it has been explicitly disabled (= all access to itself or any of its children is locked) either manually or by a script.

A trigger group with a defined trigger pattern, however, will behave like a normal trigger and match if the pattern matches. Such a trigger group is called "chain head". A chain head will only grant access to its children if the trigger pattern has matched and the chain has been enabled. Thus, chains can be looked at as a mechanism to automatically enable and disable triggers or groups of triggers when a certain condition has been met i. e. the trigger pattern of the chain head has been matched. (However, technically this is not correct as disabled child triggers will not be invoked if the chain head matches. In other words, in chains you can still enabled/disabled elements. The idea of a chain can better be described by necessary and sufficient condition - both of which need to be met before a child trigger is being run.)

Adding child triggers to this group will add elements to the trigger chain. These chain elements will only be activated if the chain head has matched before and thus opened the trigger chain. The chain stays open until the "keep chain open for x lines" value has been reached. The default is 0 which means that the chain only stays open for the current line. When access to the chain has been granted all child triggers will be tested against the content of the current line.. Consequently, trigger chains are a means to automatically enable/disable trigger groups without the hassle of enabling and disabling trigger groups manually. This has 2 important advantages: Chains are faster than conventional solutions and chains reduce the complexity of your scripts and greatly reduce the usual system bugs that inevitably go along with enable/disable trigger xy function calls as it’s very difficult and error prone to enable and disable your triggers correctly in large complex trigger systems. This is one of the most powerful features in Mudlet and should be used whenever possible.

Filters

You can turn a trigger chain head into a filter by checking the "filter" option. This changes the content of what is forwarded as trigger text to the children triggers in the chain. Chains forward the content of the current line as trigger text whereas filters forward the matched pattern instead of the current line. In other words, the text of the current line is filtered according to the pattern of the filter. For example: You want to know the exits in the current room. The simplest solution is a simple filter on "You see exits to: (.*)" Then you simply add triggers to the filter chain such as "north", "south", "west", "east" etc. The direction triggers will only be called if the filter head has matched.

Imagine the following scenario: You want to collect some berries. You know that the room contains some berries if the room description contains the words "You are inside a forrest." You make a new substring trigger for this line, but instead of choosing a regular trigger, you chose to add a new trigger group. Now you add "You are inside a forest" to the expression list of the trigger group. When adding conditions to a trigger group, the trigger group turns from an organizational unit into a filter unit. From now on this folder is a filter and will only let data pass through that matches it’s condition. In our case this is exactly what we want, because we don’t want to collect all sorts of berries, but we only want 2 particular kinds, namely, strawberries and blackberries, and we know that these berries can only be trusted if they are picked inside a forest as other areas may contain contaminated berries. Now you add two regular triggers to our berry-in-the-forrest filter - one containing the condition: "strawberries" and the other one "blackberries". Then we add the commands to pick the particular kind of berry to both triggers (send field). Now what happens is that as soon as a room description reads "You are inside a forrest." the filter will let the line containing the room description pass through to our two berry triggers and they will issue commands to pick berries, if there are such berries. However, in any other situation the words "strawberries" and "blackberries" will NOT trigger a pick - only in the above scenario when the filter parent’s condition is met. This is a very nice way to solve complicated problems with a few easy filter chains. This example is trivial, but using filter chains will rapidly show you how formerly complicated things that could only be solved with very complicated regular expressions can be solved easily now with a couple of filter chains. It should be noted that filter chains only work on single lines. This means that if the filter chain head "You are inside a forrest" is in a different line than the other child chain element triggers (stawberr- and black berry triggers) the triggers will not fire as the line that is being let through the filter does not contain the words strawberries or blackberries. Most MUDs, however, offer a feature that lets your client do the word wrapping. This is a very powerful tool for scripting and should be enabled by you in your MUD as then the entire room description or the entire tell will be sent out to Mudlet in one line and Mudlet will do the word wrapping for you. Now you can use filter chains much more effectively as the line content comprises many lines. Triggering will become much easier. Ask your MUD operators how to enable this feature. Most big MUDs can do this these days. Let’s look at a practical example for a trigger chain:

Multi-Line Triggers and Multi-Condition Triggers

Multi Condition Triggers are the most advanced feature of Mudlets trigger engine. Like trigger chains or filter chains they are a form of AND-Triggers. All conditions in the list must have matched within the specified margin of lines (delta), in order to trigger the script. Normal triggers fire and run the script as soon as one of the conditions in the regex list is met i.e. if one of the regex/string matches match - or the Lua function condition returns true, the trigger script is run. In multiline triggers, however, each single regex/string/Lua function condition in the list has to have matched within the specified margin of lines at least once to trigger the script. The sequence of the conditions is binding. This means that if the 10th regex on the regex list would be matched on the eleventh line after the match of the first line happened, the trigger will NOT run unless the margin of lines is set to 11. If condition #3 is true but currently #2 is waiting to be true, condition #3 is ignored and must be true again after condition #2 has been true. Conditions can also be Lua Functions or plain Lua code that returns a boolean truth value. You can mix all types of conditions to build complex multi-condition triggers that only fire if all conditions are met. This is a very powerful feature as it reduces the amount of scripting to a minimum or even takes away with the need to script formerly complex processes completely. Multicondition triggers are multi-line triggers, i. e. the conditions can all be met in a single line or many lines after the first condition has been fulfilled. This effectively reduces the amount of complexity as you have all the important conditions placed into a single trigger and all the tedious bookkeeping, variable and condition state accounting is being done by Mudlets trigger engine. The result of this is that the amount of manual condition checking via many different trigger scripts and legions of if condition1 == true then check condition2 can be forgotten about. All you have to do is to define the conditions and the final action that is taken if the trigger fires.

Note This diagram shows what steps are involved in the process of problem solving with Mudlets trigger engine. The main question is: How do we arrive at a solution to our problem, and how can we simplify the problem as much as possible?

Example: Let’s go back to our pond & frog example. We have explained the difference between AND-triggers and OR-triggers. If you have a room description consisting of 3 lines:

1. You see a pond
2. You see a frog.
3. The frog sits on a stone.

Every single one of these 3 lines will be fed into the trigger engine one after another. If we define an OR-trigger with a condition list consisting of 3 condition patterns:

condition #1 pattern = pond condition #2 pattern = frog condition #3 pattern = stone

Whether or not a condition is found to be true also depends on another property, namely the type of the condition. The condition type can be among others:

  1. substring matching → the condition is true if the condition pattern is a substring of the output line from the MUD. In other words: If the pattern "pond" is contained in any line of output, the condition is true.

  2. begin of line matching → the condition is only true if the condition pattern can be found at the beginning of a line from the MUD.

  3. Perl regular expression → the condition is true if the Perl regex pattern is matched. You’ll find more information on Perl regex below.

  4. Lua code that returns a truth value e.g. a call to a function check() that return either true or false depending on the condition

In our example we chose condition type "substring" for all three conditions. Consequently, the trigger will fire the command or script 3 times i. e. the trigger will do on each line it is matched against because in every line at least one condition evaluates to true because the pattern is a substring of the line.

in line #1 we get: pond = true.
in line #2 we get frog = true and
in line #3 two conditions are true i.e. frog=true and stone = true

Because an OR-trigger fires on the first condition that is true and ignores the rest the trigger will only execute 3 times on these 3 lines although 4 conditions are true.

CAUTION: The multi line condition switch must be turned off to get an OR-trigger! If the multi-line condition switch is turned on the trigger becomes and AND trigger which means that the trigger only fires if all conditions are true and fulfilled in the correct sequence. With OR-triggers the sequence is irrelevant.

To complicate matters, however, you don’t want your trigger to fire 3 commands, because you want to use this room description as a whole to fire your trigger e. g. this pond is the only kind of ponds in the entire world that doesn’t have poisoned water. So you want to make sure that you only drink water from a pond of this kind and from no other pond. Your solution is to use Multi Condition Triggers (MCT). If you check the MCT checkbox this trigger will fire only once from now on - and only if all conditions are met i e. when you can guarantee that you only drink water from a good pond because your drinking trigger is matching on the entire room description despite that this room description my be spread over a number of lines. (NOTE: If you have word wrap turned off in your MUD chances are that the entire room description will be contained in a single line, but we are trying to keep the examples as easy as possible.)

Sadly, there are many unfriendly people in this world and somebody goes around and poisons your good ponds. Consequently, you would want to examine the frog and find out if it is poisoned before drinking water from the pond. This is difficult because the villain is a mean magician who used illusion spells to make everything look like the good pond. To solve the problem you can now resort to Lua function conditions in the trigger condition list that perform certain check ups to put the current room description into a wider context e. g. check if you have been here before etc. This adds yet another level of complexity to your problem but this is a very powerful means to use the full potential of Mudlets MCTs.

You can combine all forms of conditions with trigger chains, filters and Lua functions. Mudlet gives you relatively easy to use tools that require no programming background. However, these tools can evolve into complex powerful problem solving mechanisms if they are combined with each other thus enabling non-programmer users to solve problems that would need a profound programming background in other MUD clients. However, unlocking the full potential of Mudlet requires you do learn some Lua basics. In this manual we’ll try to be as easy on you as we can in this respect, but it’s highly recommended that you dig deeper into Lua after a while. It’s one of the easiest fully fledged scripting languages available, easy to learn and the fastest of them all, and this is why it has been chosen by us. You don’t need to become a programmer to be able to use Mudlet effectively. All you have to know is how to work with variables and how to do if conditions and maybe a few loops. But knowing more won’t harm you and it will make your systems more effective.

Lua Code Conditions & Variable Triggers - Expression Triggers

In a Lua Code/Function Condition (LFC) you can run Lua code inside the trigger engine directly. The easiest example would be a simple variable trigger: Add a new trigger and chose pattern type Lua Function Condition. Then define this pattern: if health ⇐ 100 then escape() end Another formulation of the same would be: checkHealth() For the last formulation to work you have defined a Lua function checkHealth(). Open the script editor, add a new script "health care" and add this code to the new script-script.

function checkHealth()
    if health <= 100 then
        echo( "WARNING: Low health! I have to run away!\n" )
        startEscape()
        return true
    else
        return false
    end
end

Lua function conditions effectively means that you run the Lua code they represent on every single line that is received from the MUD, unless the LFCs are part of a multi-condition trigger, in which case the LFCs would only be run when they would be the current test-condition of their respective trigger state. LFCs are implemented in such a way that the trigger engine only calls the compiled byte code, but running as few scripts as possible is always the best idea. LFCs are nice and handy, and for most people the performance aspect will not be relevant at all.

Scripting: Generating Triggers - Special Trigger Types for Scripting Needs

Temporary Triggers (scripting only)

Temporary triggers are lightweight triggers that are tailored for typical scripting needs. These are only available via Lua scripting. They are not stored in profiles, but stay in memory as long as the program runs or until they are deleted (killTimer()). There are several forms of temp-triggers that address different scripting needs. Check the Lua API table for reference.

Line Triggers (scripting only)

Line triggers trigger on a specified line in the future - or a sequence of lines - irrespective of the content of the line. This type of trigger can be very handy in scripting if you know what is coming e.g. you want to parse a table from the MUD, maps etc.

Enabling and Disabling Triggers in Scripts

enableTrigger() disableTrigger()

Testing your triggers

Externally

RegexPal - a good website for testing your triggers against a set of text. [kiki-re - stand-alone program which will also tell you which matches are translated to what wildcard number.

The Timer Engine

Mudlet supports 4 different sort of timers:

  1. Regular GUI Timers that fire repeatedly in a certain interval specified by the user.

  2. Offset Timers are child timers of a parent timer and fire a single shot after a specified timeout after their parent fired its respective timeout. This interval is an offset to the interval of its parent timer. Example: parent timer fires every 30 seconds and by doing so kicks off 3 offset timers with an offset of 5 seconds each. Consequently, the 3 children fire 5 seconds after each time the parent timer fired. Offset timers differ visually from regular timers and are represented with a + icon for offset. Offset timers can be turned on and off by the user just like any other timer.

  3. Temporary Timers are very useful, and are the most common type of timer used for scripting purposes. They behave like regular timers, but they are one shot only timers.

  4. Batch Job Timers are a form of timer that issue a sequence of commands/scripts according to a certain timeout instead of a single command/script. This is a very important tool if the sequence of commands is important. Timers depend largely on the operating system you are using and it cannot be guaranteed under certain conditions that if you have set up 5 timers to fire after 1.3 seconds that the sequence in which they fire is the same sequence in which they were created. If the sequence of commands is important, you should always use batch job timers as this form of timers guarantees that the sequence of commands is observed. For example: If you want to make an auto-miner bot that digs its way into a gold mine digging left, down, down, right, left, down until a trigger catches a message that indicates that the mine is going to collapse and bury your poor soul unless you run for your life and head out of the mine. In this scenario the sequence of commands is vital as you’d lose your way and die. This is a classical case for a batch job timer.

The most common usage of temporary timers is the function tempTimer(). It lets you specify a timeout after which a script is being run e.g.

tempTimer( 0.3, [[send("kill rat")]] )

This will issue the command "kill rat" after 0.3 seconds. Other clients call this kind of function wait() or doAfter() etc. It is one of the most used functions in MUD scripting. tempTimer() is a single shot timer. It will only fire once and is then marked for deletion. TempTriggers(), by contrast, live through the entire session and are never deleted unless you explicitly delete them or disable them.

Another often used function in the context of timers is enableTimer( timerName ), or disableTimer( timerName ). Those are the counterparts of enableTrigger( triggerName ) and disableTrigger( triggerName ), enableKey( keyName ) etc..

NOTE: Temporary timers cannot be accessed from the GUI and are not saved in profiles.

To be continued ….

Buttons and Custom User Toolbars

Note .

Scripting with Mudlet

Lua tables can basically be considered multidimensional arrays and dictionaries at the same time. If we have the table matches, matches[1] is the first element, matches[n] the n-th element.

a = "Tom"
matches[1] = "Betty"
b = matches[1]
c = a .. b and e will equal "TomBetty"

To output a table you can use a convenience function printTable( name ). This function is defined in LuaGlobal.lua and can be found in your home directory under ./mudlet (note the leading dot ) Profiles and mudlet_documentation.html are stored in this directory as well.

Lua interface functions to Mudlet - or how do I access triggers, timers etc. from Lua scripts

How to get data from regex capture groups? Regular expression capture groups (e.g. "(\d+)" ) are passed on to Lua scripts as a Lua table matches. To make use of this information inside Lua scripts, you need to specify the number of the capture group within the regex.

Example: You have (\d+) weapons and they are (?:(\b\w+\W+)+)

This regex contains 3 capture groups, but only the 2 green colored ones contain data as the red capture group is a non-capturing group. Consequently, your Lua script gets passed only 2 instead of 3 capture groups and matches[3] is undefined.

In your Lua script you may write following program in order to print the number and status of your weapons on the screen:

number_of_weapons = matches[1]
status_of_weapons = matches[2]
notice = number_of_weapons .. status_of_weapons
echo( notice )
send( "put weapons in backpack" )

-- the following 2 lines color the first capture
-- group red and the second group blue
-- see below for details

selectCaptureGroup( 1 )
setFgColor( 255,0,0 )

selectCaptureGroup( 2 )
setFgColor( 0,0,255 )

The best way is to use selectCaptureGroup( number ) to select the proper capture group and then perform your actions on it e.g. replace(), highlight etc. Note: Both selectCaptureGroup() and matches[n] start with group 1.

How to select all occurrences of "Tom" and highlight them?

You add a function like this to a script containing you main function definitions. Note that script items differ from all other "scripts" in triggers, timers, actions etc. because they require you to put your code in proper functions that can be called by your other trigger-scripts, timer-scripts etc. via normal function calls. Trigger-scripts, timer-scripts etc. cannot contain any function definitions because they are automatically generated functions themselves because this makes usage a lot easier.

To come back to our question how to select all occurrences of "Tom" and highlight them:

function setBgColorAll( word, r, g, b )
    i = 0
    word_count = 1
    while i > -1 do
        i = selectString(word, word_count)
        if i == -1 then
             return
        end
        word_count = word_count +1
        setBgColor( r, g, b )
    end
end

Then you simply define a substring matching trigger on the word "Tom" and in the trigger script you call above function:

setBgColorAll("Tom", 255,50,50)

Sending commands to the MUD or printing information messages on the screen

To print information messages on the session screen you can use the echo( message ) function, or insertText( text). Currently, it only takes one string as argument.

To send a command to the MUD, you can use the send( command ) function. Note: everything you send via send() will be processed by the alias processing unit. In Alias scripts the command that is being sent to the MUD is contained in the variable command that you can change in the context of Alias scripts. Alias take regular expressions, as well. As a result, you can use following regex and script to talk like Yoda: Perl regex:

say (\w+).*(\w*).*(.*)

script:

send( "say " .. matches[3] .." " .. matches[1] .." ".. matches[2] )

Note: The variable "command" contains what was entered in the command line or issued via the expandAlias( ) function. If you use expandAlias( command ) inside an alias script the command would be doubled. You have to use send( ) inside an alias script to prevent recursion. This will send the data directly and bypass the alias expansion.

Changing text from the MUD or reformatting text (highlight, make bold etc.)

When sending commands to the MUD - from now on referred to as output stream - alias scripts find the command that was issued by the user stored in the variable "command".

By manipulating the value, the command can easily be changed before it is being sent to the MUD.

However, things get much more complicated with the data received from the MUD – from now on referred to as input stream. Before triggers can be run on the MUD data, Mudlet has to strip all format codes from the text and store it in data structures associated with the text. Consequently, the text that is being passed on to the trigger processing unit is a small subset of the data received from the MUD. If you want to edit, replace, delete or reformat text from within your trigger scripts you have to keep this in mind if you don’t want to lose all text format information such as colors etc.

As the text is linked with data structures containing the format of the text, the cursor position inside the line is important if data is being changed. You select a word or a sequence of characters from the line and then issue commands to do actions on the selected data.

Replacing the word "Tom" with "Betty" in the line: Jim, Tom and Lucy are learning a new spell. This could be done with following script:

selectString("Tom",1)
replace("Betty")

Things get more complicated if there are two or more occurrences of "Tom" in the line e.g. Jim and Tom like magic. Jim, Tom and Lucy are learning a new spell.

The above example code would select the first occurrence of "Tom" in this line and ignore the second. If you want to work on the the second occurrence of "Tom" you have to specify the occurrence number in the call to select().

selectString( "Tom", 2 )
replace( "Betty" )

This code would change the second "Tom" and leave the first "Tom" alone. The function call

replaceAll( "Betty" )

will replace all occurrences of "Tom" with "Betty" in the line if "Tom" has been selected before. replaceAll() is a convenience function defined in LuaGlobal.lua.

Colorization example: You want to change to color of the words "ugly monster" to red on a white background.

You add a new trigger and define the regex: ugly monster In the script you write:

selectString("ugly monster", 1 )
setFgColor(255,0,0)
setBgColor(255,255,255)
resetFormat()

Another means to select text is to select a range of characters by specifying cursor positions. If we have following line: Jim and Tom like magic. Jim, Tom and Lucy are learning a new spell.

selectSection( 28, 3 )

This example would select the second Tom. The first argument to selectSection is the cursor position within the line and the second argument is the length of the selection.

selectCaptureGroup( number )

Deleting Text - Gagging

This function selects the captureGroup number if you use Perl regular expressions containing capture groups. The first capture group starts with index 1.

deleteLine()

This function deletes the current line - or any line where the cursor is currently placed. You can use repeated calls to this function to effectively erase the entire text buffer. If you want to delete or gag certain words only, you can select the text that you want to delete and then replace it with an empty string e.g:

If you get this line form the MUD: "Mary and Tom walk to the diner."

selectString( "Tom", 1 )
replace( "" )

Then the output will be changed to: "Mary and walk to the diner."

Cursor Movement and Cursor Placement

moveCursor( windowName, x, y ) This will move the user cursor of window windowName to the absolute (x/y) coordinates in the text.

moveCursor( "main", 20, 3950 ) will move the cursor on the 20th character from the left on line number 3950. To determine the current cursor position you can use getLineNumber() and getColumnNumber() as well as getLastLineNumber() to get the number of the last line in the text buffer. moveCursorEnd("main") will move the cursor of the main display to end of the buffer. This is always a new line of size 1 containing the character \n.

number_of_last_line_in_text = getLineCount()

returns the number of the last line of the text in the console buffer. This number will change as soon as a new \n is printed either by the user or

when a new line arrives from the MUD. All lines from the MUD are terminated with \n which is called line feed or the new line character. This control character ends the current line and move the cursor to the beginning of the next line, thus creating a new, empty line below the line that contains the \n.

line_number_of_the_current_cursor_position = getLineNumber()

column_number_of_the_current_cursor_position = getColumnNumber()

luaTable_containing_textlines = getLines( absolute_line_number_from, absolute_line_number_to )

this will return a Lua table containing all lines between the absolute positions from and to. NOTE: This function uses absolute line numbers, not relative ones like in moveCursor(). This little demo script shows you how to use cursor functions:

moveCursor() return true or false depending on whether the move was possible.

User defined dockable windows

You may want to use dock windows to display information you gathered in your scripts, or you may want to use them as chat windows etc. Adding a user defined window:

openUserWindow( string window_name )

echoUserWindow( string window_name, string text )

setWindowSize( int x, int y )

clearWindow( string window_name )

Dynamic Timers

tempTimer( double timeout, string lua code_to_execute, string/float/int timer_name ) disableTimer( name ) enableTimer( name )

Dynamic Triggers

triggerID = tempTrigger( regex, code ) creates a fast substring matching trigger triggerID = tempRegexTrigger( regex, code ) creates a regular expression matching trigger

Registering Event Handlers and Raising Events

raiseEvent( string name, args )

As an example, your prompt trigger could raise an onPrompt event if you want to attach 2 functions to it. In your prompt trigger, all you’d need to do is raiseEvent("onPrompt") Now we go about creating functions that attach to the event. Lets say the first one is check_health_stuff() and the other is check_salve_stuff(). We would like these to be executed when the event is raised. So create a script and give it a name of check_health_stuff. In the Add user defined event handler, type onPrompt, and press enter to add it to the list. In the script box, create: function check_health_stuff()blah blah end. When the onPrompt event comes along, that script catches it, and does check_health_stuff() for you.

Default events raised by Mudlet

Mudlet itself also creates events for your scripts to hook on. The following events are generated currently:

sysWindowResizeEvent

Raised when the main window is resized, with the new height and width coordinates passed to the event. A common usecase for this event is to move/resize your UI elements according to the new dimensions.

Example

This sample code will echo whenever a resize happened with the new dimensions:

function resizeEvent( event, x, y )
        echo("RESIZE EVENT: event="..event.." x="..x.." y="..y.."\n")
end

sysWindowMousePressEvent

Raised when a mouse button is pressed down anywhere on the main window (note that a click is composed of a mouse press and mouse release). The button number and the x,y coordinates of the click are reported.

Example
function onClickHandler( event, button, x, y )
        echo("CLICK event:"..event.." button="..button.." x="..x.." y="..y.."\n")
end

sysWindowMouseReleaseEvent

Raised when a mouse button is released after being pressed down anywhere on the main window (note that a click is composed of a mouse press and mouse release). See sysWindowMousePressEvent for example use.

ATCP events

Mudlets ATCP implementation generates events for each message that comes, allowing you to trigger on them easily. Since ATCP messages vary in name, event names will vary as well. See the atcp section on how to use them.

Handling Tables in Lua

Nick Gammon has written a very nice overview on how to deal with Lua tables. You can find it here: http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=6036.

How to use multilinematches[n][m]

(The following example can be tested on the MUD batmud.bat.org)

In the case of a multiline trigger with these 2 Perl regex as conditions:

^You have (\w+) (\w+) (\w+) (\w+)
^You are (\w+).*(\w+).*

The command "score" generates the following output on batMUD:

You have an almost non-existent ability for avoiding hits.
You are irreproachably kind.
You have not completed any quests.
You are refreshed, hungry, very young and brave.
Conquer leads the human race.
Hp:295/295 Sp:132/132 Ep:182/181 Exp:269 >

If you add this script to the trigger:

showMultimatches()

The script, i.e. the call to the function showMultimatches() generates this output:

 -------------------------------------------------------
 The table multimatches[n][m] contains:
 -------------------------------------------------------
 regex 1 captured: (multimatches[1][1-n])
           key=1 value=You have not completed any quests
           key=2 value=not
           key=3 value=completed
           key=4 value=any
           key=5 value=quests
 regex 2 captured: (multimatches[2][1-n])
           key=1 value=You are refreshed, hungry, very young and brave
           key=2 value=refreshed
           key=3 value=young
           key=4 value=and
           key=5 value=brave
 -------------------------------------------------------

The function showMultimatches() prints out the content of the table multimatches[n][m]. You can now see what the table multimatches[][] contains in this case. The first trigger condition (=regex 1) got as the first full match "You have not completed any quests". This is stored in multimatches[1][1] as the value of key=1 in the sub-table matches[1] which, in turn, is the value of key=1 of the table multimatches[n][m].

The structure of the table multimatches:

multimatches {
                1 = {
                       matches[1] of regex 1
                       matches[2] of regex 1
                       matches[3] of regex 1
                              ...
                       matches[n] of regex 1 },
                2 = {
                       matches[1] of regex 2
                       matches[2] of regex 2
                             ...
                       matches[n] of regex 2 },
                 ...         ...
                n = {
                       matches[1] of regex n
                       matches[2] of regex n
                             ...
                       matches[n] of regex n }
}

The sub-table matches[n] is the same table matches[n] you get when you have a standard non-multiline trigger. The value of the first key, i. e. matches[1], holds the first complete match of the regex. Subsequent keys hold the respective capture groups. For example: Let regex = "You have (\d+) gold and (\d+) silver" and the text from the MUD = "You have 5 gold and 7 silver coins in your bag." Then matches[1] contains "You have 5 gold and 7 silver", matches[2] = "5" and matches[3] = "7". In your script you could do:

myGold = myGold + tonumber( matches[2] )
mySilver = mySilver + tonumber( matches[3] )

However, if you’d like to use this script in the context of a multiline trigger, matches[] would not be defined as there are more than one regex. You need to use multimatches[n][m] in multiline triggers. Above script would look like this if above regex would be the first regex in the multiline trigger:

myGold = myGold + tonumber( multimatches[1][2] )
mySilver = mySilver + tonumber( multimatches[1][3] )

What makes multiline triggers really shine is the ability to react to MUD output that is spread over multiple lines and only fire the action (=run the script) if all conditions have been fulfilled in the specified amount of lines.

Scripting howtos

How to highlight my current target?

You can put the following script into your targetting alias:

if id then killTrigger(id) end
id = tempTrigger(target, [[selectString("]] .. target .. [[", 1) fg("gold") resetFormat()]])

Where target is your target variable. Note that you have to use the full name, capitalized. If you’d like the script to auto-capitalize for you, you can use this version*:

target = target:title()
if id then killTrigger(id) end
id = tempTrigger(target, [[selectString("]] .. target .. [[", 1) fg("gold") resetFormat()]])

^*requires Mudlet 1.1.0

ATCP

Since version 1.0.6, Mudlet includes support for ATCP. This is primarily available on IRE-based MUDs, but Mudlets impelementation is generic enough such that any it should work on others.

The latest ATCP data is stored in the atcp table. Whenever new data arrives, the previous is overwritten. An event is also raised for each ATCP message that arrives. To find out the available messages available in the atcp table and the event names, you can use display(atcp).

Note that while the typical message comes in the format of Module.Submodule, ie Char.Vitals or Room.Exits, in Mudlet the dot is removed - so it becomes CharVitals and RoomExits. Here’s an example:

room_number = tonumber(atcp.RoomNum)
echo(room_number)

Triggering on ATCP events

If you’d like to trigger on ATCP messages, then you need to create scripts to attach handlers to the ATCP messages. The ATCP handler names follow the same format as the atcp table - RoomNum, RoomExits, CharVitals and so on.

While the concept of handlers for events is to be explained elsewhere in the manual, the quick rundown is this - place the event name you’d like your script to listen to into the Add User Defined Event Handler: field and press the + button to register it. Next, because scripts in Mudlet can have multiple functions, you need to tell Mudlet which function should it call for you when your handler receives a message. You do that by setting the Script name: to the function name in the script you’d like to be called.

For example, if you’d like to listen to the RoomExits event and have it call the process_exits() function - register RoomExits as the event handler, make the script name be process_exits, and use this in the script:

function process_exits(event, args)
    echo("Called event: " .. event .. "\nWith args: " .. args)
end

Feel free to experiment with this to achieve the desired results. A ATCP demo package is also available on the forums for using event handlers and parsing its messages into Lua datastructures.

Aardwolf’s 102 subchannel

Similar to ATCP, Aardwolf includes a hidden channel of information that you can access in Mudlet since 1.1.1. Mudlet deals with it in the same way as with ATCP, so for full usage instructions see the ATCP section. All data is stored in the channel102 table, such you can do

display(channel102)

To see all the latest information that has been received. The event to create handlers on is titled channel102Message, and you can use the sendTelnetChannel102(msg) function to send text via the 102 channel back to Aardwolf.

db: Mudlet DB Frontend

The DB package is meant to provide easier access to a database, so you don’t have to know SQL or use the luasql module to set and get at your data. However, it does require that the luasql module be compiled and included in Mudlet to function - and this all is available since Mudlet 1.0.6.

Creating a Database

Before you can store anything in a database, you need to create one. You may have as many independent databases as you wish, with each having as many unique tables-- what we will call sheets in this package, so as to avoid confusion with Lua tables - think spreadsheets.

To create a database, you use the db:create() function, passing it the name of your database and a Lua table containing its schema configuration. A schema is a mold for your database - it defines what goes where. Using the spreadsheet example, ths would mean that you’d define what goes into each column. A simple example:

        db:create("people", {friends={"name", "city", "notes"}, enemies={"name", "city", "notes"}})

This will create a database which contains two sheets: one named friends, the other named enemies. Each has three columns, name, city and notes-- and the datatype of each are strings, though the types are very flexible and can be changed basically whenever you would like. It’ll be stored in a file named Database_people.db in your Mudlet config directory on the hard drive should you want to share it.

It’s okay to run this function repeatedly, or to place it at the top-level of a script so that it gets run each time the script is saved: the DB package will not wipe out or clear the existing data in this case. More importantly, this allows you to add columns to an existing sheet. If you change that line to:

        db:create("people", {friends={"name", "city", "notes"}, enemies={"name", "city", "notes", "enemied"}})

It will notice that there is a new column on enemies, and add it to the existing sheet-- though the value will end up as nil for any rows which are already present. Similarly, you can add whole new sheets this way. It is not presently possible to -remove- columns or sheets without deleting the database and starting over.

A note on column or field names: you may not create a field which begins with an underscore. This is strictly reserved to the db package for special use.

Adding Data

To add data to your database, you must first obtain a reference (variable) for it. You do that with the db:get_database function, such as:

        local mydb = db:get_database("people")

The database object contains certain convenience functions (discussed later, but all are preceded with an underscore), but also a reference to every sheet that currently exists within the database. You then use the db:add() function to add data to the specified sheet.

        db:add(mydb.friends, {name="Ixokai", city="Magnagora"})

If you would like to add multiple rows at once to the same table, you can do that by just passing in multiple tables:

        db:add(mydb.friends,
                {name="Ixokai", city="Magnagora"},
                {name="Vadi", city="New Celest"},
                {name="Heiko", city="Hallifax", notes="The Boss"}
        )

Notice that by default, all columns of every table are considered optional-- if you don’t include it in the add, then it will be set to its default value (which is nil by default)

For those familiar with databases: with the DB package, you don’t have to worry about committing or rolling back any changes, it will commit after each action automatically. If you would like more control then this, see Transactions below.

You also cannot control what is the primary key of any sheets managed with DB, nor do you have to create one. Each row will get a unique integer ID that automatically increments, and this field can be accessed as "_row_id".

Querying

Putting data in isn’t any fun if you can’t get it out. If you want every row from the sheet, you can do:

        db:fetch(mydb.friends)

But rarely is that actually useful; usually you want to get only select data. For example, you only want to get people from the city of Magnagora. To do that you need to specify what criteria the system should use to determine what to return to you. It looks like this:

        db:fetch(mydb.friends, db:eq(mydb.friends.city, "Magnagora"))

So the basic command is - db:fetch(_sheet_, _what to filter by_)

The following filter operations are defined:

        db:eq(field, value[, case_insensitive]) -- Defaults to case insensitive, pass true as the last arg to
                                                        reverse this behavior.
        db:not_eq(field, value[, case_insensitive) -- Not Equal To
        db:lt(field, value) -- Less Than
        db:lte(field, value) -- Less Than or  Equal to.
        db:gt(field, value) -- Greater Than
        db:gte(field, value) -- Greater Than or Equal To
        db:is_nil(field) -- If the column is nil
        db:is_not_nil(field) -- If the column is not nil
        db:like(field, pattern) -- A simple matching pattern. An underscore matches any single character,
                                        and a percent(%) matches zero or more characters. Case insensitive.
        db:not_like(field, pattern) -- As above, except it'll give you everything but what you ask for.
        db:between(field, lower_bound, upper_bound) -- Tests if the field is between the given bounds (numbers only).
        db:not_between(field, lower_bound, upper_bound) -- As above, only... not.
        db:in_(field, table) -- Tests if the field is in the values of the table. NOTE the trailing underscore!
        db:not_in(field, table) -- Tests if the field is NOT in the values of the table *

The db:in_ operator takes a little more explanation. Given a table, it tests if any of the values in the table are in the sheet. For example:

        db:in_(mydb.friends.city, {"Magnagora", "New Celest"})

It tests if city == "Magnagora" OR city == "New Celest", but with a more concise syntax for longer lists of items.

There are also two logical operators:

        db:AND(operation1, ..., operationN)
        db:OR(operation1, operation2)

You may pass multiple operations to db:fetch in a table array, and they will be joined together with an AND by default. For example:

        db:fetch(mydb.friends,
                {db:eq(mydb.friends.city, "Magnagora"), db:like(mydb.friends.name, "X%")}
        )

This will return every record in the sheet which is in the city of Magnagora, and has a name that starts with an X. Again note that in LIKE patterns, a percent is zero or more characters — this is the same effect as "X.*" in pcre patterns. Similarly, an underscore matches any single characters and so is the same as a dot in pcre.

Passing multiple expressions in an array to db:fetch is just a convenience, as its exactly the same as:

        db:fetch(mydb.friends, db:AND(db:eq(mydb.friends.city, "Magnagora"), db:like(mydb.friends.name, "I%")))

The db:OR operation only takes two arguments, and will check to see if either of the two is true. You can nest these logical operators as deeply as you need to.

You can also just pass in a string directly to db:fetch, but you have to be very careful as this will be passed straight to the SQL layer. If you don’t know any SQL then you want to avoid this… for example, in SQL there’s a very big difference between double and single quotes. If you don’t know that, then stick to the db functions. But an example is:

        db:fetch(mydb.friends, "city == 'Magnagora'")

Now, the return value of db:fetch() is always a table array that contains a table dictionary representing the full contents of all matching rows in the sheet. These are standard Lua tables, and you can perform all normal Lua operations on them. For example, to find out how many total items are contained in your results, you can simply do #results. If a request from the friends sheet were to return one row that you stored in the results variable, it would look like this if passed into the display() function:

    table {
        1: table {
            'name': 'Bob',
            'city': 'Magnagora',
            'notes': 'Trademaster of Tailoring'
        }
    }

And if you were to echo(#results), it would show 1.

The order of the returned rows from db:fetch is generally the same as the order in which you entered them into the database, but no actual guarantees are made to this. If you care about the order then you can pass one or two optional parameters after the query to db:fetch() to control this.

The first table array of fields that indicate the column names to sort by; the second is a flag to switch from the default ascending(smallest to largest) sort, to a descending(largest to smallest) sort. For example:

        db:fetch(mydb.friends, db:eq(mydb.friends.city, "Magnagora"), {mydb.friends.city})

This will return all your friends in Magnagora, sorted by their name, from smallest to largest. To reverse this, you would simply do:

        db:fetch(mydb.friends, db:eq(mydb.friends.city, "Magnagora"), {mydb.friends.city}, true)

Including more then one field in the array will indicate that in the case that two rows have the same value, the second field should be used to sort them.

If you would like to return ALL rows from a sheet, but still sort them, you can do that by passing nil into the query portion. For example:

        db:fetch(mydb.friends, nil, {mydb.friends.city, mydb.friends.name})

This will return every friend you have, sorted first by city and then their name.

Indexes and Types

The sheets we’ve defined thus far are very simple, but you can take more control over the process if you need to. For example, you may assign default values and types to columns, and the DB package will attempt to coerce them as appropriate. To do that, you change your db:create() call as:

        db:create("people", {
                friends={"name", "city", "notes"},
                enemies={
                        name="",
                        city="",
                        notes="",
                        enemied="",
                        kills=0
                }
        })

This is almost the same as the original definition, but we’ve defined that our first four fields are strings with a default value of blank, and the new kills field which is an integer that starts off at 0. The only way to set a datatype is to set a default value at this time.

Please note, beneath the DB package is SQLite, and SQLite is very data-type neutral. It doesn’t really care very much if you break those rules and put an integer in a string field or vice-versa, but the DB package will — to a limited degree — attempt to convert as appropriate, especially for the operations that work on numbers.

You may also create both standard and unique indexes. A unique index enforces that a certain criteria can only happen once in the sheet. Now, before you go and make indexes, pause and consider. There is no right or wrong answer when it comes to what to index: it depends on what kind of queries you do regularly. If in doubt, don’t make an index. Indexes will speed up reading data from the sheet, but they will slow down writing data.

To add an index, pass either the _index or _unique keys in the table definition. An example:

        db:create("people", {
                friends={"name", "city", "notes"},
                enemies={
                        name="",
                        city="",
                        notes="",
                        enemied="",
                        kills=0,
                        _index = { "city" },
                        _unique = { "name" }
                }
        })

You can also create compound indexes, which is a very advanced thing to do. One could be: _unique = { {"name", "city"} }

This would produce an effect that there could be only one "Bob" in Magnagora, but he and "Bob" in Celest could coexist happily.

Now, bear in mind: _index = { "name", "city"} creates two indexes in this sheet. One on the city field, one on the name field. But, _index = { {"name", "city"} } creates one index: on the combination of the two. Compound indexes help speed up queries which frequently scan two fields together, but don’t help if you scan one or the other.

The admonition against making indexes willy-nilly holds double for compound indexes: do it only if you really need to!

Uniqueness

As was specified, the _unique key can be used to create a unique index. This will make it so a table can only have one record which fulfills that index. If you use an index such as _unique = { "name" } then names must be unique in the sheet. However, if you use an index such as _unique = { {"name", "city"} } then you will allow more then one person to have the same name — but only one per city.

Now, if you use db:add() to insert a record which would violate the unique constraint, a hard error will be thrown which will stop your script. Sometimes that level of protection is too much, and in that case you can specify how the db layer handles violations.

There are three possible ways in which the layer can handle such violations; the default is to FAIL and error out.

You can also specify that the db layer should IGNORE any commands that would cause the unique constraint to be violated, or the new data should REPLACE the existing row.

For example:

        db:add(mydb.enemies, {name="Bob", city="Sacramento"})
        db:add(mydb.enemies, {name="Bob", city="San Francisco"})

With the name field being declared to be unique, these two commands can’t succeed normally. The first db:add() will create a record with the name of Bob, and the second would cause the uniqueness of the name field to be violated. With the default behavior (FAIL), the second db:add() call will raise an error and halt the script.

If you want the IGNORE behavior, the second command will not cause any errors and it will simply fail silently. Bob’s city will still be Sacramento.

With the REPLACE behavior, the second command will cause its data to completely overwrite and replace the first record. Bob’s city will now be San Francisco.

A word of caution with REPLACE, given:

        db:add(mydb.enemies, {name="Bob", city="Sacramento", notes="This is something."})
        db:add(mydb.enemies, {name="Bob", city="San Francisco"})

With the REPLACE behavior, the second record will overwrite the first-- but the second record does not have the notes field set. So Bob will now not have any notes. It doesn’t -just- replace existing fields with new ones, it replaces the entire record.

To specify which behavior the db layer should use, add a _violations key to the table definition:

        db:create("people", {
                friends={"name", "city", "notes"},
                enemies={
                        name="",
                        city="",
                        notes="",
                        enemied="",
                        kills=0,
                        _index = { "city" },
                        _unique = { "name" },
                        _violations = "IGNORE"
                }
        })

Note that the _violations behavior is sheet-specific.

Timestamps

In addition to strings and floats, the db module also has basic support for timestamps. In the database itself this is recorded as an integer (seconds since 1970) called an epoch, but you can easily convert them to strings for display, or even time tables to use with Lua’s built-in time support.

The most common use for the Timestamp type is where you want the database to automatically record the current time whenever you insert a new row into a sheet. The following example illustrates that:

        local mydb = db:create("combat_log",
           {
              kills = {
                 name = "",
                 area = "",
                 killed = db:Timestamp("CURRENT_TIMESTAMP"),
                 _index = { {"name", "killed"} }
              }
           }
        )


        db:add(mydb.kills, {name="Drow", area="Undervault"})

        results = db:fetch(mydb.kills)
        display(results)

The result of that final display would show you this on a newly created sheet:

        table {
          1: table {
            '_row_id': 1
            'area': 'Undervault'
            'name': 'Drow'
            'killed': table {
              '_timestamp': 1264317670
            }
          }

As you can see from this output, the killed fields contains a timestamp-- and that timestamp is stored as an epoch value. For your convienance, the db.Timestamp type offers three functions to get the value of the timestamp in easy formats. They are as_string, as_number and as_table, and are called on the timestamp value itself.

The as_number function returns the epoch number, and the as_table function returns a time table. The as_string function returns a string representation of the timestamp, with a default format of "%m-%d-%Y %H:%M:%S". You can override this format to anything you would like. Details of what you can do with epoch values, time tables, and what format codes you can use are specified in the Lua manual at: http://www.lua.org/pil/22.1.html for the Lua date/time functions.

A quick example of the usage of these functions is:

        results = db:fetch(mydb.kills)
        for _, row in ipairs(results) do
                echo("You killed " .. row.name .. " at: " .. row.killed:as_string() .."\n")
        end

Deleting

The db:delete function is used to delete rows from the sheet. It takes two arguments, the first being the sheet you are deleting and the second a query string built using the same functions used to build db:fetch() queries.

For example, to delete all your enemies in the city of Magnagora, you would do:

        db:delete(mydb.enemies, db:eq(mydb.enemies.city, "Magnagora"))

Be careful in writing these! You may inadvertantly wipe out huge chunks of your sheets if you don’t have the query parameters set just to what you need them to be. Its advised that you first run a db:fetch() with those parameters to test out the results they return.

As a convienence, you may also pass in a result table that was previously retrieved via db:fetch and it will delete only that record from the table. For example, the following will get all of the enemies in Magnagora, and then delete the first one:

        results = db:fetch(mydb.enemies, db:eq(mydb.enemies.city, "Magnagora"))
        db:delete(mydb.enemies, db:eq(mydb.enemies._row_id, results[1]._row_id))

That is equivelent to:

        db:delete(mydb.enemies, results[1])

You can even pass a number directly to db:delete if you know what _row_id you want to purege.

A final note of caution: if you want to delete all the records in a sheet, you can do so by only passing in the table reference. To try to protect you from doing this inadvertantly, you must also pass true as the query after:

        db:delete(mydb.enemies, true)

Updating

If you make a change to a table that you have received via db:fetch(), you can save those changes back to the database by doing:

        db:update(mydb.enemies, results[1])

A more powerful (and somewhat dangerous, be careful!) function to make changes to the database is db:set, which is capable of making sweeping changes to a column in every row of a sheet. Beware, if you have previously obtained a table from db:fetch, that table will NOT represent this change.

The db:set() function takes two arguments: the field to change, the value to set it to, and the db:fetch() like query to indicate which rows should be affected. If you pass true as the last argument, ALL rows will be changed.

To clear out the notes of all of our friends in Magnagora, we could do:

        db:set(mydb.friends.notes, "", db:eq(mydb.friends.notes, "Magnagora"))

Be careful in writing these!

Transactions

As was specified earlier, by default the db module commits everything immediately whenever you make a change. For power-users, if you would like to control transactions yourself, the following functions are provided on your database instance:

        local mydb = db:get_database("my_database")
        mydb._begin()
        mydb._commit()
        mydb._rollback()
        mydb._end()

Once you issue a mydb._begin() command, autocommit mode will be turned off and stay off until you do a mydb._end(). Thus, if you want to always use transactions explicitly, just put a mydb._begin() right after your db:create() and that database will always be in manual commit mode.

Migrating to Mudlet

From Nexus

Trigger patterns

Lets start with triggers. For translating Nexus patterns into Mudlet, use the following table below. Make sure to set the pattern type in Mudlet to be perl regex, because the default substring works differently.

Mudlet Nexus What it does

(\w+)

{w}

Match one or more non-whitespace characters (a 'word')

(\d+)

{d}

Match one or more numeric digits (a number)

([abc])

{[abc]}

Match one or more of either 'a', 'b' or 'c'. (a character class)

([^abc])

{[^abc]}

Match one or more of anything EXCEPT 'a', 'b', or 'c'

(.*)

{*}

Match zero or more characters (anything)

^

{<}

Match the beginning of a line (not the actual newline character)

$

{>}

Match the end of a line (not the actual newline character)

Note If you just have a pattern with a {<} and {>} and nothing else, copy the pattern over without the {<}{>} and select the exact match pattern type. For example {<}You sit down.{>} in Nexus would become You sit down. in Mudlet with the pattern type of exact match. This is easier to read and matches way faster!

Basic scripting

The Nexus way of doing a function is like this: #function stuff it does. In Mudlet, it’s function(stuff it does). Note that if you’d like to give text to a function, you put it inside double or single quotes.

Nexus
#send hi
#echo Hello to me!
Mudlet
send ("hi")
echo ("Hello to me!")

If you’d like to use a variable inside text, you’d put it outside the quotes and glue it together with two dots.

Nexus
#set number 1234
#echo My number is: $number
#echo the $number is in the middle of my text
Mudlet
number = 1234
echo ("My number is: " .. number)
echo ("the " .. number .. " is in the middle of my text")

wildcards in Mudlet

To use the wildcard variable in Nexus, you’d use $1 for the first match, $2 for the second and so on. In Mudlet, the matches[] table contains the matches - and it starts placing the matches from 2. So the Nexus $1 would be matches[2], $2 would be matches[3].

Nexus:
{w} kicks you.
#set badguy $1
#echo $badguy kicked me!

Mudlet:
(\w+) kicks you\.
badguy = matches[2]
echo(badguy .. " kicked me!")

Another example would be the targetting alias:

Nexus:
alias name: t
alias script: #set target $1

Mudlet:
alias pattern: ^t (.*)$
alias script: target = matches[2]

The reason the first match goes into matches[2] and not matches[1] is because matches[1] contains the part of the line that matched your trigger / alias.

#wait in Mudlet

In Nexus, a #wait will freeze the script while it’s executing - such that commands after it are delayed. In Mudlet, we use tempTimer which that works a bit differently - it doesn’t freeze the script, but instead makes it so commands a tempTimer is asked to do will get done in the future.

So the difference is that a tempTimer doesn’t freeze the commands following it at all, everything gets done at once as usual. Just things a tempTimer was asked to do get done in the future.

Nexus script:
#send hello
#wait 1000
#send hi
#wait 500
#send bye

Mudlet:
send("hello")
tempTimer(1, [[send("hi")]])
tempTimer(1.5, [[send("bye")]])

ifs in Mudlet

Next are the #if statements. Here’s a table comparing the syntaxes of Nexus and Mudlet:

Mudlet Nexus

if <condition> then <text> end

#if <condition> <text>

#if <condition> { <script> }

if <condition> then <script> else <script> end

#if <condition> { <script> } else { <script> }

#if <condition> { <script> } { <script> }

if <condition> then <script> elseif <condition> then <script> end

#if <condition> { <script> } elsif <condition> { <script> }

if <condition> then <script> elseif <condition> then <script> else <script> end

#if <condition> { <script> } elsif <condition> { <script> } else { <script> }

Here is the sample side-by-side comparison of how you’d use it:

Mudlet Nexus
-- If foo is true, echo that fact.
if foo then echo ("Foo is true!") end -- If foo is true, echo that fact.

-- A slight modification of the above that illustrates an 'else' clause.
-- Note that the 'then' is always necessary to avoid confusion.
if foo then echo ("Foo is true!") else echo ("Foo is false!") end

-- Illustration of putting more than one statement in a block (also
-- spans lines here). Note the if doesn't end until the last 'end' is
-- encountered.
-- We also add a \n at the end of multiple echos so each one is on it's own line.
if foo then
   echo ("Foo is true!\n")
   echo ("Isn't it grand?\n")
   echo ("These commands are all on separate lines too!\n")
end

-- This shows how ifs continue (on 'logical' lines) even though the
-- blocks in its constituent clauses may have multiple lines. The
-- following lines are all _one_ single if statement.
if foo > 50 then
   echo ("Foo is big!\nYes it is.")
elseif foo > 10 then
   echo ("Foo is pretty big...\n")
   echo ("I've seen bigger.")
else
   echo ("Foo is actually kind of small.")
end

-- Ifs can be nested too.
if foo then
   if bar then
      echo ("Both foo and bar are true.")
   else
      echo ("Foo's true, but bar isn't.")
   end
end
// If $foo is true, echo that fact.
#if $foo #echo Foo is true!          // If $foo is true, echo that fact.

// A slight modification of the above that illustrates an 'else' clause.
// The second form shows that the word 'else' is actually optional too.
// (The two lines are functionally the same.)
#if $foo { #echo Foo is true! } else { #echo Foo is false! }
#if $foo { #echo Foo is true! } { #echo Foo is false! }

// Illustration of putting more than one statement in a block (also
// spans lines here). Note the if doesn't end until the last '}' is
// encountered.
#if $foo {
   #echo Foo is true!
   #echo Isn't it grand?
   #echo These commands are all on separate lines too!
}

// This shows how ifs continue (on 'logical' lines) even though the
// blocks in its constituent clauses may have multiple lines. The
// following lines are all _one_ single if statement.
#if $foo > 50 {
   #echo Foo is big!
   #echo Yes it is.
} elsif $foo > 10 {
   #echo Foo is pretty big...
   #echo I've seen bigger.
} else {
   #echo Foo is actually kind of small.
}

// Ifs can be nested too.
#if $foo {
   #if $bar {
      #echo Both foo and bar are true.
   } else {
      #echo Foo's true, but bar isn't.
   }
}

Mudlet equivalents of Nexus functions

Now that we got the ifs covered, lets go over the Mudlet equivalents of other Nexus functions. Note that this is a direct Nexus→Mudlet comparison; certain functions in Mudlet have much more capability.

Mudlet Nexus
<variable> = <variablename> <+ - /  *> <number or variable>    
#add <variablename> <expression>
echo "text\n" or echo("text\n")        
#echo <text>
echo "text" or echo("text")            
#echo_ <text>
enableAlias("<group name>"), enableTrigger(), enableKey() or enableTimer() 
#groupon <group name>
disableAlias("<group name>"), disableTrigger(), disableKey() or disableTimer() 
#groupoff <group name>
selectString (line, 1) bg("<color>") resetFormat() 
#highlight <color>
deleteLine()                       
#gag
openUrl("<url>")*                  
#openurl <url>
send("<stuff>")                    
#send <text>
sendAll("hi", "hello", "bye")      
#send_ hi #send_ hello #send bye
<variable name> = "<text value>"   
#set <variable name> <text value>
<variable name> = <expression>     
#set <variable name> = <expression>
<variable name> = nil              
#unset <variable name>
tempTimer(<time in s>, [[<lua code to do once time is up>]])
#wait <milliseconds>

*Planned for Mudlet 1.0.6

How to call aliases in Mudlet

The typical workflow in Nexus is that you’d define the aliases for yourself to use, and also use aliases for system-related things (things like checking if you’d need to eat a herb, etc).

While the first use is good, the second isn’t - because the user can also run this alias at an inopportune time, because if you want to call an alias it has to match all alises again, and so on.

Now, while in Mudlet you can call another alias with the expandAlias() function, this is strongly discouraged. What you do instead if create a function (for example, send() and echo() are functions) that you can then call from your alias or trigger. This has many advantages - it’s faster, you can easily give your function values, and your function can return you values, too.

To make a function, you go to the Scripts section, create a new script, and write in your function:

function <name> ()
    <stuff it does>
end

For example, if we want to make a function that does two things for us at once, we’d do this:

function eat_bloodroot()
    send ("outr bloodroot")
    send ("eat bloodroot")
end

Then just do this in our alias or trigger to outr and eat bloodroot:

eat_bloodroot()

As mentioned, you can also give things to functions - in this case lets expand the function to eat any herb for us we tell it:

function eat (what)
    send ("outr " .. what)
    send ("eat " .. what)
end

[...]
eat ("bloodroot")
eat ("kelp")
eat ("ginseng")

Lastly, functions can also give you data back. One useful example for this is to break down tasks into functions, which will help your code readibility:

function can_i_stand()
    if not paralyzed and not prone and not stunned then
        return true
    else
        return false
end

[...]

if can_i_stand() and have_balance and have_equilibrium then
    send ("stand")
end

Notes to be aware of

To finish off, a couple of points that should be remembered:

  • Mudlet does profile snapshots (nexus archives) automatically - to load a different one, select it from the list when connecting

  • Mudlet can import and export xml

  • Mudlet and Nexus xml formats aren’t compatible

  • Mudlet can do nexus graphics, here is a package for - Achaea

  • Mudlet has a ton more features such are more speed, less bugs, copy from the normal window, replay logging, color html logging, more powerful scripting, and the list goes on.

Lua API

Mudlet defines several global Lua variables that are accessible from anywhere.

Table 1. Built-in Lua Variables
Variable Name Description

command

This variable holds the current user command. This is typically used in alias scripts.

line

This variable holds the content of the current line as being processed by the trigger engine. The engine runs all triggers on each line as it arrives from the MUD.

matches[n]

This Lua table is being used by Mudlet in the context of triggers that use Perl regular expressions. matches[1] holds the entire match, matches[2] holds the first capture group, matches[n] holds the n-th capture group.

If the trigger uses the Perl style /g switch to evaluate all possible matches of the given regex within the current line, matches[n+1] will hold the second entire match, matches[n+2] the first capture group of the second match and matches[n+m] the m-th capture group of the second match.

multimatches[n][m]

This table is being used by Mudlet in the context of multiline triggers that use Perl regular expression. It holds the table matches[n] as described above for each Perl regular expression based condition of the multiline trigger. multimatches[5][4] may hold the 3rd capture group of the 5th regex in the multiline trigger. This way you can examine and process all relevant data within a single script. Have a look at this example.

Alphabetical Function Index

Click on the respective function to get more information:

A

B

C

D

E

F

G

H

I

K

M

O

P

R

S

T

W

Most Important Functions

send( command, echo the value = true/false )

This sends "command" directly to the network layer, skipping the alias matching. The optional second argument of type boolean (print) determines if the outgoing command is to be echoed on the screen.

If you want your command to be checked if it’s an alias, use expandAlias() instead. example:

send( "Hello Jane" ) --echos the command on the screen
send( "Hello Jane", true ) --echos the command on the screen
send( "Hello Jane", false ) --does not echo the command on the screen

echo( windowName, text )

This function appends text at the end of the current line. The current cursor position is ignored. Use moveCursor() and insertText() if you want to print at a different cursor position.

If the first argument is omitted the main console is used, otherwise the mini console windowName. === Example 1:

echo( "Hello world\n" ) -- writes "Hello world" to the main screen.
echo( "info", "Hello this is the info window" ) -- writes text to the mini console named "info" if such a window exists

Echos a piece of text as a clickable link.

  • text - text to display in the echo. Same as a normal echo().

  • command - lua code to do when the link is clicked.

  • hint - text for the tooltip to be displayed when the mouse is over the link.

  • boolean - if true, then the link will use the current selection style (colors, underline, etc). If missing or false, it will use the default link style - blue on black underlined text.

Available since 1.1.0-pre1.

Example:

echoLink("hi", [[echo("hey bub!")]], "click me now")

selectString( text, number_of_match ) returns position in line or -1 on error (text not found in line)

Selects a substring from the line where the user cursor is currently positioned. You can move the user cursor with moveCursor(). When a new line arrives from the MUD, the user cursor is positioned at the beginning of the line. However, if one of your trigger scripts moves the cursor around you need to take care of the cursor position yourself and make sure that the cursor is in the correct line if you want to call one of the select functions. To deselect text, see deselect().

Note To prevent selection of random data use the error return if not found like this: if selectString( "big monster", 1 ) > -1 then setFgColor( 255,0,0) end

decho (text[, foreground color] [, background color] [, true/false] [, name of console])

  • text - the text that you’d like to echo with embedded color tags. Tags take the RGB values only, see below for an explanation.

  • foreground color - optional string containing value for foreground color as a named color.

  • background color optional string containing value for background color as a named color.

  • true/false - optional boolean that tells the function to use insertText() rather than echo(). Note that if sending to miniConsole, this has to be false.

  • name of console - optional name of the console to echo to. Defaults to main.

How text works

Color changes can be made using the format <FR,FG,FB:BR,BG,BB> where each field is a number from 0 to 255. The background portion can be omitted using <FR,FG,FB> or the foreground portion can be omitted using <:BR,BG,BB>. Arguments 2 and 3 set the default fore and background colors for the string using the same format as is used within the string, sans angle brackets, e.g. decho("test", "255,0,0", "0,255,0")

deselect()

Clears the current selection in the main window.

deselect(windowname)

Clears the current selection in the given miniConsole.

deleteLine()

deletes the current Line under the user cursor. Note: This is a high speed gagging tool and it is very good at this task. It is meant to be used when the line can be omitted entirely in the output. If you want to replace this line with something else have a look at the replace() functions below. Note that scripts such as: deleteLine(); echo("this line is gone"); will not work because lines that have been gagged with deleteLine() will not be rendered even if there is text in the buffer. → wrapLine() for details on how to force a re-render if this is necessary for some reason. This is not the recommended way of replacing text. → replace() and wrapLine()

tempTimer( seconds, lua code )

Creates a temporary single shot timer. You can use 2.3 seconds or 0.45 etc. After it has fired, the timer will be deactivated and killed. see here for details.

disableAlias (name)

Disables/deactivates an alias with the given name. This means that when you type in text that should match it’s pattern, it won’t match and will be sent to the MUD. If several aliases have this name, they’ll all be disabled.

enableTrigger( name )

Enables the Trigger name. → enableTrigger()

disableTrigger( name )

Use trigger name or the id returned by tempTrigger() to identify the timer that you want to disable. → disableTrigger( name )

insertText( text )

inserts text at the current cursor position in the main window; if the cursor has not been explicitly moved this function will always print at the beginning of the line whereas the echo() function will always print at the end of the line

insertText( windowName, text )

inserts text at cursor position in window windowName

Same as echoLink() but inserts the text at the current cursor position, while echoLink inserts at the end of the current line.

Available since 1.1.0-pre1.

insertPopup([window], text, {commands}, {hints}, [bool current or default format])

Same as echoPopup(), but inserts text at the current cursor position.

Available since 1.1.0-pre1.

suffix( text )

Suffixes text at the end of the current line when used in a trigger.

prefix( text )

Prefixes text at the beginning of the current line when used in a trigger.

Example:

-- Prefix the hours, minutes and seconds onto our prompt even though Mudlet has a button for that
prefix(os.date("%H:%M:%S "))

result = string:title(text)

Capitalizes the given text for you.

Examples:

test = "bob"
test = string.title(test)
-- test is now "Bob"

testname = string.title("anna")
-- testname is now Anna

permAlias(name, parent, regex, lua code)

Creates a persistent alias that stays after Mudlet is restarted and shows up in the Script Editor.

  • name is the name you’d like the alias to have.

  • parent is the name of the group, or another alias you want the trigger to go in - however if such a group/alias doesn’t exist, it won’t do anything. Use "" to make it not go into any groups.

  • regex is the pattern that you’d like the alias to use.

  • lua code is the script the alias will do when it matches.

Examples:

-- creates an alias called "new alias" in a group called "my group"
permAlias("new alias", "my group", "^test$", [[echo ("say it works! This alias will show up in the script editor too.")]])
Note

Note that Mudlet by design allows duplicate names - so calling permAlias with the same name will keep creating new aliases. You can check if an alias already exists with the exists() function.

permSubstringTrigger( name, parent, pattern, lua code )

Creates a persistent trigger with a substring pattern that stays after Mudlet is restarted and shows up in the Script Editor.

  • name is the name you’d like the trigger to have.

  • parent is the name of the group, or another trigger you want the trigger to go in - however if such a group/trigger doesn’t exist, it won’t do anything. Use "" to make it not go into any groups.

  • pattern table is a table of patterns that you’d like the trigger to use - it can be one or many.

  • lua code is the script the trigger will do when it matches.

Example:

-- Create a trigger to highlight the word "pixie" for us
permSubstringTrigger("Highlight stuff", "General", {"pixie"},
[[selectString(line, 1) bg("yellow") resetFormat()]])

-- Or another trigger to highlight several different things
permSubstringTrigger("Highlight stuff", "General", {"pixie", "cat", "dog", "rabbit"},
[[selectString(line, 1) fg ("blue") bg("yellow") resetFormat()]])
Note

Note that Mudlet by design allows duplicate names - so calling permSubstringTrigger with the same name will keep creating new triggers. You can check if a trigger already exists with the exists() function.

permRegexTrigger( name, parent, pattern, lua code )

Creates a persistent trigger with a regex pattern that stays after Mudlet is restarted and shows up in the Script Editor.

  • name is the name you’d like the trigger to have.

  • parent is the name of the group, or another trigger you want the trigger to go in - however if such a group/trigger doesn’t exist, it won’t do anything. Use "" to make it not go into any groups.

  • pattern table is a table of patterns that you’d like the trigger to use - it can be one or many.

  • lua code is the script the trigger will do when it matches.

Example:

-- Create a regex trigger that will match on the prompt to record your status
permRegexTrigger("Prompt", "", {"^(\d+)h, (\d+)m"}, [[health = tonumber(matches[2]; mana = tonumber(matches[3])]]
Note

Note that Mudlet by design allows duplicate names - so calling permRegexTrigger with the same name will keep creating new triggers. You can check if a trigger already exists with the exists() function.

permBeginOfLineStringTrigger( name, parent, pattern table, lua code )

Creates a persistent trigger with a begin of line substring pattern that shows up in the Script Editor andstays after Mudlet is restarted.

  • name is the name you’d like the trigger to have.

  • parent is the name of the group, or another trigger you want the trigger to go in - however if such a group/trigger doesn’t exist, it won’t do anything. Use "" to make it not go into any groups.

  • pattern table is a table of patterns that you’d like the trigger to use - it can be one or many.

  • lua code is the script the trigger will do when it matches.

Example:

-- Create a trigger that will match on anything that starts with "You sit" and do "stand".
-- It will not go into any groups, so it'll be on the top.
permBeginOfLineStringTrigger("Stand up", "", {"You sit"}, [[send ("stand")]])

-- Another example - lets put our trigger into a "General" folder and give it several patterns.
permBeginOfLineStringTrigger("Stand up", "General", {"You sit", "You fall", "You are knocked over by"}, [[send ("stand")]])
Note

Note that Mudlet by design allows duplicate names - so calling permBeginOfLineStringTrigger with the same name will keep creating new triggers. You can check if a trigger already exists with the exists() function.

permTimer(name, parent, seconds, lua code)

Creates a persistent timer that stays after Mudlet is restarted and shows up in the Script Editor.

Name is the timer name, parent is the name of the timer group you want the timer to go in. Seconds is a number specifying a delay after which the timer will do the lua code you give it as a string.

Examples:

permTimer("my timer", "first timer group", 4.5, [[send ("my timer that's in my first timer group fired!")]])
Note

Note that Mudlet by design allows duplicate names - so calling permTimer with the same name will keep creating new timers. You can check if a timer already exists with the exists() function.

selectSection( from, length_of_string )

Select text on the line under the current cursor position. Use absolute column number for start of selection and length of selection The function returns true on success and false if the selection is not possible.

selectSection( windowName, from, length )

just like selectSection() but does not operate on the main window, but on window windowName. See selectSection() for a detailed description

selectCaptureGroup( groupNumber ) with first group = 0

Selects the content of the capture group number in your Perl regular expression e.g. "you have (\d+) Euro". If you want to color the amount of money you have green you do: selectCaptureGroup(1); setFgColor(0,255,0)

replace( with )

Replaces the currently selected text with the new text. To select text, use selectString() and similar function.

If you’d like to delete/gag the whole line, use deleteLine().

example:

-- replace word "troll" with "cute trolly"
selectString("troll",1)
replace("cute trolly")

-- lets replace the whole line
selectString(line, 1)
replace("Out with the old, in with the new!")

replace( windowName, with )

Same as above, but replaces text in a window (miniConsole, label).

Example:

replaceAll( what, with )

replaces all occurrences of what in the current line with with → replace()

feedTriggers( text )

This function will have Mudlet parse the given text as if it came from the MUD - one great application is trigger testing. You can use \n to represent a new line - you also want to use it before and after the text you’re testing, like so:

feedTriggers("\nYou sit yourself down.\n")

The function also accept ANSI color codes that are used in MUDs. A sample table can be found here.

Example:

feedTriggers("\nThis is \27[1;32mgreen\27[0;37m, \27[1;31mred\27[0;37m, \27[46mcyan background\27[0;37m," ..
"\27[32;47mwhite background and green foreground\27[0;37m.\n")

fg( color_name )

Sets the current selection foreground color to color_name which is one of the pre defined colors in the table below.

Table 2. Color table (for use in the fg("colorname") and bg("colorname") functions)

snow

ghost_white

white_smoke

gainsboro

floral_white

old_lace

linen

antique_white

papaya_whip

blanched_almond

bisque

peach_puff

navajo_white

moccasin

cornsilk

ivory

lemon_chiffon

seashell

honeydew

mint_cream

azure

alice_blue

lavender

lavender_blush

misty_rose

white

black

dark_slate_gray

dark_slate_grey

dim_gray

dim_grey

slate_gray

slate_grey

light_slate_gray

light_slate_grey

gray

grey

light_grey

light_gray

midnight_blue

navy

navy_blue

cornflower_blue

dark_slate_blue

slate_blue

medium_slate_blue

light_slate_blue

medium_blue

royal_blue

blue

dodger_blue

deep_sky_blue

sky_blue

light_sky_blue

steel_blue

light_steel_blue

light_blue

powder_blue

pale_turquoise

dark_turquoise

medium_turquoise

turquoise

cyan

light_cyan

cadet_blue

medium_aquamarine

aquamarine

dark_green

dark_olive_green

dark_sea_green

sea_green

medium_sea_green

light_sea_green

pale_green

spring_green

lawn_green

green

chartreuse

medium_spring_green

green_yellow

lime_green

yellow_green

forest_green

olive_drab

dark_khaki

khaki

pale_goldenrod

light_goldenrod_yellow

light_yellow

yellow

gold

light_goldenrod

goldenrod

dark_goldenrod

rosy_brown

indian_red

saddle_brown

sienna

peru

burlywood

beige

wheat

sandy_brown

tan

chocolate

firebrick

brown

dark_salmon

salmon

light_salmon

orange

dark_orange

coral

light_coral

tomato

orange_red

red

hot_pink

deep_pink

pink

light_pink

pale_violet_red

maroon

medium_violet_red

violet_red

magenta

violet

plum

orchid

medium_orchid

dark_orchid

blue_violet

purple

medium_purple

thistle

Note that you may use the showColors() function in an alias to display these names with their respective colors in Mudlet.

Example:

-- in a trigger, lets color all words on the current line green
selectString(line, 1)
fg("green")
resetFormat()

-- or lets only color Anne's name in tomato color
selectString("Anne", 1)
fg("tomato")
resetFormat()

bg( color_name )

Same as fg(), but changes the background color of the text (ie, highlights).

See also: fg(), setBgColor().

Example:

-- in a trigger, lets highlight all words on the current line red
selectString(line, 1)
fg("red")
resetFormat()

-- or lets only color dogs in blue
selectString("dog", 1)
fg("tomato")
resetFormat()

resetFormat()

Resets the character format to default. This should be used after you have highlightd some text or changed the current foreground or background color, but you don’t want to keep using these colors for further prints. If you set a foreground or background color, the color will be used until you call resetFormat() on all further print commands.

setBgColor( r,g,b )

Sets the current text background color in the main window. Values are RGB: red, green, blue ranging from 0-255 e.g. for red: setFgColor(255,0,0) If you set a foreground or background color, the color will be used until you call resetFormat() on all further print commands.

setBgColor( windowName, r, g, b )

Sets the current text background color in window windowName. If you have selected text prior to this call, the selection will be highlightd otherwise the current text background color will be changed. If you set a foreground or background color, the color will be used until you call resetFormat() on all further print commands.

example 1 highlights the first occurrence of the string "Tom" in the current line with a red background color.

selectString( "Tom", 1 )
setBgColor( 255,0,0 )

example 2 prints "Hello" on red background and "You" on blue.

setBgColor(255,0,0)
echo("Hello")
setBgColor(0,0,255)
echo(" You!")
resetFormat()

setFgColor( r, g, b )

Sets the current text foreground color in the main window. Values are RGB: red, green, blue ranging from 0-255 e.g. for blue: setBgColor(0,0,255)

setFgColor( windowName, r, g, b )

Sets the current text foreground color in window windowName If the windowName parameters omitted, the main screen will be used.

setBold( windowName, bool )

Sets the current text font to bold (true) or non-bold (false) mode. If the windowName parameters omitted, the main screen will be used.

setItalics( windowName, bool )

Sets the current text font to italics/non-italics mode. If the windowName parameters omitted, the main screen will be used.

setUnderline( windowName, bool )

Sets the current text font to underline/non-underline mode. If the windowName parameters omitted, the main screen will be used.

openUserWindow( name )

Opens a user dockable console window for user output e.g. statistics, chat etc. If a window of such a name already exists, nothing happens. You can move these windows, dock them, make them into notebook tabs or float them.

openUrl ( url )

Opens the default OS browser for the given URL.

Examples:

openUrl("http://google.com")
openUrl("www.mudlet.org")

disableTimer( name )

Disables a timer from running it’s script when it fires - so the timer cycles will still be happening, just no action on them. If you’d like to permanently delete it, use killTrigger() instead.

Use timer name or the id returned by tempTimer() to identify the timer that you want to disable.

disableTrigger( name )

Use trigger name or the id returned by tempTrigger() to identify the timer that you want to disable.

disableKey( name )

Uses trigger name as id or the id returned by tempTrigger()

enableAlias(name)

Enables/activates the alias by it’s name. If several aliases have this name, they’ll all be enabled.

enableTimer( name )

enables or activates a timer that was previously disabled. The parameter "name" expects the timer ID that was returned by tempTimer() on creation of the timer or the name of the timer in case of a GUI timer

enableTrigger( name )

enables a Trigger. see enableTimer() for more details.

enableKey( name )

enable key or key group "name" (hot keys or action keys).

expandAlias( command, print=1 )

like send(), but without bypassing alias expansion. This function may lead to infinite recursion if you are not careful. This function can be used to make recursive alias expansion. expandAlias( "Hello Tom" ) echos the command on the screen expandAlias( "Hello Jane" ) sends the command visually unnoticeable by the user send

howmany = exists (name, type)

Tells you how many things of the given type exist. Type can be "alias", "trigger", or "timer".

Example:

echo("I have " .. exists("my trigger", "trigger") .. " triggers called 'my trigger'!")

You can also use this alias to avoid creating duplicate things, for example:

-- this code doesn't check if an alias already exists and will keep creating new aliases
permAlias("Attack", "General", "^aa$", [[send ("kick rat")]])

-- while this code will make sure that such an alias doesn't exist first
-- we do == 0 instead of 'not exists' because 0 is considered true in Lua
if exists("Attack", "alias") == 0 then
    permAlias("Attack", "General", "^aa$", [[send ("kick rat")]])
end

raiseEvent( event_name, arg-1, … arg-n )

Raises the event event_name. The event system will call the main function (the one that is called exactly like the script name) of all such scripts that have registered event handlers. If an event is raised, but no event handler scripts have been registered with the event system, the event is ignored and nothing happens. This is convenient as you can raise events in your triggers, timers, scripts etc. without having to care if the actual event handling has been implemented yet - or more specifically how it is implemented. Your triggers raise an event to tell the system that they have detected a certain condition to be true or that a certain event has happened. How - and if - the system is going to respond to this event is up to the system and your trigger scripts don’t have to care about such details. For small systems it will be more convenient to use regular function calls instead of events, however, the more complicated your system will get, the more important events will become because they help reduce complexity very much.

The corresponding event handlers that listen to the events raised with raiseEvent() need to use the script name as function name and take the correct number of arguments. NOTE: If you raise an event with 5 arguments but your event handlers functions only take 2,10 or 0 arguments, the functions will not be called. For example: raiseEvent("fight") a correct event handler function would be: myScript( event_name ). In this example raiseEvent uses minimal arguments, name the event name. There can only be one event handler function per script, but a script can still handle multiple events as the first argument is always the event name. So you can call your own special handlers for individual events. The reason behind this is that you should rather use many individual scripts instead of one huge script that has all your function code etc. Scripts can be organized very well in trees and thus help reduce complexity on large systems.

tempTimer( seconds, lua code ) returns timer ID, ID is a string and not a number.

Creates a temporary single shot timer and returns the timer ID for subsequent enableTimer(), disableTimer() and killTimer() calls. You can use 2.3 seconds or 0.45 etc. After it has fired, the timer will be deactivated and killed. example:

tempTimer( 0.3, [[send("kill monster")]] )

This script will send the command "kill monster" 0.3 seconds after this function has been called. Note that this function does not wait until 0.3 seconds have been passed, but it will start a timer that will run the Lua script that you have provided as a second argument after 0.3 seconds.

Note [[ ]] can be used to quote strings in Lua. The difference to the usual `" " quote syntax is that `[[ ]] also accepts the character ". Consequently, you don’t have to escape the " character in the above script. The other advantage is that it can be used as a multiline quote.

Also note that the Lua code that you provide as an argument is compiled from a string value when the timer fires. This means that if you want to pass any parameters by value e.g. you want to make a function call that uses the value of your variable myGold as a parameter you have to do things like this:

tempTimer( 3.8, [[echo("at the time of the tempTimer call I had ]] .. myGold .. [[ gold.")]] )

You can also use the global variable table, the so-called _G table, directly to get the value that is associated with the name of the variable. The _G table holds all global variables and all global function names as keys with the respective values as values.

Here is yet another way to expand variables in Lua, posted in the Mudlet user forum:

How-to: expand variables

Post by eraldo » Sat Aug 22, 2009 4:29 am
Example:

Global variable:
MyNumber = 10

function:

            testFunction(a, b)
                local VariableNameString = a .. b
                local value = tonumber( VariableNameString )
                echo( value )
            end


Function call:
testFunction( "My", "Number" )

Result:
10

tempTrigger( string, lua code ) returns trigger ID, ID is a string and not a number.

This function creates a temporary trigger using substring matching. Contrary to tempTimers, tempTriggers lives throughout the entire session until it is explicitly disabled or killed. Disabled tempTimers can be re-enabled with enableTrigger(). This is much faster than killing the trigger and creating a new one. This is the second fastest trigger (with begin of line substring patterns being the fastest) and should be used instead of regex triggers whenever possible.

tempLineTrigger( from, howMany, LuaCode ) returns trigger ID, ID is a string and not a number.

Temporary trigger that will fire on n consecutive lines following the current line. This is useful to parse output that is known to arrive in a certain line margin or to delete unwanted output from the MUD. Example: tempLineTrigger( 1, 3, ) will fire 3 times starting with the line from the MUD. tempLineTrigger( 20, 2, ) will fire 20 lines after the current line and fire twice on 2 consecutive lines. The function returns the ID of the newly created temporary trigger. You can use this ID to enable/disable or kill this trigger later on.

tempRegexTrigger( regex, lua code ) returns trigger ID

temporary trigger using Perl regex pattern matching <<tempTrigger, This function returns the ID of the newly created temporary trigger. ID is a string and not a number. You can use this ID to enable/disable or kill this trigger later on. → tempTrigger()

killAlias (name)

Deletes an alias with the given name. If several aliases have this name, they’ll all be deleted.

killTimer( id ) returns true or false

Deletes a tempTimer. Use the Timer ID returned by tempTimer() as name parameter. ID is a string and not a number. This function returns true on success and false if the timer id doesn’t exist anymore (=timer has already fired) or the timer is not a temp timer. Note that non-temporary timers that you have set up in the GUI cannot be deleted with this function. Use disableTimer() to turn them on or off.

killTrigger( id ) returns true or false

Deletes a tempTrigger according to trigger ID. ID is a string value, not a number.

See also: killTimer()

openUserWindow( name )

Opens a user dockable console window for user output e.g. statistics, chat etc. If a window of such a name already exists, nothing happens. You can move these windows, dock them, make them into notebook tabs or float them. Most often a mini console is more useful than a dockable window → createMiniConsole

x,y = calcFontSize(font_size)

This returns you the height and the length of letters for the given font size. As the primary intended usage is for calculating the needed dimensions of a miniConsole, it doesn’t accept a font argument - as the miniConsoles currently only work with the default font for the sake of portability.

Examples:

-- Create a miniConsole that is 45 letters in length and 25 letters in height for font size 7
font_size = 7

local x, y = calcFontSize( font_size )
createMiniConsole("map",0,0,0,0)
setMiniConsoleFontSize("map", font_size)
resizeWindow( "map", x*45, y*25 )

clearUserWindow( window_name )

Clears the user window or a mini console with the name given as argument.

copy()

Copies the current selection to the clipboard. This function operates on rich text, i. e. the selected text including all its format codes like colors, fonts etc. in the clipboard until it gets overwritten by another copy operation. example: This script copies the current line on the main screen to a user window (mini console) named chat and gags the output on the main screen.

selectString( line );
copy();
appendBuffer("chat");
replace("This line has been moved to the chat window!")

getLineNumber()

Gets the absolute line number of the current user cursor.

getColumnNumber()

Gets the absolute column number of the current user cursor.

getLineCount()

Gets the absolute amount of lines in the current console buffer

getAreaTable()

Returns a key-value table with all known areas and their IDs.

getAreaRooms(area id)

Returns a key-value table with all rooms for a given area ID.

timestamp = getTimestamp( optional console_name, lineNumber )

Returns the timestamp string as it’s seen when you enable the timestamps view (blue i button bottom right).

Available since 1.1.0-pre1

Example:

Echo the timestamp of the current line in a trigger:

echo(getTimestamp(getLineCount()))

getLines( from_line_number, to_line_number ) returns a Lua table with the content of the lines on a per line basis

Returns a section of the content of the screen text buffer. The form of the return value is: Lua_table[relative_linenumber, content] Absolute line numbers are used.

getLineCount() returns number

Returns the number of the last line in the buffer.

moveCursor( windowName, x, y ) returns true or false

Moves the user cursor of the window windowName to the absolute point (x,y). This function returns false if such a move is impossible e.g. the coordinates don’t exist. To determine the correct coordinates use getLineNumber(), getColumnNumber() and getLastLineNumber(). The trigger engine will always place the user cursor at the beginning of the current line before the script is run. If you omit the windowName argument, the main screen will be used.

Example:

-- set up the small system message window in the top right corner

-- determine the size of your screen
WindowWidth=0;
WindowHeight=0;
WindowWidth, WindowHeight = getMainWindowSize();

-- define a mini console named "sys" and set its background color
createMiniConsole("sys",WindowWidth-650,0,650,300)
setBackgroundColor("sys",85,55,0,255);

-- you *must* set the font size, otherwise mini windows will not work properly
setMiniConsoleFontSize("sys", 12);
-- wrap lines in window "sys" at 65 characters per line
setWindowWrap("sys", 60);
-- set default font colors and font style for window "sys"
setTextFormat("sys",0,35,255,50,50,50,0,0,0);
-- clear the window
clearUserWindow("sys")

moveCursorEnd("sys")
setFgColor("sys", 10,10,0)
setBgColor("sys", 0,0,255)
echo("sys", "test1---line1\n<this line is to be deleted>\n<this line is to be deleted also>\n")
echo("sys", "test1---line2\n")
echo("sys", "test1---line3\n")
setTextFormat("sys",158,0,255,255,0,255,0,0,0);
--setFgColor("sys",255,0,0);
echo("sys", "test1---line4\n")
echo("sys", "test1---line5\n")
moveCursor("sys", 1,1)

-- deleting lines 2+3
deleteLine("sys");
deleteLine("sys");

-- inserting a line at pos 5,2
moveCursor("sys", 5,2);
setFgColor("sys", 100,100,0)
setBgColor("sys", 255,100,0)
insertText("sys","############## line inserted at pos 5/2 ##############");

-- inserting a line at pos 0,0
moveCursor("sys", 0,0)
selectCurrentLine("sys");
setFgColor("sys", 255,155,255);
setBold( "sys", true );
setUnderline( "sys", true );
setItalics( "sys", true );
insertText("sys", "------- line inserted at: 0/0 -----\n");

setBold( "sys", true )
setUnderline( "sys", false )
setItalics( "sys", false )
setFgColor("sys", 255,100,0)
setBgColor("sys", 155,155,0)
echo("sys", "*** This is the end. ***\n");

moveCursorEnd( windowName ) returns true or false

Moves the cursor to the end of the buffer. "main" is the name of the main window, otherwise use the name of your user window. → moveCursor

paste(windowName)

pastes the previously copied text including all format codes like color, font etc. at the current user cursor position. The copy() and paste() functions can be used to copy formated text from the main window to a user window without losing colors e. g. for chat windows, map windows etc.

appendBuffer( name )

Pastes the previously copied rich text (including text formats like color etc.) into user window name.

Example:

selectString( line, 1 )
copy()
appendBuffer( "chat" )

printTable( table_name )

Lua debug function that prints the content of a Lua table on the screen, split up in keys and values. Useful if you want to see what the capture groups contain i. e. the Lua table "matches".

This function is defined in LuaGlobal.lua.

Note

This function is old. Use the newer display() function instead.

showCaptureGroups()

Lua debug function that highlights in random coolors all capture groups in your trigger regex on the screen. This is very handy if you make complex regex and want to see what really matches in the text. This function is defined in LuaGlobal.lua.

Example:

Make a trigger with the regex (\w+) and call this function in a trigger. All words in the text will be highlighted in random colors.

showColors()

Displays all color names that the bg() and fg() functions know about on the main screen along with their respective colors. Very handy for seeing which name is actually what color.

showMultimatches()

Lua helper function to show you what the table multimatches[n][m] contains. This is very useful when debugging multiline triggers - just doing showMultimatches() in your script will make it give the info.

table.load( file, table )

restores a Lua table from a data file that has been saved with table.save()

table.save( file, table )

Saves the given table into the given file.

sendAll( command1, command2, … )

Sends a list of commands to the MUD. You can use this to send some things at once instead of having to use multiple send() commands one after another.

Example:

sendAll("stand", "wield shield", "say ha!")

-- instead of:
send ("stand")
send ("wield shield")
send ("say ha!")

sendTelnetChannel102(msg)

Sends a message via the 102 subchannel back to the MUD (that’s used in Aardwolf). The msg is in a two byte format - see help telopts in Aardwolf on how that works.

Example:

-- turn prompt flags on:
sendTelnetChannel102("\52\1")

-- turn prompt flags off:
sendTelnetChannel102("\52\2")

replaceWildcard(what, replacement)

Replaces the given wildcard (as a number) with the given text. Equivalent to doing:

selectString(matches[2], 1)
replace("text")

Example:

replaceWildcard(2, "hello") -- on a perl regex trigger of ^You wave (goodbye)\.$, it will make

resetFormat (window)

Resets the user character format to the default. If you don’t specify a window, it’ll reset the main console - otherwise it’ll reset the specified miniConsole.

Example:

resetFormat() -- resets the format on the main window
resetFormat("chat console") -- resets the format on the specified window

playSoundFile( fileName )

This function plays a sound file. To make sound work on your operating system you may need to install additional packages:

Microsoft Windows: The underlying multimedia system is used; only WAVE format sound files are supported. (works out of the box) X11: The Network Audio System is used if available, otherwise all operations work silently. NAS supports WAVE and AU files. Mac OS X: NSSound is used. All formats that NSSound supports, including QuickTime formats, are supported by Qt for Mac OS X. (should work out of the box)

cecho (text[, foreground color] [, background color] [, true/false] [, name of console])

  • text - the text that you’d like to echo with embedded color tags. Tags take the color names only, see below for an explanation.

  • foreground color - optional string containing value for foreground color as a named color.

  • background color optional string containing value for background color as a named color.

  • true/false - optional boolean that tells the function to use insertText() rather than echo(). Note that if sending to miniConsole, this has to be false.

  • name of console - optional name of the console to echo to. Defaults to main.

How text works

Color changes can be made using the format <foreground:background> where each field is one of the colors listed by showColors(). The background portion can be omitted using <foreground> or the foreground portion can be omitted using <:background>. Arguments 2 and 3 to set the default colors take named colors as well.

Examples:

cecho("Hi! This text is <red>red, <blue>blue, <green> and green.")

cecho("<:green>Green background on normal foreground. Here we add an <ivory>ivory foreground.")

cecho("All of this text is green.", "green")

cecho("All of this text is navy on cyan.", "navy", "cyan")

cecho("This <green:red>text<light_gray:black> is sent to the map miniConsole.", nil, nil, false, "map"))

createConsole(consoleName, fontSize, charsPerLine, numberOfLines, Xpos, Ypos)

Make a new console window with ease. The default background is black and text color white.

This will create a miniconsole window that has a font size of 8pt, will display 80 characters in width, hold a maximum of 20 lines and be place at 200x400 of your mudlet window. If you wish to change the color you can easily do this when updating your text or manually somewhere, using setFgColor() and setBackgroundColor().

Example:

-- this will create a console with the name of "myConsoleWindow", font size 8, 80 characters per line and default height fr 20 lines at 200x, 400y coordinates.
createConsole("myConsoleWindow", 8, 80, 20, 200, 400)

createBuffer( name )

Creates a named buffer for formatted text, much like a user terminal window, but the buffer cannot be shown on the screen. Intended for temporary buffer work.

appendBuffer( name )

Like paste() but pastes at the end of the buffer/window and wraps new text automatically.

showWindow( name )

shows user window name.

hideWindow( name )

hides user window name.

getNetworkLatency() returns number

returns the last measured response time between the sent command and the server reply e.g. 0.058 (=58 milliseconds lag) or 0.309 (=309 milliseconds)

createStopWatch() returns number

This function creates a stop watch. It is high resolution time measurement tool. Stop watches can be started, stopped, reset and asked how much time has passed since the stop watch has been started. Returns the ID of a high resolution clock with milliseconds to measure time more accurately than what is possible with std. Lua routines → startStopWatch, stopStopWatch, resetStopWatch, getStopWatchTime example: In a global script you create all stop watches that you need in your system and store the respective stopWatch-IDs in global variables:

fightStopWatch = createStopWatch(); -- you store the watchID in a global variable to access it from anywhere

Then you can start the stop watch in some trigger/alias/script with:

startStopWatch( fightStopWatch );

To stop the watch and measure its time in e.g. a trigger script you can write:

fightTime = stopStopWatch( fightStopWatchID )
echo( "The fight lasted for " .. fightTime .. " seconds." )
resetStopWatch( fightStopWatchID );

You can also measure the elapsed time without having to stop the stop watch with getStopWatchTime

startStopWatch( watchID )

Starts the stop watch. → createStopWatch

stopStopWatch( watchID ) returns time as a number

Stops the stop watch and returns the elapsed time in milliseconds in form of 0.001. → createStopWatch

resetStopWatch( watchID )

This function resets the time to 0:0:0.0, but does not start the stop watch. You can start it with startStopWatchcreateStopWatch

getStopWatchTime( watchID ) returns number

Returns the time (milliseconds based) in form of 0.058 (= clock ran for 58 milliseconds before it was stopped) → createStopWatch

getTime(returntype, format)

returntype takes a boolean value (in Lua anything but false or nil will translate to true). If true, the function will return a table in the following format:

{ hour = #, min = #, sec = #, msec = # }

If false or nil, it will return the time as a string using a format passed to the second arg or the default of hh:mm:ss.zzz

Format expressions:

h               the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
hh              the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
H               the hour without a leading zero (0 to 23, even with AM/PM display)
HH              the hour with a leading zero (00 to 23, even with AM/PM display)
m               the minute without a leading zero (0 to 59)
mm              the minute with a leading zero (00 to 59)
s               the second without a leading zero (0 to 59)
ss              the second with a leading zero (00 to 59)
z               the milliseconds without leading zeroes (0 to 999)
zzz             the milliseconds with leading zeroes (000 to 999)
AP or A         use AM/PM display. AP will be replaced by either "AM" or "PM".
ap or a         use am/pm display. ap will be replaced by either "am" or "pm".

d               the day as number without a leading zero (1 to 31)
dd              the day as number with a leading zero (01 to 31)
ddd             the abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses QDate::shortDayName().
dddd            the long localized day name (e.g. 'Monday' to 'Qt::Sunday'). Uses QDate::longDayName().
M               the month as number without a leading zero (1-12)
MM              the month as number with a leading zero (01-12)
MMM             the abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses QDate::shortMonthName().
MMMM            the long localized month name (e.g. 'January' to 'December'). Uses QDate::longMonthName().
yy              the year as two digit number (00-99)
yyyy            the year as four digit number

All other input characters will be ignored. Any sequence of characters that are enclosed in singlequotes will be treated as text and not be used as an expression. Two consecutive singlequotes ("''") are replaced by a singlequote in the output.

*Available since Mudlet 1.0.6.

appendBuffer( name, text )

append text at the end of temp buffer name (fast function)

setWindowWrap( windowName, wrapAt )

sets at what position in the line the console or miniconsole will start word wrap

createGauge(name, width, height, Xpos, Ypos, gaugeText, color1, color2, color3)

Creates a gauge that you can use to express completion with. For example, you can use this as your healthbar or xpbar.

  • name is the gauge name. Must be unique - so don’t have two or more gauges with the same name.

  • width is the width (left to right dimensions) of the gauge.

  • height is the height (top to bottom dimensions) of the gauge.

  • Xpos is the X (so left to right) coordinate of the top-left corner of the gauge. It starts counting from the top-left corner of Mudlets window. So a coordinate of 5 will place it 5 pixels to the right from the top-left part of Mudlet.

  • Ypox is the Y coordinate of the top-left corner of the gauge, relative to the top-left corner of Mudlet.

  • gaugeText is optional text that you can have on the gauge. If you don’t want to have text, use nil in it’s place.

  • color# are the RGB color values to color the gauge with.

See also: moveGauge, setGauge, setGaugeText. Examples:

createGauge("healthBar", 300, 20, 30, 300, nil, 0, 255, 0)
createGauge("healthBar", 300, 20, 30, 300, nil, "green")
-- This would make a gauge at that's 300px width, 20px in height, located at Xpos and Ypos and is green.
-- The second example is using the same names you'd use for something like fg() or bg().

-- If you wish to have some text on your label, you'll change the nil part and make it look like this:
createGauge("healthBar", 300, 20, 30, 300, "Now with some text", 0, 255, 0)
-- or
createGauge("healthBar", 300, 20, 30, 300, "Now with some text", "green")

createMiniConsole( name, posX, posY, width, height ) returns true or false

opens a console window inside the main window of Mudlet at position posX/posY with size according to width/height (values depend on your own screen resolution usually between 0-1600 for x and 0-1024 for y). This console is the ideal fast colored text display for everything that requires a bit more text e.g. status screens, log windows, chat windows etc.. You can use clearWindow/moveCursor etc. functions for this window for custom printing as well as copy & paste functions for colored text copies from the main window or normal echoUserWindow( name, text) for normal printing. To set word wrap see setWindowWrap. To move the main window to make room for miniconsole windows on your screen (if you want to do this as you can also layer mini console and label windows) see setBorderTop, setBorderColor To have your screen layout adjusted after the window size of the main screen gets resized see handleWindowResizeEvent

Example 1:

-- set up the small system message window in the top right corner

-- determine the size of your screen
WindowWidth = 0;
WindowHeight = 0;
WindowWidth, WindowHeight = getMainWindowSize();

createMiniConsole("sys",WindowWidth-650,0,650,300)
setBackgroundColor("sys",85,55,0,255)
setMiniConsoleFontSize("sys", 8)
-- wrap lines in window "sys" at 65 characters per line
setWindowWrap("sys", 40)
-- set default font colors and font style for window "sys"
setTextFormat("sys",0,35,255,50,50,50,0,0,0)

echo("sys","Hello world!")

This script would create a mini text console called "sys" and write with yellow foreground color and blue background color "This is a test".

Example 2:

The next example is more advanced. The user Thylacine has written a tabbed chat widget on the basis of layered mini consoles and on screen buttons (labels). Each tab page holds the output of certain MUD channels e.g. All, Guild, Market, City etc.. You can click on the tab to change the tab page and read what was said in the respective channel. You can get the package here: http://mudlet.sourceforge.net/phpBB3/viewtopic.php?f=6&t=171

Note .

createLabel( name, posX, posY, width, height, fillBackground) returns true or false

labels are intended for very small variable or prompt displays or images. labels are clickable and if you specify a callback function with setLabelClickCallback( labelName, myLabelOnClickFunction ) your function will get called if the user clicks on the label with the mouse. If fillBackground = 0, the background will be hidden, if fillBackground = 1 the background will be shown i.e. you can see the background color. labels can be transparent. You can place labels anywhere within then main display, also als overlays over the main displays e.g. for on screen buttons, micro display, etc. DON’T use labels for larger text displays because they are a lot slower than the highspeed mini consoles

Labels accept some HTML and CSS code for text formating.

Example 1:

Note . screenshot example 1

This example creates a transparent overlay message box to show a big warning message "You are under attack!" in the middle of the screen. Because the background color has a transparency level of 150 (0-255, with 0 being completely transparent and 255 non-transparent) the background text can still be read through. The message box will disappear after 2.3 seconds.

local width, height = getMainWindowSize();
createLabel("messageBox",(width/2)-300,(height/2)-100,250,150,1);
resizeWindow("messageBox",500,70);
moveWindow("messageBox", (width/2)-300,(height/2)-100 );
setBackgroundColor("messageBox", 150,100,100,200);
echo("messageBox", [[<p style="font-size:35px"><b><center><font color="red">You are under attack!</font></center></b></p>]] );
showWindow("messageBox");
tempTimer(2.3, [[hideWindow("messageBox")]] ) -- close the warning message box after 2.3 seconds

Example 2:

Note . screenshot example 2

This example creates a mouse clickable compass (taken from the GUI demo package. You can download this package with the image data etc. → Mudlet forum → packages section http://mudlet.sourceforge.net/phpBB3/viewtopic.php?f=6&t=95

-- define the path to the location of the images
-- this needs to be adapted to your own system e.g. "c:\images\mudimages"
-- on my linux system the folder are in my home directory in the folder gfx
gfx_path = "/home/heiko/gfx";

-- determine the size of your screen
WindowWidth=0;
WindowHeight=0;
WindowWidth, WindowHeight = getMainWindowSize();

-- create clickable compass with clickable images = labels with on click callback functions
createLabel("north",82,WindowHeight-220,50,50,1);
setBackgroundImage("north",gfx_path .. "/n.png" );
setBackgroundColor("north", 0,0,0,0);
setLabelClickCallback("north", "walk_north" )

createLabel("south",82,WindowHeight-80,50,50,1);
setBackgroundImage("south",gfx_path .. "/s.png" );
setBackgroundColor("south", 0,0,0,0);
setLabelClickCallback("south", "walk_south" )

createLabel("west",0,WindowHeight-150,55,55,1);
setBackgroundImage("west",gfx_path .. "/w.png" );
setBackgroundColor("west", 0,0,0,0);
setLabelClickCallback("west", "walk_west" )

createLabel("east",150,WindowHeight-150,50,50,1);
setBackgroundImage("east",gfx_path .. "/e.png" );
setBackgroundColor("east", 0,0,0,0);
setLabelClickCallback("east", "walk_east" )

createLabel("northeast",125,WindowHeight-190,40,40,1);
setBackgroundImage("northeast",gfx_path .. "/ne.png" );
setBackgroundColor("northeast", 0,0,0,0);
setLabelClickCallback("northeast", "walk_northeast" )

createLabel("northwest",30,WindowHeight-190,40,40,1);
setBackgroundImage("northwest",gfx_path .. "/nw.png" );
setBackgroundColor("northwest", 0,0,0,0);
setLabelClickCallback("northwest", "walk_northwest" )

createLabel("southwest",30,WindowHeight-95,40,40,1);
setBackgroundImage("southwest",gfx_path .. "/sw.png" );
setBackgroundColor("southwest", 0,0,0,0);
setLabelClickCallback("southwest", "walk_southwest" )

createLabel("southeast",135,WindowHeight-95,40,40,1);
setBackgroundImage("southeast",gfx_path .. "/se.png" );
setBackgroundColor("southeast", 0,0,0,0);
setLabelClickCallback("southeast", "walk_southeast" )

createLabel("compass",64,WindowHeight-162,75,75,1)
setBackgroundColor("compass",0,0,0,0);
setBackgroundImage("compass",gfx_path .. "/compass.png");
setLabelClickCallback("compass", "callbackTest", 1, "score", 94, 104, 99, "lastParameter" );
--setLabelClickCallback("compass", "callbackTest", 948, "qw", 49, 52 )

function callbackTest( p1, p2, p3, p4, p5, p6  )
        echo("p1="..p1.." p2<"..p2.."> p3<"..p3.."> p4<"..p4..">p5="..p5.." p6<"..p6..">");
        if p1 == 1 then
                send( p2 );
        else
                send( p2 );
        end
end

function walk_north()
        expandAlias("n;map")
        compileRoomDescription()
end

function walk_south()
        expandAlias("s;map")
        compileRoomDescription()
end

function walk_west()
        expandAlias("w;map");
        compileRoomDescription()
end

function walk_east()
        expandAlias("e;map");
        compileRoomDescription()
end

function walk_northeast()
        expandAlias("ne;map");
        compileRoomDescription()
end

function walk_northwest()
        expandAlias("nw;map");
        compileRoomDescription()
end

function walk_southwest()
        expandAlias("sw;map");
        compileRoomDescription()
end

function walk_southeast()
        expandAlias("se;map");
        compileRoomDescription()
end

Example 3 (advanced)

Note . screenshot example 3

This is yet a more advanced demo of interactive graphical user interface programming in Mudlet on the basis of labels. Eraldo has implemented interactive icon buttons, vertical & horizontal gauges for status reports and on screen mini buttons to show status information of his character in-game that is extracted invisibly by his system and reported to the user via interactive or non-interactive icons or other graphical or textual representations. You can download the full package in the package section of the Mudlet forum at http://mudlet.sourceforge.net/phpBB3/viewtopic.php?f=6&t=865

hideWindow( name )

This function hides a mini console label. To show it again use showWindow. createMiniConsole, createLabel

showWindow( name )

This function shows a mini console or label. To hide it use hideWindow see also: createMiniConsole, createLabel

resizeWindow( name, width, height )

resizes a mini console or label see also: createMiniConsole, createLabel, handleWindowResizeEvent, resizeWindow, setBorderTop

moveWindow( name, x, y )

This function moves window name to the given x/y coordinate. The main screen cannot be moved. Instead you’ll have to set appropriate border values → preferences to move the main screen e.g. to make room for chat or information mini consoles, or other GUI elements. In the future moveWindow() will set the border values automatically if the name parameter is omitted. see also: createMiniConsole, createLabel, handleWindowResizeEvent, resizeWindow, setBorderTop

moveGauge (gaugeName, newX, newY)

Moves a gauge created with createGauge to the new x,y coordinates. Remember the coordinates are relative to the top-left corner of the output window.

Example:

moveGauge("healthBar", 1200, 400)
-- This would move the health bar gauge to the location 1200, 400

setMiniConsoleFontSize( name, fontSize )

Sets the font size of the mini console. see also: createMiniConsole, createLabel

setGauge(gaugeName, currentValue, maxValue, gaugeText)

Use this function when you want to change the gauges look according to your values. Typical usage would be in a prompt with your current health or whatever value, and throw in some variables instead of the numbers.

Examples:

setGauge("healthBar", 200, 400)

In that example, we’d change the looks of the gauge named healthBar and make it fill to half of its capacity. The height is always remembered.

If you wish to change the text on your gauge, you’d do the following:

setGauge("healthBar", 200, 400, "some text")

setGaugeText(gaugeName, gaugeText, color1, color2, color3)

Set the color and text on a custom gauge built by createGauge.

Example:

setGaugeText("healthBar", "HP: 100%", 40, 40, 40)
setGaugeText("healthBar", "HP: 100%", "red")

An empty gaugeText will clear the text entirely. Colors are optional and will default to 0,0,0(black) if not passed as args.

setTextFormat( windowName, r1, g1, b1, r2, g2, b2, bold, underline, italics )

sets current text format of window windowName: foreground color(r1,g1,b1), background color(r2,g2,b2), bold(1/0), underline(1/0), italics(1/0) A more convenient way to control the text format in a mini console is to use setFgColor( windowName, r,g,b ), setBold( windowName, true ), setItalics( windowName, true ), setUnderline( windowName, true ) etc.createMiniConsole, setBold, setBgColor, setFgColor, setItalics, setUnderline

Example:

createMiniConsole( "con1", 0,0,300,100);
setTextFormat("con1",0,0,255,255,255,0,1,1,1);
echo("con1","This is a test")

This script would create a mini text console and write with yellow foreground color and blue background color "This is a test".

getCurrentLine()

returns the content of the current line under the user cursor in the buffer. The Lua variable line holds the content of getCurrentLine() before any triggers have been run on this line. When triggers change the content of the buffer, the variable line will not be adjusted and thus hold an outdated string. line = getCurrentLine() will update line to the real content of the current buffer. This is important if you want to copy the current line after it has been changed by some triggers. selectString( line,1 ) will return false and won’t select anything because line no longer equals getCurrentLine(). Consequently, selectString( getCurrentLine(), 1 ) is what you need.

selectCurrentLine()

selects the content of the current buffer line

setBackgroundImage( labelName, imageFileName )

loads an image file (png) as a background image for a label. This can be used to display clickable images etc.

setBackgroundColor( window name, red, green, blue, transparency )

Sets rgb color values and the transparency for the given window. Colors are from 0 to 255 (0 being black), and transparency is from - to 255 (0 being completely transparent).

Note that transparency only works on labels, not miniConsoles for efficiency reasons.

setLabelClickCallback( labelName, luaFunctionName, optional any amount of arguments )

specify a Lua function to be called if the user clicks on the label/image e.g. setLabelClickCallback( "compassNorthImage", "onClickGoNorth" ) UPDATE: this function can now pass any number of string or integer number values as additional parameters. These parameters are then used in the callback. Thus you can associate data with the label/button. check the forum for more information on how to use this. * FIXME * example

Turns the selected text into a clickable link - upon being clicked, the link will do the command code. Tooltip is a string which will be displayed when the mouse is over the selected text.

Available since 1.1.0-pre1.

Example:

In a sewer grate substring trigger, the following code will make clicking on the words do the send("enter grate") command:

selectString(matches[1], 1)
setLink([[send("enter grate")]], "Clicky to enter grate")

setPopup(name, {lua code}, {hints})

Turns the selected text into a left-clickable link, and a right-click menu. The selected text, upon being left-clicked, will do the first command in the list. Upon being right-clicked, it’ll display a menu with all possible commands. The menu will be populated with hints, one for each line.

  • name - the name of the console to operate on. If not using this in a miniConsole, use "main" as the name.

  • {lua code} - a table of lua code strings to do. ie, \{[[send("hello")]], [[echo("hi!"]]\}.

  • {hints} - a table of strings which will be shown on the popup and right-click menu. ie, `{"send the hi command", "echo hi to yourself"}.

Available since 1.1.0-pre1.

Example:

In a Raising your hand in greeting, you say "Hello!" exact match trigger, the following code will make left-clicking on Hello show you an echo, while left-clicking will show some commands you can do.

selectString("Hello", 1)
setPopup("main", {[[send("bye")]], [[echo("hi!")]]}, {"left-click or right-click and do first item to send bye", "click to echo hi"})

echoUserWindow( windowName )

This function will print text to both mini console windows, dock windows and labels. This function is outdated. Use echo( windowName, text ) instead → echo

Same as setPopup() except it doesn’t require a selection. echoPopup creates a link from the given text that it echos.

Available since 1.1.0-pre1.

Example:

Create some text as a clickable with a popup menu:

echoPopup("activities to do", {[[send "sleep"]], [[send "sit"]], [[send "stand"]]}, {"sleep", "sit", "stand"})

getMainWindowSize() returns 2 numbers, width and height in pixels

return window width and window height ( function with 2 return values ) to calculate the window dimensions and placement of custom GUI toolkit items like labels, buttons, mini consoles etc. example:

mainWindowWidth, mainWindowHeight = getMainWindowSize();

table.size( tableName )

Gets the actual size of non-index based tables.

For index based tables you can get the size with the # operator: myTableSize = # myTable This is the standard Lua way of getting the size of index tables i.e. ipairs() type of tables with numerical indices. To get the size of tables that use user defined keys instead of automatic indices (pairs() type) you need to use the function table.size() referenced above.

result = table.union(tableA, tableB, tableC)

Returns a table that is the union of the provided tables. This is a union of key/value pairs. If two or more tables contain different values associated with the same key, that key in the returned table will contain a subtable containing all relevant values. See table.n_union() for a union of values. Note that the resulting table may not be reliably traversable with ipairs() due to the fact that it preserves keys. If there is a gap in numerical indices, ipairs() will cease traversal.

Example:

Given:
tableA = {
        [1] = 123,
        [2] = 456,
        ["test"] = "test",
        }

tableB = {
        [1] = 23,
        [3] = 7,
        ["test2"] = function() return true end,
        }

tableC = {
        [5] = "c",
        }

table.union(tableA, tableB, tableC) will return:
{
        [1] = {
                123,
                23,
                },
        [2] = 456,
        [3] = 7,
        [5] = "c",
        ["test"] = "test",
        ["test2"] = function() return true end,
}

result = table.n_union(tableA, tableB, tableC)

Returns a numerically indexed table that is the union of the provided tables. This is a union of unique values. The order and keys of the input tables are not preserved.

result = table.intersection(tableA, tableB, tableC)

Returns a table that is the intersection (or difference, ie elements only common to all tables) of the provided tables. This is an intersection of key/value pairs. See table.n_intersection() for an intersection of values. Note that the resulting table may not be reliably traversable with ipairs() due to the fact that it preserves keys. If there is a gap in numerical indices, ipairs() will cease traversal.

Example:

tableA = {
        [1] = 123,
        [2] = 456,
        [4] = { 1, 2 },
        [5] = "c",
        ["test"] = "test",
        }

tableB = {
        [1] = 123,
        [2] = 4,
        [3] = 7,
        [4] = { 1, 2 },
        ["test"] = function() return true end,
        }

tableC = {
        [1] = 123,
        [4] = { 1, 2 },
        [5] = "c",
        }

table.intersection(tableA, tableB, tableC) will return:
{
        [1] = 123,
        [4] = { 1, 2 },
}

result = table.n_intersection(tableA, tableB, tableC)

Returns a numerically indexed table that is the intersection of the provided tables. This is an intersection of unique values. The order and keys of the input tables are not preserved.

true/false = io.exists(file or folder)

Checks to see if a given file or folder exists. If it exists, it’ll return the Lua true boolean value, otherwise false.

Examples:

if io.exists("/home/vadi/Desktop") then
        echo("This folder exists!")
else
        echo("This folder doesn't exist.")
end

if io.exists("/home/vadi/Desktop/file.tx") then
        echo("This file exists!")
else
        echo("This file doesn't exist.")
end

table string:split( delimiter )

Splits a string into a table by the given delimiter. For example:

names = "Alice, Bob, Peter"
name_table = {}

name_table = names:split(", ")
display(name_table)

table {
  1: 'Alice'
  2: 'Bob'
  3: 'Peter'
}

complement = table.complement(set1, set2)

Returns a table that is the relative complement of the first table with respect to the second table. Returns a complement of key/value pairs.

complement = table.n_complement(set1, set2)

Returns a table that is the relative complement of the first table with respect to the second table. Returns a complement of values.

true/false = table.contains(t, value)

Determines if a table contains a value as a key or as a value (recursive)

state = getButtonState() with state = 2 button is checked and state = 1, button is not checked

this function can be used in checkbox button scripts (2-state buttons) to determine the current state of the checkbox. Example:

checked = getButtonState();
if checked == 1 then
    hideExits()
else
    showExits()
end;

showToolBar( name )

Shows toolbar with the given name name on the screen. Toolbars are the groups that buttons are contained in.

hecho (text[, foreground color] [, background color] [, true/false] [, name of console])

  • text - the text that you’d like to echo with embedded color tags. Tags take the hex color values only, see below for an explanation.

  • foreground color - optional string containing value for foreground color as a named color.

  • background color optional string containing value for background color as a named color.

  • true/false - optional boolean that tells the function to use insertText() rather than echo(). Note that if sending to miniConsole, this has to be false.

  • name of console - optional name of the console to echo to. Defaults to main.

How text works

Color changes can be made within the string using the format |cFRFGFB,BRBGBB where FR is the foreground red value, FG is the foreground green value, FB is the foreground blue value, BR is the background red value, etc., BRBGBB is optional. |r can be used within the string to reset the colors to default.

The colors in arg2 and arg3 replace the normal defaults for your console. So if you use cecho("|cff0000Testing |rTesting", "00ff00", "0000ff"), the first Testing would be red on black and the second would be green on blue.

hideToolBar( name )

Hides the toolbar with the given name name and makes it disappear. If all toolbars of a tool bar area (top, left, right) are hidden, the entire tool bar area disappears automatically.

disconnect()

close network connection to the server without a proper logout.

reconnect()

reconnects to the current server after a call to disconnect()

setTriggerStayOpen( name, number )

set for how many more lines a trigger script should fire or a chain should stay open after the trigger has matched. The main use of this function is to close a chain when a certain condition has been met.

number should be 0 to close the chain, or a positive number to keep the chain open that much longer.

homedir = getMudletHomeDir()

returns the current home directory of the current profile. This can be used to store data, save statistical information or load resource files.

datetime:parse(source, format, as_epoch)

parses the specified source string, according to the format if given, to return a representation of the date/time. If as_epoch is provided and true, the return value will be a Unix epoch — the number of seconds since 1970. This is a useful format for exchanging date/times with other systems. If as_epoch is false, then a Lua time table will be returned. Details of the time tables are provided in the Lua Manual.

Supported Format Codes
%b

Abbreviated Month Name

%B

Full Month Name

%d

Day of Month

%H

Hour (24-hour format)

%I

Hour (12-hour format, requires %p as well)

%p

AM or PM

%m

2-digit month (01-12)

%M

2-digit minutes (00-59)

%S

2-digit seconds (00-59)

%y

2-digit year (00-99), will automatically prepend 20 so 10 becomes 2010 and not 1910.

%Y

4-digit year.

display( myTable )

Generic pretty print function to display tables of any complexity. This is the preferred debug function to print the content of any kind of Lua table or variable to the main screen.

display( myVariable )

generic pretty print function to display the content of any Lua variable or table on the main screen

db:create(database name, schema table)

Creates and/or modifies an existing database. This function is safe to define at a top-level of a Mudlet script: in fact it is reccommended you run this function at a top-level without any kind of guards. If the named database does not exist it will create it. If the database does exist then it will add any columns or indexes which didn’t exist before to that database. If the database already has all the specified columns and indexes, it will do nothing.

The database will be called Database_<sanitized database name>.db and will be stored in the Mudlet configuration directory.

Database tables are called sheets consistantly throughout this documentation, to avoid confusion with Lua tables.

The schema table must be a Lua table array containing table dictionaries that define the structure and layout of each sheet.

Examples:

        local mydb = db:create("combat_log",
                {
                        kills = {
                                name = "",
                                area = "",
                                killed = db:Timestamp("CURRENT_TIMESTAMP"),
                                _index = { {"name", "area"} }
                        },
                        enemies = {
                                name = "",
                                city = "",
                                reason = "",
                                enemied = db:Timestamp("CURRENT_TIMESTAMP"),
                                _index = { "city" },
                                _unique = { "name" },
                                _violations = "IGNORE"
                        }
                }
        )

The above will create a database with two sheets; the first is kills and is used to track every successful kill, with both where and when the kill happened. It has one index, a compound inde tracking the combination of name and area. The second sheet has two indexes, but one is unique: it isn’t possible to add two items to the enemies sheet with the same name.

For sheets with unique indexes, you may specify a _violations key to indicate how the db layer handle cases where the unique index is violated. The options you may use are: * FAIL - the default. A hard error is thrown, cancelling the script. * IGNORE - The command that would add a record that violates uniqueness just fails silently. * REPLACE - The old record which matched the unique index is dropped, and the new one is added to replace it.

returns a reference of an already existing database. This instance can be used to get references to the sheets (and from there, fields) that are defined within the database. You use these references to construct queries.

If a database has a sheet named enemies, you can obtain a reference to that sheet by simply doing:

    local mydb = db:get_database("my database")
    local enemies_ref = mydb.enemies
    local name_ref = mydb.enemies.name

These references do not contain any actual data, they only point to parts of the database structure.

db:add(sheet reference, table1, …, tableN)

Adds one or more new rows to the specified sheet. If any of these rows would violate a UNIQUE index, a lua error will be thrown and execution will cancel. As such it is advisable that if you use a UNIQUE index, you test those values before you attempt to insert a new row.

Each table is a series of key-value pairs to set the values of the sheet, but if any keys do nto exist then they will be set to nil or the default value.

An example:

        db:add(mydb.enemies, {name="Bob Smith", city="San Francisco"})
        db:add(mydb.enemies,
                {name="John Smith", city="San Francisco"},
                {name="Jane Smith", city="San Francisco"},
                {name="Richard Clark"})

As you can see, all fields are optional.

db:fetch(sheet reference, query, order_by, descending)

returns a table array containing a table for each matching row in the specified sheet. All arguments but sheet are optional. If query is nil, the entire contents of the sheet will be returned.

Query is a string which should be built by calling the various db: expression functions, such as db:eq, db:AND, and such. You may pass a SQL WHERE clause here if you wish, but doing so is very dangerous. If you don’t know SQL well, its best to build the expression.

Query may also be a table array of such expressions, if so they will be AND’d together implicitly.

The results that are returned are not in any guaranteed order, though they are usually the same order as the records were inserted. If you want to rely on the order in any way, you must pass a value to the order_by field. This must be a table array listing the columns you want to sort by. It can be { "column1" }, or { "column1", "column2" }

The results are returned in ascending (smallest to largest) order; to reverse this pass true into the final field.

Examples:

        db:fetch(mydb.enemies, nil, {"city", "name"})
        db:fetch(mydb.enemies, db:eq(mydb.enemies.city, "San Francisco"))
        db:fetch(mydb.kills,
                        {db:eq(mydb.kills.area, "Undervault"),
                        db:like(mydb.kills.name, "%Drow%")}
        )

The first will fetch all of your enemies, sorted first by the city they reside in and then by their name.

The second will fetch only the enemies which are in San Francisco.

The third will fetch all the things you’ve killed in Undervault which have Drow in their name.

db:eq(field reference, value)

returns a database expression to test if the field in the sheet is equal to the value.

db:exp(string)

returns the string as-is to the database.

Use this function with caution, but it is very useful in some circumstances. One of the most common of such is incrementing an existing field in a db:set() operation, as so:

        db:set(mydb.enemies, db:exp("kills + 1"), db:eq(mydb.enemies.name, "Ixokai"))

This will increment the value of the kills field for the row identified by the name Ixokai.

But there are other uses, as the underlining database layer provides many functions you can call to do certain things. If you want to get a list of all your enemies who have a name longer then 10 characters, you may do:

        db:fetch(mydb.enemies, db:exp("length(name) > 10"))

Again, take special care with this, as you are doing SQL syntax directly and the library can’t help you get things right.

db:not_eq(field reference, value)

returns a database expression to test if the field in the sheet is NOT equal to the value.

db:lt(field reference, value)

returns a database expression to test if the field in the sheet is less than the value.

db:lte(field reference, value)

returns a database expression to test if the field in the sheet is less than or equal to the value.

db:merge_unique(sheet reference, table array)

merges the specified table array into the sheet, modifying any existing rows and adding any that don’t exist.

This function is a convenience utility that allows you to quickly modify a sheet, changing existing rows and add new ones as appropriate. It ONLY works on sheets which have a unique index, and only when that unique index is only on a single field. For more complex situations you’ll have to do the logic yourself.

The table array may contain tables that were either returned previously by db:fetch, or new tables that you’ve constructed with the correct fields, or any mix of both. Each table must have a value for the unique key that has been set on this sheet.

For example, consider this database:

        local mydb = db:create("peopledb",
                {
                        friends = {
                                name = "",
                                race = "",
                                level = 0,
                                city = "",
                                _index = { "city" },
                                _unique = { "name" }
                        }
                }
        );

Here you have a database with one sheet, which contains your friends, their race, level, and what city they live in. Let’s say you want to fetch everyone who lives in San Francisco, you could do:

        local results = db:fetch(mydb.friends, db:eq(mydb.friends.city, "San Francisco"))

The tables in results are static, any changes to them are not saved back to the database. But after a major radioactive cataclysm rendered everyone in San Francisco a mutant, you could make changes to the tables as so:

        for _, friend in ipairs(results) do
                friend.race = "Mutant"
        end

If you are also now aware of a new arrival in San Francisco, you could add them to that existing table array:

        results[#results+1] = {name="Bobette", race="Mutant", city="San Francisco"}

And commit all of these changes back to the database at once with:

        db:merge_unique(mydb.friends, results)

The db:merge_unique function will change the city values for all the people who we previously fetched, but then add a new record as well.

db:gt(field reference, value)

returns a database expression to test if the field in the sheet is greater than to the value.

db:gte(field reference, value)

returns a database expression to test if the field in the sheet is greater than or equal to the value.

db:is_nil(field reference, value)

returns a database expression to test if the field in the sheet is nil.

db:is_not_nil(field reference, value)

returns a database expression to test if the field in the sheet is not nil.

db:like(field reference, pattern)

returns a database expression to test if the field in the sheet matches the specified pattern.

LIKE patterns are not case-sensitive, and allow two wild cards. The first is an underscore which matches any single one character. The second is a percent symbol which matches zero or more of any character.

LIKE with "_" is therefore the same as the "." regular expression.

LIKE with "%" is therefore the same as ".*" regular expression.

db:not_like(field reference, pattern)

returns a database expression to test if the field in the sheet does not match the specified pattern.

LIKE patterns are not case-sensitive, and allow two wild cards. The first is an underscore which matches any single one character. The second is a percent symbol which matches zero or more of any character.

LIKE with "_" is therefore the same as the "." regular expression.

LIKE with "%" is therefore the same as ".*" regular expression.

db:between(field reference, lower_bound, upper_bound)

returns a database expression to test if the field in the sheet is a value between lower_bound and upper_bound. This only really makes sense for numbers and Timestamps.

db:not_between(field reference, lower_bound, upper_bound)

returns a database expression to test if the field in the sheet is not a value between lower_bound and upper_bound. This only really makes sense for numbers and Timestamps.

db:in_(field reference, table array)

returns a database expression to test if the field in the sheet is one of the values in the table array.

First, note the trailing underscore carefully! It is required.

The following example illustrates the use of in_:

        local mydb = db:get_database("my database")
        local areas = {"Undervault", "Hell", "Purgatory"}

        db:fetch(mydb.kills, db:in_(mydb.kills.area, areas))

This will obtain all of your kills which happened in the Undervault, Hell or Purgatory. Every db:in_ expression can be written as a db:OR, but that quite often gets very complex.

db:not_in(field reference, table array)

returns a database expression to test if the field in the sheet is not one of the values in the table array.

See link: db:in_

db:aggregate(field reference, aggregate function, query)

returns the result of calling the specified aggregate function on the field and its sheet. The query is optional.

The supported aggregate functions are:

  • COUNT - Returns the total number of records that are in the sheet or match the query.

  • AVG - Returns the average of all the numbers in the specified field.

  • MAX - Returns the highest number in the specified field.

  • MIN - Returns the lowest number in the specified field.

  • TOTAL - Returns the value of adding all the contents of the specified field.

    Examples:
    -----
           local mydb = db:get_database("my database")
           echo(db:aggregate(mydb.enemies.name, "count"))
    -----

db:AND(sub-expression1, …, sub-expressionN)

returns a compound database expression that combines all of the simple expressions passed into it; these expressions should be generated with other db: functions such as db:eq, db:like, db:lt and the like.

This compound expression will only find items in the sheet if all sub-expressions match.

db:OR(sub-expression1, sub-expression2)

returns a compound database expression that combines both of the simple expressions passed into it; these expressions should be generated with other db: functions such as db:eq, db:like, db:lt and the like.

This compound expression will find any item that matches either the first or the second sub-expression.

db:delete(sheet reference, query)

Deletes rows from the specified sheet. The argument for query tries to be intelligent:

  • if it is a simple number, it deletes a specific row by _row_id

  • if it is a table that contains a _row_id (e.g., a table returned by db:get) it deletes just that record.

  • Otherwise, it deletes every record which matches the query pattern which is specified as with db:get.

  • If the query is simply true, then it will truncate the entire contents of the sheet.

Some examples:

        enemies = db:fetch(mydb.enemies)

        db:delete(mydb.enemies, enemies[1])
        db:delete(mydb.enemies, enemies[1]._row_id)
        db:delete(mydb.enemies, 5)
        db:delete(mydb.enemies, db:eq(mydb.enemies.city, "San Francisco"))
        db:delete(mydb.enemies, true)

Those deletion commands will do in order:

  1. When passed an actual result table that was obtained from db:fetch, it will delete the record for that table.

  2. When passed a number, will delete the record for that _row_id. This example shows getting the row id from a table.

  3. As above, but this example just passes in the row id directly.

  4. Here, we will delete anything which matches the same kind of query as db:fetch uses-- namely, anyone who is in the city of San Francisco.

  5. And finally, we will delete the entire contents of the enemies table.

db:update(sheet reference, table)

This function updates a row in the specified sheet, but only accepts a row which has been previously obtained by db:fetch. Its primary purpose is that if you do a db:fetch, then change the value of a field or tow, you can save back that table.

For example:

        local mydb = db:get_database("my database")
        local bob = db:fetch(mydb.friends, db:eq(mydb.friends.name, "Bob"))[1]
        bob.notes = "He's a really awesome guy."
        db:update(mydb.friends, bob)

This obtains a database reference, and queries the friends sheet for someone named Bob. As this returns a table array containing only one item, it assigns that one item to the local variable named bob. We then change the notes on Bob, and pass it into db:update() to save the changes back.

db:set(field reference, value, query)

The db:set function allows you to set a certain field to a certain value across an entire sheet. Meaning, you can change all of the last_read fields in the sheet to a certain value, or possibly only the last_read fields which are in a certain city. The query argument can be any value which is appropriate for db:fetch, even nil which will change the value for the specified column for EVERY row in the sheet.

For example, consider a situation in which you are tracking how many times you find a certain type of egg during Easter. You start by setting up your database and adding an Eggs sheet, and then adding a record for each type of egg.

        local mydb = db:create("egg database", {eggs = {color = "", last_found = db.Timestamp(false), found = 0}})
        db:add(mydb.eggs,
                {color = "Red"},
                {color = "Blue"},
                {color = "Green"},
                {color = "Yellow"},
                {color = "Black"}
        )

Now, you have three columns. One is a string, one a timestamp (that ends up as nil in the database), and one is a number.

You can then set up a trigger to capture from the mud the string, "You pick up a (.*) egg!", and you end up arranging to store the value of that expression in a variable called "myegg".

To increment how many we found, we will do this:

        myegg = "Red" -- We will pretend a trigger set this.
        db:set(mydb.eggs.found, db:exp("found + 1"), db:eq(mydb.eggs.color, myegg))
        db:set(mydb.eggs.last_found, db.Timestamp("CURRENT_TIMESTAMP"), db:eq(mydb.eggs.color, myegg))

This will go out and set two fields in the Red egg sheet; the first is the found field, which will increment the value of that field (using the special db:exp function). The second will update the last_found field with the current time.

Once this contest is over, you may wish to reset this data but keep the database around. To do that, you may use a more broad use of db:set as such:

        db:set(mydb.eggs.found, 0)
        db:set(mydb.eggs.last_found, nil)

id = tempAlias(regex, lua code)

Creates a temporary (lasts only until the profile is closed) alias. This means that it won’t exist anymore after Mudlet restarts.

Example:

tempAlias("^hi$", [[send ("hi") echo ("we said hi!")]]

tempColorTrigger( foregroundColor, backgqroundColor, function )

Makes a color trigger that triggers on the specified foreground and background color. Both colors need to be supplied in form of these simplified ANSI 16 color mode codes: .Color Codes:

0 = default text color
1 = light black
2 = dark black
3 = light red
4 = dark red
5 = light green
6 = dark green
7 = light yellow
8 = dark yellow
9 = light blue
10 = dark blue
11 = light magenta
12 = dark magenta
13 = light cyan
14 = dark cyan
15 = light white
16 = dark white

example:

tempColorTrigger(9,2,[[selectString(matches[1],1); fg("red"); bg("blue");]] );

This script will re-highlight all text in blue foreground colors on a black background with a red foreground color on a blue background color until another color in the current line is being met. temporary color triggers do not offer match_all or filter options like the GUI color triggers because this is rarely necessary for scripting. A common usage for temporary color triggers is to schedule actions on the basis of forthcoming text colors in a particular context.

r,g,b = getFgColor( windowName )

This function returns the rgb values of the color of the first character of the current selection on mini console (window) windowName. If windowName is omitted Mudlet will use the main screen. example:

local r,g,b;
selectString("troll",1)
r,g,b = getFgColor()
if r == 255 and g == 0 and b == 0 then
    echo("HELP! troll is written in red letters, the monster is aggressive!\n");
end

r,g,b = getBgColor( windowName )

get the rgb values of the first character of the current selection → getFgColor() for more information

wrapLine( windowName, lineNumber )

wrap line lineNumber of mini console (window) windowName. This function will interpret \n characters, apply word wrap and display the new lines on the screen. This function may be necessary if you use deleteLine() and thus erase the entire current line in the buffer, but you want to do some further echo() calls after calling deleteLine(). You will then need to re-wrap the last line of the buffer to actually see what you have echoed and get you \n interpreted as newline characters properly. Using this function is no good programming practice and should be avoided. There are better ways of handling situations where you would call deleteLine() and echo afterwards e.g.:

selectString(line,1);
replace("");

This will effectively have the same result as a call to deleteLine() but the buffer line will not be entirely removed. Consequently, further calls to echo() etc. sort of functions are possible without using wrapLine() unnecessarily.

isAnsiFgColor( ansiFgColorCode )

This function tests if the first character of the current selection has the foreground color specified by ansiFgColorCode. Codes are: .Color Codes:

0 = default text color
1 = light black
2 = dark black
3 = light red
4 = dark red
5 = light green
6 = dark green
7 = light yellow
8 = dark yellow
9 = light blue
10 = dark blue
11 = light magenta
12 = dark magenta
13 = light cyan
14 = dark cyan
15 = light white
16 = dark white

example:

selectString( matches[1], 1 )
if isAnsiFgColor( 5 ) then
    bg("red");
    resetFormat();
    echo("yes, the text is light green")
else
    echo( "no sorry, some other foreground color" )
end

Note that matches[1] holds the matched trigger pattern - even in substring, exact match, begin of line substring trigger patterns or even color triggers that do not know about the concept of capture groups. Consequently, you can always test if the text that has fired the trigger has a certain color and react accordingly. This function is faster than using getFgColor() and then handling the color comparison in Lua.

isActive (name, type)

You can use this function to check if something, or somethings, are active. Type can be either "alias", "trigger", or "timer", and name is the name of the said item you’d like to check.

Example:

echo("I have " .. isActive("my trigger", "trigger") .. " currently active triggers called 'my trigger'!")

isAnsiBgColor( ansiBgColorCode )

This function tests if the first character of the current selection has the background color specified by ansiBgColorCode. → isAnsiFgColor for more details

true/false = isPrompt()

Returns true or false depending on if the current line being processed is a prompt. This infallible feature is available for MUDs that supply GA events (to check if yours is one, look to bottom-right of the main window - if it doesn’t say <No GA>, then it supplies them).

Example use could be as a Lua function, making closing gates on a prompt real easy.

path = invokeFileDialog (boolean file_or_folder, dialog_title)

Opens a file chooser dialog, allowing the user to select a file or a folder visually. The function returns the selected path or nil if there was none chosen.

  • boolean - true for file selection, false for folder selection.

  • dialog title - name that the dialog (file chooser window) will have

Example:

local path = invokeFileDialog(false, "Find me the gfx folder, please")
echo(path)
Note If the user clicks Cancel in the dialog, the path returned will then be "" (blank string).

setBorderTop( size )

Sets the height of the top border to size pixel and thus effectively moves down the main console window by size pixels to make room for e.g. mini console windows, buttons etc..

setBorderBottom( size )

Sets the height of the bottom border to size pixels. → setBorderTop

setBorderLeft( size )

Sets the width of the left border. → setBorderTop

setBorderRight( size )

Sets the width of the right border. → setBorderTop

setBorderColor( r, g, b )

Sets the color of the border in RGB color e.g. setBorderColor( 255, 0, 0 ) sets the border to red.

bool = hasFocus()

Returns true or false depending on if the main Mudlet window is in focus. By focus, it means that the window is selected and you can type in the input line and etc. Not in focus means that the window isn’t selected, some other window is currently in focus.

handleWindowResizeEvent()

The standard implementation of this function does nothing. However, this function gets called whenever the main window is being manually resized. You can overwrite this function in your own scripts to handle window resize events yourself and e. g. adjust the screen position and size of your mini console windows, labels or other relevant GUI elements in your scripts that depend on the size of the main Window. To override this function you can simply put a function with the same name in one of your scripts thus overwriting the original empty implementation of this function.

function handleWindowResizeEvent()
   -- determine the size of your screen
   WindowWidth=0;
   WindowHeight=0;
   WindowWidth, WindowHeight = getMainWindowSize();

   -- move mini console "sys" to the far right side of the screen whenever the screen gets resized
   moveWindow("sys",WindowWidth-300,0)
end

setConsoleBufferSize( consoleName, linesLimit, sizeOfBatchDeletion )

Set the scrollback buffer size to linesLimit and determine how many lines are deleted at once in case the lines limit is reached. The lower the limit the less memory being used. On machines with low RAM you should consider limiting the size of buffers that don’t need a lot of scrollback e.g. system notification windows, chat windows etc.. Default values are linesLimit = 100000 lines with 10000 lines of batch deletion. Minimum buffer size is 100 lines with 10 lines batch deletion.

searchRoom (room name)

Searches for rooms that match (by case-insensitive, substring match) the given room name. It returns a key-value table in form of roomname = roomid, ie:

table {
  'office of the guildmaster': 2004
  'Hall of Cultural Masterpieces': 10361
  'the Grand Master's Chambers': 21546
  'the chambers of Master Blasterson': 10210
  'Exhibit of the Techniques of the Master Artisans': 6324
  'the master's gallery': 19067
  'office of the Guildmaster': 5340
  'the master's salon': 18978
  'The Enlightened Master': 11313
  'hall before the Master Chambers': 6592
  'central hall in the beastmaster apartments': 7712
  'before the Master Ravenwood Tree': 1337
}

If no rooms are found, then an empty table is returned.


mudlet-2.1/src/mac_src.pro0000755000175000017500000001234411647202526015112 0ustar csmallcsmallCONFIG += release uitools CONFIG += app_bundle QMAKE_CXXFLAGS_RELEASE += -O3 -Wno-deprecated -Wno-unused-parameter QMAKE_CXXFLAGS_DEBUG += -O3 -Wno-deprecated -Wno-unused-parameter QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 MOC_DIR = ./tmp OBJECTS_DIR = ./tmp QT += network opengl phonon macx:INCLUDEPATH += /Users/heikokoehn/Downloads/lua5_1_4_MacOS106_lib/include \ /Users/heikokoehn/Downloads/boost_1_46_1 \ /usr/local/include/yajl/include macx:LIBS += \ /Users/heikokoehn/lib/liblua.a \ #/usr/local/lib/libluajit-5.1.a \ /usr/local/lib/libzzip.a \ -F../Frameworks \ -L../Frameworks \ -lpcre \ -lhunspell \ -lz \ -lyajl unix:INCLUDEPATH += /usr/include/lua5.1 INCLUDEPATH += irc/include SOURCES += TConsole.cpp \ ctelnet.cpp \ main.cpp \ Host.cpp \ HostManager.cpp \ HostPool.cpp \ dlgConnectionProfiles.cpp \ dlgTriggerEditor.cpp \ TTrigger.cpp \ TriggerUnit.cpp \ TLuaInterpreter.cpp \ dlgTriggersMainArea.cpp \ dlgOptionsAreaTriggers.cpp \ dlgOptionsAreaTimers.cpp \ dlgOptionsAreaScripts.cpp \ TCommandLine.cpp \ TTreeWidget.cpp \ TTreeWidgetItem.cpp \ TTimer.cpp \ TScript.cpp \ TAlias.cpp \ dlgTimersMainArea.cpp \ dlgSystemMessageArea.cpp \ dlgSourceEditorArea.cpp \ TimerUnit.cpp \ ScriptUnit.cpp \ AliasUnit.cpp \ dlgScriptsMainArea.cpp \ dlgAliasMainArea.cpp \ dlgOptionsAreaAlias.cpp \ dlgSearchArea.cpp \ TAction.cpp \ ActionUnit.cpp \ dlgActionMainArea.cpp \ dlgOptionsAreaAction.cpp \ EAction.cpp \ dlgAboutDialog.cpp \ TDebug.cpp \ dlgKeysMainArea.cpp \ TKey.cpp \ KeyUnit.cpp \ dlgProfilePreferences.cpp \ TTextEdit.cpp \ XMLexport.cpp \ XMLimport.cpp \ FontManager.cpp \ TFlipButton.cpp \ TToolBar.cpp \ TLabel.cpp \ TEasyButtonBar.cpp \ TForkedProcess.cpp \ dlgColorTrigger.cpp \ dlgTriggerPatternEdit.cpp \ TSplitter.cpp \ TSplitterHandle.cpp \ mudlet.cpp \ dlgNotepad.cpp \ THighlighter.cpp \ dlgComposer.cpp \ TArea.cpp \ glwidget.cpp \ dlgMapper.cpp \ TRoom.cpp \ TMap.cpp \ #lua_yajl.c \ TBuffer.cpp \ irc/src/ircbuffer.cpp \ irc/src/irc.cpp \ irc/src/ircsession.cpp \ irc/src/ircutil.cpp \ dlgIRC.cpp \ T2DMap.cpp \ dlgRoomExits.cpp \ luazip.c HEADERS += mudlet.h \ TTimer.h \ EAction.h \ TConsole.h \ ctelnet.h \ Host.h \ TMap.h \ TAStar.h \ HostManager.h \ HostPool.h \ dlgConnectionProfiles.h \ dlgTriggerEditor.h \ TTrigger.h \ TLuaInterpreter.h \ dlgTriggers_main_area.h \ dlgOptionsAreaTriggers.h \ dlgTriggerPatternEdit.h \ TCommandLine.h \ TTreeWidget.h \ TTreeWidgetItem.h \ TScript.h \ TAlias.h \ dlgTimersMainArea.h \ dlgSourceEditorArea.h \ dlgSystemMessageArea.h \ TimerUnit.h \ ScriptUnit.h \ AliasUnit.h \ dlgScriptsMainArea.h \ dlgAliasMainArea.h \ dlgOptionsAreaAlias.h \ dlgOptionsAreaScripts.h \ dlgOptionsAreaTimers.h \ dlgSearchArea.h \ TAction.h \ ActionUnit.h \ dlgActionMainArea.h \ dlgOptionsAreaAction.h \ dlgAboutDialog.h \ TMatchState.h \ TEvent.h \ TDebug.h \ dlgKeysMainArea.h \ TKey.h \ KeyUnit.h \ dlgProfilePreferences.h \ TTextEdit.h \ TFlipButton.h \ TToolBar.h \ TBuffer.h \ TriggerUnit.h \ TLabel.h \ TEasyButtonBar.h \ TForkedProcess.h \ dlgColorTrigger.h \ TSplitter.h \ TSplitterHandle.h \ dlgNotepad.h \ THighlighter.h \ dlgComposer.h \ TRoom.h \ TArea.h \ TMap.h \ glwidget.h \ dlgMapper.h \ Tree.h \ irc/include/ircbuffer.h \ irc/include/irc.h \ irc/include/ircsession.h \ irc/include/ircutil.h \ dlgIRC.h \ T2DMap.h \ dlgRoomExits.h FORMS += ui/connection_profiles.ui \ ui/main_window.ui \ ui/trigger_editor.ui \ ui/options_area_triggers.ui \ ui/options_area_timers.ui \ ui/options_area_aliases.ui \ ui/options_area_scripts.ui \ ui/triggers_main_area.ui \ ui/scripts_main_area.ui \ ui/aliases_main_area.ui \ ui/system_message_area.ui \ ui/source_editor_area.ui \ ui/extended_search_area.ui \ ui/actions_main_area.ui \ ui/options_area_actions.ui \ ui/timers_main_area.ui \ ui/about_dialog.ui \ ui/keybindings_main_area.ui \ ui/color_trigger.ui \ ui/notes_editor.ui \ ui/trigger_pattern_edit.ui \ ui/composer.ui \ ui/mapper.ui \ ui/profile_preferences.ui \ ui/irc.ui \ ui/mapper_room_color.ui \ ui/room_exits.ui \ ui/lacking_mapper_script.ui \ ui/package_manager.ui \ ui/module_manager.ui \ ui/package_manager_unpack.ui win32: { SOURCES += lua_yajl.c } unix: { SOURCES += lua_yajl1.c } TEMPLATE = app TARGET = mudlet RESOURCES = mudlet_alpha.qrc DISTFILES += paragraph.css unix: { luaglobal.path = $$SHARE_DIR luaglobal.files = LuaGlobal.lua documentation.path = $$SHARE_DIR documentation.files = mudlet_documentation.html fonts.path = $$SHARE_DIR fonts.files = fonts/ttf-bitstream-vera-1.10/* target.path = $$BIN_DIR } INSTALLS += fonts \ luaglobal \ documentation \ target OTHER_FILES += \ mudlet_documentation.txt mudlet-2.1/src/dlgTriggerPatternEdit.h0000644000175000017500000000334511513237311017356 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef dlg_trigger_pattern_edit_h #define dlg_trigger_pattern_edit_h #include "ui_trigger_pattern_edit.h" #include class dlgTriggerPatternEdit : public QWidget , public Ui::trigger_pattern_edit { Q_OBJECT public: dlgTriggerPatternEdit(QWidget*); int mRow; signals: public slots: }; #endif mudlet-2.1/src/deleteOldProfiles.zip0000644000175000017500000000345312070466512017106 0ustar csmallcsmallPKs>delOPalias.xmlUX '$N'$NmRMO0 =D]H[MnI!EM*ڤ4IxҦK;6" T&E!.2y1Q9nvxÚ弞䓦\Vl Eh#delOPscript.xmlUX '$Nj'$NVmkF,儖rvһpzYK#[DҺ+3"[Ih!Ҿ3/c԰C+GeQ跻ɻx͇Ow_?¯]QX# CG16W`CMhzD+YVE+,.,5hh6COfsqYv-a-<"n KclVq<֛MT- 4?Rr/PIiM\ua#RY] \B؊8=i hd b^ IK~]CWꐎA*V%\dG]h1DH3Ff+d$&[g_ͨRڀ؉ ."l*MEc\ :}* }Ne`^llݤ)5!Zhs v `JRWpZ;te-Y6X4 $(57B%k4n:>p|T^4R[cso_gFcýeJ%G8r~`>T1qFLN m -ds'gА;V:G *KCe/!i<t`e{Wc-M% uoՑDl}96 "_9"ln2^$"ϥ*, ^TR]!QYLdz-LxB)괦kFZaaP70*$#d'DtR8]ȶƷm 4L[ &٪;j+HEGIA}-k)U"yT }|wwv>"@5W 8ܸNה[LaziZ(XW[1Yϟhjb[)ǵ`u`^ Aš&gg=4CMpBϓKqyZEڮp]`1Y4T)li$sԔ*%w/g⻌ ZT7o(CKy ZLL?7tArnG/"T".-3)#jNO A| )B*eG$0TJGM#ޚO/6ӣEXB>KPK}Ϧ PKs>usE @delOPalias.xmlUX'$N'$NPKs>}Ϧ  @delOPscript.xmlUX'$Nj'$NPKmudlet-2.1/src/dlgOptionsAreaTimers.cpp0000644000175000017500000000307511513237311017552 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "TTimer.h" #include #include "dlgOptionsAreaTimers.h" dlgOptionsAreaTimers::dlgOptionsAreaTimers(QWidget * pF):QWidget(pF) { // init generated dialog setupUi(this); } mudlet-2.1/src/icons/0000755000175000017500000000000012076170616014066 5ustar csmallcsmallmudlet-2.1/src/icons/offsettimer-off.png0000755000175000017500000001317211513237311017671 0ustar csmallcsmallPNG  IHDR00WsRGB7MS tiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}y>?UoU x"')6 sg2 @ Ѐq'5kK?MqpBFr&Xnw%_̴da; ^W8'p7AeH1_pt#2 sbIv վ5WnK"i/ԕge^s1*g {vn:zg,@)'-C,hRE 4.0f'?Ă$  ԂZ ΃x ;A"C4HR!bC֐ A!P8t( BPT5A@ hzM@GI0V5`} ?S,8W) ߂G`^@BD2 E>)@ʑzF{C>0(EY\Q(*UBDuPPy4-A[t&:]nDGSw aa0L<&S9i\ a&1 X,Vzc#i|l%"v;}#pF8g\(ŕq=a4n /W[\V|1ߍ/$,OE  oD ќK#$VO'HT6ɁFJ'# ]"=$!d[r(9DB~J~/Fs{ES)v,J9,eN/! !]ZMP["IHY Kՠ:Q<1$ hnZ*mnxz!g }^*i,(EZ򂤀04nDF1 cQJAN*JjT԰ԢtttGL~N'(YmY_L#Werr3raymy?lc . We=J4%k82J/L;f"ǜWWvUNWST^Ra䪴aQ>30--[:u<Qٕ3n[vh{;vLtyraW®۹owSۙ7-b={jD{+~),4(,/T)O?-7XlZ|S+odDiVe̲7Qn\^{p(³RSUlH}u[|ޚGl*~<wAK]GF}1̱c7566~>;!8wɬYnIo=vώ?wֵ1 O_3gg[U^ultt s?mo'+ yГ׳|1¥Ksc.On}|%>߾W_sv߮uoX8w}魎&M;k~{hPϰ{wkdh胱1_?xx8zOM`*081lݳǓɗi*9ytӌYٻ/ֿzri.O?k^i/ۿ^_/]F͉o{|KzX^>N/e~~Ǘe \@"D. r \@"D._ YY m*ЈhA.zTXtauthorxH!s) IDAThYylͽ;!@NhK*ڂJ#hЂ8 RJ-B44!@&Gv|^;;}H"(5tVgv}M mbܒϴs<{$**BUU }`T 㙼셙筩fݲtEQףfWWYk6_|*HBFs#L5XZŪ: C}h6B29 t;&۶@$HDx SEd&u8Ԋ-'$#z)d'xA# Z)S.yv90lB)Iu-o} 20tr]_5G) 㹁<>^), T5Λpxx \܇GT@I%1g>HE@pEVHd 0?"=C5H ,ǂ{ 9E܍4XyA>PI0fydU *·2 ^UAEyqFmpXt Yc],ItC$0X^cI;Ѻ+v jC/ !`PтƍbN@;|L< ld'V*:2+Ю8 0O ?ޛ8ǿyCպ xB QQJ:ahN 0q 2ЦUb \IQ8R?0z롌qgA|'uɤjmM N.WE"1E3:3k#>@$|[fMCcPa颥A}q$joI=}{ ivov^/]Hliy ئ B~":1U(Ѥt *l/'=L9CYS[2s֒h ľ3"9ޖ7{qU>ay; DP>E\<`y遂XMEH>N+t&ŜhwSXWOoK_wi'uDzn1q:>";\L& ^[ƆN6]Gsrb^7k'm{[ycYb~:N:|Q-4``jmhȷT"uŏQ`u5'xezFYu=۠ WJ$1|%6 6 F]H% " ۢJ(>;RWZ#Ea^MD>Lk) Mk'7Nݎ(e0 eR)1riJ.NYUL8[͆??3``\MLKE#䁤%4,?tnE<^*2fGZGFF͎~ʳVzg}NTңQQeM|?9$HVP>ZCEqyNtS3]a5fZ,j4dz76HВIENDB`mudlet-2.1/src/icons/errors.png0000755000175000017500000001230711513237311016105 0ustar csmallcsmallPNG  IHDR@@iq pHYsnn{gzbKGD9IDATxڵ[k\u>cw $BA1Oa +Lb'G  P8.]TpUIBʫ1b^`iZi}tӧ뻫ٕ*W:}t9Oa:hC@ޟt;ҋ!瑵Q$!-ҫ FAbރN eAd:֦Km>^/±lՄY #H c{5[!ݱBf!/q(݁Ae%ת,x6: !!dPjg,ٖ9Wײ13 TD[ XD~bKUcMz#OW= lY(| 30OhTt3#ֵ&1%=!CS-wx|? 98LDyy|m!0 4+~]W"Oe^3NuLh ߧlH0 d$_vLSJ^އ_a zb~ 0-?y^u%r:\j^M24d]*L$za bi6瓓 U|[44gܒ,2 _5̉}W]f&blL.fjG]w=~ +VP17Gѣ..0[ϫa J)]mA[%ژzi:ё>ee4A&G,/NU3g"YܢDT=Q^q9m evEJۢV\tC\`٢LvDs4dB~K翇eYWIo"9 qom?Nsvܩ THSk4CuZ-A^Pu:R7 !I兛;(A[J4Vےp[ZQ=T1Uh-!&VS Sn]y{ynxfz}%cVRzU\YJL%a/O òh۪V0_' dt)-m<I)wyɧQtfmyJT(+bf3aFU=ƍkA )p쯅'[Ąbۿ޺_|g72{-qj̗ xzgbJrRe;^ I4 C\"2HːwO"ii U? aS@UԚbQL[ä'D^RȨ30ZPc>žub?yM8 3²E)l#v`jfCmLpڟO4 vU D9>"}\8,%g69"oKi$nx2!c_CA}E~^@˔+bX}-)d[FLDj#i&IpTfAQ0] !N ,Vɡ<ܓMy4i $1x "B \uQ\U@E2x>O_lPOTaY.iQ!uBzR*P*bTijռjJܝJ!ԽM(5qh:=TNO 9o>#lK;Q'Lu%Q$ TD^Q, ӣBHǤ4Le)\өZcyd6$"BB)#.z̺X{)d=2 4hix+&+\ܝ@Nݮ<j]ecϾ@LgioY"pr?)f6WjoQU a!j"cx0h]>~hh>ގba3GvpBg"\/IƻoFsUhVEWnJV% !ӧ%[/J=O^Uk6CXB*ɔnrZ򄑍fڸ0YfzEЉ^@3={Š,FVm^T^FPͱ}-kBbCV$edCsȮQyqTG(p ߐ: '>!5gP\B0G!+ؿF"zRBlJYLS'umY_VRbM`§ޒ1@JfJr\@ h@liT o!)꼉/!OL@TCa}T9`?( R3 j@"oB}׺.S%<I!"hws/i42ԔeEiZwFVQj?Vs6axfnPt$A 5z"Z H]8|NPz;7Hĥ@5eI08f? #:rdN^g58fMy1]Z:EQU#g]- xBByOȳ$;^mQĦbX+~YH f-96!JN AƓ1$hr}_j_OѮVHtJ+rft'!E`ZchlPU5N1U94BHi~NAŧW`E TV >,[VM3npzJ6l .n RP!ov坥Wf0{q{Ef? $ jIKG#9nOHȌqi3H "˘ifx2a$@CzT)h<,ߤ||ک#bF)|9ZK^oQK/CV,GjUׁSbNGQx fd4GɀP*d$z,c4śMA go>z> 4FgM$~l *PQ: %"Nd:2a~Q 1FT^gyq?oRo>L\' *ܞ&@xi{ Qt@'f6+WfVjs5#JkdFɃo3U;g٨ 4,} OD mdH9a\6MeNvPWmP;}(DQAnDl9ij/|tuϬ'H"l'K"چO ?f<AxϬ''N? kf?o^ȴ=奅.f'<^wP"zTXtSoftwarex+//.NN,H/J6XS\IENDB`mudlet-2.1/src/icons/application-exit.png0000755000175000017500000001026511513237311020044 0ustar csmallcsmallPNG  IHDR@@iq pHYs^tIME 0XbKGDBIDATxZiunwmlڐhG+bQ$$KRJH#Cp@`Nb#ٮr BRD8ml@B2ìo[ޜw_w'~ᔾu{s=gF6B=%B @-" rz(Q@oca$e*Вɘ_cJ<9lelhlQI91 V܀tz;?wxJ@FU}.|.tM ƽl4d2k<3/z1eӦ}:zرڈVwsUEDKQH$O (_$8S-Koi`b( Ӷ! L}Ri %H:ɓ:;2Сڦt^H $FwR M4_r Q0H$q ch#(@7 \W|yg@n}G`뻬8LT ={W^b}04ѵo⦙ 5(@W)/@*X…n^=,DB5 tB#Ψ+˂IɃi+* ;5 T$~1&56y2 |6lxaѼrx"'JAZ!*d Jӧ1}R_'N_Ě x4,gс57bʔ)ػw/^ڿ'BT((G@#@~ۋ>9,_:@Gt~(OR~ܶif͚ţvZz׿Ƶ4m)P&R #{1d&O͞=ںux IXA)ڻ%^s+Voi": dT 9R"¾La̙n=<6Yy#9cƌ`˖-a71۶@*Jlj \q-A!Ui7ߌש&̧h)uwiܰz5ND"EXx1ښߵ !+lG+ kv9*Ba,+Zi)f xe̢za"G(ZI&Ay"F>M"XV;`%\KOH r: KZ[q+S)~DSzwĉ J^!#ߢڃю`ҙSPdp?`"{pףB гwƓԎtcp<ٮo(q,q `S![E C"0iY(o]sf zvܸqB"0l}!FN H:|5o#cb-JФr̻z ƌ >&|V՝Qঀ'u~RML>s2R'%"~&@<( rD(iEcaۮ`{w`bXthj P:A ˮ4ֽ^yBMHl'JjII5;owp6uiő#}sE3xTZfA:vBd2X.G}=I-%IOHj`fzw[JաP(T u?R>'b J$(P_3)UuznPFՀ"xuR@ΫmAH@0qo#>< 0yLLn+U, v͈a (3sÐKa#+F^pD8|@&R dR;Wy,P*ЎoQ}\-#G$X4ݎo6}⥗pFqhM+j7;EPJWhi>[${O.mx |y0|mfD"HGHOxS3r8CK #zd͜GEMN-qG's鈐O>["!,ׅ&eȎ'H^vL:œ@/.~x Rb>nvfo,U8MM&ĩrb4b(k-M"|}fJHSHԓ !1nT|-zzB߽1"dZVP\53gu{&d΄YTt@'F zJ7kb\&O+/LCTX~1 P FЕW=B4"0Z𠗠HOh%SU7 `>ME>qnV ;U'o|L8?$t YEӀ6-r~N\G|0kc4}Yq=8غ;L܃V£UL>7o _y_n_ _b|~_+P{ p85@G^T~ӨyJJQi@( "\n}!?/_ . J)-zBwսf1w.=oU>^"9rGQ:pm="'I ,PS x9#\@Ae]=>X%vpΜ9󨏳va5&! ` "?D`D 8J> )ILحcw_lj#? z; |c5.W ᾝ7:g(4ewzH`c mݛHAaF}}=mEo+$US8ڋٝav]#D!o0\v` 0H؄ܖ'ts\Ka] 7HAп&O,%PP)ĞlB+/D:B#/K#O0Y/ l>(vwpZI84ƞ-7n x} ލW_(%N)% LG#f8J(_{"0$Wq_xk"_p#~p{?RߏD;#?z\A1B:p+K}q]=}"W.#ues ǡm{+;GLʫ+ocsGJ@+ovT]*Rlh~ L@DVa_%BH.$R="S՞ GB9ߣSq@4ud۠,q" JO(-h q!@Et7m9mmG2y3ܰӋ FN;}md1,HOht?)::P.rέl}~׃,Ck>/n’G7:HLm8F ЙiMx,?k툽8l9֏ 3Fz $ 2!7ЏR{LyOH.dN}(S& :H<ɠapsmk83 #a R@ձ7_WbzPG^gB`hz1fYmȗ+- !BEhEYF) 2)B) 2J-`h݀$ !c Oi|fY *s JIENDB`mudlet-2.1/src/icons/internet-telephony.png0000644000175000017500000000613611513237311020426 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< IDATxY \Uν>=.vB[ZڪXh0jQT"$Ԩ߉Ѡ4LP(*ш| X}>9sZɖ=w|g,SJY4ҳ8 X8%fLH$H7AYgLW|4sfmr|{)^--Z652E-$b0m?]mvBe}NyzT-3]K گ_]~ryRr8 ` %%Wi @"fA"QuR3@V QH /;?qDžŸ{՝ok7hddweX Ρq\a\,U=['el !bGQWْD, EL*:OUgf*VO e#!?tmH`<,BRS-\O4z.kS)r;J@M[mBbq< o]5_G]}E{hChHf6k<1OCRwǞZB~ŦcߌB Ȼ&\jI%5Hg&ΎI^|Wo?dXѕ1ӊ, oS@D'#L7cd %5}kƑ>)1s6$m,cb ]D&C(xB(~kl+란C&yoZ&|CN/ v`g, }D~'h4բPIUt0 v XX=::mffgs]b#ʚbjLp( eoBSIF]PaoE׽;\_х/ .eZeS J_1OC3(C^úAzI7]`@j0;y0Bcz,K>c*Gl;$h-3y}/lb6!,nfMOJyKb9<˷QȸKCUFcQ.PG ?657N`,;x"ɘR]G1) 3o4ѯ4SnØ6 i^D =zG6 &pE rG!܌ $ע`0=;sh?2:}[G-!_ķt(ڷiUtr%7_d]m/!>6`AhL{rW]Z,ݏJI/G`F%MC6_[Xv^◟gЁsxa[4] mߊLMJ'cA@%jCwQhLΟ c߈ \kXcI.#0C"'勿?e{H)s`U<0 XٙƋ-M0V@e! Ghudt<\nDfNy讵u ugDFr.O45xV2s5``;$n"F$ f|Ri :pRB7#Yؑ2uC0z=nWZ"&; 2RI| ( ?&;Хkx۷2r5ee(chw'9[džA`߾Ǩ"O05snݎC‹aSDƐFl^p@ Ԍ`+߁8>y1]첗c޽ `<lIK0 LTDn7IIOc27%>z;R .2Rac$I)dCP}'.Hghh5E'(Z@qpG)kܽ2B% `%oƱ?v|IBPg 7Ø̴97:J3^qT}`q:=*1p^6( ^x%Z3oH(諬iظSLs~edvth,Kߎ%D*VH2KLb10L@[j}Z4K$e}O1^K9.Q_n%8jx2=ӆ8+αasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDATx[l\WZ; ur!!rD rQZQU o}!;P[%B"ZEH i&X)؎cOƞ9Zӭ̌xvZoƗ9?k9g|Z Jh\K- @KZu'_|7WmIǸph2wPy7s3P 68@0@^"DKΈ$C`(C  u^t^n ul~P@*}5Ԁ^,ֻ@#!`麡rgX/!ve@S!t8+uY!eBSAX Ux8+uc28__r?JDHP A'okHңxsFe F%hF~YQDȀ)4EX.>Ō|GӅ(Bng?P.@מUB ̚.bִ9jw y#C6!ob/2pp5`I eYF9w*!]!むZ⍖&Ksʒ$M҈w#aƈӦ<\~`.O?-ykㄿCG5-ONKqgvS!%r#Wj3:X|b2ސ[HsM9Zĝ8t^}SS\]ʏ&'&-X2uni2xC܉Cq)N`+c,?>3uG>|ɱO}?;$ +N;q(.ũ!2),0sL➓)}M\ݍ5NkyvmH% tƋ%q~Z§a+yɪ`\*YEUof̼5h9P:ǩs:@+ s=qw\`;!-?ę?\:.Z Lg\h};h9ri֒_!v֘j]gN|ޒ_@l62 Z\A" 4Z- @K]:`tꁼB &nHNIENDB`mudlet-2.1/src/icons/folder.png0000755000175000017500000000457011513237311016047 0ustar csmallcsmallPNG  IHDR>asBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATxKlW|Gw$$i R" @X@RUEAbՖH"*$ " $PTRTGڤJ%I4(?'3^rƞwDΌs|ByaH$e/ $R) @J['~SWζ3 GpuBC8^lzCjsx~8a=HOZ!|x?FEہ=wvuHG~½;ܽUcu, ~6i KvoGA{.@[^vnػ]}挄`]Z;7CB@C3ج '^B/;;s33kYcD.!C{Ԟޯ9ht@8T|q-:@/MCj@]hZs HV9{EZl_P8N4< Yg?Ũ5aL٪`z/B SF:[\UZ+lE̩?[W3m8`,ͥu/}W>{nV1{=cani9 pG7Vvj13 &#byd By0E4.zX2LQ<q S<'}3,sUXL {怦W0}k!8f&$ ^E8`j">sIhAP:s_0C/<ЧdhpԖ9 MwOnfbBXF` j7B&@(bHU@DE  3@`Fwd(ܵ0g+3"x*X6x6P׉@|!F"8'1rQo(ST0Uf `TmoPOkIO]'9g #q>ZP `b= "yΎO^ @ NP [Lp˕iFvb;xE3:+bDnF|J$!N]u W W*FYZ A,3_8g Cițt[?;c-k GAys# ,60uE2cdJĔzS \zAr΀fOֵHP쌍빔@լu;Ao*,GQ0@l9aҔ&ysod^ "=6Nfr hfFo8)b=\K Έ@&8sLށTq= `ʍ"xAb;[;E/ 4l<Z?f'\߰\(3ĈҒD;rv aC; 1&t+|Q*M- RHia9ЄF@ߑOXq(q;>9@PSڠ84DQıB(|hR 5S@$)|(ZQ\/:.S6QIL- Bp;P#7N/- ӑqm Z |籇Vj&PXY ]躀u$o9x޺^by?rc|GvCкN_:Ol49>3c'~/_N~-xi:.Sˊݭ6Ćjruw}й/swP34:gz&!Oqpq/Z)ap?ˆwu圽9tc W xp=-q~KNerҹk, N4 c\7BaΨu圍9i-?u;\B|Ygyǂs:j|wKu^qbH$R) @J %]:`tꁼBx1OA]IENDB`mudlet-2.1/src/icons/folder-blue.png0000755000175000017500000000124411513237311016767 0ustar csmallcsmallPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<!IDATx헿jTAƿܿ F,l$XX`!>o v`'vR5;{gW"IMȤ~0ppwxۭD}!joV[ud hP_ i?1>f 'Wm;^l@L.=,eoOd6 wz̻6߮6:YeJ0KN'ٯkA9qyhDiʮ7E LdaS<T3?,DE i Au.+@!H S.pi"&dS0,UTD> ]-̓,]u3e0!+,WULfے,UT )"hKV)0EGJBkC_S!TED.57j<\Q0#U07?}܎~t6߇3?af7\N8:,|of/ǀ%N OT4WuIENDB`mudlet-2.1/src/icons/aetolia_120_30.png0000755000175000017500000000614311513237311017074 0ustar csmallcsmallPNG  IHDRx*tEXtSoftwareAdobe ImageReadyqe<PLTE')%%6{ffXEW))uuG$$'YDDg8Z77vjFFh77GT7$$҇ffd&&I44rruUUyy[[GGhXXtssu(({GGmm~||CBBʼVUUkjj]\\%%;;;eee55UUݘw88444LLL|rrs88PP̋Ʉ##`ODD 򫤤oaaɘ?//Ժɷ^OOFFó¬poo...GGGOOOѠ@??>>xww QQQڱ yIDATxW_X%Wcd1 " A)nѱV8 ~׿ ?Bλ{?Z}og'K9$E"`lqRiзxhr vQ~-֋K G%Ea.UD-;‘O)ݦ+r aAEp#B6\ΖH&iH+ .4*¢ɫ+Wap1va0X*{:R,*GocE<z2oMԁ84u)MˍUȎc;zx(Yr({jb)Lۇ52 dcA E/84/a_60-l o${D\u8~=j>npx̴f Hٛ0CU6 g !<;p_&óD<}/X.֚Oo7}`ӌlS WLhdjw \Py̙a$=b'y9;ƅ T=)% 7|{x(.k珙uݟMH`n/j#'(RDun=E^5Aq *s{5tMiYR|FFF屈)KX,kf{{9cuJ  2s٧%|3AF H+OD~G]Q~ R)8UY· ,V~" =eDVe J&///קBbXyF = q~~~Ϗ ;Dg^S 7BV̲lxtym"r17$ @5szj+8 >ߚR1*K*f%(qy6GRW5.8k^]$]LņSH/p*kxdH$3^$3+$hONF"yb5U(* P e?5ß\]^5m=FsG+|،;/DS;_>Fka"5bCfҀ do#Pf;SUdmq!R,qJZ'#Hw^ "?P45妾/i؜c9"SUy&AÔ{lxDt>^&7[|5=Zh爸OقGYUs~waT/2'NResz^ȚBsTiv.EOadU9F^1{BMcz-I;(6 /º]gힹGr} Yɮ/ܾߩ $Ba%*Wo󗂩QasW^wuFXn2gR[[|v]_tiyzv7oM_Gs 3Wѷ?3uUWjj.]Tk^]PMMНЪD[ĊOk5rI:lvOHgaµ'cMW<2+뾭55TUAT/1LBaB!Дgrrhak2`w9([쮹D2v& \ʘq0Ðz?#.,NUXah_{IENDB`mudlet-2.1/src/icons/tag_checkbox-grey.png0000644000175000017500000000042512070466512020157 0ustar csmallcsmallPNG  IHDRaIDAT8˥10FLxgЩSz 6b:ѭQvHZW@ɵy,e|/XZ0:߸=MOxY_(&Rл'IENDB`mudlet-2.1/src/icons/applications-accessories.png0000755000175000017500000002600611513237311021561 0ustar csmallcsmallPNG  IHDR>asBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<+IDATx} %IyޗYǻwL=W^2  )apH`!aْC@,(صY]vwvgfc|tWU]ͬ~?Ϭ*">]؇= &Gg9r|RsG}7?"x#.=K4MH@wwwI|̙㏳}@p!o R$'.1`6FGGOB~;sI{D]BbY)P@Yv333޳HI'DWkkk.ˢAxu4dccCR+|rtP;$$055 '6@Fo:]sE;LD&А{oy[SO'hXu!{>r8ſo~^z7"]]]~2=~3s $Hd! 1⧒TRYW{_yr6>.) 96Xw]!A#!Ҍ7Bȴ@^bNetHH6K"%GnK*!"J\XlH5<|K:'s/->\$<)!{q 1 n.@d{3R1.#S8 hqCnڸO(,JB@YI$,I\E<hbϞz?ga'|#WWR*>&=i> ͜1&8zP8ꎇzCTGXS$@H_"шf  MC1*F U@ ̸O$0 xy|OR=ɤ3JvsY\fXP%$װYU=0C;1\.WW$3p:^zWR*".P(Hi_+'$ {/v" SYi$?Bd++[X^ބm"}V`'w,uDڿ+Orr+K\U)e"G| `OjzUJRc}/h \:j&CՊq~qvĮg˗׏UΣ\sҪREz$}/'y9Xqnaak|8sk~GpA]=Jz2,H"U?9jw e+w5amsc r} adџc$!=$H>k~YDU}+2y[XyhW3@:x!q $v ?G*}a /tpJ&fK(p0:փDʡ" ]= 0 2ΠVsALNV$g 7` |Ͼ}+pV0-F;ЕKPD*es@]A r$\ɲR3h,oRv¤q$R ]|K[a=oml=;"eCCl۾,z2R!f0z@vcW3bQH3ƕ؆dDo_n# $j+>I>gǭ^ƦvppPR?CN6Z[R*{5)&Y5@12*qC(RiWخ ʃNArYq9@9s@ZuZHcvf?%薦obrɤ\jmZlWTժ{ù:1u:Bp6A|u(@tBM nH)zC&S:% Ƚ$ ?'?}Л)*_۲0<{> GJxm ZyOЪl88S^DF] ӫBx~R $6ݩ>81蕒OEO#!}[Krc~_4OwK@~4Z:<0B } $pY J$W 3׫!>A%_A(b HT-@aah &1OAhW{F'M.k#hL1 0Fâk =j0g@Ü+ؒH^zƔ|z0|eOOT DPi`5Q&[B r ,SF7mTtZ݆gjdiBr¯!WrA&@>y m7#ˢ_AI86N]yԊ58x h)kf Di}` mSh}>]ap )NU\ LyAz`YZmg;I CpA@MKY[ȪCE5N0D+Q%6YDϾC+S@P5S("*aG"IZ=M"~ysu!8[-dApk5E82;JxCMqM5AL7`90@80;[{dx#J.&Dܻ򭴃6!WǎN1ގmQ«2a_ HE<µb af +pgc!f@@!.?͍R,F{u2w_տi>*( nvPND5lgHїG h-҅"E2VWWѓ4 Q0N8Z JCS7Bf8 E.E>j:$qFSy~ILLN(&xprҁ`0F'!jBȎ"q|[j!:tPB|9T9aPD!t}t}*U6vC\_0s%#81=?;P~ؗ'A`@p78гO`J}$/!ݾaO6= ^o~ N>m>b;E@tVh HXܰqm-ø.IXJ ^,L[M +Q'DyuJD)i ܴO!ĔP*pp͸Bk54qLoڊ"LH49q t4hSfD4t)4\fg/U&`FqoQOQ$8XZh]Ȕh/uDnPX#AuFsxw?~/="FARp+V2'1EP E5@G+,R-M1Am<0յ _BDu 3W,W`bGm4#$v v.&r錖p *Fا7s[_GF&P*]f\A(<:ߣh.#OH=Bm7i:u AuC1s/WȾV\&\֣eB5l M(8&^cFz۶0tDN*Dl~$ш>ܶP,JD) 2:qN %w}ie1bӧbiq G9911GofJB6\ņz5eG`qmO 4M$Ix:D|kk8illnaQbcGAlH@ ck­7M˸aXØZ5@`'o#h1{|-@fQ:;OLcyY#;hޙTW/C%5(4D'Fp *P  l|{[<Tcsv8,Ri@-qVp/B;m:`VL [&b|w f#\f"{E*1R cz͝5y̙L:tK,_ m:m?TB=V"D/4 ;c[\3ޫn!4:u TzKGE)>6%t6m."Y!#)BN˶pgZlѱC!L*`_8vhp[{IfN(n P[؞2XI X{T1Ab& l8Rm|Aknt0'`yAi0 acL8aejRzӧop fw7]4UחoiO iVA MYY~ K ;['0i76!}Ub婧*ezcEs6!RbFҎ7z>jdgZkJ˧,%Ēa#l*DjiއaԖa 8?] :5uu_bە `x8Wcje0Og8&A,Boe sT{bJL>^i@Hu> cʵy<P*Ђ[7o3W@ Wf2/hFTv6pݰno2x+Wߒ{*ssK6,P1VbN7( Ͻdob(j`WQHaeժ~/**z\Ը)ڙx8Z|8h8R)mI Ǝ8;`[>rlx]_1V2VO̮.J(H*D9V Upezp[ @)%[GJu*J/?{e@Lg"L\x.(d,TfgQ-l9đB[ikAS4@{A \a4j% U0 ;jD9pVn Bj Ms qACuz%o ~^= ʳ3(_s$OfHD?*J [  ϧqg;g}e=9<5ADonBȞ3|D ja)sJtS(S.$6+I8 +~&0`OD@i3*%> WSX,)ڿ!$ X6ĹA0i4 (5$ZAΐF8v L3H! \ՅyR3}}Ũ; D ii`\XvB0^``-1.00.OhieJa+N_|Wثg6.\VaH j$BD ŭStZy v"ٴL+S$6<蓒/ME8L 'NJx[_*X,|qH$*U}\8 r#K{h=﯁Eh-*:PÒel4dFS1 @scRV عsd)))9]\<ڥ51 "ti)%bZ \:Ex|կS VCRcHTѯt2>#`3 uUZʡ`mmL5^ @1h97~VHlZӶw01l#qo y$⬁imS?mGNCi1mمsJ'Q7@yaԶ_` ԀV&<Lyh3'@>!կբzy iBhs!YD(DVU(j + D0݋( v~ZSe;; +GfbR`s;qB!0UZ;hW5@6KK:˚sF:7^X#B Ϫzf*gknP!BEDo&UDpnN,Vx,TȮCcLqD7uT7?GF}<;_`H@Rh.Z|E&aʫ(J $r8+-$ZB>C.<E& 8\[{9ЃPGJ(W(a+~aBQߣ6-GaZŎ5DQN-K ,.^Z@[xŚI),cHpߥXՍ,cK%ī7Q"|RErky0˰Oc*z0**T̍(m8J:.x$.H< !9I5bzmmgP7TSq[9i/Di±EүVY`PD~ҁF($18EZܼ6y3`o4#"23ƭⷈ^ U0d/$)(-N,r韽0) YJ{sq\V]h RT/ukOZ'O[޵Gc->VVo}+Mt&[1G,^|[_^/u=URtGE9|2wҸ h6E*n%0$QJ SgI4g^CcvI5'N_!fWo~?Fk5%Э]=>*-4ZǬ C:B@%13>$ED YMOa͛ow!џd:1?E)V~>]xa T+v jc/PvvȐLT6 tȊ>r]իWsÏr@Bp>DvB4D4oԛ+W~xw-=7Gz.(9P.HcH;?ߚSʫjyR 1pxlnݕ>HܘYCǂz2w5: %!Z^~>칥3SOgf[`n1`677m|{q&fD؀e& '*,xh3qQ bvvfFpVyJիVk.]~m>Wy Kq8N(S(0 cjIE 1 2坻]Jw01/]y)6d LϨ1.0ؒ,n dLu"crO1i0gbOMmH[xRlHK?JlGMdpn\Lex.L0&3%q92QE p cpq=SǙ#g6Df0f?1fǙc̾ +7ЊY qO E a 8~mcb'Ma -b?1#6CS~BPZV)4IENDB`mudlet-2.1/src/icons/red-bomb.png0000755000175000017500000002057611513237311016267 0ustar csmallcsmallPNG  IHDR>asRGB7MS tiCCPiccxgPi CN% 9' Ef00!+HR\pu (DA,ʺ܌~>ݗStxWN$`C<WfHh1@dzA_n @=?IrpND.8N2GXrVz; \Cw~ wp98RW&rW2; l_ܯ3F&iviXGe'sG7zcu@͂wzRvn:{עU Sv/[ %\Ѐ(d"PZ@s`3> @2, vPJAP @#hm ep w(x ` X  !$)A.d P(P 톊2_se4 =&9o#$+̂aO8©p6+ _o0~ /"!" DCX#⃄!1َ"H҆ =#P D顬Pn@ڎ*FUN:Q{I G-t,: ]@7;Wѣi; hb1nPL&S9i\ c0X,V`#l"v;}#p8\UZp n/W[}V| ߃/$kB!PIh#\%LDяOI$&^'N?$#)AG:ADzHzC&5v0r:y|^&/.!V#)6"S))ٔ Yʼ8^\CQGKcVSZ]3[UsBeՠu_N>}W1Չөѹ ^^eaոI^/SUoR寧ߥ@ `CS$FFT#<u5WWޱ{k]h#&Liަ{LL?#kYt/um`K3t3YY%ZXͮ\q͔uu5߆iasԆoli`NՎcd7cm`ϡaq%'թiș\E%֥e5m۸;۽}cG'sg3//W7}{bZ.s牯oo~?_Fh6kY.!$qV`F`_%(<9h)),b-Vlh|hw6,()lqM 6hnزFٍI/llt6)'!r1=6j>~ɱs梭ˢgbcbfccU;WǿNpKKXJI<ԞKH>ǥr7oY,/,{p&u2+*ԪJ>UU8Դ]:9ּңG&/ONx[!I81%89-@ZSW9pߑs^=Mb1"C@i7o;j{>W;ks`5xoYttox).(4pS9p96yډKk94pN!zC\| σq('Ͼhg'o$مZ]F聚Pl̂z^ԫwqQ wy@#cHS0gUf%I N?LõwH?o0*M=zȁP?5%)crn4 ~!|- chD{/ 6y8&9m{'BTa.OLupJLavhh~L$P 1_z1柼 VJ_b5N ;84HG}gduL)kn$psk; ƣe:A4pA*lb1]6Bgoq?1_ێy gD;>do'ac:{w/65%ڀn ~Yу Y@=;͋EǻV[jhm V%nh_hHب] 21)xd74PQ^hnV[i3[wR8[,pQL6 04lDcM>?ً?.Pc؞µ ߅6~_h, 5 4-8ӜDo]Ap81Ф0'rak%9v&oΛPrT^ -¶/MԴ1פ'AF=`o-"Ӡ wSM-8;AoE⋢2D 2;<4u?f7a9g J(__>3'ݵS%ac3d`"\OP*/vR9v`~+~-'JgKo3&n*sr4}:[؉!P D4I)_o\;1?9T1p};[uO #xkWx|}knԛ1h²Ld>G}UOe>A#"ZgKGNJyGiC Œ.Da~Or{QWwLJێm=C^76 r\X^qZxzaDǑ}a5E6_/|O nkGcBol;!:A-ɗ2HL@D~*at/Âq_DZʱ F2 7g"hX DLYx) 0C;sXMz$`\Ыb:Ttw 禍{;uONs^m0lz`.T9'PEtl厔Ɇq$ \=؅HTR\7^ۄ5O0,C^v ^Oៗ~/s6`A<'&MNO8?_~9MĻL1xH(L!DPo [}z\_Y b j@Or 6cQ0}ZW2~:aFv~_=(ъg.u Vs0&Kv,Cy;$|LSK)"i455sk.űQ⎞8dzy б赸 ͣ / FRa޾ܓ`ngo[pJ[Rz^GOH-%kНl'/y꧱eכ`m!ܵ 0?7\? ClO YbGȿEXYOF w.dW9؈ S7l$JVXfObX[yAc~K$qr/4IH7ītFJ mn<6d`bET^Zk֚@VuL^ʷ-Fb )Qnx(z !Wzo]IJ@O"N ?4mƴhÜq.[} B`FH)}WFcϧ-T,pŋ/y}3< zVzA;GbT1".Xb|6r~#'䍝Y5ӗܕ!5­l}r޷ $Blf◫"!i76]|Z%Vӓk#dX~,xќx2\9;ՙPSQy?t{ۖد/)5}_3[Di1 B=xMFJ*e@א1QӤdC<3s/O#~ L66k+:|sW_g|BkF9O0y ֽU]?mb /`jkoOwg$a)˸xs4T֌G=Pэ/jHΟ[do._e$c:ZP;w[D5arYDhjnAQQlFsCâ$Pbo'4=J+͘ m*yƆoG ҕr{㕼ֹk`cz[>(S)sgV`5Vq@,7cҀ}0q 1q|N'u:ԐWowU MOC 3V`l-ui@i3p[,{O2Ok(]b`'jȈ{)|ӶTEp`_܅J8=hnLæ?dZGpxxLRuA'KX=M'$"YŕHMj@vDbnִ$QEP< C RO03GaIC,'P(@BI !v1*/#7ݥE A`ZW& Ut56C*ϧcgW0/E81>}-(Д;׽ `wˊr9-%Ѯ֚ZdO@: SEKVw斁0D]_Xp`y ?=ߖwww8>Ϧ}$5Yb?m'/Yfv`$"BOvG-ÄqOuZiݺb8FF A}TWHda`$O1u0?E?l=jyJjI$-J0'=`_l\e/|[ TǍ ̲Bk&ZrK)_43x%ZT-BX$d 2ѲI˵l /CӯoLe~WV PZ#&Dd?EĻ25?:D.% >FcLk!a@+oڷO,l9`8_v!p!f@ݮ=3+01'Kp^Ue}P9`QuG:,GwA:. Pgepd9+V}>5M=@oe+~a 1x>Hf>v--/cMj7yٷ}ۛ1^ǻ|7r)f|y_]߹"%0QT ngօ[p"@yx/_훷JP +ƼOMؼw $JU RH&@u̼?Q,]9J m)J-n6 JAh}{ /;{jK!WA(A_ Ã#դU X\jm0ڶ ]A%XXQ$-ٌE"LV'U'a P7d [ԇ+֢(5Zuc8 K6ބ^㐐dE $ ZdCZR)ԃ{0ʻ뺙- ݚFb#Jp A!Flo=B:AIjS`j`N( c^ʵ2$Msœumtw )F:)vwuUY 7Fn{A(AF7pwȞ];ۺmȔ ش5eu0:f7F6`$?$ٞeȼ,d"<'cx0L,񱢻S#ko,N4LxoFq==MC Kī?ż=%2*,:Tq1x` O]`byϊFJU"e^*gaYeD sT+\ L'qt ~7' $M-@NHw@Op0=>W^a ˎBb?R%bC5\];W?̫5AsAM֮Q1+6AP٤34$8]sľ ?O>::b*B5IoyUT.usjNkő>^ZDsG 32nt ȼa*X]4#C?ONu AF2ϣV}2!cTTUWaHfKzy` #>ӛbӽ>G؀:蠹1 b0-SJ߉"b}dwLj@ Pt8id -K0jrrqhH @! 0ҵae}8#|rs4F8J(4 gXza9m} zepUv7 Pqpqed|E{5T~O , " iJ`@(|ט0LK̆s#p'=<ʈ#Hi} sB 1|(|YdJȨLlQƯa|")_/EK +ČоP:T?lBvwl>8^27`LVWxjد ok#?~oRA YwFsiu/Eg Lç2ɂYk3H.P2}t2jEY=5sR3>:qT"BvZ4~Vj~n?nIm'?M>UZ7wxIENDB`mudlet-2.1/src/icons/folder-red-locked.png0000755000175000017500000000755211513237311020061 0ustar csmallcsmallPNG  IHDR szzsRGB7MS uiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}y>?UoU x"')6 sg2H1:d;O ^/n@+{,"7 9rcIܕ||3Ӓ(d:_xB^o1x?!#|eS+̉' %W\ f/-ϋHRWxdz\bntyFoĨm+a(E駜t~Ʒ Ht *K` ; l d BP*P @hg@'8.k Fc S%AX H Rt # YCN'@P ăҡh7TBUP.C7!!4BCa&tXրa6l{8Nr )MLOM+CZClXOQQ6R(唳;9qxvjsc 4 C o$"f3T,UDRǨW4Jsqhi ):΢yIdj `1Ō3QG));(RRRrҶQm#e2N2 2e:eȢde}e3e^Yq =/((*($+T*\QSd(*+)(*єʔ.*`J2혉 fs^Y^U9]NyPyIҦDVV-SUWSRRQkQ{WgǪRW_`iiԘaIXYָ&YF3E^FuX6m]}G1Չ93 |oU1]nnCS/WS~~~/&  ݆iq&v^cu:QGLL|653囶Κ՘lv9|yig,ԵLlYZaͤUUin}Z`laSoVՖkh;meow=߾~a%GűqЉTY9ƹy%+u똛ǭm}{cG3OmOguk|ZNo}'7_os?Cuu5{o_8@3 =7T$|+D6$.+iSa&aaXlQvc ("6 G7Xt8pq^rme(Ҩh16sqqUq]kN$,'%%“^f[6%$' R,R=PԮ4(Xɾ&f%eTة?;ժZh+< N~K/g|('Oʟ?]6„uOr&_ǧJM3F3ggXbe˥?%y׿lzw7']Yx.b{'?? 8 /_ƗE. r \@"D. r \@" |w#,de966@#J?d?'DzTXtauthorxH!s)IDATXWoTU|A)HL1Q0!t%]Hĝ wn ٸ$Ƹ ,Rb`A"V0m޼o>ҙLMp7RxC%8cY,^Q~`MB\Rre1@Bcvް, aJgRseb=25…gRȆI~X|~I7 h+|P_^xd_7D_4 8t}7_*-HR^~MvFT,a L[!Ɨ%%YU,BZG0oB~i "'@P)W !24&\gΠq|V7miTnĵk0O*!,`Әa&@:F1!WdOHa e[\mY]boVVPQl[J"0rSo=y)`+vǸάg}l(}e eׅqז*|Iy=zN{Brg54aC^YqQGR7i=M5 H;=#)28 2lky Q> BIi#:"|}Ɵa:i8x3,A«_1U b[JLy(a /ؿ6P;싋(%Z@p9@lM:@-INF$Ll N”BqsǛ׋\Dn[NAZ;gh5Es 6c{v456]z^Z=0,]ޤgJ,=ˎe8?[zM~^J8>_Y틶CA@@i+x=]"yl Υ&Mo ZQVYWȟ[DfU4Wgҙ7nm QnLlE='yJc-p~h :AgY)-YQA AhW?Sд[ ʂO>\zBlvih('w?ܯ,Wn<3- k3|DVQ~A^7riw^O&甈RK 9$?JJbq~6pvT@'F0LůL Թ;r;X 4AجvH (I) 2W5 rTW;Sȸe̚߆V`Q￈}?[Sy)bAr+V>(<{Hm-&^s j8hjDCO:'_m3[ͮb0 VehߢVo={=i[X/UD\E&)Uri ./1GOo;>&~wIżslELJ#]R"28Cko%x_O-$l(/X]U(!PLHFm/:%t;.r6Y̖;3 R+N0)Gqαc|(ynN,N3P'%D^WԿNĢ `|r+X<8vN^ !zatS99Ëndٳ!QJEl)FCG[}ks6Ԉ&qs)`uNWUg!rϥs'Y]r f2: |-}hO/#+<9fk5BTg0 %r s-hyha.h+"*͔@*7X_΂.S1Y԰NxI}81_HEƯLS%nvBBNCt=DL jJ  h1Ȓ 譏b]AU+ВRX+ɳaV NH&fj|&*#[Ly tmNԜfxlWojQ/xpWfm$R=i@H2a<0 ʻ1d:z7w%D˅+ΞEj1%2w݅jG-Į-Ո#ݑPLZ:ڕ*D#Qmu֑(Q]kȬt{=-H iO`dIENDB`mudlet-2.1/src/icons/folder-yellow.png0000755000175000017500000000435611513237311017362 0ustar csmallcsmallPNG  IHDR>asBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<kIDATxogǟ癝]vH]ʦ "R "z@4*27n\@HC n!JG :i{yyޝq$ʟ;3~3;N|wi@4* J0V{4n5/#o.T1Kי 3 ˳Kpq)_V_]&'1DoZ,N#0ǟ[ skwMPMF0Wxi pIaa`"Ykc `Cp^Cp@ .rW7k@?"Km13Os!8 d7s_\i޹hn?q¯ 'N`83K$_=75OV NOx,1} \Q(h2d@(]zuz{1gG{ATώ.[ߣzZ[<;PsW޿Ҭ~u^X gf/)X|ij$/㝛?\g_Y3V y"p/qoY PX| KT֯Sߠ`tlio.Ϡxx,^S0ed zUcuV:#NmP!GX ONXv)6Mf+(x,^=/"4 (^`@< ȋx90 /qPKa@iI)F u.)`vKT An""TC5%@! `:! [)  g l"hx)65Ы@~֑.48e*`cLi><9g m@<e|$pL? Xl}(;@@胡7f=6e]^ B"s@Lug!1w ^l3zBnz(כsg6:!Lc CgD yo @n 6' ai|@&I0Bxj{gȢs@H-e]SwFĮ< ;ZqH E  Joq]ɭ`HPO? à!N޿.`x`P@l'"}~+ `pL?xmĐ@q,K v摁QBd@q/ Jh/&d8@gH @ڔSvlr`Io :Rjm@P"d&4Mhۼ11ӟ^NC'TΐY. ä>]` D:)WtA'=M|TGL!(Αܸ!  lr(&  Y+nݸ`X9İw#q,4Pl#D#^Y;p@Xdž(6AD%V&x&Ym +C5;E Bx16)֑u Gn18Hq a0q~?kC~w>51^آ8x)Q‹YdrV_diXqP0˔x'_[ 0c`HŗycW_\e~8UN</SDvm>dM3-62W]]}ӆ 7@25gLi`犥L$aprn;eSd̿;vOc./e+^Y>P<-[u &n7TdwܲT&[ֳ;lȍ&h35fY5rY=&5zn=YOA̮bݱ@qvҩYֻ5>6_D"xHqx+H iT@PiTҁàS @@@IVCTIENDB`mudlet-2.1/src/icons/tag_checkbox_checked.png0000755000175000017500000000110611513237311020653 0ustar csmallcsmallPNG  IHDRabKGD pHYs  tIME 0nGtEXtCommentCreated with The GIMPd%nIDATxڥK[Q?/ݛ5Q" Y,T"?`6l()8e$t.Cҩ&h VI(B}h[m=N)%.s)=_)<^q| 4JEԑQđJWpsm#e=` 4Zihp.WhO:${֭&T4 .jlQ:(8 NϲiË8sd>g8qFq'}$" vCd,{=3mVZ+ħk""VUoB #B Y._·G#ɗI=ztuhe GX_BUdgNm391WK-/p]G)0 ca\"fir0|~U}_ @IENDB`mudlet-2.1/src/icons/folder-orange.png0000755000175000017500000000122411513237311017311 0ustar csmallcsmallPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx?kQϹd]# YXh"baiDZ2(bcag>!h{םFS<8?cDpǫ GJmx|~pa-`Ԫ5XHhݿxg0|ʩ-o<猪o-Az9n>~(YZ@=MVEQFk ߞ~#u  ཥNFj+#'6f @ Eѥ >dF("S ѨU$ vԢ/D EpS`"u }VBB3udN3(]p- BNi@bh/D(6* 3iJw6*R ș() zyx.$ U`h#dRVڏsÀvDx*$D[`kwIE=i51i 0PݣAsٽEt׮Ar 35ro37/ǏxzIENDB`mudlet-2.1/src/icons/document-save-all.png0000755000175000017500000000250711513237311020112 0ustar csmallcsmallPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵWKoEykvWvc5@.nHȅ#p'p!-qF 89!oV~]kqoL撤r?fީYA>m7ކW(z!s܆4'??Z0vq~}]z I/C^Eg p t0LJ1y^|ڱ ~& ] `eeFiր,Sh۵-Y<eeo<A6嗀[/%47Jhhǀ6\6Co*Zg93ՕչdQ@lz_NS/$ѺC۵bx3NDr0%1`*9h1mMS`gYz )9d _…cз8\6x%%!oؓL&鴦Ow-J@ =Qa}UY_+װ@V"{@l>}(hIa/'%9Pvnu(nF/֜WJYlpc9v+o.9:NJ+0^~vvv|5UOӛ&buzzJ%@Ղ۷>kvyy n.U1eVt}$f=|)VBW-F0L, E _ Oo$}:Xs=|fj )iC{b{2`i?Po!R~ߧNkH0 /.5$s$zD]N  JQ!BRu22(N^@RKG߲0zĥ!87;>=>J׎% ) !pզ -X)zx` VU@ű7iDݝ? ip,Tn+~'kϯV>Bj~fM}uxz3i5&4>GQXÀ1޵B6F))gt&8z8\; ]c:(-NS\82m=r,^gq!~Y&y)g+WtKC79NШ)ʅN9Dxi*Qb+6@%dpl/lg3 R/K S~;?[x^vN0Ɠ_6KPE.ZsH̞<7Nݛ3'gMr]0/HC5b=?fnO&sݻvkO E"ǯ3arӿY6FNTɣL323(C[=; D֌ol'G.+ƿ~!/[-:&)d+%D[InbϿġl] 0/լ5t&IP%4xMZ"j0K14tXg(x@ZA2HBZ?eVrE nEq|rat&W#nITP?M +JjPPahY%!m-f_rj˓ɇyBnǕrPۻ.{C[!@+AD(4hiBB4Ѐ4 %WŒMzT*a6GZcu x pv9B*I` LQ .p-&. ̄38:\||FDQXUPl3dy: 'B36E랾5_#P?/"(B"t FM*(K1Mbզ 228u:4Y `x>w4Dۉ"ըD#sS؍pI\ՠDY"DQSs L 좬!8T1(U+\C|iSHZ8tF Sq1ᬗdk(iApQqFMZKQd~C?>l* *|{xp1 @ BL!m2lK@ke*\:@G2e0#@SqO^yMkO"puo3e#fS]%]On`r% ^ez_m:u7lk|=TsV~e_uyU2+Cr7ewEMHWbXhm?>(YhWݨk)KsدE.s J@PYM#4@$&G\MAbmjck{M֓fq!+ԧζu2Y5gWZSŅyaM"Y&_&E!0ز};:TzZ !A.;u;< ;62r r\* lqQUv}7~탎>?yt`GkknK*K~p_g{{U8}(t3 :??}ᗇ&'gÇ_= fD7bFAWbi#{ !<.lE& \jj'B(,N@4NđH J(Qcq2Cd\?R^bHIENDB`mudlet-2.1/src/icons/batmud_mud.png0000755000175000017500000001734711513237311016723 0ustar csmallcsmallPNG  IHDRx8fqsRGB pHYs  tIME,DtEXtCommentCreated with GIMPWTIDAThMzipyۿ  p%JŎeɖۊ?#d4m=i8f2v4qgԭvn/)$@A ۻn;39<14ƘRB2BPcs ) Rܽ>V,}j,YYȌkriRmOi@eZ!D  #l΍B0YD eYF,!Sy^EKx=_d1"B88VZL cla,DZm?2,@4(x0 0f4ƞuI ly\q(HX&(1JCd ?CuL!ZkcLAc0ƔR)8"!$G !,Jֹ\qcL>(M9!!T*vV-h1&mYw\uoBB ж`#Z~HǶIEJ<6R r8 ֦Zd\*X>b$#ײn{41<-x -bT((i i6ry7޵4I,A:0)%Z[RJ!1F# 1BH{|F",\5p 0B@miL9DnW8OעAR)m^+&`XaɅcwܸR_(VmI(BXcrgd%t˳Pg^m{W|׾r/^xJ.a$;G>3O~\$NĔ^x [VBbifffff__oۥruwwKKK7o,! B\dB 9)"%4B3|kC!#,2h0J)J)PZ F,3Ri2nW<RdFQDQJڌ*%]My X8~|_8cA1b[ooT#|h -Jx*'^8mۂ L;Xy-\Q7g?t.זn?;jm90y#ž4|S rx'?驩)BH\ʸ+tB7;};oG{֠N~c{skE S+m~+v*vDsvv=x`z|-7\ cǎ=o}♏DAtʕGl?z7o\zuaǟ؇xg;$եʪ:v<};」I)1#ʈM) D R0O nAc  #JRjFG RqITr]S׏=qVm7Wdo߹}镕7|3O?SXϯ1U)-+rc`>sT$)W=F h4W.Bfk:"-~hjj\ s՗wO,7^\Zao3a믽1sy՛"/7~a%„B1!C!J6F+@HhPCYj"iLXU(1cX4J9߿꺮ٍ\T4vv0umʏ~g_cvN:eBJKoq~aeuhwb޿O>)F" (TY4M$(0 G`8 @ 6#JinF\lWʥkW޸z-/4M#Dw8ڄa880_ǔk7o=:σ~?YougkRLTOW7O^7I> \jF333%WoWK_R._F!SO^_8N^^x93L6YNŷo޺ RRh4CPS':PJVtJ۶pff&JyFZkdPHeLHk5@C  0( )ݽw`jtqs[y샏?ȍofsmQR)ev^_[0bL]p b\?5y 1M3 1"_9xyRVjՃ3^>7 ?GVMپf߯jn ;x7 W$L&&4a=W~ϖn|8J &i쮮fY-;)s,I1 cI$Bh  %RhTj c ?0 aZ JA\DzM( Fh6Juaaayi)KY|ZRvR£@˸!_gN~kLj)s\TDz+*/߇Z}g>OV$ <839Thsss8MGal;QITeq `4U&C RBBRJDRl21{">a0 s9bѠߕi"Efda=YF#ǀLr۶] 3BikkKH֝w=?V-ZSN F~cY'O?_ON5HҺ\.}G_~{yyy<: y}ߟFPhl۞_X(kF?ϝ{!$I,BιQʥ+n(1aV[mHk#ERPj{o|sĭjr`h?h4\~饗VVe;r@ 1E  xGݸ2?!IJ,@ũH4R "DRJ !D)EFr!cٌmT4MhvvVuZӸB¨f\dVP\9z3g|ߧ6Z񵯭ݺuFVWZ,;~o4?4V]Vo,ݺ|BX,Z6Hggy}mCJz3_2+JQYϾ;+3|̩g>k?~}vobUQ,J RJ`0t}jr~+>|>wke޽N1 ._8X,H(j]x1Ms}鏭ިO^zW^ٺ{ӮPRIx 1X1R$s)RHy5ԢH(RcL/Ch֔b/j>Vx2^Kdeeeeee0LLLrV69,;F?mo`/T]Z[.88 Rzn,b58nXI;h4Y\7{2r9IycthR10f\m|sh߸v=x= nk ݻGT*kZC߲zmܶ_|1IQ׹ykٲ‰Ee]+cmeYaQB! ز,uכha}S696l[ێ)-yV+ D(n  4,T (bK0(sJE(I92ZjL0vr,$ "d6pnnљ3kB0N,˱ |P,Wo#*(buMTXn6B(N|Μ؈4W(FaRcFeY ZqJ+0&BR v) pPF@DQ1 C bb" rH8SA؎&p26BIGQ>_L.,KQc渾D")dSLqۧ& QADRʜWUj9 *9`H{@\>ƔP:>>ycWVV >꣏> ~;z;Iv{I\ׁz9;<5ԁi" cbaF-"E@QZk"pڐ ׮]B yZ*%d${{'Oܼq>A B/ }H^ϕEj Z9 bf$.ƽTJiCڎ16 ׶L u2.˄fCNylԊcDQ B!"HSU,0"f;r>/WcǏ/=> FgvO>}^csc}|jGnZgϞ}ݷ_oqFkMPGqx߹ڽvG(M 0bc! Bh"U -˦m('n4% Du!ҽ\*Jihc #llv Qww؎kYvQF\Uj͹qTS 1BuHB1-j3v0 00AҒQB(#1fV'iy~ծMݡ[խ{NF'OFKʖo.mڼi69znV}(s_imҔYXIX(\/>`ssBIr|- B^)eloݍ%Zaׅ@'Ib3 ȲL@!ǡ>xBNl/P!e\HA%16cVhe@kE4BH`!@`44@!EHFh8{n{ 1~݋B)Ru.]h4vvvR^}v0tݽgss3 CuӒZdJBc,dzc{0l?W &!2c4Da #1JDږnM!I"(Ld`4\c)54[1q΅Z02%)K4e hiZ) @`1ZBh2 4C=FC`Bc`D 4L f[] No@f@ mq~N|ډ'V,zBu\jA0t:j\FEsH(1#@1PP#)%ƀRGp4qIENDB`mudlet-2.1/src/icons/folder-yellow-locked.png0000755000175000017500000000741111513237311020614 0ustar csmallcsmallPNG  IHDR szzsRGB7MS tiCCPiccxgPi$J@rN$ ̐a!)`BW`" dQ tYuqQQU}/W7χTHb'$sy!aHvZp/z7 ޿?IrpND.8N2GO9+=EN(!G}$!~_; )+ 9+SO K@[_[߯%% xnz4 O҄<*#>)]/?G8/9߳͂wzR=S? e7߳t Z0@2@-'Is`3> @2, vPJAP @#hm ep w(x ` X  !$)A.d P(P 톊2_se4 =&9o#$+̂aO8©p6+ _o0~ /"!" DCX#⃄!1َ"H҆ =#P CYP(6*UFDuQP4-E[!Xt]nBwGw ab1nPL&S9i\ c0X,V`#l"v;}#p8\UZp n/[}V| ߃/$L5!@E$&oD*тG'$VO'HTɑN # ]"=$!ɚd;r9LB~J~/Fs{ES4(lJ,e^/)()]FMHG"YXE,Kդ:S9|1 ilnZ#*m3zg}A*i"$EF$04$F cQJA^*ZjTԈԒtttGegD2]2OdQ:~YGdrrg:9\R(+2{hJ6JJJ^(K*+')W*+/ȫdԫ ,2UUTUXj1jj}j J4,8CKL`=]Li;3ʜ"kjj5hhkՁuLutjtºfuWWYjX5Gҳk՛g{w2P73o0`0ɰ(Ϩoccq.w^D$S>ff<69suZq*f]@[8X8o2_VzVV-Vkk4V(D۪F6>S5k'؟`spXrtx qru*tr::W;?uQuuiuYp5uqvt6vov_0I\YKNj {{xXyMW?`mݦu-8<  5-;C B Æ5-w^ptixA-nlݘ&ʦMg#-"}""ܣj؎C;N9g.:,z&:,f6:@\m\E|c|uD+IIɸs\*7ۿYq)))Tԃ +(--[u:}<Uݕ;~[vh{j;wLtyraWyyeyowWߙ?b=V{~D{~),2,(T.O?7TbVrS-odDYvon:x¤P!~WewzUiէZڽK9GiS+x4z͆ccǞ75gonm*j|{dyss|KI+ܚ:w*ݟ~nkog3N%◱3gβζkmڹ>qǪ7NW9_sABI/7wbK)/^Jȕ~CW=^rʀ߰q&f-[Mow u1}nۑ]~~h D'O6{;ߌairٺgS/HtsYs.sw_12|־z_v .,L^̛oM-.>}nyX>YTYs/+++"D. r \@"D. r \"\mЌpjZ/r2{zTXtauthorxH!s)"IDATXXME^L. , J"1HLKPOH)@LV!Q3ghl Vl%W;F+@I'W; ,6g^.uP_rXE.>uҁ~ԉVpySeE-|vFI=|-B 'Σ݆T =},`iEOvV2({KQ)Ø^ZiDSbt:}&ڦrn7TVG*e1ow)7 P'p<i/(R>e(@![ IJ,??0@u3ҷ&t)AH#PH+טiIaT‹Z.\Uԗ\jtNrC5ެ(9-P,JJ՟1Gz l CBةS>`jA[~rQ*#5[Ύi>乗*MZKе,q`@q ỳcJ1Ӿ59> Wnv ءE+j, %"1Pc4oI R uk0}buJs5K:@$I1myQ^ YJlnR@ ٽu#߷kՊ3H@ܤ~lf$qHJ{~FV `NdM]UMc>U^~q?92WHϴniNvʟn׆wx23U*[G?Vgc̦EYOeUxojf :ZJE$)l_J ;j<{A?]:&`TdbKݛHś$Y@xӷ{%bǷsxCa/p5 ] L﮴s6!&UDIENDB`mudlet-2.1/src/icons/dialog-warning.png0000755000175000017500000000441011513237311017467 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org<IDATx\U?9ٙٝm}ۥ-m [Զ`BJxA#S$ M+E~11|ƈb(J[s3{޴ Os~9ϝ͈sPG|8/!³ښvB8wxhFF۬1saQp^bW=#}ߛU 17rf LNo-}ۚ1b#iY s1vN-ӓEV~R&K8)7QۀD3cgՍ7u^b"p춱Fnת>&eD.Q[N7B ƨ" 9siE&1I7r/ش<&*rzoa\.8}LtHoR˶,Lkb y^oN`hFYyĆW&}$}2@>N 8 iJ$U$:Hˮ`Ƚ8^jޜnQqYB$^v.x*H>qyW{D1Xr2GOˁo3޷AQ*CzMꌂ^%i`'_7Oɲ5ۈ@-uqm , 0;7s\8_1?g+hah /r2E.;*Vg&$޵uCn?`M.R0b75N4t`zpjk0=0cyկL`e^2ϋT7cBv- 0^gp+ wU+/+Df[EerքV BKROA8)GwfSʔbwiKuݿWYe=$5;K+4HhB;H9pȩv"c( 0G| -C؋TXxvTSi+*Cd^y~zvؕoxCA`2-D85UIDd=9QqmNLi^RrhRj:7XKIaݮSRt燇$ --GƔY[}yVZ][s"0`Me붵`cUY{[_'(@ӴҸ@?XsnTVx$&>rq?=^VNnPQq66V00JMHgNOn88W~~} 8̯EGfIIg)(> $?mlnrDEd}yᎎYWpQQQ6 IDATxė{FEx*Q =y&Jb_!RԨpwS7sww@k]淳;;ƾE}E @h ^5WAyP]G+DXJhr\FP[E˕gr"M/ν:,İ;>.4}Bi[ёo_hRYQ@'6)(\Q&e.EC֜DkEٮjk|1r['6>Pno/Z~0̓F1TJYLbRPNr00aHp#LPm:pjJݩ- G*1VR){)%l꾓Vn/W 4FIUgz<V|ZBj VqX bV󚖷AD5kqvuj`\h>}? 0`9Y,bgs-PEQd(( s2@;5.NC5/%w"Vy2/kRE-oëGS-q NQsdu6m' uLhS2^&$UwR^.j^F`޲=;Tr2d%) l\R~uuuqë,GEꋭur8{p滋E 6/iSm8sy*O B3=u[)XT4m^m>Ӟ|HTTҥUbRZpx=N9"HpIZ׋'q0i}tm!s4ʽ?2U /B41@@ iErVa# N%αZyjUFHҍr@=d,H݀@F:NqopSYu$Iv*Z3kYul]nKtA|z4EXE$dgLe˺! (Ʋ'ɐzTu%gO$$xB(\,# }g6cɯj?in[3uC p t(|3='yܗvm4}~lr'YX['>L!l"NLfK٫b3L$g acnءcdFdMѠF;UjCŜ ӌ'fҖv'S3|xkL0qi2#}<5r[Ex2NAoڶ3&mL]=i4l`l{c `ٴ`Ծ$cA} *[PE_v'!uB7a,0`y$.b"Afdf-{f4 `H%#1c`8xz> dS-vfHdn K(!%ㆌsoOۤz=d1Ì}8#9 [+)}xNt%q!!$* O4wjt94|#ۗDuMm'0XM ToPWiPSboOCdR2)A|P1btC'̖BgM|EE#6SS,vǺy pRs{dP͓wYߓ/ˠ~ >)n|<+T+X9:i˘8vM2!fw´0o=d d}`o6Cb/GB*DwODsu/;^NTY8Ro"2Lc0{ r|o! x25 摽NÔu͜՚Xo:#4r/k nvey.,1x? 77ȭB݀1`FhPGj >N| a  `]o6cdX_+41`-f96x. `ktJFH-M2l̠RIENDB`mudlet-2.1/src/icons/3klogo.png0000644000175000017500000002623312070466512015775 0ustar csmallcsmallPNG  IHDR(2"ubKGD pHYs  tIME 4 siTXtCommentCreated with GIMPd.e IDATxwU]v5#f$Hnrc;.' CH!@B¹. BNqbB q${o,Ց׽g׷=G''sϻ߲?kg=ko(y( Lͣp )Gfz5F%k9p Nm:VO$ߥ ۋ"+ ٜ!I໗qÍovY_{&~0CcseJ8& +-fƫ't ;*S̓s? !֪IxMG#:Tg{2K+5L$}9Pz{8.3y}?޽o0mۆ)6ٕP͍s\l1-`F8>9Þ;]v@+qbԽpȮ̓Q_?X8]+[Y)?@y IY1Z# ۼA]&M.erхf΋ gsAHW{:p)MJ4KuN.;pG8]ocMe[gH~pab> /3ylb[⢞l G{Q9@.rɠx_dzTf7zneofdDߔ_;e7qdRd7/!x*/Op1]2Cd"mQLgw(#N?dg:M Os:^bg9{dݺ\d׼NހMjR?. eٔaaThA(9_}"8.&ޒNz;םaA1ڻj2^]F/d/<~YU/y yϧeq6CWjϺYx߁Wj' <<7MU;Pt._̠f9꒑.'*ywQLDlGr_;z>}UW6MBx퐽u/5wd8$l@8(|Gnuygeƿ{ϲo]CWWy?rԓ:&IYd/*w_W\tWǭ* OSb̹3D)O..x^cM4gdvLPXoJqM]|ZN ^m8n~w7 n>]afىd.䟙P-eT-'?7~=whV_#>qSdYG:gx%o0E:!!d6K،ʝģq t|keÆNb\׊\"Ьx[)N t_G>oN>:6ʱJ{$~W/t;xӛyOo(piJ T t© 䒭2 GN~=+2v:I:ܣ䉣qY5cD`Ktg.N,.sd #!Kwpxx^[6!g䇋rf ye\0E.v%OO_o:Uކ7;_ n16 noCϰwe.X͏c#}UPe?2i6;񼬾|j4lai*#G>j螝pnZ:g'i./)"@_p R c"\sSu& ꌬ\jĹ=SRѼ1YBt^3nMWNotɛ7Ho A0H5#/_>ph/yu}n>qCx^M0sN.έGbѾVS~Opv ogj]y5\,G.`rf NPz0IEy; Of+DA|]&edNAaNVG(^Kֹ$zffg-o88{ŭ{u†Rp gSXc53~ׇ%#QY%.\u C 6\8ܕaԒoZԂ%C~p Na&S?ΙҴ~n-j|5E]KI3= 9Ͻ /zLٽi䒫?@we#rYWD?+zjUL<5s?fvdvY=wHu~B- SU&q-MNqɱGeҡyXAnyFXW:m3V{*ũ`iF+bSvD`9-3#<"3|VO}=EKFǶaO_,{]ƺ~ϏXX\j15=K[=4x/<n/+y3H-M/I1BZ+ 4Wi5DQJB#ae϶FVz2IVp5Ul2eV5iш׌-W nBGeqj(!s+3˒ͤ<q-#]J""6M A;s94+n{ݥ'NBE'gǎg&*j#:zL#֍'8jHM1 m[dxCNtDZ5/ j\[$]i͟FK8{F㘒 N>OseUˍPfXMא.QYJo!YBx)!+n_^c^)}ĉSR+M:eB5%Qy@^3'+Z֪=:/OhN]Wl"~F"aYȷ9][vBEDVA6^7mъ9꯾C\(I W)Prb4E27XS V}UחqHb]JZl6 *:mlv4,OJFge(ؽR>whL:G8,̂[nrbuxr+Xq9Q3PM{oܢJF "Ky;993֓+V)/4ADҊUIYEUW2͍*g7ՋdSq}v] '沐ZŘ]TEioGlT{fdPŪV=TDDUm[Yl4em_)qI!ӫ{9W^Rnv>ѿEZtJףuV%tCAZ[hK,`JֵH6e@-ҙ[" " ŪjJ>@GFnZ}X7GPћ?F\]:r2͕eijzܢZָc4Ӕ5m$m%;^=\#&NKOs6kQ_| ,ҨUIŚVZHWVz(?3Ddq/fπzq"Xi6m1c 㜷8-[U5MW+̚ *Dq[-,/rU/Z ~A&OLhеN'(FjK!6  8b\k\OjC\/%(:z0{BL %l N-yrŀ΀jhqDqѮ^_z6ww5>YX9"ӚHTeK_F{ /Eh].Qle!:wT{lLpʧ-HЎN> 7CeF^uUl7KED_?;&8ܬ[:+qj-t#$J1C5g#~O/& K*R!,/3WYYmIq:DBwɖ3܋fUW_5類E 6ѳJzvWOcR CU}] Ydq&q%-Kg.u|3sR:1ã7`!(Y+7k-9I A"m Ήwt-xA2Ҏ4֦Dio?f85O/=Fjc=ulEPZJЯ7|Ln9QL& GAĨ㻒"K'd2;6u}Kvvv1 Gt}2.wiB=QLTQ}gAbS'ёϋ?Q@xrϓ<5U&7֯nZ$MRhjGnJO5ZU'SqfH?V,ǟ=ƫ_w}c{V^t%^*ȷtkFd3O1_av9=-/FyBU 2ey:>Rң /?-lUy8Y,f~4i{U<箿pڷ^3Sgf3{3C#zf)l``}S1Zֱycwy=zh,7gt_q'Jg^brar;_w)}|-9+=ȢbQ qbuAږ&Qī?poxR^,KQJo]ۿ K4lٳBA?ܣD(!&"NpCK:27oӃl-pݳr}| z4pTVP.SeuZj[[K|-: 9Ӌ8%$^-X\eÜ'uߧ{##$ \э4j%JdtW%(d>f! g?׿,GO˧~f|/۶qzm_WB}k^ nZbɖJ$-zn(0&Sк[r⪬%k5/jeS.|uGZpW1yF\h;1Q+ۇLCwzCdp`@_vVׅU I:W?Ȇ>ꍄ3gW4$)lYlDNZ @oVBn):?k3-J5Tjh%VqZAJ&^Ռ4'Ѿ+H*R Ij=cRMAl:9ƾnݸCdfEٸ{] n POD{tf8t랋DUW;+4Gjj*GGKt꒗Ǐ% 7Vh-.v ȱU}j^ܚޖx6FU8"*ΕU+֪"`v)/)u]wp 'Ys5zyx3!l+8qr7׃4bӐu9ZaB%a٘fE(#ZTQ5qH8J'MS"1NPZŦVuHmƆ)8F!i`Ulz2U4R>#yDf|r,}Aj.H1PxhqnOv!fuwRY v?TV[pYNO0$WDע8k08CU2""x~&+b Ao|+kFhϨҬױiF뒑%z3h؈ٰa@s#>Dl+>b @|R 8H4lR] c 8 o͗,hQ} $uh+]_? 2x\(λ4NUqM7PHsC\DZS( Еϐg14f~c7P@iDEl.He擈"cliM`bFah)FT4ƴZVJ iT$%l%41fLY]q|/ή BO$04Vg;uCF<s;9U$ݿ\1ZAUA2!u *V3[;HQ9O2sxB\7N}aIgM]*J\A]!@) Ocuf ;7Y<9 W ȱ*̭ o/d19uZG?C +R] CC;xź7oa:_8JV:a 2'qRrz IDATذsL7J:s]@2&\@C&&)GPB*ibIS%llR-ߡFj<cD#ͺDBG~v 8uh UWT5FMi1G|Q CsyYD+*ƈxU9%i,y~v`H>EEP ii"հ(jzaS8^3n㻮meG5oG&a[dzKĭU O.I٢*ɣe8zAFT̞a-$#$͎ӣuۀI$\TOd|<{NьzVCxu5{,)3\i~Ǟ9Kk[Bz ccG(Lh5cZ5ZY^j0]6B<7 i+d>I&[FKߥk)HXj |$:K#PΜ8KЍ_ti~ nG㺲R׿1QI$m5u!?W,I@@ n%H U%iI}^Ν9^H.i'LV="ANnl)y%zZc8đ4)Q3" cX4F=8JՊ5(8nu689F][;u 65ǀ8km]4MӗcߕQbn8x|4lI) c?Ȃ$3d\ |^s3Fn/%H\0$7:FֽxG& :+s+` F1RY^!Ge 9ZZ!61 я[*UN7M$!-u`UuHܬOWab:WxWйg:$&3Q+&Gg<}$Yx&?IwpG'Q1U4iRjKS(ĩ&Jmrx5ƈ]1mVQ1ƨ1m.#9*(ƴ/bmVS; mkVz$s3SYYY֨H=G$/NPsUM`q)fZ8^ kj/D Y/&vL=!pdI72U':Izt6r9eVfee2k_$,-WSWK\F%I,ϳ!>8ft!?dPxРd[[EWfdM'HnZi|ؤŠ1d 3^A$"6"IR< mӆ`jטe$D`hǠ)8k"?صmCXDcu]㴴9V-X "v ZL9l#Q굄g]8QWyӔr }]  s.FCPP qǀ;j80FM9j=L~@#Pn JĉC3rX7Y^#ٺuP̑FJQNBeSdMٔή~:FtM] ( ]. ݸp# "P)ZiSjRysvm2hi? =gpD?cgWm \čymK@u83_O5>:xj%Њ,G!Mq/p+(F=/<>f˥n1`l\y At;(5:]R24h44QfQ\cl1Nt:P+]ST*9ijY"S)լd+&Hd4 %:@=Xk(%vV"%VR)A[%i NVB`|" S8蒀B s-WЗڊ@ Ly DJ".݁ Uwv*2`ˠ5$tC8tNX HRAD@ 9Tٯ[ P }_S{6[K#n=Xh7%*m) Ş&'29-YjiF<'_ bر}i\`R0̾BZJkteJl[I K*Ђ;m6kr%3.fL J%&vfx6}6&;<旡$̀tohlK.mLo)c>`8\eOOS}ʀ&޷@" 0/` fO9+FBq"dd6v> ==:#~ _~FB$ ًr 5+,Xs'̊nz+s`9΀q4_;l6 h:lZ˶0 :·b?v[=PGn#eX'pk5iҗ!o #5)Tm o,ծD(*;LowPY31jZzfX!~#$ |A댯Q'<*"r Ee) Xo+@9N 0ŊBXff+A75}^u8#e VEd2R8Œ/b9Kcc " SWG,?D@D&[ 8!N "Mg|VNFfN8@/ûGDe"cs/2G.>WKDy C 2 b3{+'lTL]БӾͧL 6_iJitܱ"_DQX b˯dS]r{͝ˮz_m,s څ.j `c!|ꖻ1tŴyg26O@L %HW^]ik#+Sd'0ro/!c|sj_̔}ٰ̆&"P1"E>6?19Laުh^x>}C 2yE~r^^_F\ISGb;ExMpbOf|ۅ, Pg'&7+]ofg/|< $iqd0{70V(J+t\19j$!_BkSQ &ƗeUV#Fz !Pw>77c a,7Ιd2Qӹ :9sʓӲ}bٽ >s휺+?c.cm56yTAd~@hUs62nLK Qql7"ÌسuTg}GYşn~K):f;Ě%EqWC@V('&`i,jA9fLw ^!!r鋘*x(|# Z 3cP@A40hW UU+M%ƴ#j2E!"Ñ9Tcˈ7iЖ7C ĊF. (:Yn$*S&_)! GB{*_r`qD4?? )wnf 5eQģ E`44U͂'cӄZQނ$Gfo_`]7 uuXY:l+98Y SS0Z(Y.W7Ȏw hA fqB`ĉ t?+Wuf ?]ͽ,x u;yܬ sqT)D0Xkfj@-+¤*P(Þ;䆻Xx|ذ?vqMh FՈ<*׍ݔ\%!$ C>g9k* ýOCP.("v /{?" sC ĽM][a$;!^YPkN>GoK.+WM}<dˏPᨎ0.<,}om$1u?E BF֯ǐV|XP '{(=]]̿)/ޱpZ!߹Y.:}yrvJ ϗX|(HHƱFsPIyP;ЊUc&bȓ嬛崋.#Qm6. }{hTHxvp!| ^7]3e3>J}q`a6(Y `p X 4@k3l)~uJƙs0 k~(O(o> d?YMaTG@V~ZIݬcʋm6ܶsMP#Vp,l8wΏW5"Q(큨va+PF<) _!B"+ۂ8(Ǚ&'Z M(wn>9,cMX 2%Ҿ=4rx;зw@VːŤx|P gOQ4rR_%53g(HF7'H ZϑlD` [)GWc ף^k*kxSi!JW:v@,0u19|9q `J6,ɶ*@$ &PV`k=[N@@SgAf U+j P{";WõЗ~"` [ <Y6X_b'}fDuhE(i_e?UoU x"')6 sg2H1Nj'J/z7 =?ύJ9Mȱ$J>™i v2/@!p7N\okb2 G~e}kk3E$jv^b+<2=.1M7?ʼ|7V_bT|6 HL0t|"YSN:?[ZYI:@h]`̀%Nx6I2AA!(A 35p #1)̃w` ,Dh C:Ć!'Bp(AP*J*j~Af0`:k0=`xYpSp|%0eDa#7D#|d;R#H+ҍ#2|@aP4DPT j;U:@&P/h2Z@1Lt>݈nG_E0 ˜a\1!xL6sӆLbX VkF`ӰJ)E0v G)pθP+5zpøi^{b|?_"HX+?!PAh%\%D9їGI &^'N?$m)NG:ADzHzC&5ȶPry|^&'&!V-!6,S()YrYʜ8^\CAM[Mgjt}mno S43YZ&X6[άaZӰfJ*ªJ`ʹ>j-Qyfj˵mӲ;eon`#X8Du przć/Ƿ__:ںM׽/H l \ r * o " m ]X0 [6(1qMMΆÃ›?ExGG,DEDs88/2lUTitUtiLÚXع8 'ےpIIxT^o-u))ST(uCjW]aHL!}"::}f`-[x[joݻu:9x6*ݛ+gbݶ;Tw.®]s rKsݝ3oZc{,1VR-YhPX^St'ß*~ZoشH W2fRҬ^:ʘeeon:xܸP!AgEWZeI姪تj5iU-x4:zccǞ76gojm,l|wBpd_YSS|sq ܒ2{*ݟjmkcO%3gzϲ϶kM;1) :~۲7NW>_}ABq'gbŅKɗ.\J}}W=^|J]V߰q&f-[&Mnv1unКa]vڑрcac3~hqx'O{Tpaqbٺg'9/HTsiγw_12\ּ|_ O^̛o.,<}ni?}^TYs/I"D. r \@"D. r \?TV %]3[zTXtauthorxH!s)IDATXW=lEow}?c; v~R(@D$$HB@i)(MHQtID%!Ͼ۽w%Rd]|{}I^Oo}2CmxԞb~G+S91]'Λ3'^yd dHPpЂnG,f6Mr|F`.F{i9 Fo= k ,XB8EyuM/Ka# 8c` 2ceYRbI?3sA@YMq\q/kҊⴏsJOz|9b@1Íu.zIE%y\8i"JH ^zバ]k-n!vhe#Lwov2V2<&e'h.;:mEǏ ~nZl؛\}?4cJeBa0!h^hby1Yz : yH.`.(~3BqetxE1@س7Ǹ[?Cnsw)HA^r'QH%`"м!ZlSҡOe=(МnOrBtKErd f̘1 (xڛERb&Ea0@s OtU$Xo"T5skKC&e۴inPCq , >c,1ై*5O޼ZԒ7,:esM}TMєe]ݏgGA.>H `+dY U O'PM#J_zG,4-{Ps/c 7PKv4!7f@ihBK7VG+Wa1[<*VYjʹ)e F()rAGk[u>F +*s%{k,J)O)b5B`"탷jEIFq{-U3ߡu1@uc҅+߆r ;FwȀ4Y aƳ]i\ϵM>b텟ٖu3c*G۝.wY罕hU;\^ۿΩWNke+ߝlS״3.ܼ3RMmVoxhg]9(|0lӲ|]NNvTmAKG7\2 W݄q=PI=Җ+"zhFMC?.%OM-,".u]!=ɪiRCҳ)"4"q[[Sc+:V?ppQ˳H%XUtԆXr?1@.=ds6YeWEHĄբUy~IENDB`mudlet-2.1/src/icons/folder-blue-locked.png0000755000175000017500000000765411513237311020241 0ustar csmallcsmallPNG  IHDR szzsRGB7MS tiCCPiccxgPi$J@rN$ ̐a!)`BW`" dQ tYuqQQU}/W7χTHb'$sy!aHvZKxOߟE$s9@8'pNp'#'"`'y pqcί=.GʄBSBfkk oB9F&iv^biG8/9߳͂wzR=S? e7߳t Z0@2@-9vxBFq @@( u46pt2n`<|0 ^,C H2X yAP(B\(ʅvCEPT C/92tB7F`L`Mf'ocT8·p| /÷Q!,AlG iCzG( RF顬Pn@ڎ*FUN:Q{I G-t,: ]@7;Wѣi; 017L(&)ƴc.a1SE,+Zc}tl { {;ƾqJ8c . *p-^nk->x~+߈O &@H "TW 7D"QhA#w+׉$*IH 'eN.ސdM9NGn&_!?%鋹qvՈu){FJ6rr2/w.^#~N|\|Q&a$#,Q,"qCbjRj> uh46m7v6MЙtwz3} I4 "Y#yA@ wFq1( e/-WMjDjIZNN:ZP]zTL~.'(YY?,#WerVrlB3rayyc ) U Wv 劽sJ4%xrJ/%핓+TUT2TUTUyOj,r>u%uo\VGx F!%Mf.Y4ӝleNhlRkcYډڇ::q:5:wta]3xúëЫ,VqW5#eM3_70bhjdh؈jagc1۸jj;Vw~mkmr)tig3s3Yٜyy8e[-,vX`ifny/+=D55kLYZGZ[mm"lmUl#ml٩qfOٿr0t9t8,9Z:ns8:: 9Sĺ,^rCywwWpg7/x{l$y|=xOX]|} QQQ lG!K3m]=cS3k{ v.6"n>1:u[B]ROĕd\rD9.߬yݔ~e') Jې֝N|32~Ș̴ɬ|uv:[nv>aʝf~;=j{;w<+q<üw+̟^=u?~qhU{r oU}*fʟV*1+9R)喎L,lr7QaRQwp(ҫJSu\hCM{|ڥÜ#G쎴)}<Ak}gfC1̱c7765}>=?ټEnh;~N?wշ3ڋN_3}gYg~Q un\wv8co'Ϋ yЛ߻r1⥔Kc/Om{|%~W_sve~uoX8wu٭Aۦ;̆:kqgxp{NwktX؃q΃هI_?|xzO~oƿ049lݳS쩗i:9yŌL9/ֿ~ryO?k_i/B_^]F͉&o}K~T^?,g}~痉 \@"D. r \@"D._ .6Uh@ V^AzTXtauthorxH!s)IDATXWKU=S0dfD%hb]DVЅ qѕ.+4!a1D`UU 3= Trzޫ{޹wZA^+?>׌=3O݈7;Vg <{虰d~hx{@LgG @?ɸ}[|\k@Q,%(TEf!jD"G- եc!,B'7 (Ne՚#T^unк < y!!fYlǁmh5/@ޛPr23H o:@jAAAsbeD”S)"I8wKb![tG=b?bRH2,ϩp8%oPCI{OlJ0؂DWֹ7,",-LT">{c*E0 {l*YTW,!_Ze>ݛk@9961PqXĦ>(;#Z+ .8T70nbMlÛ}Xik5)ISC.i`ˤêHSd.575PJMUe4a@wi]bBS$U Vᬷ'iDZnc(g{PZ^LP|g4(WjI+żo \iZm3-,ZGȓy:XeCPAY=:Ο.J |"{Aft]%#ٞ14e+W.5r92UV?Bᥠ3[]iaǫuKQs]%LJ'GvDO 5&䇞6RSOӹp9h|k}*(28IENDB`mudlet-2.1/src/icons/gw2.png0000644000175000017500000002231311513237311015263 0ustar csmallcsmallPNG  IHDRx}TgAMA abKGD pHYs+tIME  R& IDATh%]ua(|g_̝5d2,@dAXD\uVlӾ>U[VQj $$Ͻ|>i+jrn7!(UJ f4ݪX:_7K;'3~. d'W%`J7u\RQz?yR8_9s1S:q)̌E|j@TS7 CͤԼ&eC# S+] ߱/"3t"530n=jd3F-!l=z}kw:blB(^߾2A̬[tgvճo}S?WA~⇟Y?fL^쟜㩵Cph‡;٢CNUt#?-5/(4+Cv'n:CzT/>^Ӌ4<HI k,-dJі Cz q_EKzFa[hVwugujɍAatI(S$:7:ՙˮ->>yqBл$,WW:qgђ a @a$dSOHyy!3%֯$!ܔ"%.H3i=$fH h.hf*LL(jxQ d$G^<\]#V:z<4Ms]+eJ*[ˎ5,#1bl:vqLiDODbE]W0$ "%? :Fv+ktv7PJdU IvB oIҹl9cV¤?̌d@iqŮ.Kf&!I~#'BK5GI} zgN:cxߝz^J3t:Eѹ5ʴCj5W tӧ/mZwڵ7nlN' H$؂}nqbpՆrMe;(a7npk|h)p[#7Ln u|/ !Ikgwl]ώ}{?/z߾Sj+kv?'u{’ԗyX-FB$h|v ,=s*b:޷zWj|ѯ=|s׫_7>Rv!DbЁ~7#w} N/|/~BW=w'NN+{ϨX9._g?{w/zGn/ZȩTr/YY軼0_c۶A7N9{嵇]1ӟםu^kΟ~PC}^mR))n'BaY"j5 R__Ѳ;]M,#dE\]]Hnr(K>m:#c^~Tݬ7RQFR.--ϟ8V#/_Zu*JؿR[^WV IT/JyƘFQ$HԬQ@dK'NoHOgRcI0T#b1RAĜN1NF[@-JQ$.rY`_1Ţ͞WoW6C۵8m b&l˪&Ja3Ylj(Kqb/"1RRln۶]*േ7N ux@0ً02mJu;\ aH,jbfo* hlٖ4/BjXeB8xkBed)}艻)swUvMkH4syۑW=u!_9OBwTPW/<-4oԱzݻ65K j?sv[[ t4^[Z9|1&7X"h6'=cUsgNtz}v9ҧ췧??.KNhE0TɆqR]j=L .ϝ+˷R"ʍ]k|egW޽< KPX֯?~Ŕ_xߝY3 OJmjz=aP膃;Ngbo~zչ=)l]pmC뮘zM;؃'N-D͕}K!p~53;72NRr>'>'n}?4){}ۇ7?p룕gWNҀ)HN¸oQ؞}#ܽlѤg~ԉB_(bo??&غS Y \{>v>_,X3g_3 w^U=gF.\Și!d"sU{yKf׶^ʗ>GV஺H۱l*%(RF~, 8.#a4 !V0=6lXvٳgO:ۋ6@:4YnԖ@ \w`/G?}@AT:ZBPNr S6(TF7,EEQv Jsg\'=0P)bfhh(J0r$lve, ǂ$ 9^D DC$#E``׶J\K/^X]"5qD,u1P* ʵc  ˕*PB&b^/-P@ `fSbFJTQGAPqn3$2Isu[/+g9 &7]wד+ #oݲis۵m{`d'_)(ߵډ)8XSUٲ_9RѸ8}yiitIHرvL~d `ntU^HOl4>/5G>{O;' 0>^HY\uw#.yB!_J??umwZW,dt߳'&\JłSg7tUl' ߻aFK>sGWGWt?x}eCX~+$ETN/ckG_xdL@4pfK{޵c١B㥣m*wߑ[v/57Rah_wp}c(,lݔJ+۶m , aؕʘ];+Á|wmT8(~R4-/ \_[Cs~(&N{[v={nZ3}o2\g[w:ME7n g%It^6 TdB e Nk}NXtߵ&-G__oPi'/"br/~>k OȊv-qY aH{EI)._x텓r8x_;|ݧ'\.}ǝWW3G?RW_~CHIuï=p˭#+BJ 2 >-0_TS_S[nęf5G/\ݹHl[ג$t_>*]7Ǹh`i__݌rr]pӹI?|]= EѶXUR<ܾ9rNYQ41\PX3u`.8!BB!R$'3S|q ڹu=%Kb$@ IH~qt#~s͹(zr]6 nb׿s/??~ c+ (A/ήzIoͭ-|'?>j.eشrqҙi }-=/JdJrkٌUrq&$zM|˽zAq|ù3S#Cc𺉵ۺhobQZw]ʱ>%z¥Mqӑ;lNj?7E@JUL㑐 "+'6KOKU+J#_LX(L]8<88?z>USht:mi9c!Il6%Y4-, tݴfve&|iiIݷkvnHYcXfq9"mn]ESeYu=;ܰR%QgwvPPjS7y$"nݒDUU0$şCv|YIQ"ʒJKs&0}yW;v슝.L_Jy`EoZ:KbUU] @2IX&fF| ؋hkrRZw* sӆaŶIR wHCFEtqFY:)Mz",Ŕ Hnvz#L`\1&`4S J]eJP0N`q!,veLiVT"@+P4+}FB|YAMIIˊB8<EnSIt:-MCA %* `|@%0cLSdVDB !quE5&1O$D3-©Ga$ʘH*8a™i@R\?eE` Z?VΡnOd² pERt]! 0 ǒU Ki#BY SEDh:L1KQ$L!**$CB)ew(4btQXpV5 S=$ɔEN4eZl3! (!dJ$Y1Sم%MYB $aQa&1匑m[ȏ"Q#$2)Y(#sCQ!9e""p!Et>jp#B QX.4mAQ}?@SJY'$qE> }{iSŢF#D!  s(0,aLbaq aFA,pzŦnd,m֊9Ee芤DT C^/t2|/RdLI! NEE"QCBLQTQ `Ƣ0┉H PYU(",z$D! &q( P0 !G ʹ(0IDEƢcI(^+IENDB`mudlet-2.1/src/icons/media-seek-forward.png0000755000175000017500000000365211513237311020242 0ustar csmallcsmallPNG  IHDR00 1 sBITUF pHYs11(RtEXtSoftwarewww.inkscape.org<)IDATxڝXkoTU]wf:v ƠHD> F g%ƐHbc_`?TcVP1!MHKc$viݮ39cg޳:{}F:,hA^أ~\o4Z;Va fPGG{g 1OOu2^KZ@(ǒ=D I"!`]Qϫ%Е=h5O)!^0.EL M,G]3 F%Oz ȺٲɗQYIRsQkǮ(cc=ξqS%1&}|ز(pm,HB$& $&ck4x/ah0F;qf' a3BNdOd*zc6[k.`+8hABpJ8#*ѹh*5Z5{q?ьYJDGIKf@ ڝN$̨*CZcOK Ow{x $j(Q/OKZO \V%$h<*lCo !?\уKSq>KP`E==Ah]\U lM,,O"r'ƩEDܦwF@Ũ<@>a-ڑD`.9Grc|c>ۉ]'xkh \*K(ވ9>]o1BCF+vy2xS1d#8anJr}AF+ %bW(Wxh?m0a:uw' H5[5F j& #"ї9Ik2iI<46y 7LـRh@8VbF<$Vdռ%ql @"WLi tB\.9 E, SAhd't'Q'쐍Cq=-!NP-f[ Ы0>&)mYPb[ Yew( Fsi8jzz+V"eaL1Ԭn'6xz Z^" xe΂Q2)@'筛?0}L%CճwciEb@.VtTEIH*ԄF¥?E)>DV8cŸ}1z`eOENLrzUkv]g&iw8tAf>}8dGp*~YpȣX,2Iڴ$S/ZŒA%T3W%i<"nqw+>4S"Tn'?N ~!1IV܋H 0u2{G(Ia5[e_f܊9 ܅Ngi9^!PyJo!}6 ! ɠ91V|I"k “{UڬuF~vW _D/CjQeȮ2$qs!D% d -feT1^d'N,&~F+;`(xa`c8Хy#z|}m ;,zP8(•~Z_olnmrRW'/|?ĜYp7' 1i)cptgAjgc?[R-@ 0ǾŶ&5R%hݛ,ۚJ d QUD8RA# IU$97 ; HZy.d|d Ht2YZ(9!kpI+Ը.4c¨E݉|ZA-`4z#$EyvE8:XSAHqYg4Le DJܱu2 Y!!)i#OaPnIJ! 2 [Tfoϝub=sx]ύտË:LIENDB`mudlet-2.1/src/icons/bookmarks.png0000755000175000017500000000531311513237311016560 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< HIDATx՚{W}?3w>_84MQVi *A?ZU+UҊVb)L, NB@8[{_3sίkv]y7Y{8?髙93w93+ʛ oraMfoRfGLekՇG+?7(>G)J5[0cKa?ZqT[mOmoY|q;5hf8`./֜r݆9gG(>dmeGRͩؤᏈJ ^d"/aJ#Vgx aiq]OfփE009Ɠ}q ^imPPľ&lmgҪ8wNGflo1o8/Rֆl)mމm$EPܴ5hW/a}5V u,)˜K dG=}Qo c;o2W%Z5pmD7op&eeWmn$fYd9A'NFqZ5Y{ MSd2C>H֘;/gF;Q0؏yک']Lܟ#W%޽[k{%B2k,oFrZGySY"ea."x,neFFMz :4~ڽeRgm ⑻.uٺ=WPoGL@ $3.ic<x,/E@8j9SM֑M@FJY$z/4?.Ł$- xj#ePD,Hhlu54zB3d>鮽^ocD$ht9x b@_]ӊFJ%s Q €S+qW]bPdboNB+2 i예" N j*jh Lt=BY NI d:ZH6u4z@K+>ZkH@QHJ i;PFdA9`"96~2*fAQtoAD!\TV4cw!& rTiNITpF)MX I$>xe] TR[X HJ H#+QB1X!d8"W)ⓚrn `(IZ%>gv` 2tAGfNOzjz,HmCVi'$c<pihg[!܏,$puo* JDZCBI|IjA.lO?oKG<^&iMqv%8raJ$$Y_Ws 2Ƚf|v뛬?nޫe< zgIENDB`mudlet-2.1/src/icons/offsettimer-on.png0000755000175000017500000001156311513237311017535 0ustar csmallcsmallPNG  IHDR00WsRGB7MS tiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}y>?UoU x"')6 sg2 @ Ѐq'5kK?MqpBFr&Xnw%_̴da; ^W8'p7AeH1_pt#2 sbIv վ5WnK"i/ԕge^s1*g {vn:zg,@)'-C,hRE 4.0f'?Ă$  ԂZ ΃x ;A"C4HR!bC֐ A!P8t( BPT5A@ hzM@GI0V5`} ?S,8W) ߂G`^@BD2 E>)@ʑzF{C>0(EY\Q(*UBDuPPy4-A[t&:]nDGSw aa0L<&S9i\ a&1 X,Vzc#i|l%"v;}#pF8g\(ŕq=a4n /W[\V|1ߍ/$,OE  oD ќK#$VO'HT6ɁFJ'# ]"=$!d[r(9DB~J~/Fs{ES)v,J9,eN/! !]ZMP["IHY Kՠ:Q<1$ hnZ*mnxz!g }^*i,(EZ򂤀04nDF1 cQJAN*JjT԰ԢtttGL~N'(YmY_L#Werr3raymy?lc . We=J4%k82J/L;f"ǜWWvUNWST^Ra䪴aQ>30--[:u<Qٕ3n[vh{;vLtyraW®۹owSۙ7-b={jD{+~),4(,/T)O?-7XlZ|S+odDiVe̲7Qn\^{p(³RSUlH}u[|ޚGl*~<wAK]GF}1̱c7566~>;!8wɬYnIo=vώ?wֵ1 O_3gg[U^ultt s?mo'+ yГ׳|1¥Ksc.On}|%>߾W_sv߮uoX8w}魎&M;k~{hPϰ{wkdh胱1_?xx8zOM`*081lݳǓɗi*9ytӌYٻ/ֿzri.O?k^i/ۿ^_/]F͉o{|KzX^>N/e~~Ǘe \@"D. r \@"D._ YY m*ЈhA.zTXtauthorxH!s) IDAThXkl>s<}ul'8qy< HQڊ҇TBBm$@ԅ@!@BjJiD_iZE PW8vP޵18iAذ8ݝ;w~=|??Wo\_\CœuHfB?3ILg=o+$͠=0yӊ&ZV$y:CRrNVXVVCk0dBH®kjȪ7I3~Fszϒag_C?tp|(jks {b_N@v9jà$ˠX= 0\ǝ,a.c`e",.j;Ia HI4."]HD90r,WЗN?c4!J"w}c > b#" ?e"Q *PpuӪޫvn{_7޸:[*!{&wB6{Br+\u?~_DEcqU}Ϊdlo3d^]Z~mZq!o?~}닿02U i%2D(A>A2>waVkOyi}U\lJ@Xռ6 H()!ޕXwI0g HRN ]c=PU4}|0;'K8 p\"¥H\:J"eIYWt˝}/vTīBW*ImI,x񤂐 6Akɰ )NESe#QaF9/,A5 L xqz~P4kAP|AA$"2&ih= VzFc B@_ aDI¦2^Ք=E-.* Y"Plq@y8LQDuqD\P>p^T)~D@{Un/D%ՠ$(* nemx;HT@U*WЕގlt#Ux%ņE^&1KgȞĊB;o1q㳗_n) 4@uEdA]HC6}# 71cE Bm, UV5[ mcvD%KY|(P(rp-/w-6NjteX曶Egdd#0JL7A7m/x򪫘p ]JhP '}_fxf 1br` OkȒ$PK YTt5,! 9X ښ4'U8 ꆥ@4 * m%0A`m8cUbAVAjhAF:5vCUb^G$T׵]w'^3I-ԑLjMKKl%(r2^<0-PS0;9TLtl;2;2Jnk"ymHu-ߺ"n|{{vg'ˏr!N0ߚNؕd}3.}O4'Gצn[ߦz &&& 7B`scJ ܡ@ ~!9 ;$җƵ?ZTkj\ֺks-j(A ;gXG،q,hȊg4ErЩs]ͪ TD"saM'nźPOS8m;sAL9uW{}u-0$ f%C5gqw(<,V9 ?d,NOz{OxJ/ E{]bn*8c}CʙLKkw@p?ݘ qkQ(%txC@3^sC0tr XN17٫!طf#٢RY9Z pHбύ?OX/XW.}MR#^8kKMU%ċ/ƈzK}҃^c{F3qPFcm[GB / HY9pńUylsXG~Ownpa>R|_f/777;::Z++++\5gϞCCCoLLL|hkkkOwwr9KKK*+PZҥKE=uJ`rr]]]ȭ[dqqQokkc =cPZ<(ǎ))=ztrr]tvvJEDZ $( 2==-:͙8Pn$7x|>/o=Çn .Gr~fiQH*A_mllEyD;|<6T(222B/ >ߧNŋ(9jyܹs|/ssskkk}G e n0$>9332B̙3 ijjAia$ i`TUKK˛ڊ+<ǃӟ6Z(HJGWO8qG;x{ݻwO ա ,$On}k"7b޴ J Ua5' A:& aϡmX,@ #Pq=vb_E.mBm<}kS#}m6`0 ǯq/8-f]"% α.@9U<>% Ar%g\Y7fv,m&g&R(MeecV66EJM뤤% 4'/ [4tdŴ=/ŹbzUe3RIJL eDCXXށCXkVlsK.ě tP("q392J`ܢtD#ƀFs0%>L> 8k4t8DW#2@B h֦ߜĀa`eW.CTZc\/:qM2 h<èȐ xD@X&c_ĨS_kQ@F!DLh@<5tI\[c(!O) &]ЖQQBXTU,=J!l .Ѓ<}5yk<80HS 8r@A>0ar:T>: ܔy}杨3G}Yީ3.9Ovwo x]?5-AeПDg- Iu6_y'y]7W=Bm흭 V9T]P%1{xx]>y*dNH1d4Q/mD c%MvIvMv%> w5Rs]Hso p2hHg7TkTު^Q7ZK&iRӻet֎ =j־[ O:umup&J5r z JW b r d9ns93cs͓^#z{2o/LxZ}tqM'49gșL}fZ3Ļ3|U}pt$',WU|(9-h2@ۮ@Z9rjhqI%L[r 3O̐]CjR&83v잓zyζ[9Dv8xtC"Hq> < Diz75w6 D ΁mKxwדeI)_zi,ɎYY\>06(<帅qZ0_r!cVƚTY,uDH{ go;(&:oA.>< ~@ VVS9T<rA@ȗj_j׷qU&Ed>sF3f9 Q{8n)WY+_(6Р;@a ҫh]Vs?@@Mk חu揎u/ |Q{QsRgc60GOV|7;80x;^io-QhWƯ^R{MH:CzRJ]a^TK(իm v-mWͳ7y-`3J!IF.n@K~ɾ.q- Ei?}LFͤI_U\wj4y d-쭱_' l@>OKTf2c`~ A~B# @40P@sş=Lt+W^w#oGƎeXTS8#pV7մ D^ܝ-$/: oAO `t"`.O<.M?^ ՅSҲ$YcǦIg>{p(Y|4yAsoaC5CCօI~>λ_zj| ̀i+Pl;wfMW`.oO<`v)Ţh~Ay~ՏF2}~wT?89+Qm8IF1?&&wz +^Y%մYt=h;-Da޽UcYGEO, 5?.zvfq?}~^DqŵPN?MtƑg Gqq!oB i2 2/a ҼMavkV+(մ1-&@5(17WA;0y1=l>0kyZBE!=XO$,ɷ@EA"ۀŎ4 -)Nx̧fQŇf~f ȏ \V4siN}gǎgs8jzHDwPZe)y@51c?0?<[W\GA^U_= g\p*c/`-hJbAkѮӀ ʿt 4sέ;4rh\h?ކc >\lx㖠m+݀ JCp6|/pT9hk̹AWPi_*@eDtnZ[fU+w vjDvӁt5SLxӀȩ-\5hvzf1@.pxֳo-6y > ;kp[-0[WN{r7e)윀ct {Q@sG{7 6Y(ÁkU r=A.> :h cSjc/-~W4l>!+ Mq6(zH.^n ǿ/>;Z?\;~sr'`PlI1a O..> xbl"hlFk,ނbז=@T7 Hl> @ R@vh_(~R# z jhhisN\'0nbA..şr&ܾ7kWu@4+Hq"e ^;$w@B(\Cj_"k~@?NL-t2 rVVxS$&r Oȼ.HT5q=ȸOy3%m\|I9ueO\|,|[  ATLʠVsc 2 '&z@5ofX H/[XÐ]ί 0'-o@.Vr  4kz3I h5 %{|4EM7zѪ A.^''ې;}9$hl'~.+PL. qwuxl`b D@6zF)Nռ69@; /x=29~ hFC \mS6§`9ۀKQ{7SQ -_Z4 . 20oR5`Μ\z0 \;-~uO([db:O<rC@^ @41' ZV90?K.}omKxٲwi>w'CM͛ToeE2ٵÍ+h0t4zKO9 h*),m4{fc ] R hfDI@uV<5)YYB%!Ap%`iہy*\M`ε-3 ^| ZR]=\G f@d: luHLShf%t<2栱^ ̻GPdoŎY7cӹ Kt}m@.?ϨPDf6d>$Xr3L]: wۆ%cٹQ̮lBc2!4g r{ Y r3|cVa|2ɝxm1J[~;94p%݀L*hCi]1L5" x\UIS?|U׵3r[D` o~*<27?rͬȪ/H" @N%@d矡=v!wQ:zƖC¸֐L:0Lи.k f`pΨYTOE^D杀:c#,dʭ;Ӂ(Q5ˀ" [@O, H&"'@jEtYHv"U"g)rHsE/rHCE~/oD\d#uDk쒁C=?&59AD`6OCGϡ e(@:ᇀl1_l*Hz j::RHȳd AQ[@3@tqiUY*ܪʆ{\-2BdHMğ[+.뉬k".XROJGBNZ;D_qgT|Ev+ϡ9hQu zL?1w0B|Η$"CD\U9B#۪rx]% ,.U_]ĭ⻇U{SU[ݳyUeKUYz:ͪoUkUU6$M\XXaЮb'׈0 TAk 8Xj>a28-iwpgb*<ZR]զTcUi8ί qA+]U XB,X"^U9@\?[(HC| ""^EE +$q Y,V|\/@"cE&{)x#qšww_8<[@QF~D?"-(T6 ,(N%E"+"zTXtSoftwarex+//.NN,H/J6XS\IENDB`mudlet-2.1/src/icons/tools-report-bug.png0000755000175000017500000000613611513237311020020 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< IDATx pUO^eH!Ԅ, b2 ,).X* Kl"[5 $Mw<Yڙޙ{9yQ"? !ڔ߿6 oX3Mpcy???wPPZ__ߴ@PbbJ Wj'DDD  IOҏf$FkA (..nKTT)L2S~#)Sfؖ<{t%<<|f{LOO?ѡCZ 3"/'Rf*Vi|;w&,VΝ;o!46'U:֯HmqӒ.V X,~Ney6UpyyCڜ@hhh jt6zuqc"_EI<bcc@uynI+@̙Xg vq}z${7xc쒒'&Lɓ'KYY\.j+VTt'榡v.hⲰJ=0Wn!555g7ntQt0K`XSjAUW5&I( 7!Ȝ9sZ*++ 7"#/9Pgq9$0oҢp2Ol 2!6ۗt2.kelZq?)I ʒ1r<[ʊ5R'CFߔ!ҟ/,\^J2^CAwՖWS&}}yax^9?H.RRR"sg+LNT08Θ_j)?"@I6&WkUGkpO΄ɺ ?OHҵkWϗr6&2xtK.HW*d%}Ds،DaN`9w< m8NQro>"wB1|sU|||J͉Hpnn&?e)ajt,'ulC幊Ji9SF &whh)dg^|(ac>>Rv(r"wV6LUEpZ?V~Kp?|ͻ/R.> 3#Gd+H tZ5ܔ9]\"SL)(R.1MN6K)ب ȣKIKH=/n_P]e)VSjyXA )¤Ir+,˕DT\$ >PUΧeوH9I*§\yQ㱺/H|+)A0 5{ޥ-Pmg#ɂef8M]~4s3`@cvyjIp:gTٌմC,xʭF`YsC1 r )J =k2Z%0ރ&Bn£ H ,[ qEr}2y@̃h}{>wCfnQRDÍ~u))rUkPx`5$Z\rС˵J5I>M#Fj`'%Bmh=-Ջc mh_ܢAi@xJ/dBˋ-7d@`=z|SC>xE?@ЯdA Sr=n-+GMuagYLV3UmA b#۽R_E=|Jj4.f58LRqv.,Ai^5]Үfg Jp@gDtzx֖xƲB96W~'qpK,d(T-YJ,b,9>'&F, ZL4~Wp\ ;L+XؤC}<tE`> '|ECAMI`oqL( A4Dd,bf4`[7-xL!icᑍޅycI(E&MO6?J?s/xq#& &kAA%Bq:A/cYo`c# [@"4Vإwf3[gU$ۙ^\GAƂe[ B=|k%k+.)?ݗw,cH$ZkzfI;hyF廓.u;Dbm $vc+r'Ql6^?-.CEx= @;y:ӥn }bm&8q/s % h}hZSLF:بnd :&Pt2}I~}cVu{:u7Cw mJ3Vk?"$6kY&3ڞԯu|8?@zB`SXo[/6gAkIENDB`mudlet-2.1/src/icons/imperian_120_30.png0000755000175000017500000000621611513237311017263 0ustar csmallcsmallPNG  IHDRx*tEXtSoftwareAdobe ImageReadyqe<PLTElBC=TTKjt蝏h352xWYRJKE<=9+,*idhf_ef9:6deYDE@|y#$#І酊ds{|_22/¦duzzٹLMHĹ׸b㒗Ʋ{Ӽ{Vm~UġVOPI޽cwti?@;FHB{sZKTXrmY785ڊ}))'_amr_R\a_\P@A?À]_[./,կV&**餰FJI??9leM/21!"!698&'%˰jphQkpn|RODu662#&',..!! JG@366@EF:??00.}~nm_ѯ QQQ' IDATxW [J1 KL\0+HmuR65@b45nuwH293/Yމ=u4!M"1H Wno$xlswai$0FDq(cƞRPuH11`-u 2"qgA,Y߉=bX?l•qYM|dj<ԇlj8&@:cM}LLGR.le[QDffb-uL~#AXPF!2Cd m8D OՎƍV6VKZȌ5+D>62e*훛cR#L\ 1?9lEơr V_GƉB06DY%4g&.ב׍3lw .*+7Li [Ro#s 3+HFUB5YY ȭ eLl>]VSײF3xA\E%,N[iYENY!)Xd]PB<' i4T!{J 2Cfa ltvGW^46-(5ͅuXZ3o/R$iх , Jt!eUqa4 c Bz4HUV[]XF+u0pzw4cr.^)]_ίte%V|9wJR#,/)3Zn@Հ y*wPs9ȍFho0PUI.H o;z hX#+ G|D' 80!t aL? $fmzt'ʣ===)&*pWY~yr94Hڜ>ȿ@4:@z^8YQmc Y ȕuzuU2=CdZQg9\4`Y[+M%u }8X>ӷxmI5jZvxzlaY gb0t]w!vsB"b'H$q뢯~hц샃3aG 6UFzfIENDB`mudlet-2.1/src/icons/application-x-lha.png0000755000175000017500000000624011513237311020102 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< IDATxZ[lffozwqb'&'$P \RM("Tj(U۷RH}KU !U B4W_'Ɨ^ٝ~db Ŀ9g;|2+keӆƁ/аڤqB~QSLJxGMI_!ӔIJq^D)}bR5 v9oJw@P~9>dqgUJ%C{ Z3pgn>f }Q`f {Y+U@g}+f/. W‹b-/x/H?})}~4۬sE9w?wWIJ\ʍ PL\F);Jyi¬Q8'CX:.G"ՁPpp 0Vj= ڻv?o"( 4Ps@7 %u*gIǒ?ȼTt1w<#1xfL*r_bZ@ZaTQ 8q lQZc~}m<019陴hmmqFk㳆C)'XI3SVTsÙ-nb"]t&drv`пU;EWWڣ0mHJXUULpȹ!Vvr$_ƖnLDC>4-=" + %JGسoFnӿ mY:b—(fb[.bvrg/1uP:HXbb{<B|?S-·}䯁@ )-r}xrKa]Wɩ X6G/Kwކc/w.,Y=\w^,=!ke w-hQSA|~hɨU=K&ߩ`3@k"JZ{# Çnu --;&T9dg2Z ]}7A n<+L0˛ j![1:1}7b8݂z֭%ksشi~m,]:d F!3UD҈Dyn3WbSr&EǑ-ټݸuU3Vk(n9X~=4bB@WW%zT pO c fzHT-Y2Q>&D -%"9D)N ܞ՗_b-ƖE4/YVCbK* @LH$`8,|؊:?7ң:'#HE*@,=*kk2te%b+b8 RN-ڥbI5v0G e:fȦQ)W3YY(i D+} JTZ3W=Qabk@~zFj*R.P_ f$$;@qF5tQB^Gd,x֞#*Pd$ "/"" f2+psV@vr X \'ZmZ8 LԉD3PZZ75^K )p&'EEhƈ]dPJXSRlV >uj&y\LԎ-p͒gI5bQt=x`+f(e<20MxZQq-š,\cHLfZPHWsz.zBAY_`P-Y t=r߻vҕSSd ]']ݛ{R?lǑGX'>֬XL,.J0==cN'BO"#9cǎ;_q+3#L6"\~OTBrl'[t+ am۶ЇkX pÙ9*P.~Rٱ cGYBӺq_t(TIתRعs\ B&%l`):UZ}⇨|n{':;;qi._.y֭LZՋD2'mx'x8 `RJH$T6hnoU'/oJRQ7dB/G2_nwoNbqWݻwxjjBBLNך~/*NpK;g޽o*{Wov]>pm^$z")J4s7NYLt(u+5R@h)oJN(॒? \_@^gIENDB`mudlet-2.1/src/icons/preferences-desktop-keyboard.png0000755000175000017500000000260611513237311022340 0ustar csmallcsmallPNG  IHDR00 1 sBITUF pHYs11(RtEXtSoftwarewww.inkscape.org<IDATxWKoEz^cƏXرy)!H!@nKC$wH$B  !86_`֏]kvOիfr@ pq<3_u}]w!MJAᾋ `!{hg vpbg/)J]1i$X*ָ$ }cH؍%dM FvoVR#LGj'5c NnL!'%Z:ixq0y$4UA2!'c@ Vō㣅l__z v2V1уV0lW/lt"[D^tz~UhՎCC;SJ *""V ;jq,fFJ(el!G͓.KX*,5xTY̡)1,Nڙ۰sw75NvTOo[B"yacv>J k*`pLr &^ lqf>R݋eNE/is!9yhxD' ?S 'S??י'勚-G0EEm9: ~l{iX][ҏ3|Vre pu[u@k40t!틀vq(2X-EkV3r-H(qEȹҾ~;GZG-2XB1UܣB*Jh(z*A$YObEg6P`tH~SX%m! 7c^XxgMu` }c  1QIENDB`mudlet-2.1/src/icons/folder-brown-locked.png0000755000175000017500000000755711513237311020443 0ustar csmallcsmallPNG  IHDR szzsRGB7MS tiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}y>?UoU x"')6 sg2H1 l ލhxOߟE&@8!sR9BNr,7pfZ0L /P+W8 2pL8‘_zj9$djZ+7EyZ]XLKLӍ2/9߳w~R=S; e7=߳t Vp)d"P@3` lpbALv|PJAPjAh ep wx ` X  !$)Ad!k (xP: R _se4=&Yo#$+>̆`)p+z_o#~ / !" DE؈⍄"َ H=Ҋt#=D!P D,Qڎ*BUN:P}{ < G-n`t :.G7W#); 0fWL&)ƴa.a0,+Za4l>{ {;¾qJ8#3.q͸0nǫ-x.~+߀OO'"TZ W 7D"QhN%w+׉$*I@ #N.ސd -9FGn"_!?%鉹qvUu );FJrr2'w.^-~N|L|A&a(-$Q$,qCbjP\j uTi4m7v6EYt7z<3}>/I4 "Y-yAR@ 7F"q1( e'%WUjXjQZNV:J@MzD SI&AfLYl٫srt9K9\G򰼶|1EdJ+ s E[x2Y%RRELI3Yc++*+)*/TTrUTT٪ѪejJj^j9j-jlXC, =3,i+$khhkhkՆMc::q:uVW⭪_5KҵmѝcyuW߯߯ Ѡ!0װo#m#QΫwZX8^Ϧf|VY35p16.b_7Gۛ0?o"_ ͖3kXk4RX3íZ lm"lm٪rmmNٽ7۷/:X8ls888:Q:888ϻd\rEzwsSp5ͻos yxܽxU_[ ݼx?a}g׿nӺuhRJۂoȆątbCCC;?~*$,?ltkÖ 76nLxaeSĦO n5!K-;eU5m]=cs f6&R)ᕌT4tׁ2fYAۃ(7.=D8~HPYUVYR*jھFfoa#GZkj k?;Υ^XƱ Ǜe ?;d,\̞ ;ugǟZu[m/~ eǙ޳쳭ZNk/:vwv BιnMW_PCYuqR1'{7>|~oUׯ9_o7,nɾyVǀ@m탦wt5=fgf={ݿ5vdh4`Xؘće O%[Z,x/A2?a?U|rD. r \@"D. r \@"?vn,6UhD@ VR6zTXtauthorxH!s)IDATXWKU=[=dhFFPĈ B (.\*\( .f…A܉U4 Wj* Ƹƨ|f_tWwMR*^WwYkq';|ͱïlu>f5GUy ^pE@p/к9iuv?m-lkZg׿2ϋ<~s1@9].j?]Õ"n ,_޳#ntc ~F՟i|6X̹\TmR0q6pٿ& Kh,< Zd1E^@t$ =-(Hrc7f38@i7]M$~ځ/'BOi Bm,'~qޟ!w#3TY,l MDb+M'Цq?`"r3`.]{ l  rUx/pؾe7zXIeDX ˴Z1_0} 4$[>H|X ,9,,T"yCcuGɻNM(Mz16i1cIHr_!s(Rp&j%JQ%W 6U.b{) 4 j0d#bjU{W"Y̬A"EݑVOD[ @iBgϸ[[J."S 9j$LkDĔtE*+T($)4B FE|[" )uCtO$WVX:i\$Zr@#љs޿܇s?&v}慏&#\u! sː_3a½!`>D hMJ{&mqeRtЍl8O(ԫuƳW*yIiϹ針e"18;u˂Q&7w(7>V> ]jXz,(:э=[L&L|}kul +p>^ɮ-9Bu@l=!F[+FhBχQ'Bʢ'EOujR[&oyf7<7&r<SO9 [;d]Fw,xv7u鴎tıHgd3-S8TZJZFPQ(`)$%6~sM7ewg?sݻ}eRJn&v;FGCv~g3T_>՞DR鳳EP8&F|/nѓ}O 8wǖsn#f*W>"^GҨ%X$>Ӯ Q'ZSYאȨc܄7 u,D<NţO?u}Tzzzݛ. j#i'Y>hDq@CL=6MvB:|;y9q#[|6QsBfgcd I b:Uy )uY<~Ovfc&ί)[o%mT!Y7 DS j 81'J"s-D=y(< @8)zGޠw8{[>oe_oL@X /0DZaT`yH̻D='?5uV gV-~ז!!6-d0+uB><1J̹sod lúe/}aC/<._݌&A Zp"z^m5L1ɐĤ}P-i\iBx:>ܛJ=]]W` X.iID.jL|^ZͽUL a-2M\g@Nǃ|9&AP]}-{pʴ]3 Q .db11LKƅ@'WL'Di 4;8H_7472njF]qaϛSձjEj 57k 2"hqQEBeZ@4f$cX(ߡ:2"KF=+#TP/,Ang~D{?19\jEu5? ]~oXAtU*UU\ڒ1IځQQ#xЂKY{nȂ,f*6!N#բ!luY֭XZZ(V  ޒ5bgGz,D4༩TdI%%{4RsLC%W{G75 7َ';NN5g{$ 4ߧJA@ է@(=7v*fF~ @Eǡ n | F$p)N_;vݍ26hi6ni=09=qLX@ԭs6ͽaI&}0Qz2.A6g;}.ZM."_$JB=9lĽxͼzJ"'2^8cgbJsj4aE kXBOgri[SqM9K=TA)!Z q 0ep\v9aJTS3D0|{sv>}ppP-hhEoL+;ΓQ$N"fIe"f9&g R*{OBGD:Zǟjۻ>"+[PpWB^w}gBΓ(e2lߡƗ~e/1y":c%`͚5DFA.8M}`?7j< NP4v1O%q+;Xy-T,}=Qu7MDk \/@{|oMOdi"̀|:zI9I$U'$e |sk>K`:Ȃ<m$3'6% yM>L2B%l L~ԥApj>0" 'I Uqu n h!Jh,2i%JbdJ9׭5 cyw F&!HIOe_%w) GIeHTg١ z yû8wXȞsɄa Θ,&m@0hc$,xo4F乻NB 555D*Jb?IENDB`mudlet-2.1/src/icons/mudlet_notepad.png0000755000175000017500000001121511513237311017572 0ustar csmallcsmallPNG  IHDR00WsRGBbKGD pHYs B(xtIME 7+6 IDAThřyUu?M5S@eEH#!iR +1@\I:i{EW/EjF BPNDp4TUeU|?~J(PCҿz{>߽w"]~~<?T&~Ÿ`C6h?}=^K^Г~gc~\u}=>rơ1UHӜ(m"AV SMqQfi_r_Uy{o{qO`]o6Wo;ZjiWeiaNM HKdYJFD1 (m&Wo BX+P~=zEosЭo/¾oM_lo9tkEU%+<c9H7`hշҫo1"٧z?m""bQu^eO~}C]M};nK}͓ο/ta+4WBQx! XlDwӘK sȡHG ҥ1Z*Q10,>sφ}/mOdu U:ܜܸ+8{XT 6GЖ7n:r`sNZoЈU႐48>Z,#O}ckoV ??zEU`aNv"X(F*sQ`}~1'HNO?7v5?|6zQ\@N`/C <{-mRM0ȋٙ.c>cRkl0"BQ,..0A8J3xň?ܚd.?P5q" "ذ2.Nm?VR? n쑃[^Amy\"ؑ'~%C뵴M&R8tTkyw p|~#ctAR#r+uj. XEXJT.EKh5~g|wzwlE%M3:EZ-*缑( p8ËRi4Kh/-2HN+^8[\^ ]p0~ͫlv;N0,yc#c[c !yq` Sa~nzL&׭} }񖍕Nc֚26>EZ7H8 ,AIOL&S=/ g*ރ5zsl/QB!ڈbŖb+kQ}Crg}j5jdV@A~E0ӯq v gj'A,`$ zm`` `̙&ĕVDR3 .>!3}ri$X qfJۄL~ʨɩ gtlND!ϩtRj&Y͇y}9|_Td]q <#"j1 Bmz!$nIx:ib/gh,!a*jfǥtsyn37FN_?'JcUl*dEN9iRx `1b0ˀ4#M}NHiTjdYYZtzK3*j.VGb ޳GOr wW]6]~Svd&h,pHa (1> #`ȳ#tc8ُ $%g)4m0Y3) `trϛu4"Rqq>FAAo/H)O 2|OKP4\0b0Bm$XGb'Lq1bkK "R|\{U3w}d]gAQ ab(4WEEu.T~0 fbG'aƒ$R-tH^(EQPh'&.|ڝ.l^sYXk4}Ra0Lqm09{<Y 0'}RƁV `KyGT y0++ "%$$#bԁ{W! M5QTN ힸ ]\juRU?^=<7rr8D^؈7t0+ Z1EDY;⻥s:>4{nٻ s-Tu) 4'8xkwcl?EkEPU(٥i_XY);uBGū@F4C^ZCfZaJ5Iv{T*}{wq!oί_9_&E `Ċn{3vWLJwJU9`8 BGvVU#x<-)A ,,,`C= ٌqALRk!&'_g0s7y,u+9튙W,W-#zRϷi+2F]_ -5sx5$!k$IJF#fD OB;ࡇɟ3Iģ3^|g5nVJ(GFdtJKYQ.ff=jjFɲ!A,4]xs|/˸WB06l.KF4Kޗ^rmF+IbAE" Q4'TqVHju0$v>s'O=uZ5\C& G}r=sUSHc[-T#CO. t^ǥ^e%M]S[ɧqd !ΕЫGd~~[l߱T.@}N>hX>qEAnh'*GW(KF`[-m ^qct )SKj|[o&MS.ƻ^Zf(NWCČTģX3uuP<cTVxY1+39=ZO(Fz-g8Wz)^F$QBC&7pZ<ώiU\@P'feUʎIァ;W4d>>S mSwЄCfvg2^eZVMi$1anbz(ir嗳cdW,W|=zuKntRZ e6t<Ǐv<T湬&a#B,f;"Jf#p-0پ};\sJ,4Mԛcb[|wqvQ*˹~Eeiw3GTy˩J4z%,tEu˒su!s|#Ҩ9vAS0 QGTČՖ3Eyc.c89=4CG-:u&0LiW/,IHqzO8d~nMнW"Lbj(F=ycm@Vh&e9U*#*~Y(lb|nH˜aVj8`[檟-"gr,!(lA10x{{?zs{rnRy"*4aju(ߤm`׮33},M3IZV}Uޒ9ֆ+{|7O'VtP[EÍy瞜aii#(w}7~G=bZM}b-415dYJe8,0 gBc]^6=2joP5*.>o(^ݿh 5 ,\E0R87Q: GX:vtrYV(yQ 7_:Rg326lp&ƙ[CTo&מCDEߏqy\w F/[bO֌>Ϝ]+EljnPcl=wp)3M&OTNv<{4ebeA12tFvvs_)&&j- g9S-9wGLiw_n*[Dd @#A9 +CфL]%.`+y-is  9>שކIzgdg?{]'8Dh금 UH'L_VMa9mDbAEL5Lrybܽ0CD? .GIENDB`mudlet-2.1/src/icons/application-x-cpio.png0000755000175000017500000000367711513237311020303 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org<m];̍ǟk,d@|{jƬͅemCsi,H"1"! z'O0ZSġ׷\..7ޞX qϫ.P@U:D?|B{/EqLRqYlaq)Z&\ȵZ ݻg/~[$٩T)x<τBȤX}) "BH` 5ISV j@ cCc M/fJ -T_^H QѰX<"! t^3+><òmrL(T!"" -`y0B(…FIKX<"(hȡ7dLɱq ySH =? Q0Bz|d+tBaF*Ԅ0٫6f^%a}>#-$1Vx?VR%D&Ƅ|/#BX&ŬAsodW&p|| `OP^.X&Ayd;p*>_P$~|<"c/2eFerл<W3i3ʣ"Ax/--Ϟ=%;?QS(%yN΅ .S4f L1L*P&>99ItW7Uf.l)F*0mΟ?B)yEɏlKy6_PNK_'Olf)f Ixy,w)˾ eP[ k׮x+ &'f_%lo؂ruB%XD`+.@K+c2AIENDB`mudlet-2.1/src/icons/folder-bookmarks.png0000755000175000017500000000253411513237311020033 0ustar csmallcsmallPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxMheyn$ƶVj[ UT,{ъZl⩊WA"` ANk-Zileg6t+$!+?< #dg;p92PdU򴮟ʣo뙸`+``c!yfyΖ:txǞ YiK15}[_z6}2@=[. ws u'bHr}\  Z`(N;2rV#XcXޓy%~ v֖B1yB&ΚZ@A:S1>qQbk-T@h=T῾G,rpV@LrcH xUӶ.=ғ2F1"4lI7EP64KW= t|7Gj4hi@$6LO[7Մ+g㏶W&pspTol,ONJ!? ~rk3Vq6"23sf1F0"'QdK~.L9Lkwq.NEs1`z5Y5"5vA( eRv{:LPk1y| n'n/am6MS`n-s X$pB Vb̿eo)( 2->@ )Ҙ$(mLs;Qe_s 8#'vQ A`å=8+ۆc 5i GZ%SF0$tQU ,NV} OC;AfL܊63s (&2ORlefff%$B=NJ?qTD)JGꩂXT;Q]n{.+թHu,Zy#DT@#0Et|V9z. H9Ԫdѽ s41Bk$p< L@„S].;(l6%ZyWy;M9,5f|_?gazA+綴kF) 䩒C,g`Wmh1n)IǕ2G*?5ŕ9RuֵmI=cZ{??nT~c;:ĥhEѫOn);ߞ^'"  齷sOe>F 6Y`,s3IENDB`mudlet-2.1/src/icons/folder-cyan-locked.png0000755000175000017500000000761111513237311020235 0ustar csmallcsmallPNG  IHDR szzsRGB7MS tiCCPiccxgPi CN% 9' Ef00!+HR\pu (DA,ʺ܌~>ݗۿSvxWN$`C<WfHh4  @dzA {Ի1 XDN2p':-tq9|BY) v0'@9' 9(rpدL8*䨯L=%dv/nAڷ}&h72IK>tx>yFoĨm+a(E ^ %\ЂI:@h=` ́ 66ɀ@. @(A53 5p 1i,w` ,Dh C1Ăl g B(BP.*ʠjj~A0栿0`:k0 =x p>Sp'||%0eDa! 2|@aP4BQlT*j;U:D&Q /h2ZDCб,t݄@_E0 1ǸaB1 L10s 3,bX.냍Ħc US؋4=S\pa8..WkFp3e8^os[%F|~L h .B%p0AxC$UD?b-7$fXՙʡSQPhMHcviWit ]NO$&A[$k$/HCHb00쥢JIH-IIIGKJKJa8$y"Ց͒="{Uv^.g%ǖ+;#Hבϑ?&?(ઐPpEa^hXث8DSQW*W)ɴg&1+eye7 z!eM@̃Z?dLfdd :Eb wV{ddAsrswNnVo;]wEؕva^Y{wOCkX`|՞Q?8wު_ 97 *>odSO+b )ŔrK?Y&Q]6u@g9MoTT"8įR*TW=ZP^+_v0#mu uEu}PZ٠Pq s,ƠƁMMEMOpOOo6onno)i[3ZNmzmtD2vLYٶ_uvB[;ݡ[{i|N~^14hP9 jP" t6(8 ]\*-D%}^^X@2rOEs2 \l`KnRu ytƠioZ8|^=uK5E]@,QDhL̑K]|dTU4a~.6 !bBE_p s*$bOLUWQNsMQC=HBEơR34Izܥ bR(2 DQl"H5Wrі&Eqj(`|׀2*sQZd:" _xdN$n[\9-+b?1Gk(F;in IQ֍hgkO,YYޥVJ1E+Qmcoh/!,Vm.KXd89<-BE棾04MvMZ9d@!gY/*R.sdPvI b9>bf>NLPT]_P4/(5T5miD703N]$=BK BSCZM VaT8ùO1 f2A %hRGP EkGlP4g M&-FTc['?sb}ko9hzV`deTE. /oXp5D^ X(aGw% ,u6kUcЦO{g9)Ǜ^8Ik_RYޝW7Z<ڪ'MbW򷋞C'qvN9t{|;¶vS]F~⛷>#(Y0[WtG8s ~'fK];:s{)\Kr{{dGw;v1-.C6ZO _fJ'nOu^qdE=P=3nU&:4Eޝ{n%˝4~?ӭ=d&I/IjɠعʋR2x6/2?h3W܉:avOMkYbVIENDB`mudlet-2.1/src/icons/games-solve.png0000755000175000017500000001175511513237311017021 0ustar csmallcsmallPNG  IHDR00W pHYs oybKGD_IDATx՚XT׶ 3030t9REHUD jlXcFc j}r5h`%6;h0bEw}y}y߷ϙfZ{Wn:\Dpp0DghhD 3knkqWӌ,X",[>?ahU> Ck<0bwbRmYIIIxxxvvvpwwψ CPFFk& 90\ivPxW?9X`1I}Xj eaa+VhN<6mڴߞw|v%˭IAXq_Y}#❐MXk 2Xtd܃fD%Q?I׻qxY:щDL}/-6Z>EbU2xd|aj2>oH>}җ-_ӬEjkk͘13>Ŝq1 H!!ՆgRk|6/ug>}GxUuob40N $ `rbt@0+6QCt=b 6QG |ēBxDUT_?˲na{ GETxv#ΫD M\J>[˝ǝ3}D@X iзظucRKqo\OthKJJ޽544hܹwUTT cxYU K2f|_--y<p!^K<,Pogo0zalnЊKRnѦ5GkK7&2mll航ؼy]Yss]wf͚cΝ~dg€\"2AO&̘x?2U3QݐtGiO#^\ nπCewzll\9Nagjs!uHh8?}˶mٓrZ `کVWWk׮i;H555,#3x(**M<[] D󀩬GOShZ/m%wAj-509o:#G߷ st}9W9w8Y3޸ec#GO۷o ذaXހ s'|x=I;_{5FplL1 CQ|5Gq 죦,Ps0ɖyuy*d J=kd7ikk3gNnDDDU{G5 3iIԌz(S Y[cS){)_co]uk .ۀP~f#N]:,Il^–_޻:zV0|p)C΀u(Z8TvȒ=aRq_ߔ /pͳ`'7'bRDi >,j?_9 Ћs!C>-`7^Yg.k.;}Ki@!p) 9q Q&7׆/e9X_:rm&H V.vrrR]/^ UXb+5S>),,d%70ax +؏Gg|X96ⴈ""ƌX. P U`|Cob_|M)Qq'u V%cͲo1}4,\{fݷt֎}гwO:E ``h\B;s}50ҹKc W-k?'Zu=;cЄ}%vR[x> \-5|jCVS^3St޽޻KQǤ|C.f`"̝-+mwW+P`?0ߦxVY(V6VSMߡ9~PA"-&*bbXl. >,mI9)Hw%LA%>>' F5w),ߜf/]лgK3 f}`?|@#cH^\w6.@œQ],e%gf##֭L 4c!OەnpIF-3Lߵz cY%"ֻqzu=kmʭDnT;!$=.>=porAMUV(Z,7k :jցn1yPt9hcviH1-bV.d޴ª<YvcW>5㷧q 69Li0WnJvVm T Ϊ4`նe!l:&m%:0V#ak:M]YMߙ̫Ոr Ǖ}{vP?q 0}kWOT5\&^+βϸY1^-a̧JW>O0zM c` 9qzC+xyFtf-kdx Ea"#`hMZZ3S%*q]sB=$_}ʟ8BEP"w*Illl:}ffe2J'ܹ(Q"$"ЉՃZ?XR > I X1B3+^l}D^jɆ6|/r`, (5 Livrj1HBN@w!:aĻ 6>>^Gbb $o96j dHC{8ja _ByUtKY>%V^ω[BQOT'e2'ȉ8zvE\ , Tfa–(D%0 BMNd9@  @ZfJL@2]:]xVRiG@TByM\`䌖MJ"b`jb:9N0*Z:#1^EB?jGA&RZX΃׌ :JTmxPN ڹAJ0 $jcBFȅY300}> R! 8brAQDV3Og(Б PVDt&SK=܅Bq%Ht" ;X ",x}x)=JOO(%ĂKʀ >Q0]05ޯ:#8p 쟟L',4z{8('(&X,*g9tpR15,̅QԄer"`#:'ґBLf[ϛO l奤"zTXtSoftwarex+//.NN,H/J6XS\IENDB`mudlet-2.1/src/icons/folder-orange-disabled2.png0000755000175000017500000001004611513237311021142 0ustar csmallcsmallPNG  IHDR szzsRGB7MS uiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}y>?UoU x"')6 sg2H1@&d;O ^/n@+{,"7 9rcIܕ||3Ӓ(d:_xB^o1x?!#|eS+̉' %W\ f/-ϋHRWxdz\bntyFoĨm+a(E駜t~Ʒ Ht *K` ; l d BP*P @hg@'8.k Fc S%AX H Rt # YCN'@P ăҡh7TBUP.C7!!4BCa&tXրa6l{8Nr )MLOM+CZClXOQQ6R(唳;9qxvjsc 4 C o$"f3T,UDRǨW4Jsqhi ):΢yIdj `1Ō3QG));(RRRrҶQm#e2N2 2e:eȢde}e3e^Yq =/((*($+T*\QSd(*+)(*єʔ.*`J2혉 fs^Y^U9]NyPyIҦDVV-SUWSRRQkQ{WgǪRW_`iiԘaIXYָ&YF3E^FuX6m]}G1Չ93 |oU1]nnCS/WS~~~/&  ݆iq&v^cu:QGLL|653囶Κ՘lv9|yig,ԵLlYZaͤUUin}Z`laSoVՖkh;meow=߾~a%GűqЉTY9ƹy%+u똛ǭm}{cG3OmOguk|ZNo}'7_os?Cuu5{o_8@3 =7T$|+D6$.+iSa&aaXlQvc ("6 G7Xt8pq^rme(Ҩh16sqqUq]kN$,'%%“^f[6%$' R,R=PԮ4(Xɾ&f%eTة?;ժZh+< N~K/g|('Oʟ?]6„uOr&_ǧJM3F3ggXbe˥?%y׿lzw7']Yx.b{'?? 8 /_ƗE. r \@"D. r \@" |w#,de966@#J?JO66zTXtauthorxH!s)>IDATXWoTU=w3SNKK[Z)Fm%Q܂[ &_|2&>>DPܣ kYF>̝{w2‹"z_aB\!:y—=BqF|eYdYeUSѹox845#|:Q\늅/tgYN;{_{YKͯ&gUbӪmg5TDExS\8ߐwH/Fg`bP7(!ۣx`pM#8o-#Xm-D Bb$$dƕ:&*rSXm;bk/ lv\*⏟kP;!!\;/r–$I6WM,!vH]7!pܴ6zqk*utwh ꛱ }[q[ܤgf}Öi&.n r$$:؄'`ؐhm B(xtў^ H،W}dlv7^70419t,6Kso6v?|IC_BpE١ (cX>3V> e^~A#uĢJŬ_䐝m:0[-hqShniANbAH>"eF^ Dx8AP lL_Xź"6g1z,+r6+-XJZ)OMûxS9; \UY%yP YRUNE(`sm)-pl"\ P H& ~?Z{};.@Hbay %PC㦇K_DT`\(+ <B{_Ν]9*H`)˲fx +$|f|I%棓Ź@_S,,[G\sZP#s(xuޝAFDzO>O"M[p$GeDU ,^m ¦,P "-9U]Y)npCˑ^ ?(`-]/ɘ(F*s. !pr&fH?vi|HI@t\,0~HqhOłX*W*(9`~ ]q<1 ^vRHaa Vu!0G"zv @%1NHNVP لRG <1@b>3&r;S̶,sp3X}S'VI{<2!uwz"q&NZ76:q$W[Q ᶎ~]"km3Ka`7[y%T IENDB`mudlet-2.1/src/icons/avalon.png0000755000175000017500000001632011513237311016050 0ustar csmallcsmallPNG  IHDRxK&sRGBbKGD pHYs  tIME 0 tEXtCommentCreated with GIMPW+IDAThiWug;y{O%KAm1ƦM1$NBNC Н8 YMX$!q;',Ae[5Z7ݩ3VL_CzqzWUS{-=y@TPQy Z h,DB( *?~^X9϶-]n0xFd 1o=y8 B$ R H- HQ #J=CDB rdPB5ا d-Y𩇴M<69lj 8lf, lb1R2qgzx{xG tvjuK(Ib(%p3;plrӓZk9,`dۨ[1d^ג@I C)AyRGJ$GC(a !Z_>ى:~f>3;1.5H%B@B[OY B@s,Z(v(TE|ЏE Cj{(@4#,sCl Y>Ii \)i+"K\n%2d5cƊ@/xDKOf=)haRAcѨeM:f-!K=6Va+l^%Z] 53dB%H!",>#iKa܈LP"i %ؖay>A@dC p{%{<XTks |:+U~K%ZvfNa $4՞2:ZU5I|-qR*=O㖫1Q ,Mt]^abBzj{)́3\~yBpg",$p|/~4GOLَ twF_SmY\lYL& EdhI3FZy y]nXTI1-$'5A a]궽¶7Bu2{:}݊@-A+(K@EPT'ث*㷧y߯>ɍ{11bn!W޿1>ޭ l]_ w|*{M‡I_%䲭9[:bGf,',@FŽj.':xVàO_yا*Ȱ#dxX#TЬ, Xhx +VgOrDGӓu3<~dY:J ;̉35^wyԗ-TJR1ߟEn]ҙc2ٗ J3GxCUZ㈛)Ʈex4G13wekV¡%nx8{#8aRom;7r/3|3{wbߓ8c3bk֒\?'_ &CFǻxXC<"㠨3@ B9G;r J"d#NAP4|t 2M02Žkt3:\}|Y&IJJT;-ZQ5=O11KMDj8j;.czWɏ?  s-JEuKyˑƷsZ $7zy Sl&,h2a2G+tVBZqJj):d싋lDr=%,=MKX<Ñӫ2{}vv/sllRS!\f/0JuCj+Or7s[Oi]w{r∲s1l~I9|>!Yix,_yz)fy%%px j-a>ʑ;6Ǐ5sغ;uInܽj@_E3ϑjn0Sd]_1K]!iѳkx6r)+M`f̓ wFF+mks'&1h!$r#3lrj C8%Rwc5]1V)NM8?{)GK0ک)ׅ\Q)J~'0>gBx$E(<>$vA@)Bd`NjZks&hr?0ZKK hlYSYOro~$o=x_ [.: <ղ]7m`]gi)9ś|ǎ,p%\7 K_0FϮP(w*tS2 yC'/rOoח uZq*T o<3ë/7IܼBIyu\9Wi U[oK |'y}ܰ#"i`]s\"=l<a=F b ZTčow@ sFMCJzJ,7-/*0MtH5w4 Anx/\d%|[!(J]*_:_uB B*͍G-wqۏ}*Q/ vFdĴ:A+OPB`ew7{B\ XS%sx*om Ix:rT}0 ׸bCD2haC<=9˺ސ81  2鈅 ]@|-[Ɠ"A :Ka(l:[jS&pƣeb((tIQ.zB.dBe $"nٷvr_@Ogt|0w/7>:P ƒʽ4_ίQ<ػc'dn!f\˔=Cχ~b||?qZF2VR|gթ57o裿3I=6Ilb<IN$|,:*5l|=T:d ; OŽI=Ŵ2k;<܃RF -P*G) مrFly^nӇS|Q! @"CҠB "RrovR ]H)QEq9_%N(W*ŁK\y(aأu󿰛h6:az~@ذyz=ɯmxÛnҭU% =Pk"x/pȼhT1`_@Hlu:pb@2"B߾a!Ip' BIV 6iyIbMZj&<2=.ہyLb2c\氙|#gg71;dzA"N<*y=(% ^U$P`|5hr@}B e^d(68?Gq]Lk5@*RrL>Y8\9 Rӡ0 T9;Bgw&cŖU6, ?sMq]ك sK=,N79$S)HY(}C%* q3ajr,2=c%J=?qsS5bU{:NE-`-oaݮ~uhp| ZxR)QZ*$=S ZGa( \M:.*W" ذТ$ qwZBJrQj$b@W}^ t@*Atw 4VeiFadS-j$K-"]L-{Sc+)с$T-s"xTuB GuJ@ C +G P Brrh84(R /p>Z{HD_e=CE_H86|.X)?g[\=,!@˒r)﹊cKPoe_X mL${;y$RPPST{ t+D\J*R()A% CMgg U:fg6kj4A BX @ xRpQXBF Y ۅsq%>+ZIJE!-5Ia J^2Ɠ%<%sA&䧑2oHmPmLz1mϋ4ȼypH RFఙ!<&`_v:fHk;pa*Ѳm" @I )IE k=fB'X^ml.vva8[fw^Km}ŷS|AeJ۪_˲Aȗ%X.gv#|ۼ\\j~]h|=yY=Dh\{Y=AhxJ5v~Y\6Lͬ$FƱLͬ?G;N?]oOR* g^Z`jv+BJOZ!=K8*8%_IENDB`mudlet-2.1/src/icons/folder-txt.png0000755000175000017500000000253711513237311016665 0ustar csmallcsmallPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx{e;gMmLLB"ʢ $IYiaf`^*REhżHZPIKKKHf{=svϜy+3<00](`+c(i94wO,oT]#/̿2]q"\)A(%bC Tx9,Ƭ{2L/#RlDe, J"XJ16,#ۘ7Q,7[I'њvcVɢ3p62˚=0tpW9\ʁ}ʉb)FB?ӟ0ڣ<|nfSFg<_5!U"HՂ_9R E|ˬ;ذ>? ZY$q9#IRIS80du߈`ѫ1]YL!OB)VʐH$Hg*-%xZP6+^Iae]xc`8 BP G(HVǣ !'vqY@f. ̹2L2I*ztJḮ -yNLW/$ibze5<~{&q${%$\JG J@%l61vKf7'R=_[GSsȘY^z罽UWj,*ʧtBKS]{jЃbEDE^\2g{֬ ferޥ87hF7ul[k,om<@kA.hv,vl'6KWԃًS>Oλcqhzڜ[T<3ټo7 .7] wuZkJp! ٛIIENDB`mudlet-2.1/src/icons/application-x-compressed-tar.png0000755000175000017500000000500711513237311022266 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< IDATxZ}TW?cβ_|,e,RP+ hEZP1c?5jb&]VcbUl@[Rj[ l+"..s;7o`f) 9s}9swQ eQQCHNثyٺ'5s1LkE]_ky_͛WWzX2[si>0[2e Y )L'h@TP-PU%PAr^={nI -e5(  8m@1_#Pz 5Y7[2Wܵ3t@Ҙ}++KwsxzϮG>4O~|#cSͤf2P "hWE؀XuLXGsJ4ןs\qxV2r$W5e`$Q1kWhצfvl`Oeʜ^lX )}\XARQ)([ɆÑ6\CNJ.تz Ĭ  ?͆i/RgD@g\c+aR(Mj#EBP9mFQqZԱ\7-xjC:,ADOu`a >2;W! 1ޕv(6yT,_ SLGtW@}NBMpy`_ MabY] 1Tua ѝ tnBFآm݋E)&5>)-H6u&DgN'0bDB YEYt8c)*EC60:> SV-Zh3sg&8M\qʤNb7@PJT  RPUUAE$NpMv3~}{u;V\Og}:וּϛD1Jvi{$K̐1$NUKZphGFއ}S>ҭ H|^Лi搮KVc~`on,M+/RwAW).,;:Y?..yӕޅW?K7pRf~#+"6 c8òxQ~KWI>hm(mo#v2 ; sL.WXلPL>rsڟ.舵ݼu^-Wv99M}z}qLN~s,d֟!Tj8D>\,혦dMݵyK3Vݸ50/|t-Wlera5UnH2t<촲SA?K"m )7;9nyGF_B_%ew-![tgT@  M`,qihf%J&*':Q7}g.4 3o1S\_\5%.:FHzLN'm;3!6_ɫk Qi7m~ rU9Xe)9҅(U-ݡ:Gr'c`; So!!QQWizaJ;T]|O9*=dgmrH,$#L" &fP v)%]")oYk̀5È B̪tidp]C\dl.'Xq\k@ BAr*P䫙 7O2ʷ8j|FUr'Hp7"v5*B} "K[!D /HzFcĶ2{ ؎ A35 9Y9/28dHleS* K ITZi |Ĥ$2~`1Y "Ζ b L챵(u!9!IY.;Zv9<(z0"Ij" ŠGĉmXW{@dEUdV R=3P*k;A uN &ǰ] S#=  /Yĵ `0fQJ /āojWn+1r+;$/;W0mpsԫq }3V˒m aH9].m04^.?w@g)KK8=04IIZ(pn4:]h7[_܄5sιK*'将EE*J/ E蟦(*S$q4ȮWFcP}ia";+HdOC y®̿?tuOA>MM͟>0˻K豙03666G}Pjbv̙ޕJӛmv k7TgM' DI7b%}x50GQ4ұܓx 8#'R3A;DN<Q~HFH倂 :.EDW ,9K{z!֛|?ze'T:& R)N~fnY8 雷W(saϲpUdUl3YsLaal~P{9`Kp#ɠi^+Z淋T:.Y ~qٻ 4AzifMA>. ^ B Q۰d&X@J i 7ZCf?C "K_X 3m-tbB8W $]MMgA8.Nő& 15C\B䦧1qb)p!*z뷥[UtwBRA0YH%dbn Uwc97jT<01~4bǎ-I]`f&?pͺ2` j UcIH뮹?w^/<ϳV^U0&Pw~Hd!ހ~Gvw} $X)) IMssl6Sqt !%r#sAW2|-Hi8d+3kL\<+$D\*w3R0 Ӡ~(Y 3.V0Mn]ݝ-#PTd Ss5!Rp\w'^^:AģC17 Lnc>[BԂT!#I!Cx N@89bChfGq N$Q])XdlHЕ"O?Ӄs9҈'&XoF0k _WY3"?]N|%'Nږ/1-&߅{k Dః;G`!WV N UqBy7ضm[C&Ybhm !Ƞɳݗ4%kOMM"M9;diGW\{cגN{%`L8ʢCUid*ޫ`t'/%Jȉ{{לƶ('[:o޼yb'A!L|4Ӕ Qsa[}tx?VR,}LI/LC&@[B*+է0>'e޲(7WJ,mo/u#cEqEI0sO#=VBjW-X|Z8:r=ıơgw✋T&2RuQOgLś6nJm|R7pxC[ )  9I8xÌ_|h S Q(,Ka:3Ɇ176-KCS 孁؃YF61[Ɔ1·"  g}qSK رc ݥvcJʏ9J^$ہX @_aZ*EG2FŰذ|%!cƔJ8W`tl=g[=$AF.X1v{ndVJ@ 1504P[KyYk mՌ8]>Zkm`,=F3 P0JF_ ω8* ktˇrGM=:^^[?p <+ qs1XCۄ}iҏ!@Pl(q4Љ~;3:esS6ll&èK@scLJ'~784+oT}PSp睄L/V X²t_xN7%e5!E8D=J+):f)^R9~'pd ͛q 6CмH"+􏈴惘TVD"k!ǒX~tD^K8+)}IENDB`mudlet-2.1/src/icons/media-optical.png0000755000175000017500000003455311513237311017310 0ustar csmallcsmallPNG  IHDR>asBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<8IDATx} eEfD|VUY{PV(m+ h(~#M3287J8v~2v#Z(4 "JcAQ|1='^^.U 䉈8/ZKNjŋpuE`-sLwY0^,].?7\<}MH^mk -sZ,e>uA TTbV|O=ᏽLBA3 I*|)_3)\ SZ#"P{_yc4/ @R]AKO-/RVh6I+BaV?>r+c7𩏒0HE?$ZARsyH"Hz7s'T)sh|1mKx ""`DHAeA>O e^ `Y7(@7>ϻzl ^<O7^hMZ3CvAPV X7ZDx#|OV~$Z>|dLuDK{`CkpA$S7}]dG5YJyM[eua)SlQe|}f#gwYe}?L pZWn=Z`IN\iIZ\-K"+r5¼dS)qPTãG͗~k ~GgRx߳(M c ),ڋI&(W( 4)yH8GՌOܿQq`@E࣯hWl-=׼ov%/t3K |'y! \{bI% j|JR[4DT#?d.1 O4򝯿 R /~VOgݹoiN`ͧCKwEZBg/S`>ȡ渂(l>pI  |djz k>5[AQ=<6pn!!}.erzd = 3|(O ȺұH O&7`!rE'iRx;;*6˗_pᢚױ׾%yT`3FFېem!p#t\c݊$h~, -[P~i)*J||7POߴty!ٝ@4ς{+tt^D;RHʼn)]||}]bWd}OKnFPYemʮК NX߾B)'N?g#% 7|?lyIf 4|Nrr93@lLGe&J$Kև$ h>_k$m |F;cRC?VNPϻ;^IgeE4kCj;6N<8ΡxBMu٧Iy=>E<#f 8ur?r7/g$ og2 Wd_>i"j~uwD1SlԮN::G{EԱ=7u"7T/+ ogah$%H܂OO8H<Є!'bׂc`}Fx#?{Y)KM|ZS/Qt,TNX2nݦk`B/ |*IS-\&=ԭ_1HXržl.SGϝ9Zhņy|hC t `]  {cC81|m;ٸ|1+\]dwV._ŋJ(2)oUWg.}AP± sLº&@1.~AZ+OFX%5| kcPLfCY;@|[ ךE$EP33ʓVj]ͧnAQ4DpCpTv 2̭W"f8 U 1T1[|}-L t7] TѣbYxLCER9 Hf+H%VCԫQrYaA1:2*Ą@fK9_3b^X(Rwۏ/ iwG׵]Pu6c@a:2Dl/p4|SxaduQkh}Xzy(\>V-j(QW5JdidDH0rޅO] xx%Wu8BI"NlܺFe yRV2ht4:h6x08wjZ^8u@'(U>xo</f#5o|6}#>i0@']Y88h9s$W7 0^E3f~rMܝ #+\shvpFc$܇A]j SL*R1G ͳqpn@5_ÊMrH*--u6s.w')H+j mLT4ta:̞|/](XraooOA\\PDPDu>?f p? # tffpZRw %>s/;w+~ud/0a0ʠBW2Dy0 O_U,tdfXb Ŵ#o,!r8YT'k/7?z'_MVv3Rj6 p^Z4NhRvkB(d%p h}|BL;2RۛN녎b3J!@R+$m1;]au:NBٷ9Φj< !Y"_Ȫ?]PYZݜ_Ȓl9grR$׉[K.%nG Z_⑁d2jgd@M (9|w(2hlϞ=ς]zRرQQ,0Uq-~2(x[ 9g kT1ZM dHp \2udDJ.=;FǃݥRW%Ws 0#d\߇5#C ]$'0u5kOD Y/3xOep䶎 p2Z۞BOT&s$$kA||[t{FzsuBseܫAYg2C @5 @-0!~ v Xy o4Xv۹s3VZKY,. =YB &u M,$m2ˎ~ ނگh\$ k,au ['s3ZmXC], +@(l6oZO]ÝãXg4R r  .!ڵΤg@agT6i:J6<U5"(1:q2 KS~*M8ɺQ< 5b 1Sdr(хo.U -_v i0JJҼ *jxe<.KKժ|8>4߀oCݻ‰`X ~W(hT*Շ^kp:ýqexvxj2Q& y'KAE*nz{NgQ鴢 2e1 " {oTg YER傅j JPAkFNgyڂ{?^t/G(zuuuA֣ *& 8$UՉ瘝tT% ;AӈO>\{ ЦS X[AP2nl;i^ܬl I;Bs"P6mOZՁZHT%xÏ=$u;=Z| FsOd+ “ fYDe'g;/6{UWQ+N0[H!@jpN/,@v, y\Ƞ,BD#"-OAuav8i&zܸ9b> xj`G#¾.+Jʊ@R!m/|aGv.M8Xm|ߏPj(iQLC>fY8O<1l|L:^yu#!I^MCA+B9)^h ji~,NB 884dAGNm5/{T1qms^c=~Ad,) 2r"P}>GNøy!Z4㾚xԅ3Ь ',2vX\FyW`!܎ |s8b~]G‰N n,u -d͏, ]=!(ȕ}1o,+7'樂{ڜ%a|!{NA_J`{8 9c(o{ǡ32~F|S]t f-'>B^oo8UWׁ_9 ldΥcQ+)ZlnÆ [.C CH{knpOé-T(@(YiLڍ  ekP8NiH $Ru8'\ "W`m@ ڲPG@[n>P2yZd+uë>[l@g)Tj&@8گ > Iظ /{qPŹ `$hNɝ9@&M|6]zryܞɦG lS4 OE VhVK U9p+tw`=OWu68|<[Z=)`ȖC[w?k5Mځ?NCJ; +lOY J훛>K?%Cn"sߞa,@dAZkBB$Iɐv+0Ka/W\oqo9`m$Uv:l& e-OP8`85\`v iks?VuX7P{a vsy:FkYWw. 1Q EIZV+}`p2#DGqIHȤS~4G c# .?oRH!#a'h F R~ g7ʞ25ԪMo%,z~x#n%ȼKTR8O\|7oY[8߿oA'T5Tn,d?sfPkTӥz1m:dF!6OH% IL).χn\`'D^4E+ҋWw! :2nYԉ`wlǾ<>cOT1U<ST*ueW&*CL݃`fJJS@`=BT]ɦHIINLu !@ݸsǵhWp}%]g𷷎+ +O)(D!l>I0w(=z3ic~N@~pM7lFRF<3}9DMI 9Cq!ğRp1jj|)44ٺe6r^2%tT` >ӁOg-zEO/hLr~`cYeT8@mN6TD. vj1Bb3I*|V홧wlB,]ns:K]\jj;k4yɲ8R"hzCPdqݡ=[6[_;Å6䕵9mD+BѢMZ!0BHxI)4Hy8j(jM?:!tɲlceA|3-| UC|7c<Wl >mt\QB>^Aـ"c6ænJ]?$uIQ?yS`&c|{vd.vU53.>~ו?:<YX{d@ºnBS4\_o}? HNMmSUvp vڀ< y- 8MbR45¶1Zkp+&.dHu_l @h_98ԬN43_;D=ۏO<7 NbJʿ}He 793wα hW*X9'r.g Z*"9H!AjcG%9ԁfjA*M9>x7^9. P'h6-W7v}LGtBdN>v\=] B,$ǘʻ;|DbKĎ|fvƅ0mOYXt/G#BhW}82hy1)Ľ$<E:k@-AxMEWnXq+š䇗/]ٱsK=zd //8⶯JQN}ܖFg0'p609D>r/Cb}pw`EѻmZ/o=V]z|뫨*|@"oxOG&J@b ;txBlCܑTlaBƅ{O(-P&Ho+Gˉ_=(7>׷qEk ꮞ걼+GIFD 9Vp 8pv -cK b,ѢXl1HCz{Sϴl=H:' )n{-gO^pRI=[Ҧ!Ov6~_#IEZB]10\IoƣhQTNZ(?c Fn9kcO=w'r/U^Y/lں7߶qֵފʠlKFB]˓ඁxs $5&.~\փOq!IGuԋk]6 ?"bR&+[y7af>[ 0#  'V _+M|8|悏4ؘZ|*(n.(:Q &, fDZw7nͳC /l; W@i^jWbyB#F< [| A` '7|  <a&|j}[ۿfǮmob7PE7v "ŷ?[WZB\]jۢ>ws%_|gN~̎{|1'pKG1 3ߦ&]^^oʥމ@vOUoynǯkmFSV\R$VJa,W7m 6Cdf5& @N.҆CbWN/z|eˊUh# u˽ "<9\x˗8PaMx'cn[ l챏Mu߾-[~#bRȈfȷ|i 3?H<6;s=ޕɟ(.|YH+k\UugHQP,b=`Fu-ؒ,x%}  x!ϫágHޝ\L :A_&BH(͖+߰eiӧn;T7DOWyBݼJ*7I8ʑ|"{X&~R9dIgi^|uOlNM>2/#'| ̾qëTnnZ.eQB b^iW ,%/5 fZOZd vsm/>~m|Ro @ǽ GZ>o[FpCIZK>- EWF" >\.ȇ=#iT"w{[~z ɟPEz #}b=_윅塚 B{)R'jB 7@x(do=;uz_˦'_^b $!=޼曷ʚrR^YB <@zF>fOZƳ|6#Áʐ`{u}EuxK_PE /'!O(i4h[(4v3gQ]9@WDf&NI7(RiG7>zg{\xWw(NBywo; U*~_!BO ~vWW&%=C]{6ӃF;=_8vNݐ]= PC' ٷ|iNmu@aq|~V+ >0zyVfmVNiӢřý޳'N端[̧"Kt@VAC]mCٝ_zS㌙UkKu~DӼ~hU8WIr,~6-²h]H&=Xz/g{ Hz!%nO `lBв@O_x0`2- Tҙxƒ*,,cO*Ua˄gsSȯD,$Pagc2S_ U Q@$>)?-3EϐhIENDB`mudlet-2.1/src/icons/view-filter.png0000755000175000017500000000156511513237311017032 0ustar csmallcsmallPNG  IHDR ssBITUF pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڥkQso&ZkR}J,tQnt ӅkWRtBPXG}[m5&c3i&s AkeKdUzgS'Ƒ] $ƾTk2Z :2 ?ͨD)-qj=snڑ]zf'cRwӱ0ɋ旫/n^ht;ƕ-j V{d+/4w}EJ89yGȠz?Y+JD%JZ/G40\=='V^=E_0 0l81ffL2F5R@߇Ӄ,Y#ȗCL",ISY/}v+ 3y! ue 8,ɼiHOSĉsG\"9S+Kuݽ`7tǂ-]W÷1c]k]H^Ã0 5#*UMh%`@5DjZpGH`j`<<[ Np AL8}FDxx"4PH KLqmm$ Qǰ``1(SU}3{] _Pr#.P w1㠬u ^k9 &CC/Ξr? pBeyQ]@SXܹHpDps9XLW HGSoǻ_=޾tz.K5;$k4N2kY BzB0 ǃ#$ZN1>mmұ?Uskzq maL| gH#w3kK߾v6P yvv4^,.-?col"q%gJ0(nYw6~d?umD'o%0ׁO> l9!lƲvƧ!xaW憺M[Ӵ #&{:ylon:L29x?(3PuKq%\5P[ {W.[0iPyqc, ؐ3! Մ7,kh_Vͣrŗē?߅5!od="cp/;t%Sgu(&7U_%PWSRT\@7/B&{u; fVPegI(P.9F;Iv' xײs]o疊{(+ Qz_$L43ʯ/ׯ@Ս "W:k}`iczЃƐmB(Ps}'!}h7W6EqmV&J$.Nß 'kbYw˦on!\؄ FUxI\f 7ضcYgnڹ6|͡ Ysfl, !J;S=1vw j")s xt"E8k1n6=\^u;u]f=i?ڸNE5ԣKGSώL7+a* B%,+A$_\+[dGjfQnrPD>cOD{Vua~x[SiFhZIEn^pevT1,+L~zh[Ύo[X <] V&jP;Ud܉q,gΓl; aCi ._cŽ86LW&hKg3ړ ;~nƳV"ۈzA0a3hvmt,JtA'/d{U«/=եt;N΄mG,uLlpÇ EPS:PXIݝAn]i}Cv_P]ٿq~ubT&UWK˧}39(6ؾhN*Ԧq^;%TE:"\ \HXA\E?hn̮ hk\q >xgJ?)lu;c$b [d(4(- ` 0-/@t\(|JQhtf֔?-KVt}<ΟM ʟqn¸]@$+Hؕ30|+>LS3h0E_'o+n-M LXnPh]I φY1|BPB-PU|p2+څp&q0| -Ps!H J%]It282+dWV0l 4ýGk :\Qm͒Cӝ[#CY+V`H,7ի$q|Q"&{9OK'[@0_;Ǐۓ*0 8J*.i$刓1@3'.eh@Jo@V="( m1 ϓͮ7R%s'(:8# [!>mA rQ OF3χ2ܮjR`n?34٥%80Bʤ S8 0bʝWqQawgbi q?9S<^6/ 3Ԓ:o vQ !x#. J~G$5>>jfظ6]h(kh>jOc'l~-ݧ16u*Y +\9pFz}8=BbW%&hsy*$֨r?=ҙF`߫+=)jȼ ?&-n@5 j2D.{[GLlơ ~ّ`r7W3}k(3nw \':;nb9jZH-_eo 5ɡK+D$Ƙ'{Ic (K;RfY)gMZ^u -)06FkjIY0n*K&)顬P%r})rbURvu'~!O@0n.7mE:L1&K=lBăq vRf3] "& nc$n}p'4@+॰_c&.1\1 _ЋO Ӿ1TEa>r1';!Hccr}ܧCG0Up.)q8'ynD^/cZP`A1,nTS0#anB((SAOOxTgxWAw`~CUE¦TWF}Y Mãj8FR#iusR9! 6 $ ʿjP<+AU]zW@"MGT,OFыD\"^xĒ(uB5yև>,.._?.1uBsX;┶TTgL8Q})gc0l\㯺-..H/ӗ2\>8'OZ*պl k5uofsXc{ @t>ۿpgMݏ!] bZ1֐r$ Mk^ Zl:Yn>?|Yxp(ov@ccq^Z\$RJ{K\Bgkq;|+evyONQ\}{3Q77ģA{B ш6;׃Hf*թ BeD/PkM|w/8v Ԝ>#bydL尼V&Ԛx,R~[f]R$S $Fz*~9:T=42n(޼ !BVj'`LGw}KOKЬ Z޶rH-5KGikSB )$|T,?ϙszT%-*ui_\QRCbijWYKzZ}H 2lgYHS 3؎ȅ,!UJs;|I͘#=y'*T.R~yKs,dӃ7KQ+ר9;L? H rfZ~3omp˽LS'H#zYj+tZ#Fw ţ$Yij:AV/ c,JA,pyl9Kn#4*kԖQ+-TeESTvhϭ˲thq޺\hJM:G K<++k5ScY))5eY໺e#i4mz$5dR);H&]x6CیeëT\§8›_ʶOKԼ&ƶ{)1!ƘKqhzóH!Fa+{Hc,RJ  Yhb w=,ͬ\H1`zEZ-P Ot~0'=DBf+LAmoZRHBJePcT)$V[XkOH)9`:bk()̸=dbQ3.7ṣϿN Ozb"PhU|{ahq SDe6Yac aG|a ִM[lG$Gf'x- Ͷ4j6mN` RhnZh*s:kGδ/ֱDw_3{"Z%ۅjxC&Ҵ&Ri\Ul>S5\(ݼ|tR j%C4ʌr,+df() ,LIYmۚ ; GVc֥Pϟ|zǍ;LѽV΀`Cs:q$lS ړmo8:13f E!D4ɧ#^ZK({,hV/FFhhgKd<݂a-;oA !(e@fgvmoHVc-Rپ&E 'cCZ%"ORnE,Zw:^fo77kO?vMb|il,3p"댛9? E!ƍIZK$ڙ3uw8JZieݎ6ւ-m^P~7Lǎy~čEFr$#gR֩vmz?oSd#&;pfo5p";#{D#"PNbFeG[Pk_mlU }ֻ9T?WV0'_[߼㵰xq\IH!i4ZQ;n6Wr_&][:_z`4dxT2D>}!qTbNoK ֽ}'OW@x7>[s&HDz:E )R%Q*B\Q+szAcS1}{?鑘XBI9I%Nēct$ J9+5U5^Go~RnKj MI~6-J(G^k7_={0VB|njib"0nk}[Pj͏=_͊^=pbA$jIENDB`mudlet-2.1/src/icons/document-properties.png0000755000175000017500000000451311513237311020601 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org<IDATx՗ pTwwn6 BB$ 0V-eeʳD@P aDP UŢ#d塑 d$Wyߝ;z&39&9Y6 hM=b2ѣG/.((r,AօO/Nڧ%|СCÏ=:^vx^$%@u)VL3Wc3Gva/졸Pg z&PǨϴꨍc!an\Jo90dYp_镤2Osek[H(xGXVJWXJn16^Ƒ-[rfQ.⿥M 5}8d-#cz#_W cyre7>90@o @_DŗůE]ʰᱫ\yЃC1PTcIT1&4еSהּ`KNߔlь  *"j.zvdH󜝔d;rn!7{ܱtUQ+FGčcdsR.b5w g'v[Wf\-A54Y6ugzskLYIn.YobK)ޏ]Zث& M$^ɠ dlŞ:d b"U|3>~>MK06g $5ǠZvUmSY3i10CZz#*ʧ!ť肓齙U\–Kf.b-q1-b%hhXZӱjRX ˸<ĔgRbObZN#س`lwx՟3]MBU~ƍHcu^wZcH:Tf0tX?g {%C5wF? ev;*uҫ9x&R$q}%`nХS<'70hd@ % a{(g]Fm&Κp7h+  Q8οp:Ⴭ 5{ ]B١-dFB>p}H,ҋN g=KbN Z,EFA:uƍB B+`ߍ>2XtR;?酳_2~LZxaQ6s9?\^p8zNۨ6: }ݗ÷u"NsZy̚Rߵ p(.bq/z 7` 6kll$yJpl5a#F6^selfu&u +/>ԉh= O,;f3`~2|~rX&>>GR>;mM`:ȾkM۸`O.˕y󷖗*"a,Ӌrz{JȦk] PJ<| ~ ʼP(妲R^x[Eȳ`2uLV@SSSOIIb-َ}2}hK_UUI~AÇT#G0p@(Bhvu"D*gdD߸O "s<%@QV##[|ѻE#tIlVuŠ-# Qz>??_B!O7*Jde%ߊ߁R}ƟaG34?o'Sg^{I xX2y5򲏀2n~]SSS٣G7 0ZA(,49̙J9awI]j2jMV8a5VF^U9ǩc l͚XZR[}#/bڧ:|jd܌:IW)puPS%@&IENDB`mudlet-2.1/src/icons/generic_mud.jpg0000755000175000017500000000164211513237311017046 0ustar csmallcsmallJFIFHHC  !"$"$Cb"/!1A"2Qa5bqs ?(19$u"VNO#;zuܟn_ƄbYvKR߄Į<@yXŊ*4dX0+a꧵Ѹ>řγ4pޑWQʠ{y9{z튼I?d2$A$muxUf?O9fx+C1w}0UwTENlĆQҊis֡?ekU0{?^sB:HѕA^4]e> D@QUrI>9;Cdlu^HS<3$1K3ccc^qe+j 2PxRGG@Jf SzJ$^ؖ6d璝|nNX1Z˰ڗmE\İ׆!۹@I<*'41 `U׹*C)|ٌ ݭ=uhMRM܎ !HcrW,[C*`Q ] {~Bzvl-ݰlܷii TUTd000?mudlet-2.1/src/icons/folder-violet-locked.png0000755000175000017500000000760011513237311020603 0ustar csmallcsmallPNG  IHDR szzsRGB7MS tiCCPiccxgPi CN% 9' Ef00!+HR\pu (DA,ʺ܌~>ݗۿSvxWN$`C<WfHh4 *b%R$L, p, g>nOe< ""@=8">HH!R4 mH2C<APL DQbT5$ՏD-hy.AǢ t}=F`0 & $`r0ŘØv%0f beXk6-VaOa/bG8"N gsḸ<\׋xu%oŗ=;i2AI&6U HT!ZĝJiu$J!9I}K7d2YlG#WOhbbbb5bb#b(x:ŞMܡ̋5#ŷ׈_IIH$KKHܐbTg*O=FB!4U#MMk]M1tM;=^D>D_JHIn g ;#Q8c|R+&5"$-'m'-](.=*Q),(_K,JVGO6KUy9[P#yX^G_>GBByEbbbMF)^\ $ӞĬd3ݔ3땇U4UUTUTY1} jJjjjj,8CK{44f5555[5'ZZZ Z1,Dwu`S8;naUUV2Z&^y]  |145L2l4|lD5031Xǘm\c|5yW6569bfmǴϬl\<¼|EgY-;,[|4Lyx'֪>>|j{o?nӺuJjfQƒ˂!!BnʆƇvaš;?~:4 |l-nlݘ&ʦMg#-"}""ܣj؎C;N9g.:,z&:,f6:@\m\E|c|uD+IIɸs\*7ۿYq)))Tԃ +(--[u:}<Uݕ;~[vh{;wLtyraWyyeyowWߙ?b=V{~D{~),2,(T.O?7TbVrS-odDYv7QaRQwp(ҫJSu\hCM{|ڥÜ#G쎴)}<Ak}gFC1̱c7765}>=?ټEnh;~N?wշ3ڋN_3}gYg~UQ un\wv8co'+ yЛ߻r1⥔Kc/Om{|%~W_sve~uoX8wu٭Aۦ;̆:kqgxp{NwktX؃q΃هI_?|xzO~oƿ049lݳS쩗i:9yŌL9/ֿ~ryO?k_i/B_^]F͉&o}K~T^?,g}~痉 \@"D. r \@"D._ .6Uh@ {d g"QzTXtauthorxH!s)IDATXW=lEb;JE@HED)](EDA *~T(U" ! "cov^rg[$k޼oޒ1Oxʇܾۍޗ @ݍwtz1 * 635\hO_ҍcc yO|1뽦_?$!4N|~`t&MI< `c N07~v $9&7qf:ljD(IO@fR1q)`g0j,ı!`Bt_^Ulel3!BH-k\8 8!8!1} +7tn5A E!GR(8Tc>qc y x z3]7qM [7X&h8rAt\'${m6ݨ}ׇX/g{~cX6˄d5 к Rz")>K`yĭZy:s!|tQ[[21.04nN,Hv1;=h3 8n'ʳ) n2 2N"RFc %aUWaFyq8<;O ,g] ,-kJ9c\cE/_;Ě$}ږ`\ &_MtZ[ ^(JkJ8h4$ 9cgrd ⅑[[ۅ Â'6LW!%zj{hw>/h>x㕅>;}65&K-Li{ 8xW]t#eZp=>3KUmb@5WM|11J9@rCh%sd!9D]w-?P1{jH|hbӕ/OJAE^9X\]^r%Niimo.s8Mz=TXlYA?VĨ4㶀!/'Zv?3Lr;z"7}{-Ik ^\/mu?IENDB`mudlet-2.1/src/icons/edit-delete-shred.png0000755000175000017500000000567511513237311020073 0ustar csmallcsmallPNG  IHDR00W pHYs^tIME  ;#^bKGD JIDATxڭY pUzLr'$L.p0. ADUwǖ`Ykm XBW*X(P!hD I9LO2=yeo̤{@46bSO=5g̙ D7BL.///`$曛^qR)>}}}}텅H%~`͝رOH|e[켱nݺyf4Ljkk$˥Լ # #L(bի+(W\ad8{V&F+fX&螺ە^}ԩ&:a"ƛ;w|ElmmU2gOOիd+X +~g *|>A`f(nz}M6W!&eM6eǎdffx^Ae-wLL ot8lN|Gm 8~G=o`pp$^p:NKM[60Z{ر8EtĀ---ms>faW'0ь?Ϲ(سg[li$i """%%%a+\8'7 5gҤIS&h%QrVU}EGܵ~2*Tӏ P3z1ߏ3X2{2\FitAR{@#?#<ǵ5RSn!hX1 &9FX(#5 \}0<%(Ղdai B 㠹0 5 h h-{Xs n`)$J!eQF@} Pd*F=>"ܔ[\b"##54F4>z3`yҊT9Iv A;ڡ7`tG@ z#tK%GQP:rDIBAQGp !Xa((i"WJ"+ő)))#AO ^ɬBX3u?1UVAψB%/ڂVf~?J|t/f`ڜ EQ3WyǧP"Q4ⵆ‘3ԩA0&'''ƆFAM]y=R3N`VCp">ahS'T ޵&MMr$6ssin P&Eﲼ @L gΜ?̜ǀŋ=xމŹy#|v-I > &O|\w L g@!/m=͡DFmu>Z/ (3|QWqF"eue”_ޖ70 2d.2.^r:FO߲gWՅ# "w,xybJQ80)謫loԢ9$u˗c`vǠN'\1?!\ ׍Cc27 }7cKMOi2wpiFҶjժE&$>mc 9 4w5{a/΂kA 1Ok'r[up̮6+DC'οo畟h e@_+**R'LFL nlI y-Ɂ]WKF\Mm=; ̴+ILpt6]D-ldZLMhy7 jD/Ȅ'w7/ȄL_E%HJBW$G$˜:/[%p0geeΟ?GJ(dM&μLJ| L|6D>|^q]R |4A>R̾~m5lV /y,)0ČbuZ/u-yK'zx֫s xP*=jbg_{׮*t ]1׵r{…8^7A]#ى(JEr3-` w֜[rP^K'Lwygv-qĪRHѝNn|r:| K ,I10˴| kŷC:; @ZX׬YCde#72x;"nFD#/ĘI<3w K@GlﶗæJy~Zkz5"kaH0Yqm@=RG:ᙿ~(?Qu+i$#+➲H1y`0٦"a---\D0~^8a۲Hq$=d܊ߢjb[\K6wck8 }B6?;\7v" <"˭J2 6(K0 LYlzO[\z?xM-޶Kqn#Q_FYgkESCBL=v޼yf7n#==N?<'$ħPu2zev:v.@-(NGBƭk$BPaeHkV`h9vVIҐB@Xot|||ޛEƲ {UDz\m[ײa[+?/o(n1u9y9ϮaĻߟF.<61Zϝ;NƲ&Lh|RUDۜI 8z{"$ILWTt}.\MAę2fb#Kčr `k\ũ>eYB}\9˃IENDB`mudlet-2.1/src/icons/lusternia_120_30.png0000755000175000017500000000361411513237311017464 0ustar csmallcsmallPNG  IHDRx*tEXtSoftwareAdobe ImageReadyqe<PLTEycccIHIbqiqrrjkk]ggܙ*'(ZZZº999nm{ySRR钬|||t|{񲲲rs~mtt䄚ajkͭңtzv~yۺ޻ꃙdtt ߟؐj~W\[|hwoMQQuꄟ^meZdbQXWv# |gnoevwhhhY_``__0..xvxXWXB?@hy|MMMDCCnnndee>A?=>=PQPswvɮQQQFIDATxđSXQ¦6D (oh'T[ACiV} `ѡݙ~ӨSI:Y9d2gNq<{fqavo)IÑJi>h,Ì~;-߿ OYy8ˎ7#ahJlj%#zH$ZxZ~*dgJyM ytvX;4=>azSi\#wG>G!l,DFcc56LAa}Ձ7:a:#yߥHbb(Fnx&7l!%owzS,oHhf$Na$[|Ԡ}->Ws&rxuX072yշS̙,)rM?ϒQ gs+B+(- 9X\֑,vG9`J/+2υ5E"b^_Pmj>UdjsG[RjG@&qjlL3r+J=@Q9,+ S5BFvS HH=!X7nwo GU!=VqGfBgs$ؚX[kJQZB=םl3y|>vG`B`$5Y/f@J0#W:Iʬx5Ü$es-݉Q o${VgoYdkĊQ3_;-=_ kф og$-taWeQݞp԰jZUN "+ T|O A3+jzSRսjIs'b0'H\߹vi:z;צ*G/~QE];dhZ?i/tNĢE xlXvyLlY`XC`E/:1R?66i0l!Q'X bdSǦǰf=/q$I\:HREM\4X<P`M#ئ5 ɔnPtf6c!-RHPe_JmYťߚ"c,/:?}} ^b`ǽ  (uw.VkwE -f^6ĺeaK/G_Rp07^P0AsV*WւٮX~+tAE.`gl|.B 4OwwB/àiqY G?Чn6*^Y`Zi+RtB.81B/Yu{eLj!~/F HQREʴ6Uv& zA swrɪNZ+}{~YϤh^WѬ,IENDB`mudlet-2.1/src/icons/edit-bomb.png0000755000175000017500000000314311513237311016431 0ustar csmallcsmallPNG  IHDR szzsRGB pHYs7]7]F]tIME7'bvG&bKGDIDATxڵVKde~|k D CBdD7mxa@u7A]llbAm&"j:8̨83=tft݋^x8=y5eæ}_)[ß\Z/o.iNw?_{---t:=H$dL&Әv=v|%%%ӣ]ְ5԰xjooW hS`PB!U]]?dW dEggjjjRgggJ۫ 8>>EijkkUww\Fbjz`^㪧G+L*--U^W9N)Pu~~w]TYYZ\\T[[[7{CCCl?7.H\uttVxtR̹B`Jtg(0 uzuuppAQ\KݻҩW4۫r6M Pa!*,GQuz:D|+yZ 㺝X:i̜zJё@w&PVbM>_)֭[Q-Z2/..XOl'f㥁o珋 BvU"qJ2Z0eONNDa&f@w cH(zpǓ$'!I2%"L[!ֱO| ߟ"W9 ƅƁ C+INW(mv:6q뻁}6̞, @6"@) Đ8)B.&5b!E0(3aB"FHl)f!' [f,a@%XVLtTH9'> iGS l ARɜ"f/X/lY.*p8""B\( O2W ikk‚/E6{Q$Nt܏cq877W(~Rf_ f1BTlMvWr >²'1$6 8 Yه[]]]!ex~d$ۑ"D@BlwZXTl|\ isVق)d?_uh.peL27~?ԬHQ\~ %@-oXmؘԓ/%Yǂ;!#|^Y [u@ Ў2ȼIa\Ra[N,V D2 n'`VDV ($crjl%oXN1#h@Z12?F[Bɍa`&q9PjdYk Hg1p<"L]@i|U@R#Ln]W ',s:-&"R&;:B<,IHNz OvIENDB`mudlet-2.1/src/icons/view-statistics.png0000755000175000017500000000176311513237311017737 0ustar csmallcsmallPNG  IHDR szzbKGD pHYs B(xtIME 8IDATxkGǿoެ#9\JϡA%4iDhCc9z1 qq &J1&uٵ_nIcC-sh07~?yBxo:o(sp+ }s]j=rş wZ 45Vpu몑8Xkw@Y'\es>r d%L pYt,`%ϔ<t_[}DU$B-r;z]pLxWa2@1fyuA䜧p #8W1 ݏ IhR89sP D n֌M $eM<{͛EaWSge%2tpd$\XYH ;/^.pT7~GOf%r8AhC4 eZ[ ";YHEt`ξtmP%&šwܾp4RtI.HW0y3Ra !;)$ٯ ALe=km80-{"ݮn6eN䈯`ly9B1>IHlnu:K b?߄ګW33YXhݾ^"!'+ ,6>XbI3k{wfގ1[WX/G `^F C4lnY!MSX"BY$I|Kk8e-shAdb dB!(y!' 4C+v OE=Gc%a1jy/c<`g)7TF\K"e5مt:2. *L9" q,1 "DrMǼQ(`{{,]W_Qf*Tyj6<l{jh_DN`J* *ǿ@DCjρ' &_C);f_ۅx_2^V!B,}`<y?*8ts HS6T31֐ ݡm3Ԍk&Da%0IENDB`mudlet-2.1/src/icons/mudlet.xpm0000755000175000017500000004504611513237311016111 0ustar csmallcsmall/* XPM */ static char * mudlet_xpm[] = { "48 48 883 2", " c None", ". c #D0A352", "+ c #CFA352", "@ c #CEA150", "# c #D9B670", "$ c #E9CE9A", "% c #E8CC98", "& c #D8B46F", "* c #CDA250", "= c #CEA353", "- c #CFA354", "; c #DBB877", "> c #F7E7C7", ", c #F8E6C5", "' c #F7E4C0", ") c #F8E5C4", "! c #F6E5C5", "~ c #DBB775", "{ c #CFA356", "] c #CCA250", "^ c #CEA457", "/ c #D1A75D", "( c #F6E1B9", "_ c #F6E0B7", ": c #F6DFB7", "< c #F6E0B8", "[ c #F8E5C5", "} c #D0A75A", "| c #CFA658", "1 c #CEA355", "2 c #CCA454", "3 c #CDA256", "4 c #CCA254", "5 c #DDBA7C", "6 c #F2DCB7", "7 c #E9CF9E", "8 c #CCA253", "9 c #F6DFB6", "0 c #F5DFB6", "a c #CDA353", "b c #EBD2A3", "c c #F1DCB5", "d c #DCBB7C", "e c #CCA256", "f c #CDA357", "g c #CFA355", "h c #E0C085", "i c #F4E2BF", "j c #F7E4C2", "k c #F6E1BA", "l c #F3DEB3", "m c #CCA152", "n c #F1D8AA", "o c #F5DEB5", "p c #EFD5A6", "q c #CCA255", "r c #F4DDB4", "s c #F6E0BB", "t c #F7E4C3", "u c #F4E0BC", "v c #E0C086", "w c #CFA459", "x c #CDA558", "y c #D0A75D", "z c #EED6AB", "A c #F7E5C4", "B c #F5E0B8", "C c #CDA55A", "D c #DFBE83", "E c #ECD19F", "F c #E3C48C", "G c #D9B674", "H c #D9B676", "I c #E3C58C", "J c #EBD1A0", "K c #DEBD81", "L c #CEA55C", "M c #F5DFB8", "N c #F6E4C3", "O c #EDD4AA", "P c #D0A960", "Q c #CDA75C", "R c #CDA457", "S c #D6B16D", "T c #F4E2BE", "U c #F5E1BC", "V c #F4DEB4", "W c #ECD2A2", "X c #CBA45B", "Y c #CBA257", "Z c #CCA660", "` c #C6A366", " . c #BBA16B", ".. c #C6A465", "+. c #CCA760", "@. c #CDA359", "#. c #CFA860", "$. c #ECD2A1", "%. c #F4DDB3", "&. c #F4E1BC", "*. c #F3E0BC", "=. c #D7B371", "-. c #CEA55B", ";. c #CFA65A", ">. c #CDA459", ",. c #CFA65D", "'. c #F1D9AE", "). c #EBD09F", "!. c #D6B26F", "~. c #CDA55D", "{. c #BA9E6A", "]. c #A89776", "^. c #ACAA8F", "/. c #AFC0AF", "(. c #B3D4CD", "_. c #AFC0B0", ":. c #A99B7B", "<. c #BA9F6B", "[. c #CDA55F", "}. c #D5B171", "|. c #F3DCB2", "1. c #F0D8AE", "2. c #D0A761", "3. c #CDA65D", "4. c #CFA75F", "5. c #CDA65C", "6. c #D6B270", "7. c #D2AC66", "8. c #ECD2A4", "9. c #F2DBB1", "0. c #DCBA7D", "a. c #CDA55E", "b. c #B99E6A", "c. c #ACA485", "d. c #B5D7CF", "e. c #BDF8FE", "f. c #BDF9FF", "g. c #BAA06C", "h. c #CDA761", "i. c #DCBA7F", "j. c #F2DAAF", "k. c #ECD2A3", "l. c #CDA65E", "m. c #D2AC69", "n. c #F2DFBB", "o. c #D6B374", "p. c #CDA860", "q. c #D1AB65", "r. c #F3E0BB", "s. c #F3DDB4", "t. c #D2AC68", "u. c #C8A566", "v. c #AA9A75", "w. c #BADDD7", "x. c #C1F9FF", "y. c #AA9A76", "z. c #C8A768", "A. c #D1AD6A", "B. c #D5B272", "C. c #F2DBB0", "D. c #F2DCB2", "E. c #F2DEB7", "F. c #D0AC68", "G. c #CEA85F", "H. c #EFDAB2", "I. c #F4DEB5", "J. c #F3DBB1", "K. c #F0D7A9", "L. c #BCA06B", "M. c #ACA385", "N. c #C1EEEF", "O. c #C4F9FF", "P. c #BCA26E", "Q. c #EFD6AA", "R. c #F1DAAF", "S. c #F2DCB3", "T. c #EED7AE", "U. c #CDA963", "V. c #CFA861", "W. c #E0C48E", "X. c #F3DFB9", "Y. c #F1DBAE", "Z. c #D4B06E", "`. c #C1A36B", " + c #B2B39D", ".+ c #C8F6FB", "++ c #C8F9FF", "@+ c #B2B49D", "#+ c #C2A56F", "$+ c #D4B172", "%+ c #F0D9AE", "&+ c #F1D9AF", "*+ c #F2DCB5", "=+ c #E1C38E", "-+ c #CEA866", ";+ c #CFA962", ">+ c #F2DDB9", ",+ c #F2DAB1", "'+ c #F2DAB0", ")+ c #DBBA7F", "!+ c #C8A668", "~+ c #ACA282", "{+ c #CAF6F9", "]+ c #CBFAFF", "^+ c #ADA383", "/+ c #C9A86D", "(+ c #DABB81", "_+ c #F0D9AF", ":+ c #CDAB68", "<+ c #CEA864", "[+ c #E3C693", "}+ c #F2DCB4", "|+ c #E8CD9B", "1+ c #CCA864", "2+ c #AC9B76", "3+ c #CBEEEE", "4+ c #CFFAFF", "5+ c #AC9B77", "6+ c #CCAA69", "7+ c #E7CC9B", "8+ c #F0D8AD", "9+ c #F1DBB3", "0+ c #E1C592", "a+ c #CDA968", "b+ c #CCA762", "c+ c #D7B679", "d+ c #E8CC9B", "e+ c #D2AE6F", "f+ c #BAA070", "g+ c #C0CFC3", "h+ c #D2FAFF", "i+ c #BAA373", "j+ c #D1B173", "k+ c #EFD7AC", "l+ c #E7CC9C", "m+ c #D4B478", "n+ c #CBA967", "o+ c #CEA965", "p+ c #D7B77B", "q+ c #D3B273", "r+ c #CBA762", "s+ c #CCA965", "t+ c #D5B476", "u+ c #CBA96A", "v+ c #AB9D7B", "w+ c #D5F9FC", "x+ c #D6FBFF", "y+ c #AB9D7C", "z+ c #CBAB6E", "A+ c #D5B579", "B+ c #CCAA6A", "C+ c #CBA868", "D+ c #D2B274", "E+ c #CCAB6B", "F+ c #CDAA68", "G+ c #E9D1A4", "H+ c #DDBF89", "I+ c #CCA866", "J+ c #B59D70", "K+ c #C7D5CA", "L+ c #D9FBFF", "M+ c #C7D5CB", "N+ c #B69F73", "O+ c #DCC08A", "P+ c #ECD4A8", "Q+ c #EFD7AD", "R+ c #E5CB9C", "S+ c #CDAD6E", "T+ c #F0DAB3", "U+ c #EED6AA", "V+ c #CCA969", "W+ c #AC9873", "X+ c #DDF9FD", "Y+ c #DDFBFF", "Z+ c #AC9874", "`+ c #CCAA6D", " @ c #EDD5A8", ".@ c #EED6A9", "+@ c #EED7AC", "@@ c #CDAB6E", "#@ c #D5B57A", "$@ c #F0DAB2", "%@ c #EFD7AB", "&@ c #E6CC9A", "*@ c #CAA96E", "=@ c #B1AB7E", "-@ c #CCF0AD", ";@ c #D1F3C3", ">@ c #D7F6DA", ",@ c #DCF9F1", "'@ c #E0FCFF", ")@ c #B7AF94", "!@ c #CBAC74", "~@ c #E4CA9A", "{@ c #EDD5A9", "]@ c #D2B47B", "^@ c #DCBD88", "/@ c #EFD8AF", "(@ c #DCBE89", "_@ c #C0A570", ":@ c #BAC98D", "<@ c #C9EFA5", "[@ c #CAEFA7", "}@ c #CEF1B4", "|@ c #D7F6D2", "1@ c #DFF9F1", "2@ c #E4FCFF", "3@ c #E3FCFE", "4@ c #D9F7F1", "5@ c #C8F0DE", "6@ c #B9EACC", "7@ c #ACC39E", "8@ c #C1A777", "9@ c #DCBF8B", "0@ c #EDD4A8", "a@ c #EDD5AA", "b@ c #DBBD88", "c@ c #CBA86B", "d@ c #DEC28F", "e@ c #D4B47B", "f@ c #B69F70", "g@ c #BCDB91", "h@ c #C2ED9B", "i@ c #C3EE9C", "j@ c #C4EE9E", "k@ c #C6EEA0", "l@ c #C7EFA2", "m@ c #C8EFA5", "n@ c #CFF1B6", "o@ c #D9F5D5", "p@ c #E3FAF3", "q@ c #E7FCFF", "r@ c #E2FAF9", "s@ c #D2F3E7", "t@ c #C2EDD4", "u@ c #B1E7C2", "v@ c #ADE5BD", "w@ c #ABD5AD", "x@ c #B7A175", "y@ c #D4B780", "z@ c #ECD4A7", "A@ c #ECD5A8", "B@ c #DCC18D", "C@ c #CBAC71", "D@ c #CDAD6F", "E@ c #E2C695", "F@ c #EDD6AB", "G@ c #D0B177", "H@ c #B19B70", "I@ c #B8E48D", "J@ c #BBEB90", "K@ c #BCEC92", "L@ c #BDEC94", "M@ c #BFEC96", "N@ c #C0ED98", "O@ c #C1ED9A", "P@ c #C3EE9D", "Q@ c #C5EE9F", "R@ c #C7EEA2", "S@ c #C8EFA4", "T@ c #D1F2B9", "U@ c #DEF8DE", "V@ c #EAFDFD", "W@ c #EAFDFF", "X@ c #E4FAF9", "Y@ c #CBF1DD", "Z@ c #B9EACA", "`@ c #ABE4BA", " # c #A9E3B8", ".# c #A7E2B6", "+# c #A6E2B4", "@# c #A4E1B2", "## c #A3D9AC", "$# c #B09B72", "%# c #D0B37C", "&# c #ECD3A6", "*# c #ECD3A7", "=# c #DFC492", "-# c #CDAF75", ";# c #CDAC72", "># c #E4CA9B", ",# c #EDD4A9", "'# c #CDAE73", ")# c #AB966F", "!# c #B3E983", "~# c #B4EA86", "{# c #B5EA88", "]# c #B6EA89", "^# c #B7EB8B", "/# c #B9EB8E", "(# c #BAEB90", "_# c #BEEC95", ":# c #C0ED97", "<# c #CBEFAA", "[# c #DAF6D0", "}# c #E2F9ED", "|# c #C7EFD8", "1# c #AFE6BF", "2# c #AAE4BA", "3# c #A8E3B6", "4# c #A5E1B3", "5# c #A3E0B0", "6# c #A1DFAE", "7# c #9FDEAB", "8# c #9DDDAA", "9# c #9CDDA8", "0# c #9BDCA6", "a# c #AA9770", "b# c #CDB077", "c# c #EBD3A5", "d# c #EBD2A5", "e# c #E2C796", "f# c #CCAF78", "g# c #CBAC6F", "h# c #CBAB6F", "i# c #CBAB70", "j# c #C8A971", "k# c #A8AB72", "l# c #ACE87B", "m# c #AEE87D", "n# c #AFE87F", "o# c #B0E981", "p# c #B2E983", "q# c #B3EA86", "r# c #BDEC93", "s# c #BEED95", "t# c #C0ED99", "u# c #C2ED9C", "v# c #C4ED9F", "w# c #BDEAAA", "x# c #AFE5B3", "y# c #A3E0B1", "z# c #A0DFAD", "A# c #9EDEAA", "B# c #9BDCA7", "C# c #99DBA4", "D# c #97DAA1", "E# c #95D99F", "F# c #94D99E", "G# c #A3A77C", "H# c #C8A76A", "I# c #CBA867", "J# c #CBA866", "K# c #A6926E", "L# c #A5E671", "M# c #A7E673", "N# c #A8E775", "O# c #A9E777", "P# c #ABE779", "Q# c #AEE87E", "R# c #B3E985", "S# c #B6EA88", "T# c #B9EB8D", "U# c #B9EA8F", "V# c #BBEB91", "W# c #BDEB95", "X# c #BFEC98", "Y# c #B3E7A3", "Z# c #9EDDA6", "`# c #96DAA1", " $ c #93D89D", ".$ c #91D79A", "+$ c #8FD697", "@$ c #8DD595", "#$ c #8BD493", "$$ c #CBA969", "%$ c #CBA968", "&$ c #CBAC72", "*$ c #CBAC73", "=$ c #9EE466", "-$ c #9FE468", ";$ c #A1E56A", ">$ c #A2E56C", ",$ c #A4E66F", "'$ c #A7E674", ")$ c #AAE779", "!$ c #ADE87C", "~$ c #AEE87F", "{$ c #B1E881", "]$ c #B2E984", "^$ c #B4E887", "/$ c #B6E88B", "($ c #B8E98D", "_$ c #BAEA90", ":$ c #B8E896", "<$ c #ADE19B", "[$ c #A2E09A", "}$ c #9CDC95", "|$ c #98DA93", "1$ c #96D890", "2$ c #92D68F", "3$ c #8DD48C", "4$ c #CBAA6B", "5$ c #EED5A9", "6$ c #CAAD73", "7$ c #CBAD74", "8$ c #CBAD75", "9$ c #C8AB75", "0$ c #A3AF6A", "a$ c #9BE361", "b$ c #9BE362", "c$ c #9DE464", "d$ c #9FE467", "e$ c #9FE56A", "f$ c #A2E46C", "g$ c #A4E570", "h$ c #A7E573", "i$ c #A9E678", "j$ c #AAE67A", "k$ c #ADE67C", "l$ c #AEE77E", "m$ c #AFE882", "n$ c #B2E884", "o$ c #B3E788", "p$ c #C1EA91", "q$ c #EFF1A6", "r$ c #C7EC96", "s$ c #BCEB94", "t$ c #C0EB98", "u$ c #BFEA99", "v$ c #C0EB9A", "w$ c #B1B27F", "x$ c #C8A86F", "y$ c #CBAA6D", "z$ c #CBAA6C", "A$ c #CAA96B", "B$ c #AB9367", "C$ c #B49E78", "D$ c #AB9368", "E$ c #8E7E62", "F$ c #9AE25F", "G$ c #9AE260", "H$ c #9CE362", "I$ c #9EE465", "J$ c #A1E46B", "K$ c #A3E46E", "L$ c #A5E471", "M$ c #A6E573", "N$ c #A8E476", "O$ c #AAE579", "P$ c #ADE67D", "Q$ c #B8E885", "R$ c #E7F09F", "S$ c #F6F4A8", "T$ c #DBEF9D", "U$ c #B9E88F", "V$ c #BCEB93", "W$ c #BDEA94", "X$ c #C0EB99", "Y$ c #AB9262", "Z$ c #B59E76", "`$ c #AB9160", " % c #CBAD76", ".% c #E1C89C", "+% c #CBAE77", "@% c #99E15D", "#% c #9AE15E", "$% c #99E25F", "%% c #9AE160", "&% c #9BE260", "*% c #9BE261", "=% c #9AE262", "-% c #9DE366", ";% c #9FE368", ">% c #A0E46B", ",% c #A2E36F", "'% c #A6E571", ")% c #C1E785", "!% c #EEF1A0", "~% c #F5F3A6", "{% c #F8F3A8", "]% c #EAF2A3", "^% c #B5E88A", "/% c #B8E98C", "(% c #BAEA91", "_% c #BEEB97", ":% c #E2CA9F", "<% c #CBAE78", "[% c #E1C89B", "}% c #CBAE79", "|% c #98E05B", "1% c #99E05C", "2% c #99E05D", "3% c #9AE15D", "4% c #9AE25E", "5% c #99E15F", "6% c #99E05F", "7% c #99E160", "8% c #99E261", "9% c #99E161", "0% c #9BE264", "a% c #A7E46E", "b% c #D5EB8C", "c% c #F0F09F", "d% c #F4F0A2", "e% c #F7F3A5", "f% c #FBF3A8", "g% c #EDF3A2", "h% c #B2E885", "i% c #B3E888", "j% c #B6E98B", "k% c #B9E98F", "l% c #BBEA92", "m% c #E2C99E", "n% c #E2CA9E", "o% c #CAAF7A", "p% c #E1C79B", "q% c #CAAF7B", "r% c #98DF59", "s% c #97DE5A", "t% c #98DE59", "u% c #98DE5A", "v% c #97E05B", "w% c #98E05A", "x% c #99DF5C", "y% c #98E15D", "z% c #99E05E", "A% c #98E05E", "B% c #9AE060", "C% c #C0E67A", "D% c #E9EC98", "E% c #F1F0A0", "F% c #F4F1A2", "G% c #F8F2A4", "H% c #FAF2A4", "I% c #FDF3A6", "J% c #EEF0A0", "K% c #AEE780", "L% c #B1E883", "M% c #B3E887", "N% c #B6E98A", "O% c #E0C79A", "P% c #CAB07C", "Q% c #96DE57", "R% c #97DE57", "S% c #97DE58", "T% c #97DF59", "U% c #97E05A", "V% c #97DF5A", "W% c #97DE5B", "X% c #98DF5C", "Y% c #97DF5C", "Z% c #A8E268", "`% c #DEED90", " & c #EFF09C", ".& c #F1EF9E", "+& c #F5F1A1", "@& c #F9F2A3", "#& c #FBF2A5", "$& c #FCF3A6", "%& c #FDF3A7", "&& c #F0F2A1", "*& c #ACE77C", "=& c #B0E782", "-& c #B4E989", ";& c #B7E98C", ">& c #E1C99D", ",& c #CAB07D", "'& c #E0C799", ")& c #CAB07E", "!& c #96DD54", "~& c #96DD56", "{& c #95DD56", "]& c #96DD58", "^& c #96DF59", "/& c #97DE59", "(& c #96DE5A", "_& c #B8E573", ":& c #ECEE99", "<& c #F0F09C", "[& c #F3F09F", "}& c #F7F1A2", "|& c #FBF2A4", "1& c #FCF2A5", "2& c #FDF2A6", "3& c #F7F1A4", "4& c #A9E578", "5& c #ABE67A", "6& c #ADE77E", "7& c #B0E781", "8& c #B4E988", "9& c #E1C89D", "0& c #CAB07F", "a& c #E0C699", "b& c #CAB180", "c& c #95DB54", "d& c #95DC54", "e& c #95DB53", "f& c #95DD55", "g& c #95DD54", "h& c #95DE56", "i& c #96DE56", "j& c #96DE58", "k& c #CBE984", "l& c #F1F09E", "m& c #F4F0A0", "n& c #F7F2A3", "o& c #FEF3A7", "p& c #B4E87B", "q& c #A8E576", "r& c #ADE77D", "s& c #AFE781", "t& c #E0C698", "u& c #CAB181", "v& c #94DC52", "w& c #95DB52", "x& c #95DC52", "y& c #94DC53", "z& c #95DC53", "A& c #94DC54", "B& c #9FE15F", "C& c #DDED90", "D& c #F3F1A1", "E& c #F5F1A2", "F& c #F8F3A4", "G& c #FAF3A5", "H& c #FEF4A8", "I& c #FEF4A7", "J& c #FEF3A8", "K& c #C7EB85", "L& c #A6E572", "M& c #AAE679", "N& c #CAAF79", "O& c #CAB282", "P& c #DFC698", "Q& c #DFC598", "R& c #CAB283", "S& c #A6926F", "T& c #AA9876", "U& c #A7A072", "V& c #94DA51", "W& c #94DB52", "X& c #ACE268", "Y& c #EAF19D", "Z& c #F4F0A1", "`& c #F6F2A4", " * c #F9F3A5", ".* c #FCF4A6", "+* c #FCF3A7", "@* c #FDF3A8", "#* c #FEF4A9", "$* c #FEF3A9", "%* c #FEF3AA", "&* c #E0EF96", "** c #A4E46F", "=* c #AAA176", "-* c #E0C79B", ";* c #AE9C77", ">* c #C9B184", ",* c #CAB284", "'* c #CAB285", ")* c #C9B185", "!* c #C1A77B", "~* c #CAAF80", "{* c #C8AD80", "]* c #93DA4F", "^* c #94DC51", "/* c #93DB51", "(* c #AFE269", "_* c #EFF2A3", ":* c #F7F3A7", "<* c #F8F3A7", "[* c #FAF3A8", "}* c #FDF4AA", "|* c #FDF3A9", "1* c #FDF4AB", "2* c #FEF4AB", "3* c #FFF4AB", "4* c #FFF5AC", "5* c #FEF4AC", "6* c #FAF4AB", "7* c #A4E46D", "8* c #A4E470", "9* c #D1B380", "0* c #D0B380", "a* c #C3A87B", "b* c #C8AF7D", "c* c #CAAF7C", "d* c #C8AE7C", "e* c #AF9B77", "f* c #C2A879", "g* c #C2A779", "h* c #C1A779", "i* c #C1A678", "j* c #C1A679", "k* c #C5AB7F", "l* c #93D94E", "m* c #94DA4E", "n* c #B1E26B", "o* c #F4F3A5", "p* c #F7F5A8", "q* c #F8F5A8", "r* c #FAF5AA", "s* c #FAF4AC", "t* c #FDF5AE", "u* c #FEF4AD", "v* c #FEF5AD", "w* c #FFF6AE", "x* c #FFF5AE", "y* c #FFF6AF", "z* c #CEEC8B", "A* c #A2E46D", "B* c #CDB080", "C* c #CBB17E", "D* c #C9AF7C", "E* c #E6CB9B", "F* c #E5CB9B", "G* c #C6AB7D", "H* c #C1A97E", "I* c #92D94E", "J* c #B4E26D", "K* c #F7F4A9", "L* c #F9F4AA", "M* c #FBF5AC", "N* c #FCF5AC", "O* c #FDF6AD", "P* c #FEF6AF", "Q* c #FEF5AE", "R* c #AFE575", "S* c #C8AF80", "T* c #CEB484", "U* c #E7CD9E", "V* c #E7CE9F", "W* c #E8CE9F", "X* c #C0A577", "Y* c #E5CA9A", "Z* c #C5AB7D", "`* c #BFA77E", " = c #B8E36F", ".= c #FAF5AB", "+= c #FCF5AE", "@= c #FEF6AE", "#= c #E7F19E", "$= c #C5AC80", "%= c #CEB584", "&= c #BFA476", "*= c #E4CA99", "== c #C4A97B", "-= c #BDA57E", ";= c #FCF6AD", ">= c #FDF5AD", ",= c #C2A981", "'= c #CDB686", ")= c #E6CC9D", "!= c #E7CC9D", "~= c #E7CD9D", "{= c #BEA375", "]= c #E4C999", "^= c #C3A87A", "/= c #B3A277", "(= c #B5A77F", "_= c #B5A77C", ":= c #CDB688", "<= c #E6CC9C", "[= c #BDA274", "}= c #E4C998", "|= c #E3C998", "1= c #B19E77", "2= c #D8D196", "3= c #D9D197", "4= c #B4A27B", "5= c #CCB587", "6= c #E6CB9C", "7= c #BEA275", "8= c #BCA173", "9= c #BBA173", "0= c #BBA072", "a= c #C9BB8A", "b= c #FAF1AC", "c= c #CBBE8D", "d= c #C9B287", "e= c #CAB387", "f= c #CAB386", "g= c #C9B385", "h= c #B3AD81", "i= c #C1BA89", "j= c #C9C38F", "k= c #CFC891", "l= c #EFE7A5", "m= c #D2CB94", "n= c #BDB786", "o= c #FFF7B0", "p= c #FFF7AE", " . . ", " + @ # $ % & * = ", " - ; > , ' ' ) ! ~ { ", " ] = ^ / , ( _ _ : : < [ } | 1 2 ", " 3 4 5 6 7 8 9 9 0 0 0 0 0 0 a b c d e f ", " g h i j k l m n o o o o o o p q r s t u v w ", " x y z A B o o o C D E F G H I J K L r r r M N O P Q ", " R S T U V V V r W X Y Z ` . ...+.@.#.$.%.%.%.r &.*.=.-. ", " ;.>.,.'.r %.%.).!.~.{.].^./.(.(._.^.:.<.[.}.).|.|.|.1.2.3.4. ", " 5.6.i 7.C 8.9.0.a.b.c.d.e.f.f.f.f.f.f.e.d.c.g.h.i.j.k.l.m.n.o.p. ", " q.r.s.|.6.C t.u.v.w.x.x.x.x.x.x.x.x.x.x.x.x.w.y.z.A.a.B.C.D.E.F. ", " G.H.I.J.J.K.l.L.M.N.O.O.O.O.O.O.O.O.O.O.O.O.O.O.N.M.P.h.Q.R.R.S.T.U. ", " V.W.X.9.9.Y.Z.`. +.+++++++++++++++++++++++++++++++++.+@+#+$+%+&+'.*+=+-+ ", " ;+>+,+'+'+)+!+~+{+]+]+]+]+]+]+]+]+]+]+]+]+]+]+]+]+]+]+{+^+/+(+%+%+_+c :+ ", " <+[+}+R.R.|+1+2+3+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+4+3+5+6+7+8+8+9+0+a+ ", " b+c+d+'.'.e+f+g+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+g+i+j+k+k+l+m+n+ ", " o+p+q+r+s+t+u+v+w+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+w+y+z+A+B+C+D+m+E+ ", " F+G+_+z H+I+J+K+L+L+L+L+L+L+L+L+L+L+L+L+L+L+L+L+L+L+L+L+L+L+L+L+M+N+E+O+P+Q+R+S+ ", " a+T+k+k+U+V+W+X+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+Y+X+Z+`+ @.@.@+@@@ ", " #@$@%@%@&@*@=@-@;@>@,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@)@!@~@{@{@+@]@ ", " ^@/@U+U+(@_@:@<@[@[@[@}@|@1@2@2@2@2@2@2@2@2@2@2@2@2@2@2@2@3@4@5@6@7@8@9@0@0@a@b@ ", " c@d@Q+U+.@e@f@g@h@i@j@k@l@m@[@n@o@p@q@q@q@q@q@q@q@q@q@r@s@t@u@v@v@v@w@x@y@z@z@A@B@C@ ", " D@E@F@{@{@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@W@W@X@Y@Z@v@v@`@ #.#+#@###$#%#&#&#*#=#-# ", " ;#>#,#0@0@'#)#!#~#{#]#^#/#(#K@_#:#O@P@k@<#[#}#|#1#v@2#3#4#5#6#7#8#9#0#a#b#c#c#d#e#f# ", "g#z+h#h#h#h#h#h#i#j#k#l#m#n#o#p#q#{#^#/#J@r#s#t#u#v#w#x#+#y#z#A#B#C#D#E#F#G#H#C+I#I#I#I#I#I#J#n+", "i#&#&#&#&#&#&#&#&#C@K#L#M#N#O#P#l#Q#o#p#R#S#T#U#V#L@W#X#Y#Z#C#`# $.$+$@$#$K#$$U+U+U+U+U+U+U+U+%$", "&$c#c#c#d#d#d#d#d#*$K#=$-$;$>$,$L#'$O#)$!$~${$]$^$]#/$($_$:$<$[$}$|$1$2$3$K#4${@{@5$5$5$5$5$5$u+", "6$7$7$7$7$7$7$8$8$9$0$a$b$b$b$c$d$e$f$g$h$N#i$j$k$l$m$n$o$p$q$r$s$t$u$v$v$w$x$y$z$4$4$4$4$z$4$A$", " B$C$C$C$C$C$D$E$F$F$G$G$a$a$a$b$H$I$-$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$X$v$v$E$Y$Z$Z$Z$Z$Z$`$ ", " %.%.%.%.%.%+%K#@%@%#%#%$%#%%%&%*%G$=%b$-%;%>%,%'%)%!%~%{%]%^%/%(%V$_%v$K#h#:%:%:%:%:%z+ ", " <%.%.%.%.%[%}%K#|%1%1%1%@%2%3%3%4%5%6%7%8%9%0%a%b%c%d%e%f%g%h%i%j%k%l%W#K#C@m%n%n%n%:%i# ", " o%[%[%p%p%p%q%K#r%s%t%u%v%w%x%y%y%@%z%A%5%B%C%D%E%F%G%H%I%J%K%L%M%N%($_$K#*$m%m%m%m%m%C@ ", " q%O%O%O%O%O%P%K#Q%R%S%T%t%T%s%U%V%W%X%Y%Z%`% &.&+&@&#&$&%&&&*&l$=&h%-&;&K#7$>&>&>&>&>&*$ ", " ,&O%O%O%O%'&)&K#!&~&{&R%Q%]&]&^&/&(&(&_&:&<&[&}&@&|&1&2&2&3&4&5&6&7&h%8&K# %.%.%.%9&9&8$ ", " 0&a&a&a&a&a&b&K#c&d&e&f&g&{&h&i&j&r%k& &l&m&n&H%#&2&2&o&o&o&p&q&j$r&s&n$K#<%.%.%.%.%.%+% ", " b&t&t&t&t&t&u&K#v&w&x&v&y&z&A&~&B&C&l&D&E&F&G&%&H&I&J&J&J&J&K&L&q&M&r&s&K#N&[%[%[%[%[%<% ", " O&P&P&P&P&Q&R&S&T&T&U&V&W&W&y&X&Y&D&Z&`& *.*+*@*%&J&#*#*$*%*&***L&=*T&T&S&q%O%O%O%-*p%o% ", " ;*>*,*,*,*,*'*)*!*~*{*T&]*^*/*(*_*~%:*<*[*}*|*1*}*2*3*4*5*4*5*6*7*8*T&9*0*a*b*,&P%P%c*c*d*e* ", "f*g*g*g*h*h*i*i*i*i*j*k*T&l*m*n*o*p*q*r*s*t*u*v*v*w*w*w*x*y*y*w*w*z*A*T&B*C*,&,&P%P%P%c*c*c*q%D*", "i*E*F*F*F*F*F*F*F*F*G*H*T&I*J*K*L*r*M*N*O*P*w*y*x*x*x*Q*y*y*y*y*y*O*R*T&S*T*U*V*V*V*V*W*W*W*W*,&", "X*F*F*F*F*Y*Y*Y*Y*Y*Z*`*T& =.=.=M*N*+=@=@=@=y*y*y*y*y*y*y*y*y*y*y*y*#=T&$=%=U*U*U*U*U*U*U*U*U*0&", "&=Y*Y*Y*~@~@~@~@~@*===-=T&;=t*t*O*>=P*w*Q*y*y*y*y*y*y*y*y*y*y*y*y*y*y*T&,='=)=)=)=)=)=!=~=~=~=b&", "{=*=*=]=]=]=]=]=]=]=^=/=(=P*Q*t*@=Q*@=y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*(=_=:=<=<=<=<=<=<=<=)=)=O&", "[=]=}=}=}=}=}=|=|=|=h*1=2=@=w*@=@=y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*3=4=5=F*F*F*F*E*6=6=6=6=,*", "7=8=8=8=8=8=8=9=0=0=8=a=b=y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*b=c=d=e=e=e=f=f=f=f=f=f=g=", " h=i=j=k=l=y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*l=m=k=j=n= ", " w*o=p=y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y* ", " "}; mudlet-2.1/src/icons/tag_checkbox_checked_grey.png0000644000175000017500000000072112070466512021706 0ustar csmallcsmallPNG  IHDRaIDAT8˝`0&1Br { ؈`i5),+o@5DAIL!d*̼x|pMӆx<Mӆh`һݎ~.UU) p@UUap\jl[~\W|GE$Izq8rhqHӉS2͘'؁, 2 s:XVg4vjcF|zf:( !,juA:4M\e0e(n(Bӡ\.? R3R1Ay\n~T*aFAףX,~RÐf$If 5$DQeYXS۶mN/1Ȕ9[b([IENDB`mudlet-2.1/src/icons/folder-orange-enabled2.png0000755000175000017500000000730011513237311020764 0ustar csmallcsmallPNG  IHDR szzsRGB7MS uiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}y>UOU x"')6 sg2H1@Nj'^/n@+{,"7 9rcIܕ||3Ӓ(d:_xB^o1x=~B.Gʄ+VO@K_[߯%r8^ZORWxdz\bnʼ|7V_bT|6 HL0t|"YSN:?[ZYIP(U t08w A8 $>9`U4& ΀Np\-p@K0ށ%A2@F O ¡C9n*: :]n@CCh>Ll p gy>Oe< "@]8 H(HR#H7ҏCAPL. @qP)"T$Շ@ͣhyFǠ3rt#}=B`0 cqń`1٘"aLf3Yb2XMc+){39Bq<\.׌ qKxq: n~ A`x.Bp0NxC$UD_bq'xx8A@I0R:i! L ےCi}&S{1WlXXذ+ NldQ)g)w(sxq q$hIE7$fXՉʥQQP'iM@vhWiSt Ew ?TIc@-Ւ$ pc$2gR RvRQR{Zm ۤG?0eddt漲rr K%@%WM*AZګ:楖֢HVU?ޯأѩ1ÒfX-qMff}-[+A]mXD;VZcsXghz*ުUc$];  =^^+}5P_ L   R s 66U_M^zկu?0x15ljf7m55S3 71c>"us,L-,Xek`l9&jMÚI+:+5:F&¦晭-׶vN.+{{}6Kc)驳ss󼋉K%W~177[ۼ6>:*gڞ|n/ZOo_j~~9~h6k^޿qf@z@o %0,)p114H-VlH\HW(6401taLF76lpcč6Q6El: oQY9qr˸QVQQVѥ31V1bfcmbc^ǻ/&x'HXN JlK%'Qy ͊lJIOXL{S ]ity ]3 gHlmتu,٨lNvorήmvC#PݑcjΓv5-};hwwBμ\~hS#Ǹ[KfAay"N͟ iy_b#%^~'K%JJ'x(c=rCC]j%bFjk,>b{VѸ\:5ˏae{}Q I}MfMM-pKz쩰SwvUVxN?_Fx=>5ck|gl+kn~;q^| =Y.%_sywS+W ^z+v[]?ƹ웝Lou 6>h:qN]Ckzm/sw[#kGFF p :"}O#v ^b.(\1r5x_؎e1ҳ4f4o&L–\X'JYY!!O? k߂c2" +<0#pvЏ!%fr\6*ZTaf\Z{ͣ73iFb1p􌵀+ƙ{tR\~LV #pz%0es.nR R/ =_FͯqgPLo6id,R#@8!,>>&0!`VP-wdgI80*pN 8 Y5W$Q;Ld2NM0{"7Z9!{1;g+8Y/#Υڕx JI$H. f Z\¨\YJ4"ҳP?r'7VuRBM@RHTɡT A$m[ߞ88ղ} K{2{؊X/)/`_gE4Jl.a!8cE$ʙԽ -3biܮBP;^^w1[6`?V0u:rU2}̯ bxƩkUTT;jl3o#3C}I!gOOqS9IENDB`mudlet-2.1/src/icons/tools-wizard.png0000755000175000017500000000656511513237311017240 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< IDATx PS? *ܢ(MAd[mEA"nASq/Uu-X,w*"  !w>;Z}O̻3ɽɽ7}?Z#YXX߿>rz(1mh+ۜ&I]yStrP4gOUC] dߩXl< jє;˧?:%=loxxxh}0a„f#0IR gQ,T&ib%D eDD5Ig?A!:sƍg, Z1Yvc~p=>|8DDD@qq1CXXXBw\~$Y"O&U$ddᕃ;I*iI+# wP>UL+L%/Y4 !ԮqkFh{x؜o|Hv32^`̂ ӡ~W'۵dTHgCJ:dWduLNܼd_|B}qrrb=d2&++kҡC^|JKKJJJ 88x_H Hp}!CWKa\Q ks>Gf㋅Bzܹs\x޽ ]1*xDT Z[%321Wŭ͜C](!J$T*ݻ#%%er~~>SQQ47736mpܹ.77R<*iJ`9Lid[nndi2_~||btRM]FXUU%ܼyspnn.1 ijjbvܩ˃B[[?:\;FkWCdN1W$O-﷑T|///4FZOMms>q{8 #ά[Ҿ}?LѡU/%P90+֦w.9qWUB*"* B p8#<( wTKU3S. qw~PSSܼ--^FOP6.T-4z'М1PAh2| G \QM׬Y×~ pRY=L*ٺu\___fȐ!̶m.o#0D ƹ 5%_&pNJ( nP@@O 7=6:t \GpPg2~0-+lQDQT-:[XX(|033Sq@G1>3U4tޝG\iFZj: 'Ѵ䐔߭g {1|… 0_ίv?V1:ǎ7vԨQB\ĄquvL=z46n3xo#^zǭ=N=l/4Hg9úMO`R>J}@iii7o+++Jkjhh(D:88ap`p֮]Kg[-!}NHH&EGrZhb<mˊ X4E0)Ӵ*ub b7OGGgbHH%/'3#PoB`@"~ T_Y=eN ̓קcc&g((3ߎk?("k$մe3 B^'y,rw`Ŝwu[ׂ0.D@zcPF-;Hݑ4LdEw_ ::Z$3>&"oL= ms>cVqͺ)4 n,O7.{E\ *Eo/(mXt6SA\`4~>0hD +ҩCytm[=1%/:xjS(EL9ߣ[" >JMc\hZgPJ3-P-6*cǃcW8Bm@r9L>ZSйy'Mw^ YY w Cv>OӠh04 =u6TT.~砻nHkl0X;/jйsf}35(PPv%QiKMN$666 L}E 00h ,(nN:WL8#Ev֍&O V,ʊB|\+b1"gC%ZZP%K~k`!cǎ齍P64!XzR `9s&˜3f b_t#_QLd͍u,+5nXf _ lhp'/ˌ 0`={6 Mrx)& ,B,\t6\|uLg 68ԕ0Kp`g&MDϗgk#!t7֣%: G9x5f ,JW,`l\j2nǺ!ږ#JPS)St5&ƃG,; ...e5 @E36B7F BmEu`fo2@UB`J{zԧQ@Ÿ--PL81JC=Zpٲe+_̿'IENDB`mudlet-2.1/src/icons/head.png0000755000175000017500000012764611513237311015507 0ustar csmallcsmallPNG  IHDR @`sRGBbKGD pHYs B(xtIME  7+% IDATx,u&vΉȬo+")"EQC"zk 3`?ͯc` 6`ðlHA H$Xu~ݫ*3#"֬^S]j[*32D9;zzD3ND`b01/ Q 4F~֜!^~%dÆI@k6l3:ME&&b&FE F.n7Ez)ngx02HEf?>sݹ1ĉwh ?ْqGI'`<lP}R>\6jcXHUikל)4} `_XJNn=NӫY֘ͱs<mǦM;~饖sͺ4.`X0†I!Uxa"#=!2w(tH8(7"CɌeD;^!BÛJCטm ^2 i/M1t L0|xx +/4Y;aD<\vՙ1pUʃHdmj@آA\7 4 @e3Һ6o$5kD T݊:`Fz6'.L=/?Xrě*/vRi$r2=<Ն)3]`g OtކAva>HAZԄ̦9?$,l'spVTNB5AAKA 1 {:Cy07v> TRCz_'I- X5qPfYrfʙO<0; dWo0XxǬݙk}hn;îS>T.##?g$B)?6cãS> S o:2[ތɺ[%.#3j%7@YFEՖ \6z`17|z_\r:N8f"hh lD$yO U->E*k6~'d{, qP"&0Q#dRV9ģ. F,DR;]wot/k1S-Dq*O1ʊ7%VDVG8 !QAZA~iO?ҵUWʹeJZKUz5;hp@ELa8ռc#FG}f47e҆QQ%} TcytBƲ4RXGX_u 4P vi[)Q,Ƥr| I"TzK U8t `1<Rq?/`3cEWa"O Uƞͼ)OJcx,X|wmhFȲV]VTt1d\T@ qxn#Д j6t x%.kYe*kOwcE6,5L(pmsǒV2tRTWofPBh:g-uTgZZђ!X,QזA, o9V͖*W.opmF|~ۺt@DyNKUe^aV>qZs<_zw&h&U]a%l1d-e 66aW#cp+m'u]/aC㵩+n)j9S+E~ Pu&3ǔ \gAasE 2Ŵ.sa2 O\ 48S|58CsP%57e4ʲKӔ7-j:t0‘(8d|{oFIR|QԼVx1"l8Y`5gq[jS. =.ooԵF#~n}v.cpl;`G& kqPm"<EOWZ6Ѵ:A:W,`wUP((E4.0ʋ`ȯsfG#qz JE\ \:`o5¶ah3Jr|)f?0XxrqJ')kc1Hu,k_Wgdt&|RA26RnaYt\Cgu:Uu8 9J"53Pʤ#i곬 AV.)RPL5%1cjYaXLIl;ZaHE!D8f#1QE+ީ:i0Ght-*WU3VVT*xJX >,b0J&DSHu64)Nnõ<0T VwNZGQ"y (`>3ϛn<~]|',u,*1%Rzr`LdHC}B$ԧ *IO}6zj+w,օǙ d =xqYhLkuM8bN KyP K7?sC;wnY h!6k(b,KUH\HT5nnϑ}eY/K{^ӭ\ pQ?9VU&j4/ilkb"1Z0&)$JX!lAdb7Jr\]/爍)r>2B2f@W0;ڻ6WvaךW⒅rXhGZs+U!.D]$ eBz9HYk?T޹ ݓ£ع,șZl "wzo\y"##H%j hy&!c4|g[, 5Z;Wl[4wY({Ri$E{tP!bȅBI],?9"J3 j|+@$~&;H I<)‘=.K}6~Wl2FEH f0Qc*iȎz{~?ԬQ6D֚n/aaιA{j-?{E ]n޺Oy{$7(:HUEdAϼe3 ë_jEHB,(DWh ~0P((|2rnQ3yǹ`qYeu/[r#6Wd+V>T^$eK!OSM]־] CsF4 .Uzw{mݸ'FX)RǸ~"BӬww_S6 刑OEqZܹQ+|N@%<4vBaOs̶ovUPU0]Jp.?I:#9<;VQVz줤,',UZH TxeH,lR˲.&HƎCQ߷zu,2v7hiJiR陈%6tFiiq@:az_wV{3/8.?TRxY 1j|_2-^9]eNN\4R, IX%.j.y."4P PT3iO^ܹC{WƊA)vm}:<z5=f2jc6XAFc"8]wV,8ح4ˈa!!39[@aw5S3l)h 5* RWt$r?$̦=ȌD^0P*T4iY 5H1FAD"bJ y\ˀ"cǥa$J RT2mTDO]f25W䕑bc J+9kc}+~a,fUKkh2-:FBwYG`-8ȹݖTa1(Ä(ܼ4 sn͡ gA}'y^ycԱlc[mJ2CAzsQ(-bB0‹ â+(HL +|mؾL3X{͜K,9;}|^7_T.C=CF#2s܌;q㺠UgOXZC"AiR_D6'|4.D" "Řؚf LmxҎy9 Vic)bG,61Ƙ\iM!unD+]+n#z Ly+HDB;6lC2;y2HizMR^f+qǹ8#>ws) I)ﲆDLdB /j`"ہ:6LB\k^+{WGͭP!PU -`{MLp\C$I3ΙL&K sfIW}@qV>L$DԋJ,\ϵ7|ٿ?s%`#;|N[jfv: ಮE,#j$fR20s]v#k\}_> M&!9zf'Iwz打>NzI5ןٹz^)%.?N|2+7ؽ#-轗߸t{Fql5 pPx9f×;>ع~t뫀&KD]GYk0q=}- ?}d)Dy^}wZ867vt]I{L 4gZ.g0I|O]jF8AMAL4k4":PWHш"Ҁҥ\μX(*#J|SVD6e0eug}5J]$V*wPi8;zcݽn}狷K6qd1"\Ry쨏^xcEwe[Q_^F;˭ϴoƑZX+@f$9z[;7~dc>|+ާ g!li\t{i_@ԥD=gۗ5b$kk{Ov'U Ua(ʐN[LAs(|ΧLFI2c2,Lȣ}$ο:M3ǃs[U8Ǎ7fLgC3׾uѻ;pܸ{s3}aٺ?t??蟾s+g޵6Lb8vvӋO'7/j퉱d?p+hH;Cʔ6i@P мnTTyYϱK|+&0OJϹnƪε<±NYpMuD2VYcif?vD;| z|ਂgkpx,MDWo~:+^SGvリk6Vv l+_O__?/g;ƥ?ILlT]^2Dmm_Kt!5LDu7#z؀>O 5&G5f$=SuD,&[۬r l@m<.aW,rq?6uN:~˖~[ y@6ې׬PL{E־.)KɻN͕~&T_ڮH+A֋wreF[߹GDus]\(eWS=ExlY\XHUsus1tʼL %4hWV PjYE 9&l{r{$dǚSCE[۝Go|f^H>f-@R9ET"XDWHNY*bgz$\9Ϯ,7~] [2kc/"(w9(O])*hf';bizh7W>o??:n=?}#"45Z#5-?=eU&Uf2P 6$0gUij·B@>؁I2ImieT V")SQJiM[vzrw^Wsxp;ߴ>tn<>^pg ,.z/F[;}yJy򹝧>ܺr}Maԇ-C6ԵMaP vtDA %yv#xxXٕ͙Ȉ Mf1ZWa5*U4׫{ih؏&12)A{wq{Lj$F~#vҾ{;~`٢G_?z/e-1D6>D&VP*b4p(< |ffE9 ӨNb2qYl l5L$ջ'|K{~o9\77y7&O,KOӓów8x[&nt4={^p'~7Y% &[z?\vnONdrJ^B6.JW&T$1@0Ag<_IxHTu.!VKAD <D宠(v˯ogcӘǟn]޺xEZW~V~޻;FwKǿ|g~|~(sizo{'y7ɭN~ßzъ0]tǯ|'g>w~; vW]PFy3Kx874!Y8 603$7]Xsn$(\ F8Ncr6Fr}$NvtœLMyzgg/~>vu%Nn_a3aP֚(6'z^4ID1Ƌ1ٰ0 ,8H$'<>pBA{IDDE#bb>=>=HJx^!zW]b Ll@h6B]6p.@ׅ|߸uJ|7%&a4;ė !cJbfi D IFrXlgf lH6"ɋ˅XA/i Șu%a#& Qi x([Ο94lĜLщ(q4!7ȫ 9d ՗~>{isٛx t3;zWOݻwO!{~Ѹ,>I$nðϲ54۵>K3"_ssju["(H\AN ~-,̆9 (Ҵ |ru.mDT.Mzɛ_>酏TsCk>_%-sB{(0(m^!2VUň!aӈw25Za1'sRn% F̟X$fSh8Yv_LL,|3)/;51Mmm_ eYW}"bU%!>/NPdIrb @:UuTUqZ|я_'|̘ Ve)'Kz;?y!4c~$$717[g.I'lmJBi[!`yNsc?.M0,*Sz֥+~_5X͌OF-;U]&;Zdr1j67Map|w/<yE6x 9gW"bUpXZB0`6 ϐJˢ-Eu$3S ..PPWAҿ$ZY(e^ bDcf,;3׶y|+/~'?Mv1<8n56 ILVFu@prC/ghijGgFObgfd]uN= A8 [[o#9z(ٲvLPJ|׊iFͭ;p!QDP9juVQHxD{Ǣ0*x*tKZ复8 JJKzwKNN'>}y;^Nl 䝷5Kgzıl:M8IҨGx뺤%~M8?ۏ=Y2 l@(k\]7$[y,V P ꠀﵶ.BYȹo_|skшZIŰYR,D.볘6]|Ǹ/[ۻdwgDMDXD@)ph5;aHtbi@` z.W| xQL,n)Yנ`2D6JPPq+Ok WHi]:7^{ h)[S?i{i6ͪ?x5Z%~x_ #ƐfJP꫷W?OɵX o}?>?Gz^<=n(6 6vWbx J^BA" S", 7`]_U쏬힙P7{229 !2"a32D{O{3y c)SxP8Ǒ=b ĵ:mi'^rLl,'fQNLU͍H"Pt;oفhZJE(A(E)ph6Ļm*f&"`)cRƄPTPke"*%˲ auP\F{IQ'X7݆,-E$ޏ̒T"+vuM>qg?dO?̗*C/y ?XmRf%D̙H;pVA $Fd6"v"iMF.ֹ"3h7&ό4A\s9È'dKޞ9O%b6-F *fH/&BTFWNB %Q@vülL uJsɠ,`& f )J%p^. #Y&Ab\8(#x.,MiG!&6A0-0$ PR1-zA9R(DHrb`wX.bpL*IaA-NRF騨^̓D,;3KӖr"W&03I崯\vtGmʐ;;[f-&kH 5}LjAk86J\-N -¿qZgA޿ic[__n|k\X {^:z85Y;O`@׆Mc%VF]c{8wh01Qc_}Q9a9sg#>E]Z^]nyX[BN{6;:r3%W:*="=4ߴY%SN>sX>90SX, ~fٱ}4ӳK~x_×5B3Pun4XZQ!5d !|ύ')m"TJ0d@ L1BO8l y SM|Saƾ[0G*#9m 2rD7/=` '7g~g]*YfX$ERBD F |A&@)h] 7P$@RDtejDAl^`&%Pe`b"h D)eȋKJuZL tzbg4m%b]7TR)Bm(Ed _3Rą@'@8O !H3=ם}DY b v櫲dCpzx+"l뮛?yO?z[;vBa0{}=}6zع_ώV]n?\˲8}7Ϗx{=kk.T_[8uᮻ'b3;b d2~)]8KlafWc;?J6i%ѭ"g"B8N?;w0SD6}߳2JGl_`hw|@Ұ*!V&֔yQ%;jeJ ;GR)gr~sfbSBbmqq:GjJ(6Hw-WJ*!QH!Ѻ3<72iLJa= Dq:cyrv<k*OKPN¦^Jŵ/h %1ԲBT]drcjo[HSrX{]Dx0z“\]1r7`\W%fmC (;7ޫ$u^fj]+bt|D=ziS#bH~|cUlU_)Yu n!v_N·N6'SO}QX$w}~'_;?n<=J]#;z?-o?z}4?=?SضmC072ߘ>sf﷾uoۗ-[Ξ;WZC;NfΝ;+g_}pAȅ%b>zamx@/ yey~͗ya5-{-ݭy7`+ ҕ%e- :_oئ, PrH,{ TMdf4eCJtԪZd %b`5Yw:Lސ-n(!T:B7_(rjc8`%Q1  ,m(C@dpB-,R3dx'b>H00\Q,\Qb.X sX8=X<&TjL1jښW*TLg] P4 5v>?s sh׮X8;9sZf9yUߺuӇV|Eec3GkAJafsp`>X t;n?z3Hsg{eSSz8-7 BJkժ.&cFӃKoɓ'_ SO?{uŽHӃ;w/to6.:oݿxbmixO.j[aLv4k(111ua!6Z1 4VjjTдfJtU)R: s̬?SyL&XϤBek8'b:tUG]bufǦ pE 7M.n-l/Unb0R8 xˉL4/NL@:t" 9X:]$͈aұ:BZd^xVYYtgb>&ܐpap=!qk﹧1LOc^&SsR1hg~_ߛrrR>Ҧ^"W=QqpUC,.%a+Ԛwl- X8J[Ȣ󶾾Zp$ǟ{W9{vȗQVH!G?r^|qfxlナï;-z׭m;_‹RN&/a/$K~Ei:V1TҐbe(""vSǬI>҆DBP6W7¦@@bDDC75㽕T}ΦYab`æh3;]4chOX/TQDҚCynNX> ` {#Ff cTl "A06{W(#BSVąOhe1S&9 U׶|yq'FGVn1hڼ Ƴ#JNL֕LIQ_F_W}phw׃Gx5R8|dUxɞXYǎqL5yE;v6o8o᳓'O )oooE4zCx{G׊=k^L{ϟy w}? 5~w<fT(, EFI Jb)B}``ѺfFF[QC-O1ƳҮ[wyNtGgW|=zp][̀JR=1 P&uKtw71ӓINl~ prRQIfɃ_fΞ}?,RgzK>/:eJXe|gAX9|h΋o8S>/_T̩W'wC?K7sww~SXw3۷oĉo\{nl,]fG{#rӽ^e3qȁ/}`…];l_{C?Q{Ob ?_35|2O¦/ueZjaz s)1 Bebb&HMmhCU7A2e%Be\2=iWÄDz֟+ffmX20*;$QJeŽ:Z#Jֆ2 1pK mEB02$3*=Txa0LpD #" |%"ȊW]N!Ä518ГmΌi<0;>u3JѾi(LN5^XyujRMajZ{ik+WD??WS[(ֶIO?^&`ʎyBKl+CXwyk8I~t "wwlwtԴ/Ͻohuk}s{f?>~s7,(6wŷdFFGܹgC{f u'`nduM= N2|EX!gΞQW2.yq]*[LcX{G|JjGS]H3ÓǎO?f뙳X2ٿe'76][L|lAz﷿;E8ēoNnWy{sC;?`@mܸl_9̳?B@۶udFF> fϯؽ̣s%f/[HB{6wb]+_aKGK_*E:J|n6{ߟIa|mӓ{Z~ooye]*Wrwz;ȟ9711qDn?#(e.@Edަ"IT;kL3-')TD!BXC!cذc&2FҞqyIk )d"HU:)ʦN E**I !!C^S @%FblUY >+I{~Yk#6X,*HQB % HZs؏d#od|/ @7y^^/XZ9 =C\f%xJQ;ɺtyܜ 3 \&"ȫ\KtvLɶbkjV|fܛue[7lֳvmhuRkyn|,չio{;zdս;zpC.O0;S}o}6lZbם{}߉,O ˛{kCs/{t=&>쉎+iY)ye+׍}83Ʒ_U>1 u_?䧧/vft'{k%_`68F,B0Hwd1a m5&I3_&G$`&|# "(!pKeTDL,ݽQu֎(&SY( pب3EZ}»C\ s KQ ^vM#L}@DRJR@BafP$ W" QBƴ6 !6Af%Sd\mPf%"H@%%t GBW,vD-EB^I#l #f$2(*iE !.HKR(GA斲-Ԗ e: ˑMq1Rg59]] \.&T=' 2*M#c١jcmmuŲ>F^]٣T۶_߬JNE);6޿y;m>+'Iaߕ5zuDkxpםϽ0=Od>I[oѧygtggϿf򁁭[xh>z{.^K2# \d$*gs)9:rru;rX~z}_R@5K6`;JȄq,@} <]݈x%=! )2ҡx3 eB2o4#@H`kLeU*X@"d1fdHC&p/K ѭt)&*1;kD@%P~ aX{w ACh7P"Ib0@ 3<`AH()py"_o <A) 1;ìB $L  @(.ef!~B:X )P ! oט) N,PqJ(:݆RqAsIJ%Q8BH` ҤT2'<`ŢW?.ۺ#fsl6QSE_ñG##æq.¥+;J&_4K 7^ppNjt8?N,==˶lZusתDT=&_b2r뾬#?55yxN?@~jz8ɾ*pG~3#@b2sOkؾ\Ǵ:r+JKx}5fN`(槦lE?hVՌ("ؚǹ&mI*9(6ڐO2smHA$e@P>̚hnn4ޖJ ޔ"AZ?CZ5f*ԲJ,żqc%gLRTm}zٵC(d9F}*Ld_iS}C2]XZD4TRJ#df"c+DBʘ1TQe#00=.gAޱ[1{^TtqL3瘙ݽ,gu2U}GĀePlY"/H'ѢÙ} m@srH \u*Uo b9xtݭ7EIwC{׬JtFM1PXflSgVwRɺ2y{>qt]"dXvbB{BM=ms{_·y{^R%=9^騅8 FB`& MsI'~?_Zn%sA ٢ݼ|TOwLtgGGF.^V6 4=< ٗ.:M|ֱA%sO}`%X0L&EmI3.]Qb.tuV bYC,B@Jpeq$@%b}_wvs#&PjtٮPPG׊R~ MoT@"HsA`-t Ҝ(*SeLַ2!:٭Ҳ> 7)!d]JGEcՅY Ri}2^,8Ƒ % HTO3X%Z )Ə[ Md2|)ۛ^1H!c]WC=0K,߲y@/8lqR]\~̹;GH~FvЭ\)o~ˆuy^>k.bmvGu1 Z $X\`vD0CMtr@r8l. }a)PɯKѸ0HGPv1jr8)a~0=.3` vn?V=N<{&:$D(b\9XZ1}Kd􊁺Ȓ#Gb32tz wb[IƺVM=_COҜ8yOj`ǖ⠓JY5qFċ{rkIU&wFΏLt珿sy5&Z1,ոry[7]- ^ͱ͢0"\JFloYf[=噪9pSR+ VD)[Kx= ŕﺾzz}R~jo 9<(ez{~o\r:R )lt,,_o鮒+ q+G}cݹZ$+Ɂ-(MP"4wưo@ІO77 kbMAIYƙ6k hbm|:)u]ߓ,b*:,( =gq. 5 A᷄6 #qa;W>B(k5RFw`Ԗ@/3Z_ƻYke=CψiS|C9Ts(+{U$Bw d"a,64qlaQ'3g6۰I%#{P)"2Lcɳohy\B˷m+pM粑Kʅm+ ~tAVĺ2~ Et!|د^fCs3sm؉6 KZ+W_;TzB}k/Vޜ͛+Vѧ=O{mֺ.m ɐP [CJg6QAؼƸؒueE2}hgC'ooQl33ggggFٱ\n"fDzlrT,NSf!ʽW:wǟ۶m\x?_~w jz|W}ɰ [hO;v7ؑ[˅<BU6"iqݶ1j 7uݙxewW(/޳xw1(L&ULdA40(DB,ӧΏ+y< 3kC=˺:6ne{Qbo% [MͮHen`K>^tR ;.w=%Ҁ1rVW,~}>0鹮w(G}5C]y(|!PX|RmBam|bcuSMG9P! 4$9gPU\k]uu2R!}4@@כ g`8!1E2%@aK$O+ = y̺4`2pİ51ջL9{dy{طvUX+<76Tȑscs3#x^ck^l,bfsZ6ߴ~7lJvt\8x+=:|b |;wmk/Jv*]7~C>|+*۩X~$u?|RoV=Y,X^Ljӏ<]h'ӝ~@B撎&ջSonM7؋ox n߶E4?2ywY6UkG 7=_z/r^u R&_vKokKKN}^ubײ͛V|W ?_ۭ[*GԖ |mÿE~z?e{CO[B@7֓'Ou T{S;AƏH6eG0ً_ֵreϺ~0~W,bw#)P ] 9w{Ue^7V/N&cjZ%kw[|T 5|،̹Wof.82k7K"*f"F׾^<]+J<5Qf|y7#Wz-eUA? IDATWB$JZE(AEWVzzU[\1~y gF̴fF \R'/ocx+X buv"otGr Ҙ@F@HbVȸgڗaU~D`D1-Gno޻jъ=ԯ3MS}ޗhocO<{6vcJٷϵnɳx~ {춶ջmƎձ^3|>1uRlv?냏?Y&s|>3W*2oy};>~y}Tx*'?[Wy5u S065}կAy; yMx{Gp :zl޿7(}aqv&TKuwڹ;X6\j޽uYu dgѽ SHٳfس_˩gBMq5Awŗj޲[~wW*Wl~pŗ[K}{?zd_९~ܾ7-M,;x-GChWg|SJx`5{UV\8{Z: &N kK*#&2?K;zW9R ![1Gٹ\4s3;r!N0Ԯ@2UA+YIKP`dmm(l^I˔B!2#X(# lULP%XIrs̉I!8iHD~a7~kHI%(B Zˍ y^w]JH"XY7QX}O&ӱXDW"nvDjmb>?ͤW6-[v=XOKM0ߍx@f9OTW)P N"Ky#/&JI%RB )PRJ)H'R51hڐM:`fdг!a.1x̻xOD1?獙l&LwVd=q' +`/:>}a,31Uͤ:{{m=ݝ=4\>~Q49vzͻ[NL>ʌOf'm{VjN7Ncwvtbnd|ͻv,Q/G0d!~ΐt'uh,R 3gNaeVUM~/9xE¯j'7ccZLbMu.^̌&&ݫVvjV=z:}M[ư%̜8q03ؾ<**D,Eu  ?55u N<޻~]͈5 ˓1u72Vgڹ,mP,NbWE5^/"NOp8iOqpN9-I%{Qm&c1F~fb2ѽJ)!h:?7snfGVHؔg(nuq n{$B %V%T:%*t?*Wsڛ8+0 l0g"`S!Nť22v}]NYO]=+tJ RH),@BvnD6̳3Ébaw~[ʸ^4I0;}Z:$]-qR8?'[63 3:'Oœ}ZgD=m |TUle^tӨ[t.wp􆵱tսcC\hT)2.Nr7 ^,%Q>]*,J{".%TCJ@ 1<%!ü nqe 2 0\ Y XXJ81T"tza(9#01Zwyd@֝t8Ub_W-tg4 -1|]Nsqy<#ae,-w]}͔`Hs7 WfbWm/eըd/P2H=G%^h R9/f\CT 6& $ Ye)1.\zW9;U*h\;TR |F+,HRE]Q&*2-ňlz02*LB (RIؠJhƛ$àʑ"B,";֮@V{Cf E>@"_xp\D`"Ʀ+Ʋy y#X|$&bb\1У:".mZ*=oUmbF*R _@+[0> l{! +# 0(Pyp@AL } #HѾ_"̮W ($@!(Hd|/:nD(JŬVID&]N`U%l@,1Y 20DTsZB c4DH#kU7 (|3;l(I!@5"8^c^[\2R:R)!$Hxׅ *, HnB&] }LbMT-|G_yq|歫,u ۵8ѭaWW'z GzW6-KPK6ԚcR%ҺE#B"i?Tw,naw6Dle&Fz.H\i1>=V$HPkEKEJ%W]/CY[B ,8568Qx;-R)P{wz 5?5fewX{/ٻ;:K{*I)H W:DKP(qlbs$^=4x+37A67q9qw@qoY6x6FMxʃlto憝-ώLMuyLuggϡPYTh{o^KJp06a3߻B-[iȂLqrYeA!("jqfi)9zDQPJz/;ޣ:8(IE*,WK@ad2dP*ծe"಻ffet8OP"2-?PRJ$@R[%ՕI-TV3 buZNL᭟>`bkw'\؆LZg֜/BbT<]Rl[%[:_l/ ܄@ %)nQQʒ1%( r$u7&k@VΛ} ';uyE! N}Iz&1UgyŊ%FqPJ9ޢ%!9̦(/^PuBeW%iRMh!:[SlV^>UڑI-tw,4w9egXnrD*^r!=9E3|]qVRW7-TT\[0.7l /}wpPm/~\&" ޏJK7ڦnw> YV%,\Hɠ{wniaCeOWCUTj4t꼛,z&'YFAK$VZ15JC%}Cp(3Xʭ&"XH+JiPAKWniYk%]^'b+U-3WWA&ƘZZkᰲ\q伖9v}g{7gMXl9'ь?TFB2QLfΘiMx%z\lwoXtlA%bpBe`L5"p"%kg#++b˙r5 I83d[@*O%/u}@CELIZ™UL9y]-<ᦗ`x &^f#,sN-'ś n:8BD-gcݳEm ]x j*! *ڧX裝ɲ[T)T-+uܬ^ .)Av{?;!$Zf,Sg9ZXHp䒝sD@%BqĊǒy~/ޗ.Ex֊z l3_CZE VR\^y' r:UdQ%$JCQ4MXI-j32ԃ0K͵(i^⤩n;h:sv5..4Ӊ]ݶ}-F N[ c&0eI9& "vŶ)TVl`d1*+T=ؙT@ ̽~ Wtx޹Ad-)+m V=?\VW̢~Ybw`F*sP* V"Eir bM:xR x -T TfF%?.eQ*R7j,Ĕy0s}rR"*u;"F*`$+|lRJ5p]s'jټ=nǑJO%XGfEfyvx16F7t67]ni1)\T _l_ٳ߄2'H 2S:{"iJjQ6\ \gi PB+:G&=n[f)B_q"fRZZ TU>\b%'}eZ؜( TON(n'tN'tG0lp`5 wϔ=5ؗ[n׏vY\xUF)cyr}Hkln7VGWrQ‚BDVOeؔ 7!} E<ͼv>"d˗e UTϊȜ@{ h:tRR& 2qGzGЍ5UiP 6m<ɴԮ_u%[w)EEr?DԹwߺ˳O>"×n !ꌌO`-kd;O {NTr8;\D]?SP Ҡ NѶD* .W\D::Ce0.oC! @c~0R5sN]ig 6Ǜ 4#R8@ιYEpU9Iy3o4Z'-CB tO@9x˛f9 (TetoyPgvGwPLȱD ȤYIB]wB[j!i.?k`AX_vkaԹ+y/`P .}Peyrz^%$8X=ͺwwn;Š:uʛLCv7PSmVB4!6N0vh*]H}'WEEO]\ k&|uIDATj!^ ݠaዋ^4TUjEGO!4)ϼ?0Q--0B?EM7/7uj"53#YZ"¤:V Ȯ,Ggðu;K3=VqP&W;-/L;6kMJV):om<9ʈ4%҄.˄jIuaClTh#]X]]TGk\xx twv ďs)8.}̢x<4ԢIi5v[v( mHżAV)N`;7([KkΦPR^).[#k*b#\aPeW-yr|vIm4ІvF6=TReBif۽tbs*7wLÿG\Rnf9! Γ⩷4id(mrS`!& @$xmzXVUՕbHbӖ?a-~mb削XckzT]5UHi4c>DYfLɕ2\;?Eܐl'fxڎ4ܪ_ aO$6HVT+ >l,*d(hr _ͼٶov_#ʨQ4!fƆ(0s!H4~.2[Y`[{>ƠiGE@nb#FX{}h|Mok`ϟ .p_FDjpv[FHI[?+]MWꔘ[ǽ6Zp .w6 "Yj*Jr0 ZoӻCv{_ hm!l=_}G/O֢za7Zn u3E{B̸ dM~7ë2ƌrVQI8)ݐnZ;;P̚lPl|qJsg㸖c8MCw'qSIGiFegS;ݙ";ѿ=/A `hJi5.wMJ$FlB忱"ϰ|jjbTT҂(dLcj .ZۛAܻnfy\VʸD1cG~*hLG_4-0!DoFq6|YO= [Hiߛ:)vM$Yѡ;{q!W%w;z/% BYʹ4;,Rmڐ(*Dmfmjjt~* @C~Ÿ &kHb 8䙻ލ,nEk$>Qǽ!ӆ[8]`]؍Y7fΚmcg^ڀL "l2X]C@Thэ"ٜG~x1{zsf_hjC,GqQ pSDiH}폪dFUε*">wgl|]A`zpFhZ2`Sb_0g-,\N.Dý S6gK-͍MMKLL-eB>ule&hD_:y~_o9ت[_?GuBlHD,WO @@5_mЏ79/R_eq $Xe8N>$/`r)T̩Z}LSRi%_35dg6Om>oJpqgnvF'.wq8eO&!bâkp233o,/}͗eY ` >-n9|{Eg?[Mx|?~G]19r˲8u:Y!xu՟?ٛQ|ښ8^XND;#齽:9w:T%ȷ*.Qfy,(eMg 5ȁz52ѝKUluK?\I-b̷3xq+v +  E)RX#ng_}!MF&Uv3(/JK< YY7?8V5?}~[Ex(׳ 0ڰgBDT!>9*kFq?PH"EKGQew޽lj}^ع9 l**Ï>99Λ;ӟ_uȱv 99[wRh4)RHb]08Ej_Njϟx+LuQ2$X+Uѭ7o7n`y.jDTp'K,Q)RHq(18e{$"EQE7?Q.oB pkS82)kg`)RHb5tAޓY/|Ktc늦%_ ؝RH"EkݻlioXKR GK;x>_=XH"ECvZFب&&ꍮ/yRcbNaRH"E*-~3'UC"6f*7V碑R)RHlc? ڞ(*!Ôhi'{%tn([09E)RHvfaA]n Nb9A1E-? 7O>it*ho lckڻ/ѡdfpQП>qxqX ^v^ww >QC L;1Zw7I0v|=vpt} q>ټ$C37q!bRr !4 h="dKp$qeOG^.'+0Unk+K(S> Z:739raŹ@b?W}Z3+癊xk%CVc^ERm q)F-Wd#C 37|ފR1zŝ(cפ4_'w>&~y7ggj5(xs5ܱ7XywI745 t|Ɨ9wz 2mW9{ t7N -ƹ!~ZwrYPf~~:c.{|QoyXAqWܑDF3?=%& YDS٧s XGgv`umk+ABZKjҺv0=omfRfڝfk/Ftc(3ϽD争\mG|:rEʙ "T?@lt Q<Kb LRHf0wp&֓ݤzk } Y3dz} 4<8O])ڽJ>H60b1X,Kfr g4h hĩxˤ0TKUzRIvQJ͐X\=މ k=Ž=}U+vecSkǜ}e5ɛ|Ӗ}ۛlߺ5eKxNd)??ҿyſ;qZɢ ta~}j"y12K]EGY/OWl-8IENDB`mudlet-2.1/src/icons/aardwolf_mud.png0000755000175000017500000002522211513237311017235 0ustar csmallcsmallPNG  IHDRx8fq EiCCPICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧ5 pHYs  tIME+/5IDATh5zggy图7羷sMFB ɶ׋qal(쵍˰Ubwx[I$ҠFM=v9~ cj_ϯ;ϩs\ط?3D 4$DLJ @`DbHU)B8Q`hN  `28IBIL !RJ)$"d@J!!C"D(I(%p) PIa 2P%p0JΑ"@(! 8B)%!DAo( B M:2!I1@r)!@U pHD"ݰH^GTn./l]zB0t=/C2B}9;;339!U[3 {I0kMcob1pTׯw] MPJe͌Mh bx5][ulͭN(l-rׇLyBpHdbߑW/j;8bEVukʵv8y|B(b6RJWDVej |5)∀ i扣j2@H6 ēǙp<)Ġp'+D*݁OSfa@(nlA@#&D !4MA뺮F;Cii ^H s/!HǏ/Xv"b;VС[Qas WMK" #,adt>y+P;7F fr ,-kb`Len/BD8K/R 5 "5aw:n#coEW_jW# bB<}й?yǏoսB U7 #i3/$:'3ϝЈO=R~A ca^ʉm@'/Z\x^}g;+Z,W 7v|oX۫O|phPm=he*Ul f}g{m{s @ϤЌ+-n;|W(܅f_޸|__Y:}qꖷSJ dFOŗ֛!qT\PUzK$(t:J٦mR@cJp8lQ̗՚ T(JC޺xen,%mHCwjRz1f,d,D0`0AhئomE[ƭp[(?tZR ?{SO^o5Zݱ,A1KX˯u _w[̞$Ę#D8^׽to8fHy*dP4zB*"E΋7H&f<(`Nݷ}OGj9g7œ4U0Rr_2ΝƊSHQRat*nx\W B ^j6 Db(1Cg}[j[ y(>t*F;, y`R:BA0!LCoSs#N.M*=2 硹6 Vݯ=GgNG3c?HLO~?wp3DUybzxߵ/Өb8AтHEP)lI [apٟeͰ6y}Zw^$<)v,LEQ0BtLeV"'xL / CJiBcH WmS? 6L=h,,,yͲ^[\nltzz !F ;a% N4e˦Kű Z>@/?72v{^wL^Ξ g4=ǏIBo$IwLܥٽh?=~QTo7v׷/"Iՠ6 SU57+c3#c[gnY@B&fI*wLᗟ-Ywzw_XQa,!aJMLRt² ]5 T\@%;LF|Ƨ0y|L?h߸_xuy8<) J=eD8TIl: w3ҎB HfS& ~]o?ōy:<t`|ލO+oٿ_ET8xf(!F:ȖB? 8,: bP "EeSgh&]#3eQ*>շ*!÷v:6b9kbԷ'?_5֮($BLjiX,N۶mYK!AxzHǘ 쑘=H-?3'vWV(gRi;-4R9z u EzdpLT..kȖ mGQ0o|g H$ӥ,2:4ۋ7z& qIgofp(!0TUUY@0ҁB{LäZx6]r_^m?xkowMr&H~ #{859PjL!^ Iʲf"1I(~hT4Ͷ-}PE@ 8RU1ٸ$|WOj{o?:VVyg޾l%^hQG7zV*C&HRשfk)mQ2رG+Ir&dn(W,NN\xY@F?;ju}6@3H,#ܿB! * X&0!WdFWX1 GqFȋ+?IKgfP &Ps҅7% CTH\zR2(A*<i5;'$T@"4UҗXRHXDBSh×bڐEcVLRɧS Γ}{Nr9vqwz֮FoHD#I1qiZӐ! lMk:SNC^G\;o9z)ʗQbb.zUĄmPp) cX by0hol;8>+ښ`GzzldjCCwX_o,u3&Dbhv"O'PE`1۲@TJic %*cLHSUތ!rrGXAXk?ppJ1pPT3bJcw3]dRA SiL5?~_а8lgMGD4c# 4€X^ MT6MqUڱFԨEM_cPIMMuPZ]+ v-]WB@x&MCl~~Nnt8 AoB*O?_tZǑz_򧥪^xUGْt뽨$v[͆[;;5mX6z`mf^?u]w+(}`GW+m#EuM%Җ ]9RιeYJ!)FUBY+Lv~O=@&b !+K.? Fj8p b(^?`lF@;?o8%F`V6۪WHY_Bt}>9?kեub޾\Vm~O=8xnڋe˯Y[FbYɖP2T|߼ӗ^B3~|!dׯכ[+yO<_?u~ksk|wS~ٳ'?4vwmÖ|s{~N&*, ^~V&BRQ見*D?ؠ(tz."vAĐyඳuAn 5ԉ rJ TB;.1z˩d&_*;ЪK.bG`ċ{f4J^;p̠Yr?8_|{]|asDŽin=?5,qSbn_լX f}5a璱H!_.dcqfSs{ DDLJ :zRf?N^)䊓= k4*wug|Kwܺqz=o̳R;*NX9m۾l}EJdNt[GP*XJM$)U#향J,cɔlr|ejF1{|!WPWf x6xNs{kjbw<0Kn3L51 #}'?ȥ%C@H̎S]k:AK%DԍT6KgMT1h²x̰L;uӴLMW= U,t:/䥋̓mooG?zyFu! kBV+<ܯնZM\iwL1=;*m +gz׮^ Ðۯ@jj=]LUx&n* /pbfV +{}łLXBZE 8L$B0T zޅڍ7]GF=3LZ`ϗa7fVW7ڽd,AqӅn;6"CR:V5MDByn^|?p ]__ۨnV`pt]_\\uʹO2VmaybT_~@8s&WIa[纖׷A}lyگgsõrh4!Ą<95(GFXbﭷ1T;923-!ֵLy䶻:L)Vv} Aw6ndn]x/:p`k־}{W/} Dz93Rizz~#Vy{|BɉrMֽ MOδ-ؔZ@À+ Z}u)FVk1 wrykuGYgF'J:{g7/7LZkkww;:YzGF 0A;,VE11e*Sv,)Fx&.L!Pd $^7kf.D>ϟI²#34x5 eʦB%IDP`ǩNM&8H VZ]Ax4V(U6!'Ffg8:^Ym3&L{f)Hb.]da,jv67kfͶmq&<1V*nܸjz=o~l놚LΞ#09=C15 W gAelޝKD|t[/-^gYT_G' nOi[X,Knx у`@-kbad0p\gp`モNOM')oΠөw# ꐨj1R0٬~,?O'#"Űp.$I jPŲB08z;ܮJSXZ^ILP ^7з&|O( 0nx8"-xgA_,iar?A#B:#/}fϤwF+ki]w7 !f[2ntx9SCי)2w~)rIENDB`mudlet-2.1/src/icons/folder-grey-locked.png0000644000175000017500000000235412070466512020253 0ustar csmallcsmallPNG  IHDR szzIDATXW=SG=wއ.ZHF H)6H(SSABEAUV4H@(;3~|`󰟽DA4y9;><~xs=1FBy<sݿ>4VN/&"<|AC$jȲlѣsBΝ;?`]>Ƌ/0 Bx@c+ƈzk׮ʕ+`( E".\^gϞZNADFXnW^EQx5>1PJaccgΜAۅn2:4Mt]cpxx^cnܸ#d8Z(D@Ax%a~y`gghJ)-R9z@(Zk8 XDD00Ncsm4y<ᜃs!ќ!Ԝc8.e{b-Ȳ 7oYakk ZkcYhlnŋӧO1͖e MSmc #MS$I2o1FH)rljja4s$cEF)\ByՖ͊16/S>#:`ie@J "ZY fUly[(TTr^uPu-5qy1Ư^lVFQdUIc0(%eRtb:8uK+uϟ1jYFZ׵7ׯ_?{{{o| S­[:亃Ue%K@uwU.(ߥi:}wv/kzΫnBu{/phŽx{{kmnaL&d!qI)eG)e̲,jCQ`pUp 8yYvskL&Z+s9'B'HDsV)<l3Z)%? ,DjbIENDB`mudlet-2.1/src/icons/dialog-information.png0000755000175000017500000000526611513237311020361 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< 3IDATxY{lffwo۱$HSА ?xU*jE[@@[!RچQ Zhy6J*JK* JIgn9J{9w>F7]" (FIQ!h3$dZNrIilH%!cC-JZ!Plddݿ8<㺳73ڑ8m[ޅL(+CrKEWC 5݇pг++P2χHg= g$ Kf׽p]NLd$(4@$YXՒw=%;&ollA3Z뫤hő<PtPE"Nut‘QzՊC#`aG!z| X'\cWAS^8őKW-fܴiSAx:9̢Ge54jcɭmH(ۼvRY.<b*` =^ϰ+ל.-/y4r&X@ =\ [~<#Ml9<<e|Uvo!Qi@'m8V<7  C=" W-oVZy:>IŻBG!w5Mؾ$EQ͓r<=Pw6X`z"QCr^z 僻RJD{al=ہZյP&n@͹p+Me}{kkn٧x-`'d#6"B#NnR6Ip4.jڎCb>ӮoAՍ D&Š(;Bշ$$(D w@O @*s@q![0eČ*EYAq<u]/Nu7cȒ ը }|i!ys ?$xs8ҩf#ȂoP\`jn"S4܏󠯚{c`o'wY|'kRF P5LbUhY,b3 Q׷l # I|^g8O3MŚk:%' T$ x &`$`*Cש1;_#yIyLzհtVhXJspI.NwgbN_mO@~y]Oa% J @AK Tz$+5YgPF^IENDB`mudlet-2.1/src/icons/folder-orange-disabled.png0000755000175000017500000001014711513237311021062 0ustar csmallcsmallPNG  IHDR szzsRGB7MS uiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}y>?UoU x"')6 sg2H1@&d;O ^/n@+{,"7 9rcIܕ||3Ӓ(d:_xB^o1x?!#|eS+̉' %W\ f/-ϋHRWxdz\bntyFoĨm+a(E駜t~Ʒ Ht *K` ; l d BP*P @hg@'8.k Fc S%AX H Rt # YCN'@P ăҡh7TBUP.C7!!4BCa&tXրa6l{8Nr )MLOM+CZClXOQQ6R(唳;9qxvjsc 4 C o$"f3T,UDRǨW4Jsqhi ):΢yIdj `1Ō3QG));(RRRrҶQm#e2N2 2e:eȢde}e3e^Yq =/((*($+T*\QSd(*+)(*єʔ.*`J2혉 fs^Y^U9]NyPyIҦDVV-SUWSRRQkQ{WgǪRW_`iiԘaIXYָ&YF3E^FuX6m]}G1Չ93 |oU1]nnCS/WS~~~/&  ݆iq&v^cu:QGLL|653囶Κ՘lv9|yig,ԵLlYZaͤUUin}Z`laSoVՖkh;meow=߾~a%GűqЉTY9ƹy%+u똛ǭm}{cG3OmOguk|ZNo}'7_os?Cuu5{o_8@3 =7T$|+D6$.+iSa&aaXlQvc ("6 G7Xt8pq^rme(Ҩh16sqqUq]kN$,'%%“^f[6%$' R,R=PԮ4(Xɾ&f%eTة?;ժZh+< N~K/g|('Oʟ?]6„uOr&_ǧJM3F3ggXbe˥?%y׿lzw7']Yx.b{'?? 8 /_ƗE. r \@"D. r \@" |w#,de966@#J?JO66zTXtauthorxH!s)IDATXWYl\g^Y @ـ[r b2]y;"ce8/ZOk~R;e$'İXṕbs~~J*A[L(+(,&4cmJHΥ8kb\1Uu*S2!,9 9leE476e׉(Krcԙ #\7Im/`uZl0b B+\îGt4&VH(`1͠GݥER"#B^k)1Lve+,ynwɏJGal̔Sm=LK`r"A"{0,n{Bh߇?gPʩ:E,\/6ڏ=H qDȹI0L2@%2/9H\0ݽBiȥV`/ 䋽Uik\<_D#[a.`-.u_?\_&n󰼬R3K&#v: hx?@q境[g$# œC)3ϋU-jp]5?цXĿ=$#G8z1>sK OCz1axnq*E¦sNQ(_@>D ;A9JP.A0rN/C| LWf' &)a,hTo:*m\z} 3hujB6RSNWtL-Qoы)%jU-@ԤD*xa.Vm@6|+0fx=#f2liP#[q<{C& ;L$|Ay"B1u'jQzc)<$ !׍w=psHd\0d/:>_$7ƙX="Mxw:{{j~j ~|Oo34kl L^ S?ϓI.-(y4-q%Uqlx:71=.3Sm;*~Wq}ХIT5?+0j7?IW|/ ;r_1 t:s:Q=X[EGzoDTz~zE8NvˊjK{&Ɨ+(u{!_8|n\"*|I {gHB*R_n)]o=mCW_n?dZ܃|IENDB`mudlet-2.1/src/icons/rating.png0000755000175000017500000000531311513237311016054 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< HIDATx՚{W}?3w>_84MQVi *A?ZU+UҊVb)L, NB@8[{_3sίkv]y7Y{8?髙93w93+ʛ oraMfoRfGLekՇG+?7(>G)J5[0cKa?ZqT[mOmoY|q;5hf8`./֜r݆9gG(>dmeGRͩؤᏈJ ^d"/aJ#Vgx aiq]OfփE009Ɠ}q ^imPPľ&lmgҪ8wNGflo1o8/Rֆl)mމm$EPܴ5hW/a}5V u,)˜K dG=}Qo c;o2W%Z5pmD7op&eeWmn$fYd9A'NFqZ5Y{ MSd2C>H֘;/gF;Q0؏yک']Lܟ#W%޽[k{%B2k,oFrZGySY"ea."x,neFFMz :4~ڽeRgm ⑻.uٺ=WPoGL@ $3.ic<x,/E@8j9SM֑M@FJY$z/4?.Ł$- xj#ePD,Hhlu54zB3d>鮽^ocD$ht9x b@_]ӊFJ%s Q €S+qW]bPdboNB+2 i예" N j*jh Lt=BY NI d:ZH6u4z@K+>ZkH@QHJ i;PFdA9`"96~2*fAQtoAD!\TV4cw!& rTiNITpF)MX I$>xe] TR[X HJ H#+QB1X!d8"W)ⓚrn `(IZ%>gv` 2tAGfNOzjz,HmCVi'$c<pihg[!܏,$puo* JDZCBI|IjA.lO?oKG<^&iMqv%8raJ$$Y_Ws 2Ƚf|v뛬?nޫe< zgIENDB`mudlet-2.1/src/icons/window-close.png0000755000175000017500000001453311513237311017206 0ustar csmallcsmallPNG  IHDR@@iqsRGB7MS tiCCPiccxgPi$J@rN$ ̐a!)`BW`" dQ tYuqQQU}/W7oVHb'$sy!a؇ 0@ 0|$;- "wc1DN2p':-tq9S5It"o$okOb2ᨐ2qdd~&L , p, g>nOe< ""@T=8">HH!R4 mH2C<AP(= bRQQŨjIT'u5Z@}Ah]%Eg &t*z=~`& $`r0ŘØv%0f beXk6-VaOa/bG8"N gsḸ<\׋x %oŗ=;i2A$X ]JB*aH$-~xNb%4:qD%I > %C2I#+b41}1w1NW~ɱs梭ˢgbcbfccU;WǿNpKKXJI<ԞKH>ǥr7oY\^Xঃ7*L*eWzUvWWV}qi[tsxݑ:G>wll89yycPq&٦'''O777ȷ­sO6vF{ip:_"~;y,lۯv: ;έ ]q]szz:~y5$/z{W.f_\rir婾M}\?tk.׮ \n} nnv29h:qvǐP;w- |޵o {0>y00G@O>RTiڿ&&{x=?>M?'?Qi5=?2w/S^.)g+WeBk땿ȼ9mߢw ˼?acǙOO?|2"r \@"D. r \@"]ArlnPU f >EzTXtauthorxH!s)tIDATx[ۓ}gm/ڋ.X$ $ %T0$N*C^$T%&N\$R6vpDF,d,!i=ӝ߯r=kKq0U]sfvw?"wT 5#P @E%9m~KO/Bѣ ʐ &<0Zz ;O{E򻘟ٌ~n5{ 6sO?gwY w#KîG#ccvpxn>0 ==7Ծ?BPR& Ox%('$[/C{^3C#2y)i,]'ͩC%LuV^s米\jKAh~OSMjژҐ pmQ$ׇ.9zp*~G}lݺoRlEC@eiH߆-:$toۆ2%RJq[Im íފ^" O"Hvh-$w QMϝ8q[Ϧ U}X{a4]$[*#G6[4 aV T6&:IM ?GsJA~ppiXDbOJJ/٦;TqdO.=00560g֠]WEҴI` U47g& Xp =+ qn ||B ||88γjX^1q,qv6 [\D/9lB.'(Z@<$Ď0 ޾f #5RQ=$FةfL`$O/})w^4-K{2!*XNo£ D\'π(rxz!jltcY4Asi7$2O"@HL˩kO(Ҥtwwcnhƿߢ{kיg@}Xc3)`f}l.NO~R$igi{ӝ{ c. xrx`:uB HW-`*&)XH7P|rF#)򙁊nOp"c(Jh,Zq+j4>Ņٵ-aPDz7.̢q hv~H1[Ld [W54^|a库S_l-&E9I6,#[槡?J$K.u!Jy~ku1Zq#G皟yHZD1Pdl&v aCC*shg&Qe8s<;OafH ՙB`tr`i 1^j+v6跨I2V*_i4i/C¾oaPy,9+ \)@WAwQweWb1:!#u݌H*ٓƥPFXy oW%H9l 2~!.ߡ)mϼ.gtya~Ga-TTBU_x]d!)B `f-!Ԃпd`Hyt=^"RT=Nz)<ߣ o(I|5ș+Qߗx&K^"RX3HBhfLCac4I>!q= w|-~Mn޶YB5"NsO|wy ,d S%\$q)U0XHumrPA$Etr"Q #IL_xJ=|<>~# 'lj]?OݝꮈƙMtvb {6w?NGle c痞jn)RM9_'011v(/OӃ{wHpZMvE2O3nO<6Cw;dh{mf5u 5r2&+[жo+8x8xG !n!kҭ"eH&}XrP0Gm&!]^`́|ᝏ5I.SH|ǚ0G$%8Lp'̜jՄ(bxJ˩>F6ٮ7*ӒWU  ļ"d1$6 ^c۱o| l:XSQ Sa[_y^>&K&o*,I3i&~ B+p|3" l#٫K{3yV.W|݋U> o֑DgQmY8u0&yxīDtN1"1DŽrY霏kרN /=qp1ۗf.<0V"uߡzL_? }ǎϵ\tk?, ,E}:Z4I Ǟ0@}ٕ9GO 5"!c?13<;~(d<ty7-mpiI<N>4 /$c{ꟴH2 H/(牄C/Dx? q>SJ="I1x,;2%]G:/DuT£LyPei؈Drϖt )qm`醔BB!t6¡ŔPfKZaj,.u3vޮC"%m<:HkQFB-Ě@m_6"ӫPz3Yoi^ۺ_'{}#ݿ:^>sᾈ,c4X&7/ꥯgb/=x|T!RD>ǿn=kBxOr#Zdڲ<Wh0/0k+ڸt*|=kjEK-\5Y7yI*\F$ƕ~H҆:`RWOƔJO =rz{]CkKO#ږ4ykI׹Dl,yO,<A|%[&1YPgNj`]36jOGX։'86ޡľ!p3Q8A#R PJ|or&]ZIENDB`mudlet-2.1/src/icons/chronometer.png0000755000175000017500000003432711513237311017124 0ustar csmallcsmallPNG  IHDR00% pHYs7\7\Ǥ vpAg00WbKGD X84IDATxwT?3]]""] 1{7$DbQ(F`XPA^3p{={>3 33./=rB_2/euiߥ3FJV#%xBP$C'CxC'\'9v 36$8nQGh3udrL&W*-%tt_lnvnvݢnY=HF?\"- j7o7m7ӷzZ cȁQTک 4^f0#1لLrսf Dhhh9]1bE4jm^Xk+˵g[F JpUj\Yf:14ztț脡τ!D(x!dGoQ,dh9nOykfM5NSwMm"r&GKe%kYwYݯ7{b YpOml۴߈_/3o}f_K-RAط9/ IqGn "GGOFq<'atm}0dz̳dz`l-cF/y6o%BN"4NNX;֙#錀1e2SV:sB ^yu$$L|*6S6/Fy1luye/s&@fr˔|3Jj`fmtMzgޗPP:gvW]Q.Ox +cc2wwi%¶wmo'-^fxOa^C~&é mc#1&) ^cɘ%x0 CL3DYdzdz~O6躕ꖕʓeehB4ygMX\k` Yw`"حLݫmiy:-|UoV^U2+QGq S.Nta}?{@_K! HLkõNq<e@ˡ&&ۏHLjH]SSvfz=-ݭnvKiROm:iל04_;7\J! =UmUUm{{{&ދuuԥ:%tcߍ;~p77nnZyֵ/( ^Bz]TU*U=ӞYH7  >Rw2$y!fCcvha[N!0ܲp}a*;R^v!ٯ, 3?on{_Gnizg99g( ߿64ghzOz,a#gq zzO5O7w 1{bkcmWe*p7I\ktNSs)8A-6)ZY_vA/,,,HJZa}R$~&jqRSRcRsƴly ۼG=;3B[k)e3s9?;mCs'w0;;Q\VhbտObg7 zk#k%%`ҏRtK<߲/e.6EU+WLqcĤy7{tl鱨27o]tvPMFͣ= Bͼa[z{/4gtZޞR_3x|iypYMk OiL XYZ ,-d8qxy/zASm9zHz$ A".:0nh0C-EY mhBS+ṫ?dWuڡ@Wc֮'M N`'??j 2ro$;`@FNU֘඘m1jHC5;$rp2ԯRWv)jޛ7Qo'g'B4q@' /vYBcxYYD$KF? ѩt*@-U{={z#uuCvrrнLb1 Is"%`7 qcP...Y2Ymrduvk1uՖ+g蜙7c`MgNpl%ilXFUEYEcSe,b+ 9OYwdlk喿"O"+^^I$3%aP7Rm6L#4I6DžcNƜ9DiKXF1S;wuQo7=nhҵ:ZMI`` tpvrg ЩйhTTxl||q@[ X^&9 ff@EE(V>6mL۔)@ڝVOReadIܓ T_RQ_+r+<(\9+ɮ1f{#YѤm=ڰ'0-èVoķUY|_d]/ x it%) /uwjoaxyϼy浦,|b#J _,wb4ʟєyGfP{k La*|G׎䐿?tzpps/$$>ޙޙ5|[^Vz~\*YV haa}em =mjԉxU<С~ PgLM>-l}j<=ZEJq/ eF [ik]pKQܣ&_o+?v=\XB}5sj؂Ql0NxZ=ϱ^JTi.~W]N= *+|/83ga/Vy7$uwI Busȍ7C#04zK@^tPP\.v;Vn 9(!0G99@Nde{Ɩɖ_hhnFl11G;OOX]|[CS'ZRv.jClCH` i7,'Kp !󜤌/ x<ōmKmG| ~5k__sohj(kh6]ɻ/i#6SxBD{H=yHAo81ğ=uK[KK[ lڿԟPiՁϘP L9  *͕fq3`pCtVt'11A$I)$2o(qqu?12մK`6B`e`wO!C=QsF̀‚½o"_kz}W? ^+~x+ޤ)}}YǎV?3UUUL'c:ߵ7cjBc5 QџWO=i݌֥Pe6}\GMj4ygyOa3/Nf&'X$L<& r|k@,ݢo-57;5s"^m~$y4.^ZIZqZ &UTF֭\god#Џ U!d(R$+ Gp{&|} Жk@NNsyffzf:04sr@P#\)\ ff(%% hy$I`B}TYX,I_Wי\wV?/$=EH:˦G@zF^0k4)m%`MLA;%=ykǚCׅݺ{&L}痟_,c~x@&nnİirr-M3 9swVz(=Đ#*8@28 H`_ЭLj&s(pBn`w@igF36\~}x[&nQ {כeiaey 5;|MG ~Ž{tѓ'l]I{Sg<xZ͠d9%ơ4Ysg;4W.˾\xƤFmt+kpP&&Sd?~DfSSҨ4=$|(|ԯI;J}G} wX*|A2&oZN?HܲIIu{Ifq@o=Zii ynKVsySSHgJJ?ߖLGݼXgVZ}&!uov}Ԛ〾J_>\...ـ 3OAc  wmq?V~xj5d#Oo>̈́Tg" R9J9 |H  x'x#xߴ.0m0 Џef3ȵ$Pm7nPu{X.F+\\&QL5KjI-7Fl7kš|S*z8=(-V#;.. hn9߬YCC\Nz)M_я^o|m|:W#v*qfaEWx~k=<"^jn p`r{c2cAgJJؗFZT A@,'I^ ^J:P*߫jNIWVW7^<)rDrNbMtM%K1BZH ʊ #qb-j5]ݷo#eD f;ʞ ]{4@ ,`/NHxzI=0pv@)(R&?ϭ e5z֔A;vFL֯W/]WWg+Ej{E]xr'@.M# W_פYzGUC( #Ts`XkXl ùSP4BA?%UdT '6|peʔ=;~.(t4мQbѸ˸ -dOsD(ޟ^~ymqF@n)/=={A*I%cLv0;vv|9@~ vv__z~^IC P@|W=<|ƺOuc)A^d (,bdd1 wB!S*"+X 89u^4lvjv2|D?(ryǾ##a0^*W $_ɆIafR@|XrW2 z>hvjnhc"]“SO33{U' _/d.__&a2w;Roo $O M laa@3Z{\{h!-0k8 V$!@Ԗ-/Jwg TT(y؂UL7Vxw{]?[Cw:Wv.3>]gv y..\>HJ|%sʰ˸Z1eeO|R|hkuo L4@> YB@i]J'M,G/vݰKթի"դ`((6vi!A!AO\oo8 UeOwO7u+V\C27>7XӚ[knDq8;;ڀNmػO\F"8gˋw>|0w0_iUFWz@FKbv.y.tq@``oPfoDKM,mdj ɢedv|hKzcvOUeaM2B٦ X:X$[; UKIf28 ~{kvdd 6#? ,& ֙ʦps,$ݤ`0ϙaM 8J^k.n]M!`7߀%n * s@# HA aMa Zs0hM|DKq[|gmCÀK2b:&b(׫Mbx #cFĬa4FϠlg?ۘ(^fJXΝrtt:+gi83מ HR$[+gp3?]֨f{DkE;Da@w"`45OCN3fdU n JR\sQ;'h~V=;=__2XYYD"M@?k \' =BrI.|orCI24HL6 6l=i<͍00U| ȢMOxLb;[[%?ʮ=Z3&eZq"YR-]&x_` &4@RTo,Y\7FҋKn#K80,pS1@$4 M?yTUU}ΝATT4E),Jrl/4,,Kˡ-5CQq@frs\]Z}^uYݛp?/R I .f f(0 0TS_h. *[r:al JmG&9?ZVH)2rjt ;:pҁD< :M4`ā-dtRw^3KKW^̾ﺷ\RϰՓ_~8C}5'ìOSq:]b5 H n餔 aJu0=SSݱZ3$Ilb8x 4+-i\a33::A9s`%NMv/zPq0V!B>22d=ϩ/uFt' d@StF0Yy"A$e/߳|N]!SӷXF{ݪGDl.4׿ʚڒ_8p p<)V?Q'L30ꡬoY_0޳Zru53/kkk6wE"`4"SXhGGqtlQ.v&SSțgϳC7; NxA9 ivIPU'WAO F 89uϞ;G]w<{8+XO1E|Ouq^~2TP+T0S؊l݁qXPbP})[P;JAq5 2hqKG̼3›T.۫ cmi cCoK mߏNQkE֢zTp-l%0ۿ>}>3hƴׁ#w5y^#uB@1w:;{9lmqElE<43+fצHm}~y+nk?L7F<%"E$hYH\11pVCA b&7ćYb/ܾg[g+i]\!f]+?_ ƵPiێi;f옡Y (o{ܬRs z,|]=y,#g@tk֫[/7o(;^b(:9w ~@q],ށYAM   >Hik .CO:{{kA#bA^^1N6f u@y&py-d zu/_K?)H_I_m۴;~9<n |%SKҸqڛrk_)2"2Rע~n@J*OnT%K?2Vη*AݩUӮ rRqJqOWk#11dm2Iu/d⸨yߏjkӨ:?@rO_k5q {<`?~:4W߮׀kt/GQݿy0&&IsC8t#_Wbx^<J0V)pmoOmm Ry3ofμpo˽{[ern+W缑5 (Vhy7s270ܪyV5B )=>W^C0(AMo9|~xpw?'iO޵@tzݗDֱG:Uyyh-IKW+&K8Ui,X1~`>ޱBBCH(u.FBˆS'l;\uz>btH:q%Oq޻TU@:߫opߗ?FOOǦSS -[ hd }^c >xm< _~;A>kZ^.x x3<[[ꬫxb^_-ppw}h4Ljr^u37|a)m ѾѾUK%L|0v=h (Yh63VrA9G[E(^C_C?y=1)5ZҬPgXeA-~$&i :tt0ׯ_P`4 lS+<)(OY 477?\Y9.*VRuhӬof/^OptǏWn^CSn-o(-ouA;,-9>?nxlē6>=bhog|8U?V> _:w4=4i&Ĭ ##ւ:7=uPF2YswLAXiOu{KbksZɣf`z9Т@- "f H{=PꩪR{@Ǒgw AAAw5150zC)[h`ZO%7OdeQYw[i\QC--s!Ϻ^Nm'ԁ)ʅ󥫭n:֩RsR)yrG%b0{҉1Ϗf~{xG?:Ts`.O=wя>66 eiY@O]tA"DD&<$C0WKkbK[yƙ5knp N .mX6WWO}WO9G4[{Gp0p@ RGՐ{-Rȟ՝Z9xho')j&hO3I}.̍]GSw<)㳌ML=٢fŲXմx]{vaIIFhvtɒۏbOʿ辐v뱥}X!VkVM%wt@&@W ݕK@릡 `}H``o ⸤I ΂oAMS;)U?W?#H1:CJrF9zy˪Qw>eo+v`7TNd޴M_lvCԖA?DUdN|5sRw'Gj[L362bl}oczN,raГ E6֎wv/7o}v|O|#|w(lfZl-H c 7߽a/1KGR3`Ȁg@ZCY YP H Pc 6=o,Wzm1G77f%mZkz` >_{ M !&逧ALR&JK֒3:t+x@5+֬ujV~<,hvmثIW]M!En̎ܔ_RT+v^Ss wgV_7 "&S\i4FcԒYYBOYm9|i?2e!b4؋q/fW چm0}C/eO=w񀢀":(wXLhSN;o >9VV t!Auh`?1.}7SҢ(ؗu̿YF[FGy<.4Ή 6M(N=ɐ); ǸXرtaG폈m5N,U[[X5`EĢĚ"awSTP^l9:%BU"X3W(5G>idS?f'fNN̔=W.!YO/>" =/0e"+r`@H<"h>Ͳ*Mл:{itB/g2D̄t3>AmRvAadaAu8/+2+ QVmbة㵎-1mvZ+^:uخk2XN||݅jVlhV5M֠2eFÑ^ʭ./+*vΎ^di;oysR[׍YUM/d+KM/^F)zSODC!0.#Z#Z[Q* Y4崨7DUrHHcߖاc|bN\u鄨s;Wv_Ϙ_;| 꿫ϮKiZigzc! o҃e =u\/BDhJeҗJjy2aAhyCϣAj#L3WO~zf)Y]XZl|fEu͋>ӟvsWWΝD [Xޖ;\\ߺ6:D!eM]{vŷgQ=(9wthsjw!QA//$I&)StR^H{HhpߐPc\\Hg#V6!z7&J[efol7F_O=yD(Wdjm`ndr\'f5_5!O [+[-Q7$4ZS3En Ӎnͫɫ˫nvU_DΎBV GIKǦ̱ xvzxy W|t|B|4;UwjTa ]F)Hobj}A*<./TO 5|nO7{9\|}ӽƤ6ơFZH@~sZD#E_}T@?eC72kJkEi՗Y<CBaaO%3Gz Fo 5n0cb;35{#qkAo[$_drI$eee4q{ (C?J)lu|=Fr7D+ǣ9|W컚XK~S) !!!r H,A|#6zYA3ta^W[ZŠ+f*Yүs͝kԼ&}PFGGh7Z7v^z:tYx$m:9˫cso7DjH]nRTo\4|fU|ɪ !sC> #wH]?6[niYnY`Yboo)9FMizMwn_/?rh峕CϾYYb,<3111(\G] 0 tF/;:8FFÍZ ˽.^_X+k1bGRdž~yc]zG=q^Q27 n@l1a|wJy8wv%@T&au"MSQ ' ن =3;-uqcaM< 8Nj<|c<%3-A^Hdz,۟і|7}z aaatEuC?RI!U+uqpfjɢH&EB*99w@m6PvCr괇wQj.X=gxcuׇuc{2+9AEm"zTXtSoftwarex+//.NN,H/J6XS\IENDB`mudlet-2.1/src/icons/edit-find-user.png0000755000175000017500000000667511513237311017423 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< :IDATxZ pTy}vbAd򐍃G6lwNi;'n761uSq3')aBj$}H46)X`ccam@vW~W{0 8ijRcu=s]~(\laJDIV5!I `̂ylhFط+˕t˲Q:kg=/+B :U`.`V+rǖmx'AFBk$  e<2zϱ=ۿ5vbl˄m[PgӚ'i 2i>gCl~/*u2 P*(orEdU6 \od  8v.9 U # Yj"e.V Xmk$"t#܉>q  @$$RCzpؕuOGjUFf27o7L4b XD7 E"E.q!G2,6Rعq&hCehj?Zi$y$&C*D;l#)s '.zZȴ ѽm:6aI_lnFmW'bi x( 5!$ֿW(O} ' ĵJ}enj(=O3C'`/5E4\J1gԞ%}*D*y3@ߞLDz|8`Ǣ1 _ 2֙u*qf2o=|&|^r1Ι 3XE >7pc~iyM{xЍp*Dm.xie _j>@&w1ũCp*%H8,f̽nDIrg$D*44!d0Jg cMPy %$ À?@V{oQF~ ^{ WRlڴi%~I[d}۶_O?lF<"o` ˴`;7˵ib"W~#\Я ?{憧cF B_MܸtիW/`Ti/', ; 2, Kk#$ CkЉd/p998~**}|.^ow?r}>򵧞lTH$s(*UD$3H ,B.sd&qHv%0MH**?~W;P:AkMR,"JK A>!ò^!.Mi.X4̙dD2g7ʊZh#)ɹRJ0kjHV2whz!HHcHn |ٰ7O&5uҜb4_Ş\6psUՀՈ{/Ȣ1CC yTx13?w߽ߛ z$Kܳ~BRj?7ʉd,IENDB`mudlet-2.1/src/icons/folder-orange-locked.png0000755000175000017500000000761211513237311020557 0ustar csmallcsmallPNG  IHDR szzsRGB7MS uiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}y>UOU x"')6 sg2H20Nj'^/n@+{,"7 9rcIܕ||3Ӓ(d:_xB^o1x=~B.Gʄ+VO@K_[߯%r8^ZORWxdz\bnʼ|7V_bT|6 HL0t|"YSN:?[ZYI:@h]`$JK` ; l d BP*P @hg@'8.k Fc S%AX H Rt # YCN'@P ăҡh7TBUP.C7!!4BCa&tXրa6l{8Nr )MLOM+CZClXOQQ6R(唳;9qxvjsc 4 C o$"f3T,UDRǨW4Jsqhi ):΢yIdj `1Ō3QG));(RRRrҶQm#e2N2 2e:eȢde}e3e^Yq =/((*($+T*\QSd(*+)(*єʔ.*`J2혉 fs^Y^U9]NyPyIҦDVV-SUWSRRQkQ{WgǪRW_`iiԘaIXYָ&YF3E^FuX6m]}G1Չ93 |oU1]nnCS/WS~~~/&  ݆iq&v^cu:QGLL|653囶Κ՘lv9|yig,ԵLlYZaͤUUin}Z`laSoVՖkh;meow=߾~a%GűqЉTY9ƹy%+u똛ǭm}{cG3OmOguk|ZNo}'7_os?Cuu5{o_8@3 =7T$|+D6$.+iSa&aaXlQvc ("6 G7Xt8pq^rme(Ҩh16sqqUq]kN$,'%%“^f[6%$' R,R=PԮ4(Xɾ&f%eTة?;ժZh+< N~K/g|('Oʟ?]6„uOr&_ǧJM3F3ggXbe˥?%y׿lzw7']Yx.b{'?? 8 /_ƗE. r \@"D. r \@" |w#,de966@#J?Ql7zTXtauthorxH!s)IDATXWIlE}uؑqQ" Q5[8"q "NK "!('f*~u83Ɍ ]n53N;CyhA%1i^t1 wP(,<'NM/|R1:Pgjvfi8tRMpI0]b$‰>!?5soPO; cJ0.o&&KmNɹg ) DۍA$yhUߣtS p MHyg8vVAw{zPj;a}H5Zѝ{9M~Ob~jt)xi > CwiȩK TײՇ1H.7l^5jڎ0{QEZKs4~7Oҕ1ji¿GDdw~m1Wn}Upڈ39꼍/";ޑȦ-Lg68 _Lj}dxd Ycl5X5!( ld[0C'}n\P>VV!heGNT t}]eQ+84s:)-oXC\ وɅK2T:l`FBI=\yd[r|ۄ,q g2$OPf+tXHijX%qIC3C2ezny*Xbz:+_Nu@ f f3F aIN[SR&HQ. TjڷXZ~?DGH561m0zta=3(BT"Ȕ%fj.=P%=:OU' j۪Pbe֓@ҵ!/P(8Т9E gD'V*HU@؟5:^C HW] ,VfR2F&Eh-%c@=ч"PNߍ/B 'C+3Yql"%\,&:QqrI>y[a.7y#XVK}9"GJAIPc22 fg ސ!~T Сu? /a$Ap6SʨRNz+~GI]mxUЖ8KY`@he*ZnԦxqZE H^'!(k zyy:7Q,50~V$Z7Uυ;\Ymgx?me%W;6NVn_cՑ`MqKyqH3@9mڑ]8nm({ mT)7Q3PD1w\\쎞o:6^m?^*6\R"0L3AT)@U.Ml(1g`5LWIch#D?PG#%9qto\vdTddNग़r~?\HDup-9dx/VF_%:`<"*oE4Ylh~-C/;zoܛa/zŲ͉K}皢I[PP%y <veRgi)jNK }. xzweN/ [" B!GGI\d#| oɺf|P6ξ4sp>o7d)+| #rۇ[(2%H㷐~QB7$0у/+ +{ 7oiç6X hj>%"  JL?lC2sNPF29[ y ?uIENDB`mudlet-2.1/src/icons/document-save-as.png0000755000175000017500000000732011513237311017743 0ustar csmallcsmallPNG  IHDR00W pHYs a aJ%tIME  &7'[umbKGD]IDATxZkTյΣ=33<`0APh-CEE+KG55Ws&qhDKDFR1!ϣ'?}ZZ{wWlm3M`Ukut, ]n۳u:~sPdDp|2>{m;/p=ò16ǻB TUf͚2o\d"8[ZQ {5p DhtDgExLOv~vlX\ŭ/{jeYh&BAnhhɲ4LO? #؆H\| \[?#`?hY%W4`0hcY-xsL&uZ%,2 tTD@#{l')^`wT 8LN4Ea]DXeI%qɒ*cw#jԦ0IϛR㯥D6Yߎ@0a/@#Ϩ .\ L Xk,O9K15m+}y`MӡiCD냸3:ȈGOx}xv#e>sDesgQ(y(`hIiP1a,G.ǒKUBAH~S#A2RAQ,WcdYy\]tLlh uJ'Z#i(@uEeKD^X2Jd N`͟b2գ-ʄuGPg D#zו9}[ Vu^-KDزJt+G@HDZo5鳠aZv{.t_Wmb @ȏ׏0C,!13SOb6|_߂ >6W67>ɳU)'+1E*Щލ򊕠$yjLD+ħn޾ܔ̗ƙs [NJ\ir2mSi6b[`:¡H^ȲpҜ3&X9'Kb^#׏xQt^!^y*k Bm7ZL#cHhx[̼+>DfsP< Ti2ar7L^A8ƶ;U% +ؐXnJ|l,*V!4$T5qO`p`Ets$|/+E$=sVU A:(Y])WJ2,@PNat?Eog(td".S `wK0]Ks@@ܭ}΄VNBl)ڷořu{qŅUZ\ -L}SJã߲av;PaL%۹P(ރ@ɶʍX8@8ن|n^O=έN  fv 5IZDD30I:" ̼k P_ڎSZ aQCi{?[%{5 ;۞f?RbRo^FR1!pc#9 ߜǜ#*FCge[Lˊ"q͏e4Ńh:R:>chhEڲkqy LqӍ̨yeg 8J({}gPk۹w>}GdqDP qpO9 \6 q>>c=kGgLEkmD{j&-bݺ/WX`ɗqA޷[],|ݟ3%dRT⺶H2**LTT1纻p;r~87Wxj5k_`s o}}"R경L9D4'ܪ-17|/I"2:u.&|m3O4`^45/0֍'YǰihG۝et qNL'ZԼI7ʊ ؎eJ4 [Ɖl[ZPzjȏWse|cޖř-lnkIBa<{&pvq8C}y%D>aHrO0 <^㾥8 Vǰ8'" )dNާ%0ұ4z}Wɦp<{7ăbH_.m4Š#)^.K, _g/{R)6; %}wqgcZf5WDuB^ŤzvQTUq>pD,Pz+&aQFxtӻ6m17bbX'DM&(^cGGGVb AN䵱{:tRk>|̇}g=Z'?GUe?&1AlHqdc[GtV<(qL?XzW(&5ѕ"B"ni RJm  1< 5Dh3E^ٳggAp@G?cǏznnC=2Ɣ8m<=d琦)JZz84Mi$b!32uضu]}RT19:mǖn4* CaZ,pcEm,Efii*8T)e !(眆aH ^z=g0Xij!B XivR[҈QJ˲۶۳k [ǏG|$Ib11YYYxw,϶۝\(MSH:)b?3N JiV]~=zT,..R cmcI\)Y[[{0˲W=asFAcD)(APtg ,˪V*k<Ϯljjʳ,PJ,0ƀRH)Rp˲, ID 5iqcscLeY>v,x&7777?|EQ!)#a`friidY@to\x.^hy䑢R!Čm۞eYXF)ulvl۶c #=Y ʲLr De&"1  \[[[˲,ܔR 7|Wy !F!d$1F~kb5ɲɲiU$i8K.{-ɵk+WZ߳!sjU#Bq\NOOQu2R$I;˲BkfY־tRW!o 6777Ķ1EQy ۶eY.C=*˒EQd@av,nOx7$}|oj5!cTq1&Df2 ';*eYBi퍍$IeNz='NBL1&mf!40 8LH,JvիMBpB?Ν;gN8R˲8 ؄u]{`}R!,"yn,aEGQzɓ~_ AqcS`E1Qm0amRVIEfy,ˍW_}5KJ> EQÓ,S!B)#s9w[f!\Y^\tiOƘuX!4I)mXe!@xBJY !<ϳ8ͭVoAp16xS /@K/m{¶iq,u##RJHvy~ԩS%y.5/_~},|R(Q4L`0H{Al6RbGe:8, kI),`0P~?O666|r~mBc,(ȶmL)Éu5<{i|D!0<#yB_n 84,0`ܷA뢧zʩX0\3ibGR4hzRFC^2wT6@Wc7+\L17,f}Ҕ@~M>4UQe™x|>G}TbZV:`HܖzoI??{4ydVǦS_?2w˳=[/}7pow`o2۱|Ϻ_/mEm;VW5&_[\b}aFeǮeDŽ5|cVac3]c3y- T_|@ CYN[^״n]hxn} p0蚼fY򞉩ߟOM5_զHRt"u=5SKL @dfecf?.h ĮBqҠ~e={qWmfĈAkgn/ v}k^^·ݣ5PW%Ou+7[~Qʟq%𵾾ιLR)Ťs.@N2& w!46B vIENDB`mudlet-2.1/src/icons/list-add_small.png0000755000175000017500000000106411513237311017460 0ustar csmallcsmallPNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڥMkQ5IILiݸH]DD?p"čӕ`A@\BRn.TDqL36t;BEpDBy8# gU|!ߗ|1BHC!KS[ s/d)160Ɩ-ЂC8!&Uu^$ R0v{!!'1(t$ "O~> M__{FJ[d(JmvˊSp=DIīP*Iÿㅃ/@BJ۸i ?FsN*qg '8;P $AL⅖ѝLD8hn)bXbRŽ;$u?Ie6z|cV}; BJl;"b g(Z, T3kF4),~oeR[X+^@r-Ew^nC)2 9L@x٘9缷$*(D)4r.(o&N<[q =H=oF?nJ,2Ǚ{e@X10?FUYPYaQ顑\S lH i;-tӟپF~~N}w~r[ڄ^~[bo;uw RXQXWxxPGNj{HUISΈdmINp׍'FR |pmkJ@@xĩ~G=ƒVN髙K&A8@T?{sʩ*>X,(j2љ#glV0BЋ9I /6*'B C#{)Z(,)xX[2?HPOa>K-K@{IWM x  r08`ep"J;K |_ݵ~mrx`UgSVɀYg#O-H =@M  ΂@1Јa6ƻt_y]:Vڷ?̳cI"3gpmExYHm@wJj ̶` Y0,]w~|TǫDPgX5T=F ǿȑuIs- +! @<(' {hԡ/jl~VYӛ8g]=KiY+*@%\sx聨i P'K9,#@=˜B\[0`/*nOžz&`,K1*-_棟Fk 8T .؋59h̓:`Kḫz.c჎XLoېwvOf{w x13F 8<")ݍ,}4[kX#blPwQr t3d,cc#eyFtY k1߀Tu%Po@YE 2&qAULm''i]L|L % -H؀@PL=MЂ4XI*V>F,t3FZm$f#\I MpEvl[U,]"bS5666`{ЁKZtV;c~ PF-{KwuQBI 4)` ]@  0uIENDB`mudlet-2.1/src/icons/arrow-right-double.png0000755000175000017500000000424311513237311020306 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< IDATxZklW=ξm؎Įe7H%jI$! ͯJUADTETQRHxq*!uPbkY޵;}1!2wٝswofvM_ި- ,"H WM^qckd/y({ȳ!b˧@p [5R=6V[}85c b=A7F\.={}| dv6ND*37c##^TIOnǎ#7d}K#k MP?5`3 Ō1@]Gk}k .Vʀp‘ea HfлtܣÇx.g.4#=_?m]ºX1 Jqڜƶa}6 B'4JdIۉ@w8GaaEٰh"QLϏ}$ 2<$Ĥ1 0c*zg, .<]hy s̼F ӂ0sjvBm vKxoni_b@`(7-yG.@=xs,ҍ߸mĎMxPQ(}^bRpylXB0~z#: BpSFT 0WPYq'k 䙙B|?o.LyLxǔXt* .􀎼#@?1iww"Se&JBPpw? MۅGLXūbj74K?ZP X H2$n /.v&ZťDeeTbl^T 93;xB;t|WĠKPŪVrZf Xb%z Z(Ds:}?p.03/sZ=ȌDr#-N!/\KAy'#BDK>kqs߅ 0mp aRFyqݸ(Tԙ8Fb`Bse aj#c'NGW<4 ~'8rK_ޗ7@޽nkMu }E.6@hw`d,tN \1P폢˰F1L|&VMȐ'_?` `w|* ӗjlZ25k&C[+ M3&##bqe$%~'%?!*^W>𔾽a}#羛MIɯ@Wh ;lIENDB`mudlet-2.1/src/icons/application-x-bzip-compressed-tar.png0000755000175000017500000000624011513237311023230 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< IDATxZ[lffozwqb'&'$P \RM("Tj(U۷RH}KU !U B4W_'Ɨ^ٝ~db Ŀ9g;|2+keӆƁ/аڤqB~QSLJxGMI_!ӔIJq^D)}bR5 v9oJw@P~9>dqgUJ%C{ Z3pgn>f }Q`f {Y+U@g}+f/. W‹b-/x/H?})}~4۬sE9w?wWIJ\ʍ PL\F);Jyi¬Q8'CX:.G"ՁPpp 0Vj= ڻv?o"( 4Ps@7 %u*gIǒ?ȼTt1w<#1xfL*r_bZ@ZaTQ 8q lQZc~}m<019陴hmmqFk㳆C)'XI3SVTsÙ-nb"]t&drv`пU;EWWڣ0mHJXUULpȹ!Vvr$_ƖnLDC>4-=" + %JGسoFnӿ mY:b—(fb[.bvrg/1uP:HXbb{<B|?S-·}䯁@ )-r}xrKa]Wɩ X6G/Kwކc/w.,Y=\w^,=!ke w-hQSA|~hɨU=K&ߩ`3@k"JZ{# Çnu --;&T9dg2Z ]}7A n<+L0˛ j![1:1}7b8݂z֭%ksشi~m,]:d F!3UD҈Dyn3WbSr&EǑ-ټݸuU3Vk(n9X~=4bB@WW%zT pO c fzHT-Y2Q>&D -%"9D)N ܞ՗_b-ƖE4/YVCbK* @LH$`8,|؊:?7ң:'#HE*@,=*kk2te%b+b8 RN-ڥbI5v0G e:fȦQ)W3YY(i D+} JTZ3W=Qabk@~zFj*R.P_ f$$;@qF5tQB^Gd,x֞#*Pd$ "/"" f2+psV@vr X \'ZmZ8 LԉD3PZZ75^K )p&'EEhƈ]dPJXSRlV >uj&y\LԎ-p͒gI5bQt=x`+f(e<20MxZQq-š,\cHLfZPHWsz.zBAY_`P-Y t=r߻vҕSSd ]']ݛ{R?lǑGX'>֬XL,.J0==cN'BO"#9cǎ;_q+3#L6"\~OTBrl'[t+ am۶ЇkX pÙ9*P.~Rٱ cGYBӺq_t(TIתRعs\ B&%l`):UZ}⇨|n{':;;qi._.y֭LZՋD2'mx'x8 `RJH$T6hnoU'/oJRQ7dB/G2_nwoNbqWݻwxjjBBLNך~/*NpK;g޽o*{Wov]>pm^$z")J4s7NYLt(u+5R@h)oJN(॒? \_@^gIENDB`mudlet-2.1/src/icons/120x30RoDLogo.png0000755000175000017500000002156211513237311016657 0ustar csmallcsmallPNG  IHDRxhMsRGB pHYs  tIME A IDATh]zw|\u};vX$@ ^&"Mu˖,El%?'c;V'[RTb(( .fb̖=swsjrK_ 0W a!0PJ9 kx-h rs !/I8b?iyyػᄏl2׻w 6={vǏ-,7eY]@]Ys](!ro}[nliiIR`nVTTZ*H,_|q%K\tibxx#G\" "a)dzj@:_E_!ˠS) (0\{B@ ] !A7v>i㲲rJ)x<; .u]Gd2$)bbH)y^4M( Bclq߰/ݾk׮C-XҥK׮]{͟?_7o:y$FEs{c㣞bw2.0 ̩S@1 B6nR@ A(#$i,j5}n]O?J$XW?<4qʥB㓊a͛W($IgY>#̊+:::$!D0800!dB0sn޼gzzoѢE%%%x}y55{>˲g67W/^Fueنt6(rUTS0(" QM@ RRbaX@ K`)Bfb1oC)&<ߘ0j3)9Y_,ohh墑օ.]|p8|Edzp 6]vbb"bh4nݺ?ODb׮]vL3g(6 ns=۷oX,>OQ۶o 1.ҺR MU̬)䕱1>.3"T8 C#@]fhC@Q|=S|=X@@P]P0#``@tcjæ q\ko%U%wal31-d2Vʲ\UU盝XdI2r\nҥp8.^8]vtȦwnf04!:s|X,ϛ7!dX>\\ʹO¡Emmn4PCP4295Fh"PͧCwഢ`w'\ B!d B/Q)()Z T'0E /.NP[0ϳddn~LNjT7v\ 4u+V0 Չ'A8}G񊊊zv?^Q oxxkݺuH$ X,<ϪJn?/12/_N`"J3b3byE^o;i"H  00FB* R%jSJH0D7DFA-ShˆjC@Ixjrk|eK/@jR4'eHh*6D!FS#vmd4FnZpіrz򹣇>='B0X,]׿;v, ͟?妧5 M61 ٩i뛙z-ˊ+[|1ZpƼhX,ƙP'(7=-nxp`M+ˣ3'O:9K9R [6=~~C͋cT UP,L :">RR[˖=zz'z͍UB8~v&,\obA}b 8 N65UɩP]\"}~iY@)ڭ[nI3Uss,D<_tk600ԴaÆcE15(mmm~3ZfBtMM(˗/.)*C Q Uͤ>8mn]xuuݸe /<o`CC=v#ǎ =ΒW_y>?PÛn.3]iw<<攳9eIY|![jw2) ``zfR|]"G׶̩YlY8cqllfamMt{}RYsG==p8ZZZH[[IZ[[kkk4Mf7d̈́t:iӦreCimm-( @6i6Ϫ`udFzo쳃Xo^|@`۶W^8J(F8rs|uݗN U/W/Ml: DoΏoiPGz?zǗ߼>Ăht LfCj]zۗȓ%Ržkw7Y7526:07weocfZgd9766pݥ%EMe%jFD"x0`0`0mܸєLFM^aAzzzbXCC$IfdY6Z,ݮ(J*DNgd8nyskOqbLelٰfUQ8h$7̼ՊbI'H+rh,ةb_^xiɬVT MJLQ 6ɒJt&fgdzlٲi 6ƚ5kD.X,d2 n0 YA rt΅s 6!:rXoxla~+}g/MQpFCбÓa9'*jڱM3R}c%Vit0X]e58-R)^lK۷cq`.3쯭b|h4_PS3w͛|6og'NAH0vW>}kll$|uu(lHe˖QYmf*!Rt:2555drvv6J9NB(uuuEEEi6oik"/ǒztEbts[k5 ːUĸf[DBI%;p"/Yw8=Z]y?Qp[DûlaDߠhhU ED{v494=g8@-0::޲( 6zO??ouݥޞnۑzV0\I`Wt.OXpI--- $ e| (//H$y!L 3 )RR) q N-Hq k,dTVZ#Z9"_U5+ׯeR0`+N'beeix""TZ^<~[" 19?yras/\vlhb_Gn~NWUʱB,a){iqE9sWhh 8zh4zh0 3}DhXz{{%I3YM.LOLZݻP oHd*}#v~#_(5o}}3gD6| n70X\p< <FbT Xm6-_9r~u:5vuXp<8=56>?@1|'kf3r"ͥDmukl\vojd2\^w۶wrd &f\*]Z}?;D" |>hn{={|' .yRʮ\2G뺾|rEQt]r&;E!t:eYV*~Zή?s=W[ &g^~*Xt7lݖO?s6;lnjikm(7c;/\EˊښZLJBC? -,'>cMDݿg؂I1ég}vWQU ?9E4DT-&So/ӻy۶mXl|t l6 &- |n醆#GȲfXEQ?.IɁNaf̼STyy)A;vlak?_=88n=T~kGOןXYFp:?է g(!ĆFzVknbxБVdPJdx׌>;;0$%"ϾwDz]Zm@T3O>#!PbKtڥӧϻEp;]998H hr,]>ka]%I,[(LYl6kҹsέ]VE&La pݷv[.&$ɺWl6۾eNyXxF|wOwɜҦf"ˁξFoYDx) C#nð[mbщ`0vlX "k™lA4mȫP) Teenue$I#YeMB\ eF"&حRUX*:zR *^D麪:D4.r<ɺQugsu ѣGE,Z( HiZqqz4(n[UU& jkko>44488xdY;wnccS tm ٚkwwY(@:G{B##~{Q()l9PJҁ>-wѾS2:2QՖENep]c{z?GA`t\_rxvDR ``ɷ͊ʪ]7]li Iy]\6 c;QI0 &YFlgJ !qi] P1% 7mذxٲ Jb$F8V׬^޺iի78P6m;qxTT[/shnS~:~=v筛,]ǟoeZ\w-֧zfUuڛEl{-Ie8-.1Eʅmi Hk@!:((i fp6{L2UTl6egggMziɓ';;;u]ohh0st~=::Xz 011a&:qy&Ҋp_4h0#jekkt]onkL~g/;lٲѱ @勗ᰙݻ'7r+Z8$̼kׯ yމںpʕ+vJDc67k׏B_ߝw;|a|tFVѪ*A1*L6k`R *t0=xѨi`QBΝ;m۶i7t柬0LC4H&,sp8D|3Ξ> D5 P1U1՘\!IW/]vX~[ -eWd`X:}颒ʲ WTwv4/l[RH%Nǻrl:m.vJ/gj.ǩAT`t`l(2;MtooO>YԶ0Xcc?/[-˞=t0H$8==twvjN@.BAU3቉"kvM7@was)bŊ}֔?Rgϊh-U333$Y,x2$ x eN%̸O>}9M>ˇ>3JY-VUUB.\ˠౝ(//߾ߔ}rC>9NѴx3bAz-eNuk;::Μ=^ f0`$M/ ^MP(rD ^!B XCRz|>bŊ3 cY1re:áPc<22B)E tɬ6# @< 㓩d(xSk`YMX4-rQ;]ݽΜ&oZVZ  jW.[ \qva 1:!a )X(XyHPQQA( Bxտ`9VMt;]2E! 8"&6J;X߷H;t}RE_MR0hizJd ̃7 k*A'bƔ>]Ҿ*[2JM[43[ WQ73JkGP\olfl[M |ٔάI,АN\8A560߮.R Ns6C'GnR)#UfR¦U N7NS(<<  ԪX]|N@3\ sifk3@)qT*Ť"8jl {^ a0 B0uEDL@XB%:l-V Z8U`:b%)~-" æ(Xc7*/Q.GQH-P_"TAD FmB`1Z—+!N8]>SGNC"pqᴎt舢iUP`+dy?:܅ |6| 6ؘD9%,(| 4iB"Jy` rCehϭ)ᅫ;RuhӍb9++>hb %:/3U.D8utMc*>|CbZe5be Z,:bK ŪOQZ:sSM`bpoTG5rxhh($ >b`bǂ$$jj P0GQQ΍t8+4kR\"Q;Q(8>UP2bkl F,V<&Xfv/ˉȑ*C=+,TZ䷿},42Nߺ-:Ogn}1UXgwͤ cwzzo(ν XRu9X(-fGm^G>_-[,r=1Λ& ۷E/ b걠hfLG:cd]w":nݼꦵ.#pژrcfuz3$!*FBlAGqK cMW' @!\{ر#Q]!ӮzHI9|{VꇙNGˉ4RF1X QԂt)%-ލYs8?]H=$ >+kߗLH\VHU 1]$+RPUɷǧ2Q͸OOY\@`%YLqvl[SŅyt- ψ!,K`@rWiBL:AJƌh-F`/#ҍ#Ok8U[d\T;o _ٙű͛֎ildS) lh]fܹ'fhƏNNη_1^J4 b>n~"/E 6"hgB>w%ۛbQq8x#.3yDYRPF]cK8WDH.Y>:/=zjXIENDB`mudlet-2.1/src/icons/preferences-web-browser-cache.png0000755000175000017500000000402211513237311022362 0ustar csmallcsmallPNG  IHDR szzbKGD pHYs^tIME  - [CIDATx՗]]Uo9sΙLgJ3RE&0@k \n$ j4!^441#ʅB!ЁNm+?ڙ̙39eNdZHp#s̹_B?^`TIn[3+쒶\D,dUH褫Ov89"avm}ǯ!_C~ֽEq+Lip).Ag}/zE]`t|o~ Ga l~kUr5 #M{QHu|׸?I"N>~Wk'L^x]W3C?BY .! 3Ռ鐤5"|Ii BcL-@7;{jq01ː??RD.ޝy!hk-.H'xHnwg8vY7b+] f%A7 D4v&NHKx-dtw\(2wD( wR{.QYgQ?dOSoRoYxkw*OՁU;TY^:`QZ84?耠: }0!h坰!훩#cUW?s: l ,m`DOlG>F*\6@%Y5:/T֯ףK٪@%HB@'sT1Mile͠čnH=b VW XZ<;`]ْX\apH!y%&3Y)HS X:$8\ @#W0Mx-8-WEŪRPuP h =vPqIYlm dKI5S` .YY,+Fr3Js0 pzp.@MM1$aR30z 9`N"8yb}qFð$0/\׫/ÙW5Ab6 "8,▣v3NW5X}C p9pvWz7!zV{["ɀ`c'czyRy@47xlڠ+; {֒[Öfn9Sظ[<.^viuu5pf&ۙ;#:DZhrYnB4FS-k;' .ہw0&H Z῭¦[װ:?1_ _HݳӰWƓ:s/|_kah +RY {Jb[[8JfƬpüKH{39{7RGr0"X#) N2Bgu^}zU ذbP_ /e/&8r$t4L; VpuKLljOQoLaz][APw鬱xo~ŵ(@`̆@` ի_FB>BWzݲ6*jA@='q{_ľ#B"Q8k^A7i~oE֖Q4w{!gq)ˏ0K ښ~S_ʮjc搱V'&՞V1H2}5(( Qd)&i)T+&/ӿ?)W]*ރT&U揳> FA.<c,DsuQD?PEZ=if_'m;Eh ((?uR~o+c eCZR!t62΍0aDo:$dLC3I 1 h쵡̗ \ȊPG b0! SXPvSI EJ'[g%]w(+x#H='81bPPV>.jsުWZ΃`Ҝ,;N'>j!RХ,KtuRգx{<UE1b> ihfi+ 4AQR3 bJ F,KE%h3`55\'qCrCxQ^D)LzO$!{_BS64OawMALi".#WB%p`J2b0e}Y:ArpZlp8;<~dEҥ!컜s"5o|QsNW>쟋ԗq;*xt:뜳tH0>""X,vDb"2"u N@ ::wxu/C},c{B\iiXTKhb'B-))bL:H vˍ|nZH&i#)8jC#VY)&/j#$mE8qkVd$HlT?#{ "[-<O飴T !Oܿxc ϰsŇ{:qO9}p_ƛ1"Hey"]{xVUW,wY}Q3)i⦮ldlZ#AtK,ivSG:|' ,ˏ~; A!F$k\8Y'%MV?tZ-B&<0',!%\9͖Gh 3SľLl"Lq {p%U.X<]cvb_?K9*ײgdt \%е$(;8bXvmP^RIox)&m~fVYc Ԅ_?K6٣L|ѡ^+n*  k82\;7'GJ@ *Wax|YZ~l|X8֏HK4V t9A#*LEm^) ÖQ"rOQx-;0P+ `ƀ*\.x7Gq{I/ ɲuh1{ c \eO(ŨeTfnz J~~a.7=&FyxCMP7$ )#]4tB|ck|кG ҒԽtsúf|#rSG}UtpWY%|AB6|p=gdsS>CPvBqoFnk\7uTA)j>p+I;w0{U޺tOL1a V0ipT X03`a)*xD;(^ʸ?m4ZMWy!-V':\|ރӴX`"AM P91`ӓ\sm&u굈4us(<"u$?3&hl=O 0\w~oag͵֙۞֔( Ca+xCp]!abbV&3- ew և̦FZ u1b qc\S[E 8}fN!^}T=@B*ZHħV7'( ֘^:kӪ6=9_+`Wr8]pIy›00H>-uXZ  S¡ *fdOM5|{m4kg+ = rӺ#ÿD=S+0@jj1 y(I 3G Ys;rHvGF\ W(8!câr#W5fiH`BBKIUmH h U ĈĪ"zJT! UzϚf= e:}$U_w TIENDB`mudlet-2.1/src/icons/tag_checkbox.png0000755000175000017500000000055111513237311017210 0ustar csmallcsmallPNG  IHDRabKGD pHYs  tIME 1sNtEXtCommentCreated with The GIMPd%nIDATxڥA0E#Cy"^kp Zwb aQ'mәNf> W`_ۍ 5bu$Ga^/ ϧ?'.s`B2 !'pvHB0LBI9,X# 8碻`qX ]{JJt_`H #Y\T9qCvc68mIENDB`mudlet-2.1/src/icons/accessories-text-editor.png0000755000175000017500000002444711513237311021352 0ustar csmallcsmallPNG  IHDR00% pHYs7\7\Ǥ vpAg00WbKGD X(IDATx̛TTWb#blb#{% $c,Cb{A+(J:3Lro{xֳzolms9M;'xZ~f+ӈ- j賂d`V3>"B;n-$lV;hv=B0^B haؾh٤ۄ@ ~%Qb>aJm!v'~)o3Ʉ"J/㻾|x0!({J>yj߱OcZ$DULjfS#lywQb h:l_Ul܏XڵF2{> %{Nusw&|26Y;߄-Ws3!_1l&h$"JMXuJ1c8DƫD B߽OęU Ƃ\RSFe/!+߀WH!\)tnUg!I;xO$U}2z*6:rg2'L%R]cZ1=G0<|(ccnfOofNrww,ɽ o )BVugqeDOB ((Ӹl_u݄k_-" ?~=QZؒ\[_oW(+":"4~}BJ7"6%L7 Lf3j>#`{iGx{" o>Vq r1,&l2'40㷻sn#O$$`""EMͿwZo|J nTS"ڡ2DDw_ N$!RGE0(^s8qh1UZ'O~#%u'XK4 C q`,nnjf b\\ >cPK;l%͢y;L}A0|tC)6t u|5;e>&MARG.{gh "8bhܭ. &^9liS%j%H0A0Nz`i F@5,A|@$RAk!`3!Cߘ1fZ9[X-u,ֵ]٤'h[&ww 뼐`;lhp&' >`N=$" YD%7sÈcU61Y›/I0Vؖ`hpzވ7Db!J*,G (ҳ ƫ_d4u44vvv'V\3:11]k̿!bK =83V2dLT/U2kؾC )trt96+׮wuaLvDH=c###~- 3/cĻw(SXWCrSn9F X<.lMx#X4'K ~STWTS@+ʋsfzzcEEE"#_˺G|w% >}-[!y(9Tz>*+nC8KaJx@؃i,ԦNXz "5~3-@۩ 2ñXO2C6,g,BqPWCZo9~]_w3Qq)ZB H@|0rv;b`"xa1nbLP@\-|#YIJ3&JPT:[gžR?W[!lŢEma)ڊoHfK좬&FA]8s=cSn _UNd,uafX˼ c`9~)) nkn'j gꛮ c/*]Ɗ<~^%3\Z;c}1WveJ#H-dm}o#h>YTj~T1l?޶C:k;#-֖hu"q[**~U B ~_ؔFwK򞊶Ek  U;͐g:j-佘y` Qz;")Ąh 7Ŷg6_de2 (K- HG] aG) Dtօ^ {}E|j1L wNn MQZ16eSa߼Ls?vM{эD1|tt{AB]2l.9HU4_Qr^qKQ:G=D3&(3ݦ)Se"d*s~,HvbAeI<:?ijCkvVBQNa[8x?c4 I/? h7;`| iSܵdc>1儾&0) y4rjV9~st9mEssVߟ{닡2~?ڬQz;__X-BʘԍCEBN>O-_R 50Bjmr ]' .SX{kc6 { !=ޚ8 u|+r9=FYDCee 8zkӛNo<7x+؂+^{Rg5jGKGju u7aV\=^Ӗev#V/z[aP*\ЌSjfnO枌=wZ:!E4WUKjWGWQQB|k~ [Ֆ ٛnzj !hSDviMγ͓)+\/RM pgp3Q(ZOTz9])v^SG2Eć7"̜>v1?-iH9}#oUGJ6/p8³s~̯vN>UT}xw@7gG80~u>^ܭh*2k][7Dik-sixi]bZn9n)@[7Xdd Kp(ޣ;G($RTY< )KO"5p6rSQ/i8uBp'zW1_?8=λ;(aXCM6AZiQآ0~8Tqg@{{+\\QLʲ%N8<{_1[J][5\N@1H)!Hp$Waaaj 0C8K]K{\]W5žCmrBsBkySSf uǽ4k5wQkaS,gWJsc-gvO XሿnC Vp ֔RŸ޽-,,]-ရG^l0_@nfTQ`\[\S53nZ$s /gf&cli64Ŝk^渎9փu0/tH%q-as2-Ʒbr}&MbaG]Z&>D؝`6t)4r}|b+[IBY|pةsz뱾Ǯ' tz&*mȿ0h'i ?}|.O6бP: 6[-H}j%8l'JZK%[ACl#m^W+ܹ}vw'v +cy x&/8yy^ nـT]7C ??%O'p" m#;s X ٛδO[[Z@ T4th#ND?(CP(iuyvD93WxHl=qrql򂤅gOzy 4~*?P^_)f#-b,'0M HEe. _oK%\&axa: qu]v8s2l6wDj;~mQY½*vJ= ;W.en؛Ovo'إ$O8;&\;huҏ- hχ6MX@@@I5/Dqldk#(8D ck]Zb8ت*74.؛x)lCGwDWh5<` !;ԝU(ƩKS^!IJ,p<[Kk6cƮF)V0(Q#zJڔXM+Koό;#JGJ3Yh8M}0@= $X]]vhq`Vwt$V[UX5/kpo mHWuW%IE $BE+my|7P-SmV&y"&OvD*(k\VR{-\ /zV>'q6D HP0T[bWxS/5D.k)g+WWiVe@O/}"nss %{^x\hf\1 lן5~sh摪gʀys/ZS9}[ DhBڕL7 Kܚ<#3[c,v6GgZ%K4KA1 '="_G+{(ꌪwd/ g,INHN5 ,;,u ߧSdg f1W8s`3;;?ȝSzçȷ3:;Qm!ȧzcƄΩWv_dm>hu,?'|%ɪ d]ݐ@Ybb-~&T2T rAO O\є7y"SȚANJWFYHL?K`˄B GVYa2uR*G">`+K[1kWM Pta)%sXb|*]LkE* tyVǝn %m11PQ"{zh|xqΩ[nN#vQCrM?X{O;LRwI-Rz+(hPP?.K6YZcl /Xp[Y˕RV],@rtRQ'ئxkpmw}VsHMcV!̈́ qHf4.@ψNCQ'?98lƌ-feAӟitW!lJB*xUV02.+-L5@͏ʳ+̱$&!e1#?mlM\@gԙDLsKr2qF /^)G^ŸA?͌[fʮ!` }rpMgS''4-L]΁U!/">GpЃs> _1m9a>~}"{v#3zތGOO}_.ꂚ48=+YbR=Rwq2/;B,zj7O־|x1Lb\ݚX@g ]{x+F=a:Ԋ{t/r}= V~< `3'`faegk*d,[}!; =gi"y0']=/x v\̴ݼ{7?~tLwJ?Cӕj*]Q*e V ˗! |[ $n~3I٥!"kAͦ7\aFD|%9G޲޲HAu^X=`%[zxtb=c^S;Jr/"Pl38Nv!"O7,&p7W>~#]ɽC)R>,7zvM~ EeL3c{?oC-pԷF|b0av*Ÿ( o?ibga&Iz@z;2N%i4 _׽q}*%.U'f:~uls`yU1x4,xg#7l ZgW^zOF$yQ9.UP;'J#3%u BŎ"\oxa|n#î,m]iߚlaE5f RΨxqUʋH[J O6 ̭/ *lTXlҬ׬}Xíl+@OM( ʱo7t xm5:4YlM5x\onB,۝㽈଻O4=_LؘȵCʤjy c20Pl Wuuvw:΃)^mߘ8Ͻh"ܴLX1i͂Z/P+QaBm% ͙w g$b$ipθ {_΋|[9=瞳syJFۛ-ՏՎ? Uqk58]Y'rMW".U?]ɖx`>X4(I䓎tv;9F* U"YSҕF=9Z-F[#FvX\&'yܝ.%FΑV}Xɐ ~Z){86.T'uIC>קwB}!^Oz&y^8Td_a@ҨD DiO_AcK)(zD\qe2U@|> o084.e[S`mmem;RKj?Cu|>>яef%z1umG˚O'J'򺒬__/pFҨ4" 뛕XbQ`.@wc} 1; .CFWFWQxEɋAFna9Zt2v +x?ˉ8~U{C R>v[2ZJˢ >=ܣ;h~h'Zg A@D Hr*@4U~Sv~ HlB}cyf+d.) Z934Y׋~\&mRuѰf?5/UP[&\kњFF4U#`\"o$| ݝp)c?D-#ӫ!NܓybJY6+ 5l7^o=QY?H'E|`D:{n8o"_ h.w ]-OBwض;5BC3!~vrE\g<`lcbyކ0/(ˬׁ}.6џ2%Zv@QλQ T Ľêġl`Lo#X;_/+oz}&/4vzX+d }X4;5Cde+,Y v4{ĻaSz1`b`n!0Ӿ#z߅!q@"zTXtSoftwarex+//.NN,H/J6XS\IENDB`mudlet-2.1/src/icons/media-tape.png0000755000175000017500000000223211513237311016573 0ustar csmallcsmallPNG  IHDR00 1 sBITUF pHYs11(RtEXtSoftwarewww.inkscape.org<IDATxK]E>gc20$>B'QBPt#hvu#.P] dpep(.0b00Qsgr_n:==L.ld>5wU l.9{x@ #*Q;>FK߾ g.&W4AjLruYM/a"jP %יbIK=:@ztA, B WLDŒh37Qd#HFG̼J WҖUu,g .F nzt7!DĽp! Z Y_cvQszoɈ+}H!q)9:4uDt$>k^OA2K)c݁PUV1|-Dz Z /Xa^ i)pxTfĜ Yn^K UE{X,W3ó|yOvpk؇f)3Fh& C4fcԔ.vqO)}x Ax7c|9빊ERh'#q` ܂ @RTx/,3J٫':,x^͘+9QtMPlS9x,iX5)'4s|cM%_K,Lfz2@~>f=w,/)2!9[}pky8 vz*8kl1F& bar#76I-2N7ăb`A@2YWa7юv9G9EoS])@ }|O1k1xhQ 44A/eh$ҠtT>`jSSB}ΆNMqd juDmU*[_uU5{Mƣ|i׀tM7T`eh!m cc)sg$mUasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< @IDATxkg9;3沛%mM-Tlk7 D' JM"RUZݨF[P?TbhK`l&--qwe33a/3Yagsv<;fZ J~!si^hi4Z- @f֎Cg~xѡbo^>?' ,N~l= ܵzw=?}5={# @5`A}:6 l3[68xsXeߐ޴fx_ߖ~MC  7:Ͱu_:!M&f R.aolۢ!X0Kƭ p,`o]ϓ'W}"_G-z7nkPRӿkn?'] AkO,ۧ|a XsuXKܺc{*du1 ѴlLՀjx@#j8[LTטF TTh4]*]ԧhL7قҗO?rӣcC?S2?ύݴ6=ٴYKqozq埭 Vg}vuw?b;{v p]A'OkYaS;X~yr/5y ( dDRv'_jq+/O5ASW!˥ &'qs9[JTMQ-ZTQyZ{`[ Ź'/ylqO`QZ46@.ngV7EWSJޘ4uXv,,EKߠ,6@S`~ꔷvcb,//A`ޏ] HhdLEM`6<8ADf l@ d'N8bωsD`0FPjF6aB^tz^FOڼykb!e| }M 04 _'5BwBj&p @.@ 'L̼NM{<7iY@ imˋlm {r9!g@BH/#"UNIyi^ (8{X6`TrN!O2YK45l$A>ý:ir&f, C ȰQ~"l*^1H^ @1FX.`/x7ui @(L "eH~J7\V< o B\z_a7zֻ+Dl%@ ?z)ػN°kb:o]'f1RMvF`R&f,zOwn>M 0ͼ@w+Ho k6:X 0.-'2.cBzWPc !ThW4 rG"@tb+R]cBH"v  WD6%q9h'P$e%30*ぁt8KuY p#B0"ۆ W`Zt{E;5e`~%"]H& w8w"tL'6A81N"J>H@ܱZhfM c+c86*^sI[@(&(4BAW(N1Iאk^ۿO82QBAsvQ|qCq)NmqK@\K@Gz0|"ġzc}n_ gPEKq~ø V/~>z9\NKq*n=Z&b23kń5DU˹9 2"s632Sҋ8?G u `\*1 u5x9 1畞fH\9gg8cqOD bι7fOq~N9r̹ uDžI`3ț#׹ as姞ث L]g{ܵ] @zJ+^ V.Jhi4Z- ڥAȋ!@ < FKIENDB`mudlet-2.1/src/icons/folder-grey.png0000755000175000017500000000102212070466512017006 0ustar csmallcsmallPNG  IHDR szzIDATX헭Aϩ[}K18 HQ#' ` <Ǻ3 Wz]\u|n4pۋc^_+ꁔc|WU˳χ0c3 ã@RDr<94#*d2Z61>o.}?p$sAܻ4X,{p$)GlNc#Ƙ,1{!Ym%RJ')%iH)d$ #"u1KDj0 \8Uq\BjlcT5ز,qQ~EQ ČH򇁦iRb1 1?ƘlDdo9W`AF8j ﳎZ @Q y zCQ1J;@>ضmnǶmm5`U鴲MӜo yf9_.|ny}L~73TIENDB`mudlet-2.1/src/icons/export.png0000755000175000017500000002411511513237311016112 0ustar csmallcsmallPNG  IHDR>asRGB7MS tiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}xWO?UOU x"')6 sg20PNj'fKލhxOߟ!rx\ Q! 9]pfZ; ^W8'p7AeH1_pt#2 sbIv վq͕`ҢD-?K]yqiq9+ Ff;`)^S; e7=k,@)'ZYЀ(d"P@3` lpbALv|PJAPjAh ep wx ` X  !$)Ad!k (xP: R _se4=&Yo#$+>̆`)p+z_o#~ / !" DE؈⍄"َ H=Ҋt#=D!P D,Qڎ*BUN:P}{ < G-n`t :.G7W#); 0fWL&)ƴa.a0,+Za4l>{ {;¾qJ8#3.q͸0nǫ-x.~+߀OO'"TZ W 7D"QhN%w+׉$*I@ #N.ސd -9FGn"_!?%鉹qvUu );FJrr2'w.^-~N|L|A&a(-$Q$,qCbjP\j uTi4m7v6EYt7z<3}>/I4 "Y-yAR@ 7F"q1( e'%WUjXjQZNV:J@MzD SI&AfLYl٫srt9K9\G򰼶|1EdJ+ s E[x2Y%RRELI3Yc++*+)*/TTrUTT٪ѪejJj^j9j-jlXC, =3,i+$khhkhkՆMc::q:uVW⭪_5KҵmѝcyuW߯߯ Ѡ!0װo#m#QΫwZX8^Ϧf|VY35p16.b_7Gۛ0?o"_ ͖3kXk4RX3íZ lm"lm٪rmmNٽ7۷/:X8ls888:Q:888ϻd\rEzwsSp5ͻos yxܽxU_[ ݼx?a}g׿nӺuhRJۂoȆątbCCC;?~*$,?ltkÖ 76nLxaeSĦO n5!K-;eU5m]=cs f6&R)ᕌT4tׁ2fYAۃ(7.=D8~HPYUVYR*jھFfoa#GZkj k?;Υ^XƱ Ǜe ?;d,\̞ ;ugǟZu[m/~ eǙ޳쳭ZNk/:vwv BιnMW_PCYuqR1'{7>|~oUׯ9_o7,nɾyVǀ@m탦wt5=fgf={ݿ5vdh4`Xؘće O%[Z,x/A2?a?U|rD. r \@"D. r \@"?vnAVccgy*4i=ܺuzTXtauthorxH!s)fIDATx] pי9t_ %q0elC8[vIvmpdk׎>8Yrm69+q#’Ffݯ{f$$1oU3D4d˕[hd-YdKْ@d-Yd˕T|W'm- +D9rd֬Y(3@p\@/;աЌ@2bVӆ_t}^) ӟTyK6S!//j DCS -%~*++Æ6Țq;} KADvt<{q_ᄃ Wb{r͑gy(-kaN!rrCS/-< A`6Z;:7OV^%R4 cM_ɝ,ƃ ]J.35fyUgBpa5hh:~SP% T9I!gISB49t*s&]T?4L)3Cנ>5IBtݏ M]_وFqsW}ƟbTB_S ʓZ/KȭLׯ(%}lfH^]T ЅF'>b ?lkkCnWP ŏr  #}`kytoLJ?*ġƆFT*IM@I1*)0I_.vX]EJrJ,j_|¶s`U*N>fC~2迍RHǸ/\okV˪1ct=+ 556jČzYjTӧ),X]dEE_=a:,.C9INFA ~ܽnw<ī s)<~|@C#%JOhX}>\h9_*h7/a.ˠ/v DȴlG?c'Zcqr 3RuH G"Bia8:kq [.T&0]E/ @=< 9Ўq%IvT>R8j`>">Vr9x趇pNN`DSk(ZZ;~ T8I7(;PF&R8*`!}Hv=T)s ː{TP- ZjdmZŧ]L=B >Vv|l}Mm.gxa45A a `_˛XU{-\f@ gxA LI Z8lb +m$)fpȒ&s_Ah h` Zfhi{kƧ'YR8"}8z=:Ӆn#+Ee ha4]x\'Lj1F +>RI5۰h"4t4i=Hxnu/ ASxn&>*4]EtHE 髝R߁h-CHӄRW C"CP6եS0~߼('ۇ Hߋ"o5n`K;/j'XF>װn\#pRxH!Jߙ&q4A./pBsaac`#MtP d $g7wq D UX>|]Iu۱8yڽerLkX 죈AtZ9MoXvaoqRh2K>;phBKw| Z85xj/"(3hw#eaP2h8P6jkB+9%SC!Be CM ^}ս\\<-E4Pkɐu xO(XBĻ' -)x<=H,hUns>CDW K.0C+X[* |JRHg> BM?gaiWHs2Y 9-XBV/F_bˢ ǗJ*PBzw%}\{ Y~ d'Ti 4s>9 0$.fEB=|7.t 1BLGzDc< @e.S RkLilY 4ae13R8>tpp#}|r޺VRkp~1AFv@ @! 8J'KH~9T\)Hg8>>*'8k..(.>]- 9ͩ_㺚(-Iޛ N w_ )oԇpSؚm4G4P"2S: >6Pr&d콌mpR[ޚLVKT`?K i'LH߭ފWDdTHیHf.Hڗ)Ry#܁?6}4I ?Ic#L6` xg~Ny<}t+'}ow7yl;h\̂THBfGP*{sBgrkho@Sw#̈,U( y-A>荧Z&,Υ&LƤIذriZE4 AT "/wD @f 2Eg>iM57`z1ބp4rɎ]gl|-|a?Y7º:TMByQ9T4qlW# ?Dܛ3 ,XO $7A^B7|0C]e4!x:}=/s,zel%\ں[qc ї97蚉+ %|~B#N4@N\]@kG+O`vNN!<*8r ,YZ@JP^fMM&]5ȡ(ں c+J5nPa[wK8k&hg(bLPw_ž00<ާw hwbߙҊZnttp4z{2S$÷>v .lU2TBѫG-|ٛ Gş IeO$f2(o6r9+Se{16fJ֑y9fw1zC:.َ q.r.JӬHBƦ?/(^U)8/ Ɵ{Jj\k艆YosHP84/o ҽv=3Y-\(lqFL<.w!ѤC yAԳf$h7;ޫH;X:g1zgRJ-͆`O$mwpRo^ `rhDAjfrԤ9p 65Woj,]网=X`M2?/ Ɗ+-?+[ҿߴ&TVUBV-|f R)XU"Iߓw?>Z5\l'1\KpRi~?abqU%Gplx߼PUU:@5~O,RĐßxZXie$tue.AD=#^$ONdJXٺz+jgբ*dvp.&B]@`~z SͻKAL{{f&ѥX5Qn-;/%kHA$ t%|nv:m0cFUc*Q/[~N +Gw~$3 ;^዇ut\}yUX%qE3Ćخ"5WZ$|ZU@ vq :QWMS kmg܄UInƂK't8H߷>-3]+~unɤMo7 l?r%u~}bEc8pce^<-)tfo.o~Ñ#88#!j5뗙&L̒VD}g" 9ຉWv] )CI Dr"&铹sm`' 6b' 0poכg:/S04x՟㖙[D%J*q(}v,]MMA*OIU`Oٳl@r6&hI#݁?lٙ˘NO~尣wO*l/_^s'z F]j7rAw@|8Yù4oĚU:)T 5)?ګP*ӋήNRƯzG ]GyprM}L?u|,$&Z#9K:StG#-:pӼ0}P31#?GF8?hh_{µB/worEهe+ZU_ S4|Z["{ɳ7QDo#rmT1#X};+׈m$|z|rm*l 5yE`ʼڊo/_9 =@L b^ϽW Pa>M|ô0b>6 .d4vL1Fd)~>}8UFK~cHTѪmݡʉE{ 9 jFKY i6MJMZ)܁m~d2;U>{U L*ՉF#= V˒0:TХK8@A_NI&!v $4itl۴f>Flp*kI MK00&AȖK/n^ bp9s=}o>=3g8}0,_{70 \,qN9e(.q~j98 H=1Z4։33Fm 7/0PD~^q+M/L<,D~- ׇpj g-B헐ٻ,Pۗ?ok}}eຨRZaoSXr/7%2<Ҽy|=r.;9ùz=CIW3m  |\}Ƥmʐ_m ;u*` 4tCEO6,S:2}|m&A ` thgy93xS]<پUК$dZHF\K_~ g!!HAz$̣]~}vwGCabl Ii3 .292Қ5`h[|5([Z}F'iv T.;\8y'&l ,?e Fz %`6[U+p,"Ae-E9~R%'0w/d1|Դ4 Ox0ߟm0gzr9tpTmSYEkP5L9faa=b 7ލK"Gis>I=۲/Mѕ$ }09vRБ) W( _,Ff>VKBE Fl=_va…((&G;1u=zB2+ҌQf$FPm4oGi:X[9'Z1qԿ3g~};bT)Dپ|ikoir YQVdĊ3nPb$2w"1nV?$>g&J:JUm!0DkrzjO_}uϗ"rm O^O%@sz|_lK,*pxm?M>KDs9YQ"BF_-efFTe+qW%zfⴵpٷt y"a%,[`>jfy"&eH}&5f<- u6GeJG%g}$w#v87iqf\)3'|1RG:#!#_ H{1h\#|/$$ߑXRhQA1,Q <h$< ;xIoHOI? }&$?DQ Y5Pcm(*""’[o,`:ey.wk)^{,R1Od}ژx#0Ijbؙ-|J=ӞiYD"&2Dp50.\OG14Y#J=6iF {:D.=`mTw 'ڗpJ7Q2Ӿ5UUQjk@"NfF}~σIvÖt=V2$b MN!N׺#Na3o[bg3mg'yMQ(MZ$&$ W59Un 91 ~dH4]?8:rU i$TGܟ qe7|72- fq\lWU'M0{  &Hj`"î 4 $?8% 7]' IENDB`mudlet-2.1/src/icons/folder-brown.png0000755000175000017500000000122711513237311017170 0ustar csmallcsmallPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx헱jQ3nv#y;V bk!>@*ja6GP1{ٙ{ɲ4ieF q{詈 pwozjkk6^Yʢٴ3 Gǽ6׶xO p8QYUuwREaup^`:=RWs䠚W[>쏮/@p`dѾ}CHRE 5N}TH$ a8$y0J' iCMɨ솙Aj4rK "XA ɷ$8 uB m2);DMHy&_J5Zi#/S FӨ@ͨJj6E)y3i!]Q5 )Pe V1YE#)LA-Y9 ,jIɑRĬ@i)"SeCj!d2T{E=3mʣO_LF팯!LnmN=یD|OڼsKP،6IENDB`mudlet-2.1/src/icons/system-restart.png0000755000175000017500000000551511513237311017602 0ustar csmallcsmallPNG  IHDR00WbKGD pHYs^tIME *-z7 IDATxXYG{zvf{xw6>6$q:JA(Hr$H(/K</y 1B,`1Z{qzvf议vmoMUTWT ׍!gp`3n嵃 SHpB~%4X y \NKazj6;bKy=O_:5rwڂDta\{H}l>wQW)ç?ox?^1Pw )|iQoRX}vնI7<}fH0W°RzXy]J0hE@*eMamzɛ0@ +<l#ι7PN_JWŹR /^H>5r rXMNSM5TCD&NK 8H }HI<PH"Xˉl5y<clپ(Q\SŖ`Rġ9&=M! V Oފap]ڒξ(9nfג#\@:ᡌ|NDq$\ۼ:CuINN,8%)E uˈqJH uXR0\n6+q $$Hha`u['mq_\kI uXѬlΥ)K`QV$7v¥ 0sQ>E9Hp! YK  nhJg A)ז+`0tio&w* @,eEɊXrfal};AA|Xd^nBqld]F1tFn@1y9;Q^֐%,PsuB_Vڸ>Dqf\Fln`s7`ҕz.Z+BfYqtUo6S8*$=+>@ XM\ZwsBOQ̫X2;OO;poN:,>\]i \5\P.>P<=1p.@2.RJP9|:\Fm6!ui $/ndd&e&«2):)IZؗz"ۇANM ~MCp-rHPB%4 [{>}F,45`< 1 ,W^![oyRw4Q|xY?6c'Wԝ sr_G +М3U (xu:Ό<DK@O=HW$UoHA)m~wCLG`+  Hd Ik ^:mq8xT߼"tHn2CյP+jk~c^v,R,)B#TD+\ +h6+wH/@$K $u@V@vOh6ǖ޵/܏g!7R6}=َ^~ <?W3MҜ U+s*nϬm&E_R$āP iJ&bDc}] 3h?A?a:ӼOF w *{&לh([111?niOk辆=(fޯCHN?dr8[{+$te'?)%{uDyS `"`"9RTG|^ēi%k-<}ӟY)dj #L\1ő::?lZr VKrO.iWDn%z #u%F g}}6HVA_}Ip!bg)ű EECԐWUh>$yAf:X{K`~ae `f!x>:} 9{-z ̌ 0 5l^ 2iXPA+A Nt  RYXsvS@؍4Ytwx=ܙ>wRtM0bٸ&0fk(.4_asRGB7MS tiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}xWO?UOU x"')6 sg20PNj'fKލhxOߟ!rx\ Q! 9]pfZ; ^W8'p7AeH1_pt#2 sbIv վq͕`ҢD-?K]yqiq9+ Ff;`)^S; e7=k,@)'ZYЀ(d"P@3` lpbALv|PJAPjAh ep wx ` X  !$)Ad!k (xP: R _se4=&Yo#$+>̆`)p+z_o#~ / !" DE؈⍄"َ H=Ҋt#=D!P D,Qڎ*BUN:P}{ < G-n`t :.G7W#); 0fWL&)ƴa.a0,+Za4l>{ {;¾qJ8#3.q͸0nǫ-x.~+߀OO'"TZ W 7D"QhN%w+׉$*I@ #N.ސd -9FGn"_!?%鉹qvUu );FJrr2'w.^-~N|L|A&a(-$Q$,qCbjP\j uTi4m7v6EYt7z<3}>/I4 "Y-yAR@ 7F"q1( e'%WUjXjQZNV:J@MzD SI&AfLYl٫srt9K9\G򰼶|1EdJ+ s E[x2Y%RRELI3Yc++*+)*/TTrUTT٪ѪejJj^j9j-jlXC, =3,i+$khhkhkՆMc::q:uVW⭪_5KҵmѝcyuW߯߯ Ѡ!0װo#m#QΫwZX8^Ϧf|VY35p16.b_7Gۛ0?o"_ ͖3kXk4RX3íZ lm"lm٪rmmNٽ7۷/:X8ls888:Q:888ϻd\rEzwsSp5ͻos yxܽxU_[ ݼx?a}g׿nӺuhRJۂoȆątbCCC;?~*$,?ltkÖ 76nLxaeSĦO n5!K-;eU5m]=cs f6&R)ᕌT4tׁ2fYAۃ(7.=D8~HPYUVYR*jھFfoa#GZkj k?;Υ^XƱ Ǜe ?;d,\̞ ;ugǟZu[m/~ eǙ޳쳭ZNk/:vwv BιnMW_PCYuqR1'{7>|~oUׯ9_o7,nɾyVǀ@m탦wt5=fgf={ݿ5vdh4`Xؘće O%[Z,x/A2?a?U|rD. r \@"D. r \@"?vnAVccgy*4i=ܺuzTXtauthorxH!s)IDATx]ytřuϥ1,Y%m0ðI lB}d7 !‘v&f@8|_>$uXiڪYrwWw߯}UDA\8E$۱$v | _ȗ<%| _ȗ<%| _}f{Ep)R 3 0H'R6җ%1ЏR2ԅ"Pь>4H,gs }Z*B=~TC߼&|x@"i#s63z=:ZT~<'ط^Z]KuO!]$1}&@VZŅ?WjqLQ҅j[6/HS?q-@p{\p C'Z;[}K{O4e/.y,+*bDALUWЯ)@Iz2 pwXoFp)ȑ8KQAfVĒ(-*e @AKG]oEz@9#IEŕ}TJP^86'ē@`ou_K`?Oll׎UK]'s ' ݗرY(g?ɸ~C VEZTVbRh&M@Cř33oS h zP>7 1P$ݶK^9YJc+Ybb9O6شRcMUcrZo_(R BUy,(1O-{]c#{ޮx<,'+]++*QZZ@ P0_ Z[Z݆sMG < p59R.Ʊ=̠hۦ 0aբ |K3$Vg-*dZ}_ >G?)YܷUYoٚ{U$0P@$Q%UaݎuGp #;ƣ:`RYىh(95}z՘Tgze@2*HIs`K/vKvYn96~xΡNԷk y}XBIzyu,<퍽<MMM[P=o:j@Jbqn9oF>,V2XsM|oDiqea p]6pAN{)sMOQtSM{- hתP{vbՖUh>b9 9y4uKh"׎Wn*g3f#l4J*DP6]LǛ4 :/C/<ċd2H=IP`v'w ;׉n?-<|KYgc.rQhݱ4S`^ e?rCi@[F -E;}5 h YOh"p*~IOtDWν'7.0խh 4BO 4N'VHZ ?볊 FɿbDF'Ыn41RiTUcZŴdY ޯiR$zT|HU8gh4M MQL^gF89lT.')`ckn@($Sk0d3*T|񮡔kՄ*;7_gOy1gBLR>qdd DѷE 8 '[wOQY}~ i'b'PвKI뤯8Q_!%} )ܓ lVu+>{s>v?o@PYlyrlHkYwaBܾ!'}6SRxBYIFTg#^0s]쿃yYm6߫B{0JhyF~a!}B"4Beh*˪әp $e,]E%{(-R'sT^y B&)ܢ.CBiA~%5KQ,8 L8䯕@X)%SPk667J 7(? >H9|. 7+=YjAL#0AR)c אAI 2RO{nl=ϸg`ѼAr_ !cP4g>iFj'GO2oH`VRG Ow7lW;.nc:(g퓝CB})( F9G_^nG3s/:o`Cr+QcmCg2J¡ :>+ > G^w4 ?i>^~e7S )LR]1u.VkW^@qcr?[k~1+]z+맥'Ng5 Z `%))TtRJW`9s/kh4a; EG+ zկKJHnS_=|rd+_zRyV+DY]K%Ct6T+*?.Og#K)RBݚ܉KB$eg+x]6O-TL8݈HX@Hߣ/=$}B'}QRxNYm 6@ALT`Ja]k6\8Nt-5#}tuJO&)>uI U균VZ$e v"/N@jf0 &NBsS3G mʝ66a:L( +hn@~Y/ hP9m{taΟÉA<[N-0 9mő=7@`{mO~~+`cT̜!ɖLӘ }ZP~Tfx TCћXai.XMquJTNDj>BSq,f$46sihEXm-45>AwrdmG=3C1nr-Wc }l@I?Tû%)AD˽HBϢ 'p %VgIJY-/,ֳXejp8α ~+,({)\~:>Dp>N( l۵\w-6SmOP|[ ih7^xCdwL \(,(J.?@,H"5޶PMoKGpebQ[oO ww[\Z("F<${'d KfW; \'T>cCAB{Ds<n[<-Pe[$'GBЙl*f%M <Dدm_M[^n@2[*rq67@[n]2// XPS/C5Fac@{<3CG<C0#F _γ0Utgg$iдW,W@hغaZTOGMYMzD%r>U e=@6i @i@~d/x!"KexӇG0?+>Ss#Jbf&ʫXf@L+hwiX/@6mg‡[>īʋflN|vW3r]D _ᄟ 3lMĮm p.'T_7?iA%ZeHt$"lIJ _ZwS@V2b)_^p^,8 ;$)-"0'0V-٬G.?@ Yo]f~'p|&krJ$t57m`9q d N"C ]uո٦ YG>?!7+oX؁)jL+O4A.@p&ԵŃh* y*?>Hӣ#?vJ U{~w !HIV.@ YnXYAv8#6P †ǯIߨUl|D?n$)7 \d?&Ծœ . b3Ap?{ӲX^%VK5@@ ' z G>oP`36)Ot4l;jky@5 Hc Bv H|Y^Sy -[>ԩB Y~SPI:X I2 <[8p)p@\ CW$lA+uBY,iNAk}%eKQ-l Ur \`[U?DJ3 !qpfNmaUFWXIv,MS> W6f 6bcZxРd8:`}<J6RxH~T~nlIA" 3PSA6hBMi1n %,=B|㿾1oH`6J OSRHR;NL.pYa.~~@]W[& 78L\TC@N˒Kp㷏2A}z&Q9T9dT )R~Neu"8{7.r,dQ"-{!}C QY0N-Ξgu `[Z*A )7 Ѿ9717J wIpq"}'ݐ9Tt.!'h(|Ƞ""`K|%(?>-aJڴ0 QU3'1QIFLRXGMAN 3WT9s+iY\r NS|W`BF6kQKFC)s]'bQd;]\?G"$|IND*|̜D^%~hTQr){[Y(.PjlE 5q`&\fR+} JkФ4#9h3f#-z?/l!㷒AzJ<9q>'}&)lH_,&'Ν@T[?B$ ! K!fWZ;Z_oT$GSR o>9US d\r ?#`YF7`V`J 땻 fl{Q\Z00yJ$}"UM9"=}yP?ҿyHqPIڱW=?)̆ 6B helZcf4?S;"}c&)즤B*Xw;&}JlNI-|@aXNI_l쑾1WBIlbi}[jfJf#rưR;קsm:#MG,AI_tl#EI(k9ALt`; 0@݉Gw؁OoF OSt%l 7aִIRaƐAg*f:60Ia^uKmD?&OQ h^*RxcT/BG746@7ITi)i>6f9>5'Cg'8B=e;Ha*.'tfN B!if!:ۇwJz)ko\$J -R ^= T1gTW +m/#}+c=>-+~AƷI7kyFq_췂 |2璿髏D>V==q!qVV<"~ǧ3Sl12iXM(X.wA)n+rgn#<!^jO_/"pnɜ%o|zc?.`N o=՟>TWS @"`f _ gG1t _g]能Tm9ZEP0tW5;H/sb.sk{QO,#UUU 0 V &T`~z@/yK@/yKz.•[QuIENDB`mudlet-2.1/src/icons/logo_mm-120x30px-verticalBlackBgd.png0000644000175000017500000001375411624306130022611 0ustar csmallcsmallPNG  IHDRxhMtEXtSoftwareAdobe ImageReadyqe<IDATxZtչ3jj+z%۲"*Ɛ%!8 I#wB#49f `l9qW$[mUVҮ}gfwgvfv]mPc${|d-ݿ|?_2ٶI" %tWt"ek+ ڻA3ߞkm?] U7*l@A'Cl6{CH UՆsz'=鳷S*ﻮ>*e,ZiQLIq#"hJr*/+W4:}mhh`TQdIYmV.t~L\̾Ns] Usn0YYG\1Rl{>;ǎE’QЖm] )XeQ\RF"T̛X6DV9 m:& aEL1 aDrh(Q$ЍaH2)0l<f Sfe8.aKױY8I'H _|D%>ZD8jQ{ؓޓ,7V[TڢNǎOR:BmSs 2OXmad<NJ #%fjMN[e[Ow#=E5-Rd<6,ArEJH>NxcWЈ&e$qz5 d*Gr /<qd95w\7M:.ИPV~|t}դ?}{m2OM^d|~뇁b$΄lW O޷X?L&Ñxq.u춷ce?ʙK~pFˊfoUQ#[Aiͪ&/ )M}fM^S0]ѯY&z>TTowuj|M17K.}2E| Ab2|~fy#vw18Tp03!68.1O] S,qڢ16Ppz)Z]ey>$xY! a!uƯ]]1+[~5\F.0U52Y0nh<]u_;lFgo̻fӼwk/M;,$~p-eCᑗ-T@mS(VRh`Ş/ bCQߵ]u#1BfQSlkR|C@yDƱ$V#2#MGc&˖råw,ʳ@f$U<}|fzfV! p+NDf[ܟ<1qm=꼪8)Jt4*ݼQt× zepzK O4H,\s-E/쇱k[>>ܸ*_֞x:~w-Y;oZKY^?ɲ bYe2nT YB1͝=}uITk dG9Iɘ w3/?֏P*VRHP'@ 5A속fFI@>FPe^FZI*(I*n\ nJ&etNi' b4 *^nw\Fnoɷ,I40[l> 8`[7G=,cMaNaV .[QtZjղ® 7]ט־tK[7J0:cT[I־s/oT\4&)-),0eVI* 'H.6#S+Jdg֯Ԛ :n2&^_;l9 `323=ݖ^=zb!.&(ź*瞓"KrrNBO$ @C ێe;½SxD{JB8ڒg_=G|쩝?~zeյ5%kR`;rHRu)V &uݡvw_jsO\L#Eb2M^lgX|𑝏>Ώ~{ Z/Hqr 1ؚUs8{ɓ޺z(tQI/A %P21{6=x85h@J~Y贚-l,}H0x>vǡC RFêKZ-BMuu%?r4 mukZu:¬|kf%v]sMup)^XLeECL\8t7ƹU--*fI7U{ x+ ォXdہ $DLY8h|*>6Cd y9awj5SvJL`+.P4ȞꉄCb}x\!qh$ ~@PW%!X&68<~.M:I6*?H$zzi?ZEFx8C,E.//&&<[RX[Y2tf>ye(Jf>:3LK/iQl390p\щEK2?I4Ґ[pDDN;L8bVꕷ\t//64dBr|FR@@#a *g97@k(E>ubs{c.rbKkI d6y,w̕,$!j \&,_PTmn-ɿQ b]ou,ɤ E>Sw:թ Q1l"ed48f(Lg5e6j\$#χjZ㙹poz`dk#1UX'#aF! EᗹoA}вr؆ $CEtd\B(i\mTDn_{{trғR7CT"IL}΅:9>WI vQ"1QEZ϶:WTw\Sg@pzvuKKi^MBV=}TH&}]R0'ߋFH;4:G+3x  ѮD)/}2yF^A)!I>VUb#Bs!JذIsW/-T#R\M,VTe%ԡ9$}†ꂛ:]\OVy<wOp3?Ge6!dW S We-Omwrb$A to^[eN͊Ͳs3ߊn{'>?a$7[FHo:Qw7&F=Q ǥ{u&eEq;'XP# gqJk xNpJ⾯gMUkOs]a(:#$nc[ҨY(㺺;n(z~;G>?WGҕ?|ahAd( 7my;s{ff'txK(TJR-߼ ɋ enc??Ϣ/4M #`{m'QDZ4/1J,_mͧ8;O=eDkh1vn KWb˽n 9BV-(>gtFƍeZ.SVݼ4!cL|e^ l0 |4p> K BIRiT*U%E)XDg'ܞҟ ZZ7|o3[gUB{Eٗ_{锳HҬdvQ_"?!*Q6:5$mj\U!Be8:fwgYєc1c:.e~HC]Spť 󵦭N Q'(Ψd_6*!Y²eC)(ȟVȕ+}w kV Du @4ԼS4 w${:( Oڵ G òws6R[7/).vn2k IQ_ܵ@fҼI@ +rX2XWTV3b4q A JFYh\b.k 0&)e_Jas׊Uϋ'Fiܓ~m=~?8?Wg/nVWYr :5;FmdZ_P`91@?={tL~=h|jnG8>"+J{՞mS)-j-Y=ABnش({C&Kr[|Ɋy0^ W4Yl *~ \hhh P(PO**-u8^f|;W%.).uUe+]81bpgsLHQ t:HC:F3y6MvSj/.jP8|Χ~Нf3}v'&eij얛V%Egjz&o'"Ue=˝Hڳeet, 8oe;ڸna~L$TShn*+(VUΖ68rƁ,by?Ny/**i^RnXzmvyګ[ ŭB 3>$B{}ʕ+[xs,l#я~sG߾}#G'Գ^I~juƇ{t Âbjl}tm< #dWXO@(IR]M*\K 5™ʰ|vmxxP7fC^Vy8PO#ђguu'Z!fgxؗब,@БSgLGf6L 69 ɨBARϋ8A)IͰkJR@P*~,ʹ;_8(ʨ׋iB3,0@In?MQ1 L$XL(AJ2$] Th 5glVJEMyfx?FfmlˬZ H33)!H>k\u& ;?xf}Kα ]DOo' 89IENDB`mudlet-2.1/src/icons/document-new.png0000755000175000017500000000463511513237311017203 0ustar csmallcsmallPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< IDATx՚kl;3kݍqp)(R!(!?- (|U)"_8%"y RVqgn5ah|pqyuU{1PDķž(q?ZO"C)E'f\ʕg]X^_bx3?,$I.~O`FGjuB5Z[ G.d[)EH9缞e]w ofud+ek_KdX/KH3hi"h) =NլrlY ̕r]x?8̂-[<393#s@N)&}}^ Cy9 ,[z<> Oɚt_qrlϱyx34{r~h@H@=j+`@`/u.stuM`sRG`*>OqPר9>YkZ  3DOEũ$9w ǤД>q% a$ *nqg?z()k>'CJlNC8d`yP qu.@B8q@0{.[9(_}ʂx O_(NU+7mL@ZXxd3zGXɴP6<&mdmL &n- dJ4:0F0_ʛ,(y>\ TBa)L!`|[_nXBL(DobiS8Nsκsy|q)+yh` QfP) pʐ68 ^~{,#] G UWsٳ~9 ~|h]@=Hrx߲8T@Yd2lڴIK{n=@\Je@G ^ tE ?@^ᵓx%&q8ؓáu PLF%$NحcaA s@ho٪ipbx=:z ZZ@tlzc.akJ|oq8}}}$IeF.jbd֮]0'@ND3V` ݬ^˲(Je|Wu]_ʔCWW@p&!a\oo/6e@JH#-r7M8eh-*AmX֫#۳3@`%ʃyv!&꼌 ay vHA6`=S.,#A&|Ί q\U:Zyw .3 VzY]qНPniۯnh!&xxR|>mYTץl6Z[oO93!Da'Y/05umգk֨щ ;>x ! mnUuglflZ(@FAe@lD!y  )DyX)$d DQ"`O_uwl8ޱ=DʑnUwխ=s[޽<ugjT*0ƛgffv4-FcƲ2!* ERbc mɕR:ZGJDJI)#)e9O,<,K8,˂,,˴2㸟e1mۦiZ*J2MSEQv}<u^4"WQFu*c,m;r]h48Bܶ&4-4 Ȳ,߶m֭[Wg!!sZk1cR!Q1Ʃ=Vkr==ƹ9p|k1+HEv$z$Iٳ=!߿) RXYYY-۶2ƔRJfYi*lVeML:{9 Pk=X\\l n$⢹r;>c r~~kJ5k1*MS8x"3LBdG:sH4sڵ(EqzV.>:E)&8cLڶBhlDya&ApΙRQJZ… -B5B??nǕR]˲qq !@}R!$IyjyCѕ+WAp_A}x7RH_{B\Y,ӶmI7*.j#8 hZy_\Ru^h4 ;wlx7$BJxF.)mۗZהy'&&СCK1ˌ:BA)mZe!@}څ2Bdi&AVWWW0'czl4oa۶˶mO;c!o21B-i(^x<9s>X zs}yRR(qTTf4ž_nZ}ewJu×_&R^$IJ,캮%$!H ( !!$v횀Qng}\bٶ) FC:u|4^>"bcP*Bij!%w`\dÌ|gݻqT?;G4^C.y!5u'IKw1pCindr5vWO#p1{c{*|ꩧFu#>s!u+R鑩ٱcǓRt7olI)_94M? q21mc@^+S)etιDR)Ťs.4s~݆.yn88j ι}?t:}/_i'N0i)wɲLazp4uF@k}Ï;&~N! uBʾ׮];v> ~ZYp+Hqݸ~!:Eѧj^:|8FNthպg BjԩSʲ֭[˲,JAy/,///]z_(Xzܹu}n~E*W6h]|X->n)r׮][* 8-|pu0 vyiDah^?fvi h~~8qgZ-:.IENDB`mudlet-2.1/src/icons/filter-locked.png0000755000175000017500000001426011513237311017315 0ustar csmallcsmallPNG  IHDR00WsRGB7MS tiCCPiccxgPi CN% 9' Ef00!+HR\pu (DA,ʺ܌~>ݗStxWN$`C<WfHhā!dzA_n @=?IrpND.8N2GXrVz; \Cw~ wp98RW&rW2; l_ܯ3F&iviXGe'sG7zcu@͂wzRvn:{עU Sv/[ %\Ѐ(d"PZ@s`3> @2, vPJAP @#hm ep w(x ` X  !$)A.d P(P 톊2_se4 =&9o#$+̂aO8©p6+ _o0~ /"!" DCX#⃄!1َ"H҆ =#P D顬Pn@ڎ*FUN:Q{I G-t,: ]@7;Wѣi; hb1nPL&S9i\ c0X,V`#l"v;}#p8\UZp n/W[}V| ߃/$kB!PIh#\%LDяOI$&^'N?$#)AG:ADzHzC&5v0r:y|^&/.!V#)6"S))ٔ Yʼ8^\CQGKcVSZ]3[UsBeՠu_N>}W1Չөѹ ^^eaոI^/SUoR寧ߥ@ `CS$FFT#<u5WWޱ{k]h#&Liަ{LL?#kYt/um`K3t3YY%ZXͮ\q͔uu5߆iasԆoli`NՎcd7cm`ϡaq%'թiș\E%֥e5m۸;۽}cG'sg3//W7}{bZ.s牯oo~?_Fh6kY.!$qV`F`_%(<9h)),b-Vlh|hw6,()lqM 6hnزFٍI/llt6)'!r1=6j>~ɱs梭ˢgbcbfccU;WǿNpKKXJI<ԞKH>ǥr7oY,/,{p&u2+*ԪJ>UU8Դ]:9ܮ` 9s1ŢT!@+P0mkkYW)Ą˷tN#gvLLeTDQd?pL,L&ܹWp{{{ qA-P*0kZfddiX;k%$} D0 i LNxo; -e\-l# =xY@ɀx~dP`*eRkUʂZH}Al„AjÂ7oFyqFX{ѣ u]޽{ u"d IP Psu(AzL2\h"APh>r333,bn‚/Jx__ep>k ܁Z!qP` 1a"PRixoV// wu#f+0|Pb\lB| `RLXJ@kiiwñNE} O4QAe(%jPy 2MhH6Et ِnH_s>1iruԔ_i=4L`)f#]P X]S[… $Oh4KGcpY # F,p>pV&ttq_2jx$"p m'Oa8J'~@yYR6}c]D#苨 0˗/;[-ƋQիK8 fNj; y'>}:xꩧp .(*Lmzvo.\8$+rOkZ[{*~3<:l~\^<8kFn<4w?3ڻ" ؑȹE+[nl۽zxmg=cq;7>_e]==1շ!T/Pu\fW\ Mɨ~uR@6>£1ͪY~zjX6ˆ_xuG٩o9|.C5<:2G?Q٧9o[hpæ[~7 \X\dlz?kkkR5>?TБ`pĹܟ##ՇX)hZyv) [vI״Ao: x*%Cv?'GJj)T\XeD;\XEڪf{^p}6ReezI#\Bձ_ V8hS2d1:4<3}xm8ǔ\IۥذEoFQZr1$cjT_j.|7v\֬Q%q&WMRJ,NZSvH/t]s[1\@cmq_u: Ǯ*G њ̪'N*T *A *<*-ƀL\}ILv߅O[AWGDk˦ͬ'zaռ@UTdM |9JvpV} JAzO'}߭AA3:y-?hPDD3gv ]O-Q־J IDxd:~QR QYU+~Ӱ$dėf _(?h$? bJKM HBQ2\R;~;Gx<0, q*O姻k^!j=o cV p+a;cg dt7w=:tOќ*M=ӋT1,_\RF=Z^5Xp0ZXZ>}SYE!ȭzq*T<71م/𦘐|$_EaeMf3 ռU[8MZ&e+fY^[e)fW{lZ chя~$S%Ȃr<@XQl.{W8DZA}?/쳨!#?00D"AO/ATiAf W/VV.=/ %H=mȟm(vkꁞD,2 ݗ$?[3ly;ozW=1 n%5lzj  i1+vpLݷb,te[S(:r\~i0[toi؍XGIENDB`mudlet-2.1/src/icons/folder-important.png0000755000175000017500000000271411513237311020060 0ustar csmallcsmallPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IIDATxW[lTU]sLg:H!"4 iHRRS$I4|@GERjQ>0L6"3w73 -1̚{Zgs&y%$1T1T_S4(?!*{'zXɀ ^ҘV6<6=@Ura< ZX ~S[9hle ol`r Wy k63 TD1w ^"Gtֽ:: R@buaLv(CJӢd8<%J餕 Si2*MVt]7uM">X"^:VQHTA]5MmkI,b=Д4#2e#EӚ]5)X85L OW`/| ӑ2M-p1); ^Cݟ5M0;/\ЃX(܀ ɀ SuiJt51+9uڛ ZB 4-p1|t'Zڊ T 3DY ?ΒPKaY;35!-ɑImRB(GYu/W:\eСC|ƮaLt?;Q.bM֖AtBJQ. @uP#Lbhhȏ ^ R} c-dm4ޠ%AeMIٞpioőHǡN3L/|6`mD LXr0I(ߴ!*lxeMMȶ}u"Ȥи]2'k&k)(TRjQT "G-,ȫ a@asBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATxo=wv!BՈ UPՈ'xgTʼnb1x#"DV}CTJeA$^PxBTmeU1g^ؙ=g};3;F^sfw|{ Zk .zqpqVߔ}škszY5Z rԩG)^{tǦX|o\n6 hoP9yR?~3\U,RJ)D$.?4`KtpFmHR$Ǐs8cwt8(}v|CB@sfTN^¡ϋ.G w%J>$015u'._qRIHN\tWCp8h?_-=v:#$g{677FYP- @b,%2vrukna̙c=_^|/]X|9˗.Uz f,r/w.3g7R<0= 33t( Yxţw7X<> ׯw~i ׯ Y\1< " ~ֻn:i`aKrMEMNpV]Y( CGrL9O;HrO59'}/feWv!{{c{UzCOj3 dMXuI >hi|5U IC0MAC@;K@kUHd$/M#{ (=Hj~anAE VJ,'E"Q~tOC eaw@T)U |A2R zOxC5rss,)5Lv7vmR˙wΓ@W1(sǀ9H}23bGmS^U@S#ksoJHk'a;bowW^&X 51|Md; Vꒂ6ĺ2E"^5U%cFm+'(*2ۼ#}N"+|ӨUd;۽}'?(xxh\WWMa Sf,bK-,tyWxd쁜e #rȿ<lgP3d+`:_*N*z" < !r䋠NhbX8R"mK-d;V$)< <ܓ@sW#9" P<tRrK VjU RbM'rrFbcϫ%uH;)td, ^Dr9"{ gI.r,ާFZ %5$T*]ۈ ;@8Бtg\` &N*_WA3x^>ɱ:W=dS*=;5ArX?5v0$Z"Pi<2A}b xDv ;J_j!I'EaD) 19c!BG VHJ nF椰Um<.c!B"& &;`^P_V*ZF:9r c!!$6{#C@_|IQn)<@%9m~oOr=8HC_{fs1|~0>.ƊEB9$ߣ#BLwO]/^}+W'\6k%w\Sr;Q#]d#Usl#=!3t+߸k8]7Ӄ @[v CIDy_h, ||4/WHC9$㸋wvBsBJ ˉpq8\.v@ab`   O]T֝UIENDB`mudlet-2.1/src/icons/document-decrypt.png0000755000175000017500000002050711513237311020060 0ustar csmallcsmallPNG  IHDR00% pHYs7\7\Ǥ vpAg00WbKGD X IDATxwpVվ{?%@h @B?HPr("PQ,bREQ)"(% i{s{W.w]yNɬgVm% \Pz wX=! xg6B7#ζi[6] |*V` P~ a}7VK !~~ Nqw(59VMD<-~_3E?qNйk'aU1XCܿ |ǂ@K $@WDEX}mP72=EWD&.SWI"j}F@೼AޙDvbg{wZ% ]0Y%Aoej LJ_4  iBwЃ~*ycni1rlGEEQB~mp7]/t!Nj{bk-ߑ+ +}AUUSEoBz/&(?6v@?c?.cx>G'ImWy=,ܑ V+.zJwy[L#cE[\w6x: Z_%$vLt8uzBX[ 5pֽ-r膂3Rndk SD."d$ܗ* +/F;wF& kjBΉz_pgWdQu'YCpY\2M@fD@ W[yՄpi’bHn_}(F­_RHeE痈jNEj+~}u8U1]K8黊DZDߋk Sւ+FpsFBЇxбV?\y\p=,j=*ҕoxO^bυBAXqZNS~CD~wE<+˿!mv=sbԻTDfN=,X\ 7+n M 8wR0mep{nLʺC@N~Bϴ 5OLޤPa*HʼBը0= Ϻ]vSEds^-.^/ԤO Z%GD ކZ2ҫ `Y.(ad.lmf;y' kxq1EOx8|t>eSӧ 178QS|]1x]=.5D{*Y Z:$\'m(-?Nq38s=pS V6ewH['&P>`|  G*A"*g\1zD'/}'h,p+6QH4Dpuh]`vpL.#HpJA3El3\k(X/6Z#?EESCh(8bGP5G0ۍ|}!' t0# p\Q) /S5Wf*Y* pto,4#toEXt;leU$s~Y"L}2LG`wo%!8c' P}X:c?IJqî.TPsa(pGDPqLK*!"yqvO "o$ C9K? "PQX{W"jk=>$A#Dd,⿎0 爐(n H50.pP߀Ld89[?'jZVD.36p3'䯺_A~$_stQh⫋q[O7MVBMӎO]TdM 낝`__7}Coqe6cxKz29*` a&ӓ6<`!&vE-ٕTrʁ'xoAZއLsv;|37=C,oT:cn5s^4Zگ%\Iߗ2'娙ǿm-xҋ3h Wwà =r'~'q}KKh{mo ޱ޵>rzrl׆=D2VFw;ޭW H8yosJs%egV{ "$=Կ~Hp%/"ns/9[ݩCd[ACW9C dp,5x=V Yk\<@}meN.x;N_g OM;z5Rp-T(NNEa٫5vG\Z[O^]:O%!G܋f\kguxX*\L{w`S .{lȽ9WM)LN'~mnpzǃSb /.֦԰S`zU5tu(4t)dI1 [#BuM&zZ*০X.N{N}/A*\1/L@y DVވY(€& l83R{ުP-`hj?PZ7Luӕ~ҁ8}}"S8e:Vdڀ%a <4?`:P*YĠo"qPXV&<t;M3W==X=^`0"S\7rLbhzXpwB{g\2@a^0Y]9Uq4T~ EĂ:kl~2-ioL뫊$Ve@Mj%A`7( lgb\*V((A)sh:Ac414GM z!X(pUWR+hY` ArFFњ`6QTe}N%qGi 3M T-4"̠DBE-B(Fu z#W$Rܼ H/p+'@_&?0$jF!??pVkڿny.s1>rL rMcppcJ ^' 9GD-B-IӐ'߫* Y,6`x[Ge@"[b8O^|UN!{blP.`-I6 Q,4e:b_ZKAki.umy*+Bd<}xD I4]s'\M> E4ݙc$R"@46h2E,_ɾDur@#Xj6*z#x0 p)$hBpKwAN*Q rT@ 3쪺K)uT8YHi{볈Eji򻟛VkJuo5rJP\L)tE|i^kMWRkRZB2uzP@U~Nl1 ;֟*֠6 FS\GQ*q@WٷT@!ex$Рb&ji2=6&V1}fjڄv%Bsnt:T5} p3$B~4S$T XvH݂{Ui,ęVӓ8iڐL'z^UMFKr/Px\ DS\x܈p\C"0pت|2)˳b PWՓ#|Io \\ AIP#)T>Ƣ<`QOkު-9q \dAz2z9[-f@! D, {@41D~l.W"?%o y+& T$!bZjvЈ*. P^@-Hqj@Ed I.idq 4B Ne$ ERm@} k9jnz "5߀)V1@~eD @,Q(@!@ w… \~&ɴjHL#51c뺵'5Ui#WMkP4k#wѻU6軵WU4]SpO=\W!kioM2MпXMt߱Fc=nDMDנ 2HO^ z39P(s4ý׀| Ӝ h`^SSj=M Ҧ i*&%LOH1b;0i z)@gTL< jfZ9{L++[$SURAQќ2=3XV%.t%'Qi <߀>!H=9u L4큯BE1 +E&|AYQ]i-Qz.+HSY9@6P( r]:X@~%DPwӊ@~S6I| Geuq~?&ViP-A9hVhδ6(ZD UkT & br HH޹~3{̾Y ]r+m42ZÀ)-p5Mǹ89 dT#ta"'Aq Abr%) Lc?N2d91br|N dI);K pC, @!݊H!ȠZY8ydɏ UP#H3ⴀt YLI7D^շ}f1\2- c/B\ABN $F`k dź(Гql>TFJ92E,C,yA x99$/%[rD6fy,)0 -b 2?9r4oS)mܿl^ϩw lEH`ZGd("SմE|`_yK[-U,P0br@qVqADjq*@ZȻ%]&(WLƣ`4d@7s2v $f @S#6'3zs Gzq HeۨQWd& ]@TɻL2ι}A_xXKv{~W=c8Y=#l'#qHݷ}Ê?ݱ )y7K{gӗgޤ̪3#72#hq+G5^T=ky,uZhMzuRA*y_'VoE^ :Ku7leݻ)55U(W9DGW#Hp$GMKdR5{ >-+񕱾}ˊ+>3-3=˃n~S6w`[ܴt9lG.٬]'j~+4SLӺ[zCdr̕r7RRH2n`22V1X?˥YH"3tgB1~ft˰ c"nK5@ħ  rY1}Xľ-7\F;eͶ 7#mɺo_)]KmF'dt,!h0%AE0jަ3ead}9!q__7G6qE_'nKōpn+w}i }.74auXo~ذ?v$:a8oɿmuSF3U^Vr~*5S#.ڬ67ɮ>>8!wTGވx*9*IifNb'ڻLu镉ryݴ 94`>w\}FF/!^eN'U&X%I EJ3I7"brGYCt>:E0NHd0xAɿ=Yj۬;(`*#գ2_o$?UoU x"')6 sg2H20p'5kK?MqpBFr&Xnw%_̴da; ^W8'p7AeH1_pt#2 sbIv վ5WnK"i/ԕge^s1*g {vn:zg,@)'-C,h$RE 4.0f'?Ă$  ԂZ ΃x ;A"C4HR!bC֐ A!P8t( BPT5A@ hzM@GI0V5`} ?S,8W) ߂G`^@BD2 E>)@ʑzF{C>0(EY\Q(*UBDuPPy4-A[t&:]nDGSw aa0L<&S9i\ a&1 X,Vzc#i|l%"v;}#pF8g\(ŕq=a4n /W[\V|1ߍ/$,OE  oD ќK#$VO'HT6ɁFJ'# ]"=$!d[r(9DB~J~/Fs{ES)v,J9,eN/! !]ZMP["IHY Kՠ:Q<1$ hnZ*mnxz!g }^*i,(EZ򂤀04nDF1 cQJAN*JjT԰ԢtttGL~N'(YmY_L#Werr3raymy?lc . We=J4%k82J/L;f"ǜWWvUNWST^Ra䪴aQ>30--[:u<Qٕ3n[vh{;vLtyraW®۹owSۙ7-b={jD{+~),4(,/T)O?-7XlZ|S+odDiVe̲7Qn\^{p(³RSUlH}u[|ޚGl*~<wAK]GF}1̱c7566~>;!8wɬYnIo=vώ?wֵ1 O_3gg[U^ultt s?mo'+ yГ׳|1¥Ksc.On}|%>߾W_sv߮uoX8w}魎&M;k~{hPϰ{wkdh胱1_?xx8zOM`*081lݳǓɗi*9ytӌYٻ/ֿzri.O?k^i/ۿ^_/]F͉o{|KzX^>N/e~~Ǘe \@"D. r \@"D._ YY m*Ј?%E3zTXtauthorxH!s)IDATXW=lEg ,(A *( E %H A*"5"B)RNAD;6on7sA$sٙ}͒1 v.>]=5J7/6O I }Hx掝sN{c 1)Ě> /OG)j&Kow"6:J՗[w%Y\qMor>,Hxrf&kSA-/#A&%P L2G=!"t "ݿR6p$K$>Hl}Ebȁ'0T &áÕ}~9B/DŐQ+)dHH@|rG֛C_b6ލq*9l,9n C:`O8D>Qbpp"B&klcrm LbE`l'2bq14%D)FP=C 6Z9]Y 2dV@6Q!rSiEq"Ê'|IO<сr ^~ Nk l1YMՠĮey=c9C|{-X1{B6-Ӛ4@ RcLO4ISGQ}w]HYƾAnBa<򹞯MX%D9 ʃ3TxG3J71Z~ S fp@$1\VT%Ʀ<' ڈ!Ao4tt6ntG(;p/1#!PfI4[΁ae#e@ O"LfN y'g3i-M{d@{*RJk{5gz>4+5#To|dUX dClO8k6zxlUL7avs@āMFFsW:a&R%(-bcU>D^net8C<IENDB`mudlet-2.1/src/icons/folder-orange-enabled.png0000755000175000017500000001012711513237311020703 0ustar csmallcsmallPNG  IHDR szzsRGB7MS uiCCPiccxgPi CD HIdQ20$L "AD\]"QP ."**7}y>?UoU x"')6 sg2H1@&d;O ^/n@+{,"7 9rcIܕ||3Ӓ(d:_xB^o1x?!#|eS+̉' %W\ f/-ϋHRWxdz\bntyFoĨm+a(E駜t~Ʒ Ht *K` ; l d BP*P @hg@'8.k Fc S%AX H Rt # YCN'@P ăҡh7TBUP.C7!!4BCa&tXրa6l{8Nr )MLOM+CZClXOQQ6R(唳;9qxvjsc 4 C o$"f3T,UDRǨW4Jsqhi ):΢yIdj `1Ō3QG));(RRRrҶQm#e2N2 2e:eȢde}e3e^Yq =/((*($+T*\QSd(*+)(*єʔ.*`J2혉 fs^Y^U9]NyPyIҦDVV-SUWSRRQkQ{WgǪRW_`iiԘaIXYָ&YF3E^FuX6m]}G1Չ93 |oU1]nnCS/WS~~~/&  ݆iq&v^cu:QGLL|653囶Κ՘lv9|yig,ԵLlYZaͤUUin}Z`laSoVՖkh;meow=߾~a%GűqЉTY9ƹy%+u똛ǭm}{cG3OmOguk|ZNo}'7_os?Cuu5{o_8@3 =7T$|+D6$.+iSa&aaXlQvc ("6 G7Xt8pq^rme(Ҩh16sqqUq]kN$,'%%“^f[6%$' R,R=PԮ4(Xɾ&f%eTة?;ժZh+< N~K/g|('Oʟ?]6„uOr&_ǧJM3F3ggXbe˥?%y׿lzw7']Yx.b{'?? 8 /_ƗE. r \@"D. r \@" |w#,de966@#J?JO66zTXtauthorxH!s)oIDATXWoWΙŻ޵ΆcPҢTZUH/HUy(Ч@ SR"Ŋִ i6םovPGiV3}n !A.xk?>5U uOa:j܁Í;,{%E7$Y:StI5_HY|8s*%Ș{Hٗ:=ɒde#V߾ 4\ZݔB&HgI L ƒn򉭂1Iĸ9#Ž U\g%Ķ9KtG’$ٜs"@I#xE6PlFw޳'`EQ^aƄ-sIu[<sa,ƛ $fՕgh!#ޏwåa /ѯru2WUEaxs6I/Z~Ae8o(7xͼz8) T,lJ,. :0nqw^"z?3=k]?nZAeY>eYb֒#^!=tgR)4q8GTg7w>iryKJtdHjst V4u{G4^$AyO1nj뜊.}T-zɆb>p|m~/ߖQ+@Jqu?@B@ݙPt! B*Vco]$}{ؿƥRMc )6$!\ُ`;݇ Ik~m3s8\Ev &S{*ջNY4 hiy-W4dg?3-'wmrN{ D#ڴ.ΝXR{ydພ H%1Tm(Rz,C$PZ"-ض)*R}:4 nXHM<]f$2)=Qڠhc QfnXduH-I1@^V1o,ȵdu={׷Dʐ]v=G-;RQh4{bH)@@E ]B X +V>FTi!aADF [da ="Er$;lnJ,w$ID| it9(K6CJ$ Jvʂ꘾Z" 0ib@IT D "UG;8eL'w7[P-v6%SF1<SlNh|1! +Hʊj }"(K B$hm~ zO4@d]ɸhELYM>:K! zR%V) -BITd k4HL]CJRXq*pFCDȔD!RА .]8c`>EMc}3ckG)A6zEfR(Kք!QI 7"F%5ܺu G{&cE5 }U1ۛbu  !T`;lBYѦ< HIҒ|oĠ +*ںgTUx7`2EmڡA)CCfZ&)Du͝*tOF13(%REi]q@ P6ψ!҇#gľ#0x [na@^DciyU-GܼSc M\1-n5g JVOwOhk2F фaHB]MO5qYݒ ܹK b<ڍkeAVm }Bفiq0)Yoj PRЬjܶEdA? טLmG1stm<Ӹ ?< jƳ}_'AH麖y:d^#SWwԛK#$Pǹ/?|/OYYێ%] Rcsa"Ta<)Uc.kх-2Sl6km8%0`  .&P9ca_R%.Y!дR+"0@QUHeZ;2E\!G4=GSD%Ch %{d}ރ91ťӈGP/Ɉ|G1FXmZ-B1 zx7CIE7%ŨW$4c[}2؞I:W85'5YnPZbw-{s2SLdXpm 4=$122hr\Xmt[E42K%)d V*:Po!m;u> zK7x^ D$Al)lB=MJ$AHUO|,MCzHz;R>KԣzR="ދ0%ĝ6M??ȗMd"/r mDK۵GZyf#c" @jEh_}rIh1YRӀkܟ}'q?6zjC&l%&8/FP،`s !,II yͿt ׾BeOuhЃﻈ:{0 (*פAhh3.W))r*2bHtmǐ 0i6$H4H(gܽ~,/\K$Goz8U.?{QAװޘ,I!RT/~ ]rx'1@%#"Y tX3BdJ%lcM :YBIR$@+\)\sq) mߓBD(EV?2iC‹'(`?O>Kq?@eDM7P 9e }7Vb|k%gl^[_Mvv7yC?He'= +'ozO);CO8”T=&_ a"$N DoWLsNn-(9D0&.q}naZL.#U* ;t8m[Fx'>Urې%1:I'!@ Zs=6hRCq! !!^D$x}?~؟\ƑQR ֛7TO<-3LFGvѿh֬V+&v8L9^.h줤@_f}4{+mI): ށ0O?O[L5•H« ۯ|?F l*JS؜G]ݮ)4Ȅ,Y1{/5cS{PV̂;W qlf)G0Z!'Y_ɃCW^hV"`2XDYAJJBp' 7OgZQ5CCNTH%Z!F>w\sO_Ⱥޒfͯܳ>x;oxC[:in'1|'E,Wkjx+~"aDSp9uzF̦cv@w2K3ЦQQ DǨ^2B8_{nv 3\QY7 H< /&3d#tigW*!D$t  ˌ\YdϜ?}pXR1b3(PG48Sa?w쯼6@8bc"++2 ~)Vd;o)Ei =L/uݣ:bs${1+EM%y<~Z"Gdsro|ф!aK!B  FII9G70*0OM4c*>::λ~t{}'?A%(dQKrDG%Hk:cdŘGH+3[G AJ=DI+|߃H6C)S $"kIBM{O<2H78"m 4c7ލv⋏'_@N׿"aoc zl3|Gއ}Lj?Cybe!T_8T,~C箓oQkfCW)1xLPށPq9999!39=0}^(&NΟ'~՟}~}є [_]qͯz"qYq87kb.#D$J֛-HUl\1;.nVk…D:C9at"h<=C>{ W"q3h}Ҳ\(*P) H.x ?<Ͻml%Œ!$(xO='rE¾Q^;22}C NǿF4yAj;\D) ֠Mɝ0~)t̩9ǀ:GT꯿ W{ؓoe%blf{~PgX\7~EBV K>x#QYh${08O@<26Jj7'~k#x#2gg)=sG|YFnH):tmC C "_̇a H.a]hGDoNm68n+!!}9syE,/9)TyߺFUAy*(%ǀ19E9rJw2"Ý?@ۓ@_|Wyk {<1RHAZlY ԏ?pĹkXG(ΜC>4lz`>5g#tDy;rO%3DP"UDnIK~E4pFM)@ޡ}RHRP՚t ?%l:ԏc|VPdzDa@whK6Pu#E°rWF3+ RF%؜,91Pef4YF$߼oLHiGH%㻎!9Cڧږc=56'{~p7?ӌ$˯~+qg />ކ*_i 8RHtCmle9BŊ?80RD eAmuMpvU }-1&DTh7-S[-:J")zBDNzKIVx)>.Ʒ:x8;@? J/}齗Xr9%dBrd!BDA7"ED!n)" _"& ADD1 Ǟ;.,^d#t"BKQlږmݣw.C#O4B+p4b#ʇ} JKbC0YN1.ϨSxu`eO5 T%)fep=\EȃL|Whc>wod2G a_ 3q\ox'SR~"Mrѓ8翇ʷ9sE=K1IA-NIҤB<}Lɳ _֫ (Iwϟ!yI1%#DW鍘ǿ~mo阔iC[CH~[\4)wP$bCTtz=c$* Ȣ KºFM#@\C72ĀsϠ: h- ΓrꧮDb /|ݯ;2eeIG@)utL!Ǖ9wwʌ(4(B@HO+^G=f\D*CN=ީ}ddJP6XFmN?+E"np{EQh۞MH %xϠ<>!J$ H=kM{=wmHF1EbQ7k /ݸWoj*@OH%* z o~%_$) 'єBIi XDL󧱀EY? wMױ7 ujqaۑgz e^Df%ˏ } $il:BN( ˝+Kpf 8ܹ{"0$?$Q}ݢ!S;y<R͉"˄H!GgtO) 0|vo>Ϭzu]FJ)ô90@9)чN لp8UP%R( e(eP5A={G42PJ!@iQ v.G-PھG$@rX-jAGHh#NnXY_=i k6-'M5MĮ%"^`X_c<9$ͺ_2,HRLĶEMB0$K`{ :M:EG#[=²8~ۚ2E|H.%äBJ@fh[ˀ8hvwHILFDJ=}+qGk3shRSfcB\MHb-gьxz}Fx1"bbiwi7Lt(1>=hdyn;nY,n(8{a{:c m$] -> Yxd:Qe\linCOF3m!qBw"M;.kLxR֞d,O}5dl F=BKz^qڿ[]3{3[rmq!1t=YՄ]D_$rI19EJ=$G{t (/'8s|<U9@&c&98 ]4m@g9*Aiz@*K0&T4IDATQ5HYZ܂Hd!xvKԬMC$ȳf()p]ɦEd'9J TLcFZp\s} )b2Y-ɫ RǞ> ,Ljy17^cK6?k/0px!B%* ]{!si)EG c@@jC^Y+7i cT>,h55ۘl-PBn虞9Kh:[G1bqZBz2djR$A!>&$p]=BJ HZR@Ȓnk%qA)KɈTH{ Yx㮅ӎAJ6^1"a:?vq,UYrM%woWG'$f~ KLq*XMK[g(|X0Z#D^Jr]Cs-8"Z(2vє !cX . 1Zc$0W.]#E5CDLD!@K|׳Y-Y.qC`ÃC,caPV!ub#zcwܭP )CR% 4K !DRX&  E^l,z~ sl5!8!6=yf2 d(meZuP"qƷɤvFx:%j5,^_sx[ן&쎄01*ÇH6Dbd2VG@ %;LH!"J%|xVX0`$$XRE34"/9^pcLжl+¤3Q1:DnJF0_Jv.u%l5ndZEJJ"GĄ vKݴt~q1Q@mD<Ȑ$2.?9IENDB`mudlet-2.1/src/icons/mudlet_main_16px.png0000755000175000017500000000154511513237311017747 0ustar csmallcsmallPNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8mo[Ew]i4 VQ*S-M Kv$$6ٰ,P` T JB(Jig?lga$;s=wΌXk]ӱz9yQ|ﳓo-tvceG/gR#6޸ :-?>W2w:,dW:qɧSFJX+To\&1T~{aNLv1JBIv=cN_#d7M굙nǿ8XdX2̋_cc;*NJEE <\MizdK@YW$;ͿOP=1:gKjpnyxlo:X"1T$P$1Qfd)Q9,*t3Q0&5D8 z}DJ@~un>l7΀?h%AC>aߧk\Gq eVቇ;8D+h d ?2MuWU/҆zJ#kxA4GSBk#PVo1F(ǥֹQGSL#XئlF ,~zXkɈRqP\- X~N++% 6x0(`o,/b T$oWʠPΖO=qh*Rb,b7yw$[TIENDB`mudlet-2.1/src/icons/Slothmud.png0000644000175000017500000002153712076170616016403 0ustar csmallcsmallPNG  IHDRxhMgAMA asRGB cHRMz&u0`:pQ<bKGD pHYs  ~!IDAThWasپ $AR(KqQl'Nn%En3LrOL#5VED(b[]Mխ-8ܾ@)FB!R v ( %aT.ӋˎT$(<ҋ/M `[*;\X{eH $ &,,d51RbFV`Q 42Jr af KV ďOg0&s. o:v֥x8uoݸޛ%*muI8U*"O]c枾:+W[g S,!XnW)pJBi9i?Yj,#(,N6RA,)dGNj4 p}%a_ ӂs Nӂ_C1+qlj#C$,L2 YwO 3p563n"l/nRL&B)9T`A EBp\aiE`.1.$XV2pqùs_| ķІ2Zøj ?R\cBhk#^`jct\Ȕ+@Q@(@Kӽ#wwA>@1BГ wjM q.%G(_.iwB,4/1[ T7Whf4H^Z#30:S jT(=WW$5sZ:۟ly b+g26ج` I^ # 2@̣@k?I.mzU R~q:ߤA #-tV۶0z2׽d+0+0{o|)?ROG<›}r8UE<0 c$fBeYL,^E2*x)>B^l"B} ĒX$IA( "f?~\t*;", y}bi19gr"i(ά?xŸ8fUy؊TD"@f ߺeԟL!/Q 050>C0%lk]qUߚ̒hѝ.Uc@*krIE&nuO;wD0<MG.zA_i*1q\R FE 3RQqJH mmOiAf3٪>lmx=lkRǩ{)uܿ?:>>;פ"7J!h0@mڵ4BiFwǶmWoE ƌ?w$ŗ~QZpwiHUT%KoóZ0Bb/''K Uzp  \+ 7[__ȣF,: DvKYn1"`VbȶKݥ}O*Amll'JuzV5_+Zl"N"cL]~ hO9:pcJөC Ģ&p c `aaiޝ.ͮZa!PC @owa߿aC7g cKwoT8'J| A@4:T{?wz{pz:]35ЁEAmsBS#V[S8'~&15R-k`[ޓQR!ueG_ ;dUب>؟roo7._6>yduQdD09{mVGsUQHO!a H.ywLSN׫ 7]X47r WB8ó?#h2<}7=k\, a4РJPΒ$&I\qw[}O?B*4~}k77 M@vSQo@ ׉jNgzrG^ovyIxsıL7+ ʾ`Z)XXoT撋a.8㐇BmFXmJY,өTZkR18:Ҷȳ%o GDӝ.(˵ aBNww5wq%:^no\\f{tj I  qHHwH:eрTϦI%g>UkD~pǙsȆCyAFة'x] h}RECgWM׼2';ǧ 8E_Dj.o561SUsJ dPdۤ%˛'0/219L)0;_B΅RM@QEs++Y7|r~_ѭ;;V'ɲ_Firt6Kֹs;I3["{}8ϹxIJryj{W6*ʏ_,*KbdBa\ιJ;Y90fI3+}.pwL(k|~?M3 %W‡Q\GK|dZr+,]l!Zk00hdi%!es 19"mϢH xaZ9&Ww>ˣ(7?z^NE*U~r޻u?nJk]-7.y\(,oKa&4%kZ7Ӯ1\?jW)~2ѓ٭6FD \_u<߆B=SJQ2ŀ[P" #B@:<.5|G/z|g}o6O y&)9BZmX;ukf>PBKl51HBAR1:ZF9t,.ۻ nO&LHHLuV@\"qxMLgQL`xuOѳY"77nΖk^k5$aXL|9J/Ί;G_9G-ܲǫ.^o9Gl2yQ*#ef ٥4]k9y4I) q?.e{zZ,YQq^,_\g.U_vLR ⼷f]\rRYmKv}؛ ڵ$¤V"J@(F ؙg(Ny4 pw7(C3ϵ*)\*c)D[b?= 'lzkv\I>OӢ`ݪr}w{?WR0AON"tgp ZӮUi;LJI(v] DH$H h̗0?FY0 Mϭl.-\2MQlr6+ >ua+B+F29*8 $|aJmDYr1ǹiMFa3i@C^$՛{!?Z0э JY}XL Мs4&d{%XZR GȵTBiNϞ'vid{l:M[AYL뗪ݾhm ߸~I{ 4'\2l!QWolCRiq'ΤGR 7c D+:!//&kw={tDJͭw.oO7Vqkh=J H2$ 1@;@cfWΥ- Q/9!PH!:NEvQ, W18pk+ҹwOnVQԡ1CX8TV;cw/E `Q^avFgGdGӏ?ʘO%CxZ(C?b+I%z)cΙw00jUuXp ?`4[^Gr5$2\*䒹Q{{wzQ|{6 J6]4ZH)YQ:I acTrL>ZZ[mA^puo?>P\kٮ@67qV94zscuh?~h.\*'(k{CqaQWJ_ (9ryZ8=RkPQpOJbR(A@9*֭eK$s7egWz'F_T! PF*]g8n[(GC(a(dW)"sfPz0Bt`mrѝii͖foUOK, n7 jLb5򒅡2j&ʗx50.2Ej,IotvD8pIle]VWksI f`U6/=y͛ZTzK۪V Ȃr\Leuo#1 =UYxUl2m:UTU׋]Q5CBsS u@u3eSZպdl[I!aZE{P֧,Ih :Dz_LuJ8?t=eewベY]n9=S ߻BLc~~Ta `\߱| 8Am}.Klj p÷; $e-qY)xVyΥVV&$2$MGCLB?0Bl48 9 5Pi#4XD˳{Ϗu'xRp"%k[ 8Sq{q,(KC5"eJ)}h@9dzw.T>c2ח퍒F2{_f,Z MQu\vysTn6W.l2}*#~`'0JTRg8etcH we;Ȗ%p8.&DqCBzTԝ.IfZ 1B Jr4y~˾e nDDH㴘-{k Bd\XDrRڴpQ,EJNCt\ӐblfHevx8WWlWwq2f$I|=}ѯN?O)=a߫٬Ġ~4y|b{X'BH]w_Z岗ͨ *"ڠ^_ ==SeEqM)n|pG/{ò}IfiztG)eM'Y1q1 oח/սo^j|p\ gZߛFt(\UeڝKݟʈ[nIo[ F: ccaI4J$̲t|O88ODžȓXB7+l ^zg-B.\J-1\K]s~&k$"GKߟ%QQ0-"Qrd]* dHrxvla^dt+/&U2wuk/}ʎՄ8 zsqkwVbVgTc+?pa3h4;]iZrQm%Uo/6Ȃ;;S,6ҡR/Uǘ"B&sz>D\ѳӤכpcxXxzd7bK:XO>V1۾ɴIe[{/~z2y:'A6ٜY#lvQvx2vpͣs0z֋Ga2SL ,+V<Z4Q۔؟ENJ5MHdAB!Mƌ bsM@\- R`RJCX\kM΅T ,^OvvƧ^i( V”)i0,9bJd'qQ,`i?4L)P͚{FObϡRg h8pLqi1!d1 4Zk|yJ *."2C"bEfTO9؁вH\ B r0ERPmB4"YmnIѧ4* M h6E ϳ. \R%tH9С$7Q+(9)-IlWxmǯ*?+wojH2Rs%S8$+VB92 a \quǪYSMtyiv nV*Tj`5XAcN1qi.Ù0 mٹĩ y.56eb` %$eA[6(\Ʉ M0!s!K  0ʆ7?f;mZ-!i!GI`y2DYl3:O9V@"S}CίBBj۬Sw:RrгTFyPL$s7.5x6-qA!NDY(`5#j2x8o+3D? cn 7%tEXtdate:create2013-01-06T15:42:49-05:00+%tEXtdate:modify2013-01-06T15:42:49-05:00rv StEXtjpeg:colorspace2,uU tEXtjpeg:sampling-factor1x1,1x1,1x1pKtEXtxapMM:DocumentIDadobe:docid:photoshop:d08d55fb-0091-11de-bebe-ed59eecf8ec34dIENDB`mudlet-2.1/src/icons/3slogo.png0000644000175000017500000057364212070466512016020 0ustar csmallcsmallPNG  IHDRmWbKGD pHYs  tIME -'@W(iTXtCommentCreated with GIMPd.e IDATx_Y]9'1@4TJza.~hv4, sBU.zvpligC/ lz@)xc>e#YP; )+m&R(8=`O4hРA 4hX7M4hРA NF ܠA 4hp67| ܠA 4hpv5Р! 4hРA'Aٌ5 Ѡ! 4hРAazMC4hHs 4hРql6 Di 4hРidk&ܠA 48dIvhА 4hРAlothА&Stߜ 4hp`m9iА*iV<ֈGaA |Wx/Qi inpp{'J_ h<}HOjHt IbLMc4иg{,/l_e-ijcqߩyt9wF#jW t_k5OhNBsyFe4  s4H/PNxϜ\*/?}DUa}Eh=4VG+%ڳDj<% rc[î;g,cKHr1zc x6`C;`A47x+X!TJEx,(5'^^RsB@.E ۧ#'ȬEV?WG !!\_oμ,'UF!?(gܟ< iMF NkM4i7E_p"~K+0Z̓1;_b_c=BeJGL=C2e]Ǯ[Ct AJg߇<1B3Ώ_38_g65HËZMbDH_LD^",V|W-q~ַ8;D=q/RK^J!ƒmcsC)M@o`( =^'q58`A$_#Ĺ$ 'ݟBM;<37h!q8G9a]&j t :-e pL D tYVڲ|̫7W4To>N^WBѫx@DqCAv]!};z}B["i9֜]erYܠ! ^%U^R\3eqpV+::$҈d~V IҠ|zF}(tR)}Άh4)w wt 8 ûӟ))U6Vfm]'<O$G9l{'ox~X&EUt0w|¼P_H_;N1X1<|`H|.I^JӝGC"y3 {9%m@k=8-"XB $nՠCyH;Fo0=l4o$,p^+} iN6kАVyD1̸NΎ0+w~3 y ۹<$ޟL_u_$m=H%My5 ZԀI]rI>ry21͝.@?'OoKS]P>89n t: d/xt 6  U"0_%\l ںڽkcuʦUDu3i࿅aoeBG Sk&k`/Ǝ@~xQVj/&-`2ëO4;+u2^oZLf&p輥,_y_]Nڠ˟6L|Y Z|oٿ@HGբ"%܅5vkO:˵n6@!pcX~{EtK_xs}$KK݇? }x_ K pů_q_}2~W?å+0Tzg~l NЎ/Ɍ|6 ;eg\Ͽk4/GrO8#*Dˊt8L*~YE|4uV^̵hnVHQg116#4Zq'WV g'}Dg ㌝=$JHnOHGHYe ?zWvyS{`X:{zU&K7(xu>}%Q}J7`֑po=nA",5EByv /psTqoU9XHy*k|_%u|RG|ߙvU25"]z ;q AsmqGE!P| AZhj_m ~7*%ҷ[*d}ǐyR!ەm;ڏ~ }9wЏ@'Y# 8Kt`Ϫ(6=ƵnVdNo=j 4hH{ȟa wI+>˧"^9i5RuA'Zf68ܻj#@( }wgE][lpz#,[^g9r۾=|Q/΢ʎ~NU]v*d`\p(v*kFi!ћJq7IPOQ](㰟{*x0'$ޥݷK}؉`bb77ңN+`|`ӏrN!r<42gvܟ c:{Y$Ki i~qcYO^Dݼ`1?gq,QAg W"fZ͓D"eujkk^39c9u 31蝗hkep^s,mw8Sp{y$˫It!zQR܆n*zß3{-l'EL Hmj$ꡧx Vv6Zm-z]xR=jE+݈!J4⟼}Ime)W'~D'cOrD~ i>X8 W,\돵@`la$ԢF)j ۙeBzQxt$!i0n+(ۋIibW>M"[[Y#QZZ8vxI]%/t(}km;pxNC?+-;^ax*YPnsI"',sms6*%Jo$ QK}@IkJlb[X^TcpA >2~8 `֫ȇ^|kqOE"ςE1AыnCQ4aܞG L?E%l^#Qe^ILq[˱q|R%y̧ϧ\| Sl{"? KJ= ]ygu~rO%$z݉"61c[~^L+JZk]{rulO[rM$ͺzJK|z K:zttX<bvb+l'x:8$ [>y0X:T=iFIlr4} S-'ZiU_v T2|zx r[bӌ;aρ.dդi2΋l&}nUnw Ôv4jɄyWfϧN/Ya#nyvC\I4p\3BQ,"mh\)oQERAU*^E.E&td Xir YGeuCxTdmA2?GFPFnMW''J!yyYG~s2^' L!H9sτM;B(MHK0܆'Fy I⩆T([K򐔶 \Σo g$j!<|^:}SA8v3wcim p} C-iA{ȕ<0ٗ]4H¦~pIqr7x鳦Qxh(ק+YXaiM}im0_3/<)救bd=\4y!KIu\mȾhU$f\2ڄh ⚒մ楣g~}^*_=KsZ3g6JOs.a1ybr &\bM`2+L%"UBօlM.VY[ ~I(_NgZ\ Wldv 39*{gI^q屮O %3#YϬ¸r/ n\z'ªU[-xb <<<~u d߇1Rm_+Hr WT T-`'oN_.5Dy5>v_$ ̗Rj}r;f<\?-X?e\+w~ܻ̏|Ÿ#\dFq~a"VӞL3'.M6x/Fu/cr?*E#OѶ־>Nz{6x&$YʫgVFsb,]Gy帑֎BbajpIVR 7p8,W"^Rek6ߐSc8ߗE"q譜iquJy;ߖK#/\e${AQ,G$= ;QFBw\G͟gP\Eî{jQ3!= t{ +%FP\d"Es9^JwޫngNnAy~8ҌF|&Px1Pi։Dhކ[$5Ô[v%> 3p3XmF+6o LRBbV(M>]JqS)ijǸ"fB䬕$8+f!ȴ8x W['Fkb=>K5{R?g1 LA4m+ϓa҉29yrn%@H~] \]}}Das+\:D9j !0Hh !QDPq. h6tt$TK%Y։ d'":coqæ2s喢6 {iD_aBncS̻\$DUudmc[4_^_.|O;f>P6ؓoC ('8T]xxAιT{y'd;s$tC*{]mJ`ꥤ2W~]%u9w}cwao}Q]i;bTsLb~   nu+2(/yI ~ͥ@#"v)vV{9{ineܻrR0 Gc!#eo&2B;IA*PLoj:QUFHsݾ0:Hw- J8(j%$C3'I'|Y7Ϫ_2amU:eXOnKyxC(Լ8Ⱦ!"x kwj/0%c!DzDx%d=Mq!OwSÎ @luc=id#S!% DY@Sy - j!=J?l)νѿVc'tzȬ>y^Fg)Nؠ!t̫"E \ٳHAP9ƳȒ$ 6uO{, 3B<+-QcUTƔܫ`}H2.q"[Ӎp"쪌,29We+6 U!na :R]~[0/O䙣W\lNyUw1]A iT4jP8pm[1&sx.HE h<o4ۡ4NxSx {0=9Bͱ~p;;l 2 Ht[sG,"Iڥ% 6FŏR 6$fvaad=yVuܽ  z] {,{72~%h}{iGnHƀ5^ɪRŸaVKA= BѕLSu!0c1 ʼk1%I""Fyc2C.B8+&/:E<=`!v\T|բ9<JU(+hcVSF/UӪz!ߝ81;X$EOkE ҌP(b!߱~{"{ÞG9>\~Bp0xcgID6ng|/keG6X)'0ɜ0O;]Nn\vxuN8%]/! vp3@rJs]\:A2Y IDAT43P'u?3 GLc.~Jn˼mX"uL1#X݊K]=RlϨ"̷?DTZ[T!,Muu|XίO+vjZY=_'嫈yukG[^t[=\FQtFdKy=ׁpqϺ9q!dMT3nK9ɁN`OyWhe:)Qe?;Rx/L}m![ۋIeC'Cؽ%1JD$: `r{67v㚇92\M*''IBv3N~luI{voEUDL /SLG wK ɀ8| WU*.(|r1pZy\1nH+,ӌD&NN}tZ KQH8eLIZ$"4q/Wa.;qI'DH`qr8~}o c !;1\#+!ݟ )zwNoqm[(p9<5/P-s88%}eýyĿtHl= ܈q5OeB l M2&Ǡb~?OɅWjxzB> abX0O&_C~L3q=g˥(JYlE&ٜdE]`'Lhq_3q9T qal+>~ -3sL&'mO ?ڡ^xZg2Uϋ\l_d=V ?"ıfZ<ffV -_r<Sr75tX Ҋϯ *pS jl_9ܺ!+ð } .KpSj%/.:߄uF w~1f-xzj | 7 p{go".0-Kofp%}QهS|8D 1ieQE9~Կʃ߹>MSfMWT(Ifm_aS7M i>_|<buwٿ${bԪEDK Mftz'm.6vɅk?`M(п'-7KmťкԢza//IB񈯾]fQxUh=LT/5x1#6o AZ&Iԋ}[g9nBG%:t RqԟIIn_YkaŞny0Gy^EHKC)iU޹ R_v@9YTH2`\p#/oKjc:T etYVYU ?>,t84y׉<&y\U- xvL5ֿ`rV\ v;rokӇpF)IpX8,#2Fz|ZѼ7ё~A4SUœȫ)fvEKr}ڎY%-0nռHV4j DK(Ǣܾdmy(ע֩ErW* ֹ`JIvS8X.f{(qJ=P(44A=K~Id(I&*&!ꘅN2bw XVږ0 G`@o]HuWTyMԥד p͕<> 2͂܍( {>V;HI=j c!E7 Nyrc;}rk,hqyxc $ 38;/%/~(:Hy\ų߰@T-$ ڲX !T: tL\, Sd9 #tiSx4x^4{K W!A袱.%։HUUSϟ cԫP<&1ԑ~ڡh+yW5D[uL৩HJI3I\w Iϊ(L1,N-G(F=B$6t[V,ۡ^<+$z!]E8jP2.ҒZ졇{p~fPtLEW:G>/3ꘅm6QHh١D5V@gb\hħoX Kǣ8§hcRC29prMvkL}[8ֻOD/Ny 7laoyֻ9\ Z"A_?5"ɤpҟ:||9ԵoaP`s*gXݔv1_WD|@yHg ߭eB%eq;"Q{ܠAC*~sGlv{>qԁH" uw%\qەÈ9A-4'{?k/d@#eEC-Ejk-a/yGʦA&ӑ7]QϢ Dm ܃3Z]=|J\메揞 wHB`O ʋw{Oey[6zCRjсApl+c:B5B7Bۜ?tM;w@?t7z;m 8{րlq&&x zN*o$ |^p+*\eD˿ Jr @cdau&VhQrenVL0ѠK~0H#2]HUPc%Ղb9V9l3'I{%(q[n`E&=IЅ!X,j\R#%.?+նҎNͣǐC"u$[>Z=E-:ߣۥZu2]&׉rݲC!6Wϳ$.ԼU${sc;.d&+tTx[O }Ɛam'r'9H9 ]8|\ڝL]He~{Ar:  l}=/Ҝ!:'"S=9ƃ;0w>W:}t;|~O|Azv|N `nqQ426y:cn>_kQW;-ЭVuu۹Y{Zđ-._Wba&k]9 6s_}-\!ko5~-u~6C~6{Z-[!{o2|zSb|_Xl_+l|~L(~f/ƉFl֝ؾ};ۺ% |҇n](q25|}"uNǭ<>mʾd'=~K_S΅\9eq%_9rFeRD"ߐ3|o#s.^LzòWx33/lRFW󽇜=y?IK>QZ_E#reY|ಎ1Q%nmfZSh^JҪ T*"6S2z ܆%J~z诵j8R3#Ot:\D.KQ⺔zVK NF/G2]H1gﳣESQs*SYEuY)7YTsF^rG0r\WkE.<%vIOީ hpo+im@SM-Q; ME~ad3HgOB T )εkz.oտњ7HJ`q^@iZð4|WzI#TBl_`' _PTNkH%(b$ بiEP:ڹE^~LD(WO(仚HNe|uSPNM(?Hヿx)'3RFe`۹9fooQβ^(niV ~.R |s9+ȫZQuAᘨ6Y&%IXVE)=DsĽbؔD#[*; d#M' (5\ }+Ml"!ltHlߟ#d8嫿Y1%=lv{Dϣ^-FՕ?@WYJԢB\y}0 m.$rycoZ]w+L s^/y~ł(lr?GQ>hIεmE( 7DfaZ@1ã͍rlI;(v2 y;J3,P1]A{s巌zBoٹ=u,PiV*pkNH3q 2fp06d y&{`9e猅M{ij$h[7bhɅѸr#/^EA' 8J*erc!pE^_(eCryį4Z8/n*\A!Yϗ>օD>s눣y5rX?e gmqt@qHjIX0OWbywd]6:}zE\'6BNB=* )ڮߦG36DnLjkuG%8^_g.ecu𧯧( ~$upw)"{ 2lk 7 fdh`[i`3#I6ewI6v`S6!Eox9Ź8$ԴfbKǵ[t$rۗ7۷pރ9;C5'{ CO=a!Hq5Gfu(CC':8"U8`9 _U#JgTb0֋{Nʃ,"4+Ȋ)J+O3GI ˹z<*=^:j5EmIDەYbey-&-io5Di~ s`h[~U &F()~ =@W߽]{ۣ:ٿ'-\?q뫀p}qeW J9 ?x7b+ tRo2ʜ9NBEyo]{!>yODb^ۛ#ԇnO=a=lo74k⼂BzYE:fcN$y  VFH<*䦥9Xԩjpj^uVnR(ouJ͓Q$fA\:E89^~y.G,V|^'\s8ʜ copŸgUĻA^IVPZd:Tޮ顦C'^˵&co39hE wq.sUH•va3ٺyG;v&턼#wX0),X5C.Aw#)m ̷ vyqdBoIl8~}]vO(R{R8JUDQґc8Jq!#8,=wC-/Ag>I'/'*Yk5YrB]oX넸ύD)J<_۾Vɯʧ"/n{˭#wR=Gn@ ssOs n7F i>x ]\ԵyE., ]?vuz%1/E?4"XTϸP)זpie3"pp3f3V".BNi ${!7FCݓCv͟vNޏ]'vqNH;}\?XϖdaP)oCl3nO: wWZ'Lu,[pP;'i3hHCihg^W.*۸:[E`BK]of!0^ s|4@<~U߸@YtD2+K(|].珕GF*0d!~;8'>rVdXIc41<2'UJ S>*,"˂3Gռ'il@`KDzİ)OdJnD^cona|Ti)OWįߒhBIbŶQBஃt"뻓xE|wGB=Z[ & qnH'Ǒ`"UXq"[XES z}^r1swv9%WSzKQ-+ 8tj*$\ (a*SBG&x1+gTu^ Y#U*H'kBsy2y:i9#e./SpC2F_TEI"(5 7&xxIԮ"̥~7IvVRdC]籝'Q"|pĹND oJ+8HES;:,DԦ{ dEG2z'oup?=^;p4D.^ԮЉHQtnOsAȜg`_"\k-؎HL;Owу#߽-m/4, 'Aql !@&ar*Az0 /W tFí/zXh̓ Ak\K煽Lؐ ;0aO d>NDFR*tW4ѥ|07u~ת2+~p|heE4`Y6|e] "EX΀t4zHrc}) VZ᝸Y4dc u$/EJ` Ta;^*T ~Ȅņ`y)#ԑqQ 8^ͥ(=kWEܐp\ji+@85ypXcCFNZQtL_ H x7st0΍M*@>r~X2?ژ9v?FjU| oz*1sٌC] ^ +poJr ЅrXߙp}Y^' }QOo)U#MHKr6Wu .[~I⥃̣?P3 |-h-i7Rջt&;E wqc ux"Љ@S)gRuѦW]:%@, q$ZD֩u)~x(򑘨fU`mhUa/E)i~&Ȯe|$Hlo ֺK_I0WqXhLdJxE.YQL'lk箑R@'aj^nW0y/ OLzƀ ^ *@5؂s-~J^ yRkY G]7!I!=7_7Yyceؼ~ka'-Tayx >v kLs85$J;`S]'&Bf6"E8>2du>t ;99>zs|>4MGQ7[ΏwE1ڟ7X~]IGWrS (đh ĆgD.L|Y0᳞Zŕؕ(K0-SFk+p!:6(fX?.Gql*wX?cRN<5\ )ZͲ/@te:- T݂+FБpW>k\4mSH1hh-DwuAۦ?}@jkGsﳩ균M%8DyH<AhmsYz(HV§6>餵m^ O]:o6bd,^gr|rD=-ghrv sՌzcosߪBd%ˁ#/D4V6sQ/hi[cUՁ&kZ䓬/a%s|Q WZa$(P~S@;8pjgWi+DĎ[$f!bbMy{;?Wt +g%Ζ4_k Qߕ005h 7[>Ѷ}&Unղ'و8Wn-pi`p~4}L`br=zJǻ. gF3?uOe6DIǰ_O࣍2SqXw|cϺ#aҗR,F=X˕請}F5 ^} Q͕k‹l,: bmxL}7]zY<_AҠ!ц$I1($ Y?&f{qBc }a|Ulb-X WvreaՅ]I}? @&(3!\bf:y(2i=\y~٪0]\Y\)AKJ5&Q(l ʫ-({VגX(lhK2 Se|bsym}}d-`a}kٽ+^gw/F$,s,/{k놚@zG[G訛AԊ%co.2Y0}؏t"H:qe[7{п| hL3$-χQM%}߭'r= Ȃ1pݕ@$V@@-v7/QsTz=1|n u.~B_8#Js0V|ŀMK2f\p:azMSሃἈ0m n;qoÌv*zNjY,9OgAkn:\=^rMPF]%wP+ Du"_AT&V 8'!>r@i @yF1_T8:Ep/@:sl:80YQ sA[:Q]JrmԹoPkMGi +ՄBW+BoGKJ66SA*³3CbGol#r.?u `PoQ3K8OΣ&okl9 DT@9sOj ad;@/71Z+ ?\y瘎 u2a5`V^fs`mv>c0Ɇ40ڋ 6mnENPG;7 l؂—wUrͫ|Q|YW0Gܡ6cZ;X)Je u75B:fhm;u!qJyZ^BCMn̯lnH]%h0荎Xs]`Ǭ+ 9pU}7꽕GYkJC&aUe[:]%D2׶<s3[0ӽ swn:da{Qw}xY+ͯm@!c[ͭ)`򃻃cN-NF8Laݎ@9Da)1Lߠh.J zN?=H^0|1}Îϕ4 =VIu/$F[2{48n[%ޓz yAr9~FګAtuv}gE1dυ%&EPy `$F$J2 2jl׉{|o>y R]ek\,  j/J F̦^tEW{;L1]Xo)Vn_('{bE]̧ӝ^5iڅ ":5\R5]ZUDW,924 [ߺ32"a ohRDQgAx]VͿb|~͆ngvZEcX1cdkztLVzNS"˨NsGo2x 72-.~[ !sɠC$f7XAx9ޥ$!]pṗКWXlolE zG&NTx8"k8)yo=(=݇2+rp"m q@g.q+J唡KLWݚCq;)ܣ{|gh#对q uK1WSºct.\:|eݒh4I4e칰IAcϵ9k#"PXxl vnbN:jEp$~MV>i*/0y8iZ[ @< @t-¿y8pAOPwTF OjwWip05׵uخ:&\y4c) ˮLL6Ü$ 9g8YKb߄qV7\7eZ>jS^e֏w0Ҵ ت~QO<A'h!9廱Ed01lkCU`Azw~^w0^RPm#>5(WtS'#>}k'stcyϱ$,̤>Cעz P;GdNfTڞƗw6GA+iK#5b. ه+Ũkz׎Eӭ;cmNi⎓~J :JwI+,nWY?%V_YUSnprG5`Pk-JtGq+߂U|xհkTX6+5*+ȳ_\ٙF.~X> //=+^ <5}$,Eʢ϶\>Z3Η\^a(~G+W>_2<Κ;d`A`w>_Uل +..)t~ C߉zwY}VV^#JNn/(|JlX/<06/on8p3+Dy~e uyz/?t{|c_c O(.~ GmG[Cmɯqۆ\l(Nz>Y%VMfK RbQD_+I"Կ=";7.o&P&$/!ѓ0Kŝ{ndEϜ+ z7N,a0:{:oK7ߦ^T1+yJ@>=7Kk=swӺjJjQuCdt{ț4-7Z=OOy:s4<9>e<9/qÞ$:ç1Iks|ñ0=iݽ)Olx;PH.wۇr6c&CJOq [vow) 3W;vR_*+^glv{%MԒn`qU's f2 aK& Ƶwhh3s2 0`:)y"8soVX$1' IDATiYBD$,kEdCq'k{ (i,K{r#W5Z MG])\ڜhaqW̼q6Ib#p8+o[ r0[l:ɀz3 pr3x&!+~^p֝g0M3HSšݤP[8yMFS'm0g)zxqn̋mP|_ޒfN<$Z|c'qQ)$g܏e1zl|GlM\:R,yHRP 6ۛfG-Ϗ) xZ5?9`CizĝN=a:hxKicze譧AF"aNҌұN -g3l^`x8 2B}ز= Olm# o)K]Dbȓ8ף'`@74m ks;ag3vVje`KKI7I W0׉\f ޱ+ь4QBlV`a\D۬u5vWE 95 ls6Wib.ͭʰ>ЌRSW6/co<88&[B\W2>ͯ)Z~*7 D'QGCf a+猺07.d!Фjl9ݾӡOĖu8hn19 2݇zVS =k5"Lo ŽGq{R(ϟxOpRxzIF][V@zYnwe9be5+G4C[cÉ?括$tV8P 5 Y* wf1ZQfbX?4%s̩IET/y<ٟHȡЏ7·-7pHubTzo{{609FkzMD/JpE9[Lc[mmCYp> h5-/YZϸB^5ܽX Kſ rtMŷ^q=\Q15Jqx<ůwX|˗Ͳlࢀrɚ,Jt+"˗%X\9e%8"|:ґ)NXQ(KE)Jh:`-FDBD˕CIQ^\zDouqy..ՍlŲ Ze Ri_^t\1\v}ɫ^څh//YheiDw N(X[w}ZȡUWem̚A<ppayY3|0(,67sagݜ]V-cZ^s yq_`6WUuTscI&nQvWaq{nAo5 0) ,rr cuz:,*xꐔ34YiNNٷgeKWL`#翣#&HdL(ϛLS#M%lA#CхBÉá뙓gS )\I#q!)Do \sDxxywp` Ґl$ [Pu {ޑ&r ndi 4s.ڵx?2}Phz!:qط_G[hڵɍ"K( گ+'?yʆvԫK7jp_ sV |qohp*6:NyóiNj*[@vEe>M3]*>ElHZ Xpx-ڍ#Ued*ܶj=SMG [mF4p oO'[͕>zϪ8LdP@FU ]-q'K-|B a1''<~[\1vy+pD<#<=cS!O77go!HJ+Hrf`n{dcݏ^{`.l¶uW*kM-If+P=|RI`v9ۛ<٪5 M&QhZ6Rh=H`U6h"oLM,-|W 8v foG.y~qíAtkJH+vw<_\9.sWl:!4n<_Dn,,@6F/Y[r-`kOo7M4YvnY#zo+9k9k  0݈P`䜮K`[=d7\By2κtD #t0fUmA_!9()o]KFkO$Y.i 2J}g_ .o /Td:feXj~+$UH{Ik_PZX:y\-wrcǻe! en3׿z5\3jMm _fe^ R^^09M[tF%4wǪZWXiDڜa>bf޶:ۍk6O ŴbW۶;8ߖqd>Y~KaD8OL}@}w3C{n|Gh*y-߼[;v’j(9F46 (b; Q;aGg7[u2!%`“r:{?10=I2$AvTx<#@x2`$jyI=YXpSa}*tjzKWw-[ 8g>"QthmωCdo`1{>i[L])S;a)φ'$i]p4f8lli< C{43ױksV,y [1=@*S1J) !#Z>ijaPDɀs iC_Xe J(f 0y̽rr{Q雋_.]0&em%c7x2o&27h|fjmza"PNPy-36A5: V(XikDɀw=`r0Us| :/2 |4U \E9g<=-rmlTV2Gh2\y4K^u^4\k6c~AHw1<H@t:sB)T9=k'gӯzF?Yy xg_sI"¸E^ $VR`o `d0ƕn .{6vȝ1Cɔ'GU|$Ks}j)ke`, UvRxι;!I IbGhp! 8? S &Nx& _2`3޲:r@ 8+ s;?l w?2S*t p0tBJsκ8<,FOw=AI# ,3 zl fxoOC\[\ $IFڧUpxO~TGu=A J ;G5ɔ$ :$a;p~=$08voɧnɐO܌6qY^t9wblr')J<72ͷCv =Qޒw&M$~!D(C ZCF ?O+5#uhSjLyY"h+)-y rQ.x{ `;07AfLCCjbS%<~[Oǚm)lqnwÖ7䊑67x!dŊyj']G݈$I䆪]k0dPwqvsGv-}Eh-NЩL4hBg-6,yvW^;jLٙFN '⻴6Oƣ3r٪⢫ΛF_ ֋lcʿϷ`w 򇀑L>M0^D'Nx$J:xp<˼)zYiUVz^0uvvIeR)%$R5uR5F O<{;G loo$2yxǻDa'\=LJG$IRK1Ė-L?oILm. ܯyA=(MҊؘ7^iJdXO9QxHlV6DZˠw8\ģM_x)++];^Q_0GaJֶmi/eufzq_aU,HL-Fr]V7מYĤrSLޒypzgwRH2i|K5nNdzIfE?i%jPܳ^^Vl>/38BI m0jJqxǠ2vL.cubEWөbp1WyP3g:_2d,rG]F)9=ϋ[H>lmOd$IeH+4&V օݏ p hep/B4Mi5w8~ݑ5lhdW(rΝmrA9#MR(9O[9HeY>W;p](B薕 4?u79{@VoGCHyvtxaxY,AW!:%!D$(I205o0ƈnf gE7XBj0'Qezs_+<{8`ą[NGSz.:IHXBIL3<+MS6}|; & o$*PG1H=I:½#loݫAO)R zCz]rYG?eoko4'՟yl 뙇bf,{s{|k6oqh\! :\xQaٲcΉyb+0Mhz:˨@֥E՜ IDAT26<2Q]O߄9 k4( :|Cf,|/8-}ag <<yAVIƉ`PB8D"Dd(QS2*&cwg A/%N:q[8b [SV1)@?}zr[Nq}%!lT ;6b3u3-9Z-C%lSkhn%:;Q]7(۩gItx?*<ݫ bhyIlFy;d+Cqcj4{L3us](Eָ)WuWona"a+9U/Fu3NQQRW.U#6A*sŎu5C\dm^A2)75bQG0CS$&JlKCJFɈU>W8U%` ?g<9?H$Hg2)9l>{/~Ke:/X"屡VbLWG52vIbSzi,ADG)y6f{gbLֳ^8H4 )@$ t| 䓌Q69Hx8k(l 6-5F cUY^h%`4sa˙ebv87D jj ^AQήR|kvc,tR0ϙܕu Q*6lefk{WL=k +D[̢%+̮Ӫh, "#3MF=j1* ']ӻ۷n:sE/[ٵR[_uV_9"5L|LuLX9pN!vY5ïuѱ㞆RR%͡~ %zU~X aؼa=0͟VWIgM)C7l{j=hk H:kMDEuDm9].clS}@:(/t1DmRۂXWBNw㰗1IqgGA+Mo|@rhQ+<&0I Vw[8tqI-L([+h9W=J8lΝ߰h9q=pnwsuWB(*uP>K'*p!V92<0:=#rIʹ|q)ƒ8(lNJ@T3ms*pݝ2k+wn|,O$2?|:H39MI~*i4Nj_]3"#IZ$q 0>Fn%hwkI6&IKmŦgR+##U2plP֘^W"J nmcH0tlr@E)eW Ji)MͶH^/B8Jq>Vr@$K m0̉%<ÝP7ASR.av14'J&.թ4™` yϰy(v>dӓ ,7Lrz23guыpJN Cp%yu'uv_:6\AP8==caLOxc 'x=`)L{W?7!tٖ"C$lVfNO?s1<$G糐dͶWr?GyBfc>3E&o(fׁqxr߸drp#;kqhiCaFU(M54AU|ۨuˁ553B!IXWIB: Gօ[8׿uq3pn dKZ 935-[>eF9AoǢ6:knp@n 8jT.|U㢼 W@xꓠmA@pbE5gX+Zp~}D}b0;zxn#BI~2)OxCqw>\X!$/-͜)<pb\^/Me׺o@Rk="x4wk0TIc =\d5|aMxgdTZ1 R~ SIK .wpg0Ŕ|_rY ;śyZsyj0oomopksU-e=x Ղ:WlKoVixevPW1eZwwO|'wMw:]xu%H|P\^~7s*nV' ?(; ^^>~'/˿ 5?_ށm^½;-;ݿ? gKX|T_na_<$8a W)_}vr~rmv7wŖs!).g ~1r%:tlgOlU;~?{??9|[wW_syyxǶlo+Ƕ'/={_]/W9{3Pgy$ǯʿ`9x$w>; -p+g$IBQ(O(ӼiF2%Z,CI&KK(D e Ѭ":rįXf(dP|X2bẺ.JXj \˾ս^ʍ"Xӎv}"k6|H~:Nַ&3D$.|߮U<[Al/wU0lgc(b웰ZZSnz2Εws9o$xkds?iaZ >y4X)QڄE{1W3 7 U/rќC-\];3].&[9k }0*H3ȁu[bww|5~|)R4>EܐimDV` ' JzT< ;g~nB\ }F:c4eڜDkFLa~d=2s:6HQFG$Uq/[w_uCnV.); Ȉ ' "sΧ 4ɼm*FًUz劵"̽խb蛼Y+PJ&lC}CFYHT=uA_o5 _#߭P,JU5+.+U`mפѼfno+`v@N۠Uj0f{y:1r.rא: !I:c<X,st6Z]S+ dtYt&$Zɦ{&Ola9!0Esߐ{LӋҖED;WvCC1Bnc ا 4!SW֒Nk ƀHתc UsI4W:m$r(MXK,WnkZoc$ve"BRESFJ3mVČ]._r\oGZP8_ oߥFd_qXe笇Wse'7i 8W"=Jx p-l Ë^6Ρ';y] ԀGO`CpΧrӱ%p=WѰZ6˚QUzW>{J_aLQ#:N(XPb.F"~Q''nZ0L&"җj.e'Dptsp`=5%4͟@s}haU PP+eu5Nf,2[W~]agȎ-t2SE 8pw& 3pO'K#mpxD8 }s~|Lm$(]DEGGt_X,߄>P$|3^:!EZL'H@)P. REUI:M MT6dq΅LAZ-U zK ^* ۅ%ez0x7;ܟto˳lH2 g =D`.˜)/JHDIq2Q:(=ӳf$q9|j4o̯C4oaAv [3|5Yk 9ef5WGK )za U~Mg $KO7n*e/+ 0rgBK2 b*ti4s%(=^i&1WƮc W%H0cMU~.b7u{z++(Zj +E#9K{S\LCJ`[VQC@D`Y @dGlI2Z6sb`7x,nςS8EkqH-H-ig>Đg0$'A;"'NOZ4D E 'ˤUo ^(u"`Ԛ姇G)!U=1\QՉ6J@,)mki|޹XJҎ >m9ꙋ sDvઐ,G ZcVzJ9,2Ӷ^(%kz^rsڞW Λ/15$m]3pPWLm_Z KM͛ɜ~70nF7@y~$P$m`C !fe=m^9@!] x>19AOogi 3vI*f= f8uhR+X_h]3ͅш&O4LRE$BLءEIQƒF֠ bgG y%AQ 6$ .r~' JR9$–3E׫}10L3gHӣq9Rq>1LeJ|>_>Jx|qXkGgP4{D,+Oiba\1o{M/Dıi߸5Msb;7[ŵ_2'@/ndF([}X5 rJS>|I1tx] ;ж@nJw}nkV*k[Җ&[was׀Ƿ }$5;'Մ8w>z|ċC#0=ݽ^ma N5g|ϣɯ>1J"<ъw.q.-f|:XMBR^x I[;~O.~G F e>cbb2t@e>TMYmp>1. JRb4պ^oSlf~i/ s5ç3w=zdw n0A4,sN_24i,zܟ=;aEׄ,&}dM7bnǃ;TWc .5>¸v^=2ϧ; 7wxem+>Н X{.s`Fb+F啯3<\+Z_uG!%妟W[[\ ] V(WWW;[f;kBp \xp \Ưg 1ӿ77>~G#3~Ŷ\}˿w_`wBpo<|bo>pW_'1wGj_/^$]0_m̠ҳV菶W+ɏv ڂй8 ~ο<Z$9ŏ~O&~÷nKP+$/zU{ua[\^:^~Mr󻜟߱RÏ7^}}_'/^w33?f毾ۼzɿ)Ooꄭ9'c+Žp.ynW>})u+sg;߿crȏu?ǿ%~d!M3O~.Fo_ |~.?{ں?3'qR ~j[.O~F?֏e[u0_]yu§cy 5Y4-Y@! #@RBΪ~`qPEat-r5/jF(YhzŪFts-GT$xQ^cuT)!=U:Z2҄"B|wj+Ղ@)kӋDw>DFZfl &9%{RJ3X hz/{#FX"TLxj7Y\nbxFk oOhܦm7r4;{$ ( ZMosyD/T㚃9H5ypxX\iEi==c62+|hs}|@އ;X"?@ySK:bξnX]}m&[E%0ГZ׺ÓcJ =炦FjZF?^E$s\NA]9t/xcSZeaKclR0p>e> IbC`sxc ,%cj$^V*{_G>Q\)vn=Rߍ(}I"R E bs~8h>ns(Z t[e\6=ںOMDĴL"5\,[RNUX'H2K<[sMjT/Ӡ]:|f݀e$KSV(ReT+%aM(C#(M4}/q敾&(ʹ}'@RkVs~T 6rssQ`9<8ճqWzl3V2ogcpb+,Zkf<9/O47sm\ 2!*Oj&6 a+m|>^\~"¬-6|{ήJBdP6L @hq(r15u_5iXt%_$M +Ӯb@*k]`nHPX UbK߀.諓Jcj\-@^ ocUr3nk:k{+C`+s139} ~ϖQ'\8ivz(s5I /!ͰRr׭e\+pQf?j8F%@{8ڇWyhGYh8@=f_MFW2ajBZ} 0EO6^f2\b ֠2X;B }Ka =A(E]I(),^,ѰTsQ=j_tS k@neMYar n"&= xqQ:RQ zS.9~\%껓B{ [I*9 zYH3gǎHHjV} YRfp;˂D4dzydW͏7w wXmǣjMMHlNH2{Xm k*4l~Oo-Ckmfl[D[Q/4 7> :)!~D4~E#*NDLlpf~>MuV(%}Q$S+4Ov.wjLk8%mv~Dan0ކIeo ]1$x(RkPXREpop;{P= j/Ņ {]A{ A 畉@@A16qGGCjg.6EcF[.;J}yC_!22Ly2 AfYA`Y}219=s>'7% ^ҙN $s_:d/@W7KL)X9 5Sz}s<91GO4'1#0$*&@}-E`0DZb1}즨X&IhAf:[`{cgK䳗z9l Hc>}D',Z]t>ns!#+mu e4rL/ƾ3$k[`FfEcN0u}5 -_sH!cDe׫q\W!$+AGWu\B,2̕ E[\%ֲV?c[`ntxn|zabҋrJFf)nE҃+A&L8gI\Ӌ)찁iՓCdk!#A7 Jr>X ~s9p!p<?B2OV y1 t<|_a+]7syH:uY'Q`g[v"zEG@|JJ6* x0hXSAHuBn{5W-Ej4w.G w0d;C ^zr=*Q kO<}`8f4<=<`wdb:zIARa] J==ڣ%R:K,] cq>狧/0b:%cP*c:BQ~MH\R-5V>t_1"e;ke.^vEѭ$'E l`v{+0pbyӟ3==c>}җ5}hg߽~ D` P¯OZ&Y5ݍqG{P.IWVښO 8,eL9drB2"f0Yw-"JY")CzQ:Y\ScGqmuT)>]M_ } ;)\[)L:c0mfPx`pK`J0B-3n#ehf]om= eu#7ߊU#@䭤7VE_:f%B-i 78h3 Qa )ye'}5oVSu60ﱽX>d8r\z.:6]! g<; <r`ؤD.mMox^oH7$ ]SJ,cȸ xz4}C_&5NKG9cIg޳/^TR<8[&4'? 渰̰6dɄұ;AxFd)b] q\  R>yz<.5``8Ãt즌xL)þ{8Lb3瘋"c:deQRѡP&ƱM *=2 :0[_<9`89Uҙ@!{6a+ldm`E`;}ΫXT"E`vES-~ϛ~oR3L–$Uۘ_XWv6΅-k_iʦo3\Sw:U_Ґh [z LIikhsTk'NQs8MWמ}z+`.t9&hl+\1ʆ 5R 8h>|"Dh"!xMQ|=HZ!u=A$sV]u{\ :{e&X0EDLjP'`m19섟Jt}5kxtּ|>t5~s1ޠGo$قH\2g'^,阴7{,zЙB6X:Ug3M/RPcr\!%>lrvHgpT;+IB_0M=#U)E9Q'$>8qN0gpB Vpzzr%GimfenC^A˻)Zw:s 4gy IDAT_COƠHh5~_7[⿚9{ϔAt$ǭ*95JJST&j E"++}#h1<Z&HN4ѫ{ ԫp>)s[Q V.1$OPYeum(x$ոk>QN)I`a ]ϐ췸dCR; ᠺM1هbV|X!r/Y1X$5x` gbGb?JiF wwB`Thqq>9[kticXzzY(.xLEbsu|^Arz2a<ޥLag@&H yٷ9uyM$R f3C7F%8H1pbÅNe`+`dn-ȆCv;"L?޶cZŨ8aR1'Zjh5 oKl S$z` Χ90|V'A-)ʇ`A[Aí閃FNM|\,^Vt,nۉ2<2rkp\+zZQ^ I.Qt_>kZu{(u^md_J ,װmKf%~~aoˬ* ̣S zԞ|IԈy4Y*>~a` x[ lm2/x<{  u7lC Vcf_vڤdwlVn@~7e8 yβ.jo_o; :$ Dbt_9ᕋ†B4wQ U`59)ڎک9,LY?دIEKX9R*u!O&vŋ0Lޘ= QΨ ˳ӰB%-$EqZH"n ;ga. |}sҩf%P1=1X`w*|(.%h§gXa=$Q[s͐6p11hMZHی޿ _vN'%%JEtFb"ͭC~JRRFfO֠*bX:~:jT&]ZG 8]4k$mõAq~XVo+`6Qb|-ɸm~\Nq{I0,j=X.=sXNjOo3|5)1i`C!Td^l*iuc1a/a)9wSvugrvkOoRY ZEUӽ )=DmAv<Ͱ,% ;,>Ee j^rzzF?0=ګ(zv=}?̊+HLȆCFED):Aqxxo-TSs!կ.嵿e7Ȑ^+PK,l'Bx^:,)"(4Mz5u!b?6SA/H*:/Qy5Wˤ* 7 V| 7ߒGmWĥ_uH:ym۬MBV v6s5`#oM4E80uI( XuوݥoN:F^w׳] (;VkP.'a:I9{W&> t* 84؞jH(LGcK'h,KJtU !}Y%[>NC`O2z~?n&4Ay.Nz=/<Ȓ7I fU?bDRBD:Fb'zY0q`TBf.;H!;Fz9fi[͹b=Z1ݩ<֬U@ dƂrAZ&XO$3bLNR [f0A*lm!Rvέ6T>A".[LZɓlr|qQOD+iA=b^->OLw7/Dj9z/KQK5,p[X5ƿCX ěm,Q2X$zVRI~m\p%ց%168*`^96߯ 6xft}ZaoAՕb0>21k9/[3i1`6wOl5Q~~0: `nޡ/ޭ˿% A&⣗e:f /<l]_~ryBHS;4T̬JlMw z$"a[jc1c] APvSX1k:ۺ}bRK&p/#nۄp}mHXP] _^wi!$mFyS\ n,><>H2T^I+}]g{hSP,em)fM]6lKiAg홽-7/[Cu5phڱ㸼8ϙ_[@+.@fF\:x~`.(x=e[/j4A< '@W'1Pe}@8J;bөA(1O ijY~BZqpȋoX NC";.VV3TEɆ$"3NOpqzS<=5ȭLL+lQq/;bfD"6 *MHaևHogG6UzYݺy&t "X'B;y.$Dc^`dz**ntBӚ4iD*Y,.B>[\te|F}e|G+i-EY70v.m_ǼiA'" >^ڢf;ĢZ(Z, IEF65۾Xa}^6$w Y{ӝy+#]i=畭 6&yqΙ_"P<ٻxv Kkg3戝=Y$c.<y8sAOSCMtfbUR_b\{B0-|HY#}./o .6rg'v{x9ঐTE$aYMXXק_O ˝ CEpWli Ul1gStҡx0 gS"t@,:`;`CRd5jj! %de.ۂT2aFOJrd?!$ MDE ̷k~!#{!rm]l7hiv|^NpƐ`g\WZI|>evIfКL <* +8<_^Cp^Y]XR&J"qB@_y7^i0eo{U ! ͫ pK27k̎Yk/Wv,v$ES!ͮwb {%x t0"|x/}-˨L77/f6꣩YgŅ'MXZ|纮V%P!] o!fYy/o-$QP=[!t#ɾ{ HhbЦĬEFb6+Fʋn-_b]ڏJ] I9%Hv?22S]Uշ8Gǒ,R̈/W㛜ܳ^zNXyzqA1a{.b~6UU2R$Ŕ͗jMUUPR]WBqu|`W(+]_$1B@i8޼=f#f-}jJh+:1S&f%oޞ}|G J/i{ Q5$i[o*)(06KӍ @-"춸[D r@Zwy"$Z9>4idHjٟĘ,apNfvk|O|lcrf2h#/Ş*v~K?m&2EEnO~(ox{糹XDޮ=?ݝӜ6ii_2ۦP|$ÖŔS 4,mSc]{ X%],m3 ̢YD\ϟ"מG +>ADU_nK N@WyOlۈebxl01VȘroƐ[&LapXk@b[Pw>mhUp:GʪX5p&әM^ēv2L>mw,WoNj%9yhJFِ ƈl/|1Kn``G=g>He܎~#2ʄѧ1zAcb:g`f| "HV 6YL34iR E{!=J5~U0S4>㝦t=On\- <n-h)IOsLkJa-NZG>tw Ra*Uu*x0U @+UryY>2?۾Tǀ\s2{\+z ) =XP=CY6M gyΩ&sgc/.P(*xV"9!EsE>R0܊Ճbq2 w "ӏi+ \66 .n~F5^sqvn62b=V{+?c̭Cp^A.'(½Jqwϣk]⽧ VBSTS|ͧLzDCL P&5պ'*aEI/kb8;_Rnn߳4MWɘ}O)3y&ʢ1v'inc~v#W$ onP-%%(tnSlo^gv,>VxfLDO-K3hlqݠr z45Fd scwLHcѬ ;-(W™{ ?%":y:d}i6&T E3f!#`ExKgB_POlR*rfO(&4ɢ'nAr0'Q7Q [xN@.:p\5n0.P4fLDw{' [h)_=[5ZFK4FY*sDhʘh+\j #'O"~ʎA UY4h\dP2^Z~8.]>f+Њ-F^3Qɘx'돯PKW?7p " O*kOcK:ziY"H?,C=R4b\?le8+LΰF΋qqmdyb`6d%C-$j*@s[B|Vlď˳W;)fPUAQG ʟ<ܯ94e~̳.9>^W:JUv[5vfEoW M9. Ҷyl$iG_]p(pg~$a IŜgۨŴΎA\USw͚q3WIqf)Wq6F{ߟ4ޠFp hYjշ0lM{DwU_pqc}<<4i7qN= TוE?C5`lsnF]vQquK/ǚt%?B22W\ͮehgg}o_*x?iZ lI֥"FפBQy3 kdx,U(T12qw>ծ|L3& LShpޖPNŀ EiyFN^Zc}$Xd0m FI1oxQz11p'V;\-Өn?,xp{FcNE<巊fru\}>F5Fc }Sf##PJBt3t):Pu'x N%WTv$:{*-C0Y}k|n (>X4VaR_ǥ,XB IH+ oy>H3qjS .n7HupP>Zivqel<+U>a=n;6f.H_oO0fPyFftdeKǭ?e T~}y.Me-ŗ!PFO`|@bfB/9* }N@T]ρ$#X(%zaMnE;;>}Kmuow^ɤqܮaWR6-f ~l#$é _$,/޲\^-N T1eZ..;-Ȁ"k[hVkIp~rONI;_mC5:}mqq%o]Pcs62Efd_[@ކx\s{&4x$ZjW r}ͭO+hs/g3Y*b<؆Ҕ[6[O^アzyYquV|>Gtk-fS { )[O^-f)a;h~* O- iq)%DcoG**+5րEU33O.iX> ÐYt s3d }LKɁm\dQz 5 [rSiÙy@ :%G*/6-5UĆPP/$f<0s-Pn叻U'exnCPk %J::O\åS6W-[߮0m0'~}61̭}chK8xĮEzЮXH4J:L$bN,#u{2,.PmK͕cE_d0_t{!BȩLdanנ͂!Vh& Ʉ,nn7)etITaϾjRK pߖٙXIQEq&R2yιMUq:;c:-X'KpuL1?_F ]ۿ^K`(+]XNYj:K8`qb3eT?ݬ>PX(a{>lBcɼ>6$OÛG(樵LQ}np>Zdᾊ"g) 19v^@PP<yP[FӠF+k[v;+NVGbc 'o~`{mYK0lsQu 6~$v pk|x4KF~kSK/*n8a|Y(@b "sKoQـen6bx{O`(Lׄ v+bx:p%2u;O\JA:P窐 #7*qN΍wWBS Bo(i]PY,)]˭W::5ܭ&H*\6;޼u__MOIׄHh%& 3vTUջh35̧\BqV!mqa1|Bh5p<Nj?_wN8=($rIkA1&j{n7yl|tҤ(؎sT>N,Sp$NpoqM%3sgL aU1N i1>:8(*>LrύGW +SC y2G00K9J&ZtnY0QjF*9len.B@ti؈(|Zp5+裬sk׌6.a{qzT$o\\ u%/A/%C{v(+EGCFh+7 "-~ `^nm{S%E|&h(/AA3PGj,5/0 3[=pbQ7LUkV2Bb9fRh$MUH{*w[n!8Bb,66F9kP^ȇB. ok2kŊ17 ]cUprO(:D =l܄J4E}q\ÇkvntZj:aR,z}RȬeR_;~L,G(l նTΛ sˀLfFRA]N׊KItЩx96;|nmLdm+S&`i:9F;/ }Ӥ$#o`+@nXhW l:F+0k*KM6tS$#(N,@]`94+ }B<՜;Dԩh%is毲6}ludžзX{F$Ts케uǛnUc-wbMbMw< ~AOw]  l4'cGF!*pbiaǏ7z?aY O'*L+| Zp(*ps0; wtyxL,s[BU`do/WU~sfN&{P9mEbԀ!dgpŜ-k&IO|uuI#Uxl<'k|?B@Z= 'vZ.XUec0SoH` ƴ̻cgL&MT%B!':-tjPi _Dr+ ͓%{ z̧">֑ @eX ˯kT8R L[4?[ M(}88暑8dH0s?d8CiHNN*:Ms[3ubRL2o`n'c+hژt#ya烂#`vdXRm& 2K |m.1Y5_ 6Cӂ0J+d]qg@XZ՜,s`fR<  f>Ɔj cݲp+0ggy.gN$-S܇Cf|zgo'o},Q{͏J!m~ aM316YwR |:m%{'DL J>M'̣-kt+ﱋ oyy]ob--hťmD{X(7)sq0cHd:i\t+ww8` `6_iyF3|hrje MClrk3q,.͞jAeT5qu)>Y] 6Zb;yV2/I8lP@y(-im{[nV~Kcw]J-NCbc@3Q^-(n-??Xb;~Ȍ&4H$o:#8ou:]Wnm B)U(8G}EdJN 8V:Nƒd鋹s'ņCYFc=JwA ;ҹ[̲@}ۇ/Bl$\?U ًuG V!z}kd гK ۠_9zT8UyA}$/N6V߾lz\բ!ڿ8rG.Pݔl7l7; q=7v{O˭gk-1)q{m3_FX߳pę/38] ,ĽG&"c2K~/GlZOh" A__9ib'f9"ÂCpzx} XB FWi CuW,Ǫ+?fO_v7G)$ J*Hw <9J C XH:l~k&(+iIc-YE_T us/sɒ,7_窚ή;CiX.mwX@yPZkHl3, QϲήyuL ]Z02S8'aaTY`H>~EƓu6Z']dr1mns뜑_wꑊQW&L*JR(>\U|zg9_Z>%&jxO}mLVt`1Qlv6E"/ X-$gca 7Jp|3T_6ǨV^:u¤ipq)W$aLf`ҴWS:Qc76g![nd'uPcJtl6b2;_-P|-CnVUk-٠UG5{(eHhSy?++WZ%>LN/quE, Lwe1?a9jT͞0's  ,3,jThǚP?1h$gjM:&Lè!o)8)Asx8$ЃE' _ F aMg"#T0mP`)伾@gWR>Sph{Zcl0?Ү0 'Io"C/u}om1 gnм_/n1mwZ)>{٧W(%eXVJ]6h#!"vsk-vd⫒l)MXq3]X5b0ݜFI]Yf͙<;^- l(uv(k!dǔ=!bvX4}GE[ k\. -7.56Fﶓ U.Y CLc x2C ˬ#:`274@̘WqՑA:dvNSv̶ Q:W:(aɍ)(.8WLZۈF=۰r. 3&3]jEف"k 0L#œl*%-p^qk30؀&j,9u=C\[ܟ%Ə2xXEw>a"k(k0H}U7\["BVJ]\i3 (#7^.װ@OqӍ -`s|k.ȋccs_'ibsⓛ&p TrLUn*SK${#ε0=`upL2De. Zk$:pZxqlDv4]tq֙pw{+H6,0.dnne'f '1qmږL mb[}-3l&:jt5*jfbv[L>?IG 45ֱ1ﳁժ7ja紑Pǚ\1۟i~VV_$ܲ>ρ,# ra?0(QdA\+~+ǺnC;<Ձ_W\UKdWUָC:"8)Xo:`^Qh\DG/G}ZSv^XP:#}vcɡ :16RabaĔqp4/ƴhrx i\tkWnO 8IAr7`+gbFJ:r{@OgqxɗpQ7sťR\h2a2G7̘YǦ-q C@] &N@`Yph[>4^H.KY楆OE0#"j es2X8ۃ2\y.-`x gݽiZcycL*YŐ4^h-Qb5%AXX1#頻W MP()I,?Z X.Udu"+[&MmIU.h&ʰzxdL,oyx<-mb quI1D0ۻrl6bW(lsZ dMæIҹ[Ĩ~$l>vC=/T01&7Pn֢Ab2`T^*G ^8I\׏4zRQd 6J;MN6uORA): *ڔ9yp-zAog~:Dz [۹Yq}^i2f {pA+PI^MP8_?qH+.@ΐcT1Փz6D~U !c2# AI+АeWUOX/iM&u-:j KWؚILg=]:C7R z~*WL{LNT#/K4Ζ>8U謦!x3=I7{q1~`7\µ eEۺ(%,|MY֭?.h`;0E`%Xz+33:l%Es6 6;5;I1OJcSQz"saS}!,vz>wA\"75YET:<8=N1ZV d]'^M,*@ZQM` :)8WX&'.2B0 Nk!\a0{[g l6 [p^C(Q)A1x'sՍXSthȖTyz݇*}8Yb|(9WW|j3>iew8p-(` J@wRth4&FZKcC89wl"l }.s,Ǩ{Wtqկ){u2+ l4I#ht?_Sx-uk۸dctPU8y]ھ>*^"~]V uYX U\+ 1fWU&B%ݎ&F \/p&™uW969޽gp86|\*$fywd}ֹ_jN+yLϓ9c"ǝQv<z]:_jQ>J` B 1PCı#q0=[&CsMnx~TY W7I|}(y(7UCfhQLw^gſ\cg9Wqb2fav +q5fs6c^-nYj :ɧ;/BvoX׭*U>&ہ]_➤ӡw498T'wŨmE@^ Rtt~̿/$ԡh}H˗-m_a8/Vz@71}?=F= XWYvE?a0`bvOW_g RPްm9-h{U [1zeL2v.ʄ_ 6>ܯQmeokV:D9M, l$|9ymj":eѮ8u|٤(jikHfͮ]zٯuǛl3l՞cjA7LI[+/KTy~}m?Cwp7)lwmYٍ"Ka\: wbOh*FRagsT08yl3 b9G9? h~7\B,G8T4(M4:d3(0_O@-kv"SL^XeJvb^}j!E*=e̼IZf˶{>>,l%#( y/~_\U'62pg ι/'ڧjaJ+7!9H ~jUOy o}}sYP&fmOY|vLCOJ!kH|5KmՇcId,.QP3rc>K`CWY[m^Nrkpj9J*Dd鿽 Ŀ *ep/m3ß&Ila7ݶ\NbWK+Efa~HiJD?✷4o 6zJZ3͙3udwa}/gQM.;P 5g3n7ia_Yow ' mm%pnW7\^^GgKbƶ܈nǚܰ+Wھ/{lP``C罋ւвkr\qcc%a'bƴQWl7k초sST>ShXhWq$)|*S t[zŽu>a>xW3} 9nJ'V׬ {Nma~-pnĊE (]hE}V=u n/2vmhMIHuohM]LeMfQe*\UϨ3ĕPnW$D`훴bM)^W!P=V#'Oa: pQM=rJ@ ͶF4h]m-D bJX֥2FwhTs:R(%mؖpBO' ,\%)%eTnm˫魰5brlCz=I>D6+@yPx(b4OCsln -#OU{,a_[Hx 5>(7y[y="-w?]A{^kV[ @2o8=Ed>`OTL>T8gb ~ZpvvJxafǙ_j\=>j:j}LJ20|jR,gb>g:ι6J°Zoh8&bDNu2&OVOw1zrt):qm`y.EqөfTbd11tn{ u, ʗ<;vm<;pyKC@slsН:a0 fM^YLcI;;,UՏ 5|uS150{ه E%˂rqgs?ʐ5u TޡuifU& Z;ֽ_GJ z@ q?EKB $?W盬dXpz؅yB* vUT]HkX\vF%|)i<_lUSշDFZCDk˴8}nGYFviz*-P?qۼ6|zo&cvR0;6kEZ FӞ}2)L~J,?du b"ג=Tm\GSb l&c~cO6~&7uu֝D&,K ֣TW6I1݁n{<ɺܝISYguh_Lt'א&lE1ۨX̣_uB_3j.`[3߫{AA۲ }J|-hq_Rbޗ߹fB+4*r7.iC Pl7Un/gnIN1\G+ÈJRxDP@MpͰi{0(~ieQJl=;+QG&)߄ >GJ|[ nY.R|ͩcKOAw1WMБɪG@>R 8[p"@A=T!1ϙUdS XF@_z}ߡ׬25 v Z磆ɿDR@aG9 ~8;}"A7 &'O* @x=Zw;rFXs`YH&ꝇkIgL9-hBXb[n={rG7%s[*r!Q|]L͘UUqv}oSmtrqSaztr%򉏫/?p|yI1-MU#J+>n3,3\*kS >\^icp:/@ }O#s~!`^sućR1jtnɢ>//1цj1əߢ1Ryo+i1=vQ!oIQ-HftLf zJVɶm0*~ |X. ˉMo {wDI69 h ʫsD/[4Ds 1Y|Z plh1G6bBRV%E'L"ċU%ܱЕ䝺Fk} 6iXOEYJ$Ԧ N>͚/+{XfBg0GT %,3< Gkh\yG!<]SDd%]Q)>ϔſ-xvŔ\t KFW(s0|[\*U7TGfK4:|mOCsc/lV:H1ߓaI)ST2H_g翝0_.Nj6VQþAwy%TQw\UƏ'/ta4XeLBKx 6+[t~Eȍ=M ӛ+NI#=* Fk Cv$}"k8'Oӂ&4y{C+u TCˍ\]]츿ջSan9'JB4j#{7N]&AV7^P'(kѳ:cY^^LJWK$FffEc{%c6)e8vGkée"> w8h[`<9#i {GRr 3OMqn fNN;x|eB|g?x'` ^  b螀zǷ]˵b?D@Z:6_ ?,EŒl>ǖjyZW䅡(/e|/?{dYj'|AYZrJd yJI!,RR%]coۉY Xrq1]Yf60NF\Y:(?? M ,@B{[FGhN&۝ATH#֌3IᲨaDzE"YK,cTO7|Hbc]3'HGwb'JL(m<:] kiz£%s0ڧ;:Җ\@[BAD6CY_4U]S\>+aoK\m||4x!CqF"KzUf_|ַqY\릛Df]^4ui%0Bȍ_vXiGnVVNJ D/ܨ80]|lXVl$+:h97ZM1`|휈k^QiP fg!I8[YF&S:\u[oB_̗e| _3z6R _U贬Y)BmVsXB拐}3c.FL<؃_C ݟ 3zfX[XgV;,^-a~D>-2kM}t7?.w&pSAQݞ5ߐe :r,F@tQ")s +E`)EEou'5`VKN'pl:fvKFJ#mS2w1&GtbDL5 '+O{NךS/(`5lh#RJ}ƓT>=Y|{3Y\iUt]ÅHzrl$tݵ &7?btfN=>.oYQɳ9/ͧ(눈ȖeZI,e6KDN@s͞W;4>β$yu;phJ|D݄ ):Woi]9t'poj_l^`GRJ! \O)@ fK;(r[ck-Rnbyc߻iKyrIa-5%`C܀ Ե97~xhM$6Z@xaNf. Ǘpy93%2KK޼]f-Yb/:jdqՂoJTB:=u"2\e] Е4˸a7l@Nvһn'l}DC!uHdQngȢhO8NJB!aV8 ݇nPt'O3,5v|~̧As  Ccŏ'n0QVm}&G.u p"$B::4Rf%0$ 7:a5L#b>OM[7Y=7t`ooM' vѱv,!qr ̺xͧsx){X+pZ۫NFWfYF$0m`mW9^/AII J@(t"%tz7s%-Br-&7Z 4vye6!R+^%$WptDgevrThK {}709ʇ,CI:3y3Ơ˟,sa\ߚvNB6z^Mz(p}@iL_l B? ̫s!@d 3BS%sZ aU%X uyGB%#![yuRc-VƆ^\6YbRȆae.d^0aBj K4^!KgaWt 3heɮy}P2[klui+j+ӹ;'yJW+~Ua (,e!!l.kz]҆y~x^y3 W t֣>k}-^ IDATz )LjV]Df$LAɿ=5(-|oޗp@Cw 9~TpG#x7 Fa)MN63 >R;k\=%h3gV4Rqhl̥3e,8zɊH1,uFH)};FLsں<ufŝ=+VńrL׮urkNES(?N(>!T̳ҥfHul$ѷ;ؼ,CMInt5?zh>*!]ވPOr7=xmt][ @&7 Һ<[PEN  $áAaCw0hY6@'p4,0 XPkm%4v+>C=8<9 N^g!5I/HqLkdYJ:>At/= QktUxx2G5`pi>yIl|Y $l{L' ^gs8إ4ND"~c;W;gN8QV7쑋9T ]#24Z$VM#+@AVM6nVzND$E(mIg(-@wFrf:1ͮ/ϭ vK*x0/ 6aZcYvХtocm WeZD P=[nB\uPMZ(gMOgb˥bmٌyВeI,Q\McWVuJ`}kzaN8hu&Ơ:1X;˨a_4_,ao4AeUfڟ|^(ʼn31"B6צ୙fCԅd &ɫ6>:[9h~<=Ϳ9%%)e F>7ӱۧ7j Nknщc_qlbN9f)HD'|]S,y_8aASciI$JhOeܱbu~``Z>Z%|v %: LhO"'`B@U&ӷ;?&"2rCU=Zɍ"Btjg6L'sM2Ɠ)i2? "67phlB YPaet MG8K8 $ k-F%ӃMߓSJ+:@ti$ zcpGVy&56Ay<.+1߂zC=+:I`$P7vTZ/S;x|r߇QF(d̝~ BpfQ:l&Ϗ2n\FP ۱yNBi" ՄղE>'R1BXZ%EZLezݯRTfa"wdiY+k0vr<̧ul2q"u/[cEk4:`HJbZXT-!,+a [TXZCX{5 [\iC|KR2W?k} Xy<}#񝗝/BQH$ºB26X6J9v86UaW #畎]mJ k@Sa=Ʋ HP?#^?q7,_$TgXUå7b_辸q_b|Wz&zo"±ʾ mˣot*XwL c -0(/Dfp1frri=ZȬիA;k =cܿ`/r'~(`Xx]C)V:3S#~R`Y#t2%ϼcpNz0(KiYsmlFo0% 6]'L&g=y\s[_@.ABkM 9 *ze#ͨ-B@݉&CNNNBMIKbwaL5ZID!aBðtr#js,rӰx::w$E^Љ$R$Hk~" "?))R$Ny?wa<3In>$RΒ/3 !]!je| l;`+lfn}A@`A[,V,(%Ԏkd6 -r%Nw(tZB@`!'w- \[Qmi,hk"Aj@6}ڪD@"h%V$>+Rpaa*g# *($ƣnUCwGCwb?)wsNOAh^p=DhF$ϸ^t Ф7仄툰V6x/s)ϿhAB+NyLm)EZq~[.ZBvæe[lgnkmfnZ D[a`ۼyOϞ0xS}BkyO)缫"^\,xyʏt>l1R]CmDc~_ gDB$|6I %iI(Hv:|^qv{t>_DEÖ/ =䝪0pah !S]DL.Y7ے:En5+rYB8YIAej9` kYC홑J0jkdnPhI4JܮR/^+}Ȓm ֧rۄD^"D)`V$\T]R_f~kqYB^?!\v2 X"Go|++:+/,]v7X>*Nf;W79LJ^E3mSw6t7c={5cxs.O-2*{0vUAR鑿6F+/K- kYYÃDvH3~nlp?.>1r,S̦\;[lƻ3齦0t 1.dŹ\'D`l{UfsҒv{d<1BF)e\5yQ"u$H{&T" 掑K$C)g!]n5\?bt ݉8y:nt~~Ʀtwt?xtZ2cܭfeiV*w~4ƦӔӺoA2kLnzAJ  ϐRa3jf[N%g?X>wH5D3ELiRgE]lSpѹ(o<:=!2'K7tL' $_s ?~.݁"`w:pgh-CvV ul rc"asFCp %t,^BbI'8Ʈ[tJ&<9mF{3L'Rȹb<,lg˪. DDnv8|·rzYAFsaO)羡pOgaw3?g.rZbfGN 0Ҝ%wh 7kˑ19e6Av{NnSDEԅyUtdzp8B1mt~tU> Co4 >iR'kABm’ $"MEn1H&c&$w Y2"`ë6#{u2 !֦Kұ֘M^ED+sl_~XN:|6N:87 kStH-6OɌuvυ.XdLE46t"/IY޶Q0yzH̔H9[+ C%B[z%qJk$wb4)]3"JmBq:=/X{ { W1B8rLD8 dYN&Hf锓Js}z4'±؅ḗ8>~ď'?o40<8DD!$k`cɱy֚U3@7>q|oe:9v+QrxxcVBQ}"pqlь.3+Pih̼͘fo'z>9k5RIlWjl,?BfSHz];np-1ͷd*pΌ N~MkI#ML<"vn2ДP&̏d˵B(>krּ6vp5m_k䶄08]EJ;ɯt y2G*cȳܢ_Ӊ;Kk~B|Ag,ZT%]o\"g=[tLN]4lS\Qh({E-XfsU'zSg'{z1nk_&Wl ԺH^agk)7)ɘ[E̓eu36] ɱ\ PX AKd`Y=ЏA4#d8۳oc&  ;W-"^n~EiA\,Fb@I nHn%!?ݵ;$ߏ_z6x%#D?b6ӇHx&Ցgo3ѝ{Xsb>s2~у&Hpݾ S+8d!e:uDMruDpyuXÃhޮ `IISk~;ZfPX2B._Y )-o4;y026׃ *=!JP0J@?Y&5[ݰ5, 5"˩~W3P[!½R\ZWnY{ FuQGnK省,K@:e,֦IY5\N:/o[P._c^[ܰޗ5+:sl[h-]#UZtqX)QD d| ה_j3oo׽p~ϦozWst+k,cDH &LF>΋8t> [8tL?BgxVO\^J-G20x $x 赔.lrsGwyReӾβ bQ%7bji j8D3Rd<"}(>%2?F!QFNB|$\q ~f3(S2(&3 PGo$ZJ9B$ئ &8"#{V;<rn`e:=[kĔKI蜍Xj25 L"|UiG,tzb;= 㢮JQ#*Eyg}AtM섮pgGx:yqV~=08),@<'J.ә!Stx:gYX'S:%}fn\n2l\R5"Q:>?{}ۜeߪ $ApjIVK]HZ`$-gA|ߡ /QX/f˔|gf1bjߍeʲpc-A:FRYsJ:7M8AsF_}Y۲2^ԼfWiFK2:&GikR5E+kb5`FkTlc&3.FRZi/ >ѫڃ _@`çfAkK :| (ֺ$싸mY%uxa7QiRcT@[n]wyO-b a"Ya aZ` f{yox= U:.sFqXHjR[9E/Aо=Ia0vz7Y%no2uf3e9]{ruvsaVIRbL}N[uC ?{jx< '~& @^H/bAdvVhT`vV/?\LuO= ʔ2xzc &+@At] AM)g#b2XY4=Tڄfi!pr)CM=LG%cyꢘ6Z6Rc-Zk6٤ x0ؔFXG6|Ԯ sO@(HzlZ4YiP+ Ʀ$:b<1P1iV?rϧM$GwQi!jS:lA:D`KEUS.|4: 39X8pȕ2=BJٰGw99I.tI{’ˆi^1+ d녒6ˉhE؄%&1˨!rL}4:5΍kKݚ,7(lJ3HRx?{78Vx&!wj|D0m<|+lM.G֒n'` +Z[@%.XNvNDa S(*ZEV_rE:` 0 |kX^`*uUz QBD!,d@`Ưy@6k*SF!q뀻 ZՂ0mvw_]0j\o+V,[; 3j|_;;J5۳@TTwށ@XTRE`Qޣ xqAkEea[3UaRVhm6ha+wݷVY/b{c9`AE 4eWۦ½n /g Bk_,.h ,XdW%Xuli)?pɧyc<9v?`GmX3yy.* hۊ[-6_UΊma_JkNQc[\~p|~SAb>iq^sǴC]g_>|C/`=x",e7gv)wvڴqN >OakւaV[^LsZ[yfiE甡&3.*Ce 0zv n8/sDb@TgحXc͂*haEѧ;ع%vn 1b9{DюYD D&jR- jڷ?ɓd(Pj?G"vvE>E9gDmN> `=lN d+1}DAMLloiڴZmqFqq Z%kq|INȻm-ӌ[;;>gft·· *c TmZ_GaO?ea/0!_V!'DAl!v)p}л [&Ή;Ђ(A- ɭN9>s9z%̜E;L1'UmվEqq{Ec4 vinɿ,ٲ,ۊwgvhU3X1/ ׇ/\7Bvb"c^d!iqa[NѻZbyʋ9v;{鵾}xmwwEmEs0yR~!ba ]3``@{d Yl_ϭ@ Xki[{l65Tdv#_m; HEvLn4 .a}, `n~Aq64 6Tl+rJJZB4 B6aißp ^nru8"C v4S W- YpKE,*h6 1.vO)O䏿Y[_"9wl@5<>ꖂ &1~8/_`wu\ yͽ]Vps0[)Ѷ6Wϟ[>|_T{$oI>k^nm  j zɻL?;g%9 {g "['OۤiJ<~~8p6 @ky狌gNBdD-1slg=/D,˰6avAbd]p(V,1٘[bߍ1$>Q;n5N١}ŎRDRm( jon/X؀<lB78f+zN'ENbK>g s'w6`o\/gFTX ?_ п_s~ BW_XXHG,ʴxa]` ec[a~ *T(aE?,DO%`Š K݀fDWU9ҺXobv=h~\3燐H 2NM5t*&P ]ۛ}aofXc6{3YL_ֶzݜt]dM%ST\rh* ]?ވӳ~l{ʌ>}(+U|vfnyx?Mr? =7N #oJM `R_q[ٻAu`Zg+p-#]ܬ[?;h(艆υ|\M`m흘 4$#RBEx6ų%Y٤ 1hnYFz3ܰp -^@zkNεe~bsS6=m^  ^ć)M?z\IǨs(( qcMhx2[sy[ɱ.v.2zHϧ MGt4m CI5Y ZQgܾHTteW`Bм4):˨!y& e0<\:#YAу<ۇI.=2_= }ϩO?|{[2qrHp h-4vzKlݿ{@Ԅ ZTa ֯H䥦k$RY3K5 8ycҹ:f{]9`U#ư1b-EQJL !2|C?ffć ^ų~;'t!RuzC!vOۮد#«9f#e )H䒔ŚeBk - >^ ϟ enאpRhK/i |N)Is' 7wZ|(/ ֶu,y<hXA35g5&`|x_wĥ<ΐIlYtxk%X_  fHT4]aWع"2§H>}V fnZIzg"ף.?6 SkZL3,Gw3 # Vo믐mO% W_J)&^Zf#|俼Qm E}A+mm&侏\$E V$+bQ (̒ӆ0!]YTB+FJ_\X9V,V!&rh.6,+ʨ~uCbW'”4sջFQzr0DuK?HTA#bwB66Bǧ4KMmp)oAA}o1> N3a:"AIHs皡ҋY̾PLt"eb\!T[%V4O̊DCɐCt3Z1{OGBiWS_ހ_>l pAY00Gxś {Nae7'xVswBX2>|^cK);ubbch @֭SvSv>aynUzf Wi2IsJS+Fb] 78KY:I&¤ 4L:!UJ84Ӥ)"MWUė#A(tvL6Plܹj IDAT9wQQR &gs%D]R(H[۶헶f|'!eR a;rG,0JKoQ7*v0 {vͮՀIz@7L>Iέ-WL;ھ$NЏ `RdH;sSbQm7ھ_u>_>!>t!*:S usR")]rbݭ^GaDM(1 9O=Omp1˷iC{!k!Qz ImAW&Ii{2S1Rİ,t;g;9mnl9E8mSW}ALf {) @xDϸ\WNWW^{߼(✂AC(zN QY>௒f`ߞhײccj]=?މU0¬2%C]T96hQ9jP-'-(5u"6<ӄ= f;FNm0ׁ ew @'2~'2s0=7l;s>.;,/x@Ǿ,t%_+ܘ0R^ՀZlZ;,RlP\QG=b;%6:oȲ=r̲F{+¬+i+dYtEƅqt9N|iG̋[l"Jq|ݟu_3pO4ZjVgn5cϦ:ޚ[89;.sgy <-Z'~5k?qn{>ɜ#.SI3d=fYxZ\/H^+XZ+˸yC14\wQRQ7sX_|})[\^fAi4˕DА3i*rlqLg}% *>3 o^C]xCաIY (J y^4#0!Ej(;Z@ J¹:O~7Mx~nϡ[DeKV Bc}ll֯Z8Ac)ϡǓ2)7KM1Ǻ@JP9dZ`)Atg ħ#[BC1["4cvdT(EM#'8xTc]!rNInGObu rkS"`9Icq 3K6wRBs vi/3KdM=|=;ݴܱ6y=4c9qdZNLb]{,W|>gm°jFgo|6KMLg pNCcI#-4?ܾ? ?f<ޯݏxysn7\h73؏<('Ͱ*eիP.o3Y4W1YrOtT> H\Ghs[}^g66iE<% z%р<ßpxARySw;s Yp'TyY\eszqѢzcY <x^h)ix:E4Ƽd4p ↻BMۮ' a],\FV<2moÚۭX67]a6wBP7pvֹ^xk.XҹBxs78N|T$HHj[,8C)\ّ& "e^,,#RPCD4+,+|HiE_ĘGC&/?*i}>$xYbR>x՚y}1OC1BYa,آ@FWFSXqQФ/MqMu"6o`#h5;4Up%`wIc4S{gWD Z HI`[ y Rz!fYuQ@/HM?"Bn5 $i!e*_^\̈dQ2酡T|8svmY-6[di^ˮ"OR 58N -dRC9Rp"N|&di d}z/dCJ3rrBi &ezTR9uI^Wo ]Χe}vӂ!$́,:%hiї9ɱOp㞆-I'ED'mw;|Dyl~/rI1~.,!ʸU/bw(hyRREFx?|[ ]}@nµi,'LC[ޯ[HR4E:& 4da4*?O\ l΍ZT"Eu.UJ`4-yh8B7!ӷ!(T LY E^~*JN)mb67U1\riJ=ڣQ}eکLNO6O !VJcr?BUZt5uZŃ& }djC_ Yٓx8y[Yϫxv~g]0vW*q*Zܫ}6v/o픜A  =w$y>#Uʆoa~rcwӬTzY;A27\|xH yK!'C4Ф+i˩Gpۈke'_'1aԥ13msn<{)}5 .; R!O ]_n@4?hmBF^|<I<޽m$v8O쳻l|["D],e*)[7A41ep ޔ\P"Ӆ.%=I?"yf)ގ*~DȎ_Cʒh tFK5bMD+P8fc7+\-QW_W6XUi~XX٥Ex+LZ{@. sVQ2wJ27}z`" %  |DAã{(&jXxbn;AaxO5yl5sgSdCk=IܸRB=+LtskFrly!f|mH&`<_#GyܿQ|c!%f +=2cֹW\M1}綬)m  GZWxNNf<'kXv61\!Oٟ~_dofS8p޳]2S4#q̋8&I<~u=_{ޯ~u[I<m "q/_2{MD(%¶V`MAg\RYŜې1ep ls^ @\ZggLTW?cf\Qq<b~>6AoylPBgO&^t䒷re5\q,Zg3zYI61?v򃯓ow68GRM?}\8K;q6 KmJioX/if^Yl}og?Ag]x[|9G vw|rHfc_fs>qofSWíSGpbbVPxG̴[U/- k-Ny:s̓Mwwg:24FҘN?/b;W';q\GB7:WkxU#+tѕ΃9MYǙ@+T(YvR+ip` Ҕ𮩇q}t1KCoKx8!Lɜ2S˹s 7 s|Q[ rSg'Dwmv=7 F;9,Se3W}昸=e 5YIkTYjrHLS4NQd>`/_,v\0}| iyyAS4@]dRGUps]|.U8LsF$N\v܉ Ad|Cl@ɐ/wv,Dr`$FcG}?t,nw˸q=a] vuЙp-ۑo;2{ ݬfo!N3-L$BlԵ)zah[({UkMQmܸ@AwɎx`{>mZss{RjU/$)ۭeblE`o$1;;&1¯Q  Ĩ"T߽O7}DIHe{En{*Xփ  LfW2r|u.JuW1{w"ɨ7n(@qD(>mt10W}58Ά$_0~ݛ۫ǒ<(׼_%y>trEr\]AOq^7ݾwGzoswõ/ C"Rz]&A_p4Kܥ`v\"}|4iݞ!MSP:E O{IAĿ)yBH!*qr  pnY#f"qviP3yy%ZȽEKN/z2(N&O]6'ܪ/c(WX.mRV,`' NCmd̅fSjM YғDcBEmm}9ׅ  C0jpqHW{O/L:;$BiXstN9@0E(Z2B /4&Sr;[ ~Hv.,?5O --2X^i/mG-i0򵡶 9~%\eԓpimH2~|fXy EGﳗ%)Vs%8=J9aR ~9eN v| g^I.c%=)% w, N.hKnE[hFȳ~F..mL=f lzn_$? ыF8uTT Ba; }U',)H6jOוl(') Uiۧ#C$Dѐ0D!a1ma4F` LR7rLMYf4ԌwMPn!yS*2!H9fZFs *Lw0S"e8ImĻ*dქfa(&ee9ɄtQ9(#CY&M "W;;1mկ_֣wnܐh$uҿ(B)APܹŝ;wU I,fYWd =}fdxF 04% ty1Q_5`p(1Yg1w/Va~w>n,3FwZU-ELrt0<`ZT)Z~Ѱ]Jn].t?])NXlsBpAyJ DiD-FGkPA+#W"'[ bز7^B*tT Lɛ%86`E5a=LaWfϳsw # 'g3Oa/f{u2 Cd#}lfjZn2RjϜl_.b[ڤ%b=ߧ(LW/πR-!Wa ,iNX.>c] |!]#6"ARfS.R4%l %I\"Xv 5<K`-[̧p"zB>C!7d-0Bq 1@1,^RzX%fYF˗ [57c=3;ǘ |0 T\b6q8Oj( c/5zI~\I!-^?}[HA:tWmnGH Wkk/1UġH[N`p)ɽ/S@Oa5&Gؘ%ߏ_&Dl5k `.j ^9t;!|1HX d vɅ9]B]!bѠt;t5܆p .(@ ~GddVcYq?sz?a8f ϘKEomZ?͟SevHQeYR'<+?yO[gϟ}[8[j~%W˿7v9r6A940Ʒ7V:Cz=4O[ko[Oq)K)mhv'(DJ~g{nހW,$38v?X %)AĊ 77ٷ :-J !|SS`S2)-Orկ43>G7))PE0ܷ( Pˌ*#ŭ@VcZz Wu0rs߈=R֦!3~`1l2̉WRFU'gƏcAtq;:{zAEi B({T5T%y>Qwe!0'=PW\7""]?Ͻu4AϷym1̻Lsbpf g58'>圑,՗[[xxm,.|g, ʍ^|]*+ZX|DKkgY՛W(Om3t0i|;|t+u phL"T\gbRG.x=[cFn;) >" Dg6JkͺiJykXGWzټA|Lc:zU`}AJ3DŽ%նXDk2 L.;Ժd\b-|.9YryR9!,#0J객\aVA3CiL5WWk^,NA49lqդw9zٻK`5!uI]SJsL JCdc g'k ոZX#+J+H2pT)s߶S[r()|`+5zOcbuN/iA uvp99=Gsfk4Yٿ97ug*3@hS*?z1ʶUH4\a9Aӕn͋if=Cgfaڐߓ4(/./ f=ӣ&@ J֖_+g㠱PxP8G Cb/kp.-",γe%e5f Ё^-/vTOI5캃ZeiP̟#\WU m[0xQh}#FW5:mp?ݞm *엁}@;JC^cMSA/[DSɲIM֥Ul~nӅcBAkNDC++St:c}9a,>ۭ@8*~5AȷWZ00É#NAzo8ԡ,~ 1u.d@LDZ3 ]Jd/@_ΉWh,JL0(7 fۆFY\c}hLR%˕$n3ڶ[*9?]sګ+Z@TF EYass6Vkf`5a+ϦϦy2?Y^E Tg.L3 *YvvZ'6O(u3.c8p-젒:O݉êA^҄Y ,JM r|cP[s1]#b:qE5JdJa_LRGW^iArߎ'ͽuikP Jm錢*RPF =1qi *:\`` Jc>˗_1BQ;؛؃h,U0@j,t˯rG)뇗;؆ ,.p}lS1%ArXvQXZ,l J1z G0Jב j B)bzpk@usgT 24;2p. 5Y *hmFC%J s@M@t5heʸtUr~8-JJ%o렳\}Ȥm@u0}d D=^uB1NGܶ@Ts]q$gYTT%fit8eEŤ\,f5쎱Zysvcbρ9M99Yu-}4qYq4eb:Ak s)C0ٱX+̪DVC)Z%o?d1|sP}fmkV7)^@f dq+Yfe.bx\ w= zc/[zt1 H?t/P:vdV$`z`\1 u_EYG%mwU^wz mr1+xqY@ {zg[,}s"oE7%Zd Ք"es4(Kւ J,m]n~RnYyqquƥVd[ՁgllMU-jCKMd!ۡns CeJv-H)C!0,+k"k_ι-h o7qwٶ[@NPU߶mKkׁ%֜r˺̠Kk\g \e|XrX,H`x4wzRܬX $]cc2~Wo?{(İ)V!}nJSj>=Eoc$<ܟ`N^PĆ̓;cϒ(>k^X+{4JLw;3$2t}1ffuǏk u/O΃5둃߃ϛv( FvO3~$kٜIA`=@꤉53)EOx-=Vd=pdBPO1|m6*3K-i0p0?m) DcNnkwe ;KwWQ`/<02lx._ᦏ\rAa0}X!L$~mƉjK`#TMyHqYJ8&fO $*΃˘jMQ]#2*BPf^Ϲ 1(`!EOOYjsVX,hVKpBnHd2.4NZ5+ ¥YbbzO }ےrYf%4O,[zc8.䘕"p^[G~"vHt&**ٶ[lGvr\#akmXTUf+̀WY45#¯R!@'e`8S<,=k.3츑!꙳&{(Z >3kƉ5ezfy7)03JR϶D࡝gXޒmnS1P\!&0m<Qnn=ނ.4fe164@.P% 4U$ss@H!Xf[Z-؍&@Z*]!d0+!:A_j$O1̌Npƌ.j춹=!eWۆ&Nt "&`٘bPz_CsCڭ~8.H5 i|iۥspp.2X\]H09}"7-JLҌa0٭gqg'3=к0yG(fgzJ2aGFu~>;@4a® 47٦.>At*hiE. yclB\öi]L.k`@vYsjog*\&*6ZZR*Hšd".PbArI\t}0,@,5 SSVLՌ7glB8̤ufzMg%UYSyImSptr v`u"2Ͷ @-ۜkX)^}?^UO=p;.=H`95V yrdhI֓bjhqKlg\(VޜD.Orc`yNbHPc,@=|#E愌W;_xXᐾUxMC;4# !7B#0U$GZ(®:!qX|:OuTEi~T:6jY\ J@Z`ŽZ%~ iFl"ew.K%i٣Oz=ߥ2gpY F˴^lUkPKJJNCm$FBQn-v$ ZXc/5 ?M:G^2ĭ˘!p F 1`*7E7їO:z2c]s3{Le ӤjG,s뮲?sbG}vsNviit\dFJodgA_aoEm6lԧu#v><=lH7hu} dƀNMT*MtގUWjVB'ZKBS,fegU*WÕdyy$x %Uulf=5Sb"`ulTΣsu frXSHnGjQUm|I댂6(Ͽ sv]Gri\("LF!bYaґtؾ 'wtz<۲mxc)Ǫdkb|rOm+( :c2CEhŦsp8 ṳl:fEebR:{^{:WW߾s]r7}o9Su>'yNa#g]"xEуOmGo+aLpWم?@I˨mѐmOc!Pi{v*SRN,)W6MCQcB(YYz<ﻺ?pۥO/OQk\ &xudı>J)FtISybT={v{ %ՉQ6WfLOCmtQumuР(`d Be@mwYk)i(ճ {?ujR!{-LRu4|rg, +/.oZ+qB@n!y`% =:L쵘B ,\ѥm20I7lf.6W=]H*|;r&nlAI#-# ^P;'#"pLp)E Y@x<񬍋2P٩G*6.Pi*{qҕl|Wo(9B$X(ŴɾEqzcF6E7߿sD:Kl YX,£'~|ٴI4ovu ?~s/ /g!λ3aI&6Z(~Kc49{F^(BA !ڳX CV~2 &);qBEX*6@ 6cclpv;y*C_KC̭P« Ժ1MIX)`NZZ5'>8_ی?"D<~&ꗉ 1alHz(DSܑJX CGlё i7o8bY'Bz ~B(֭TR?nʸa5dټ0Ҡjneޮfrӕ 'F@a#=Log_M滲lA=qBs0n @ moFu\Z΋,~ď2OapAZ$& r1+>nOH:/QDk1j 1ᤉحEGwbUdLGs4"n ֐{%_UX:`ҏRkTM@s:!ԤB3_b?k]Hf|cV⹭~%ǜ.gWw`L"XP{WUIv{Fm#xւ 'Z`ekK "%t.=7zoB+!zu~gS< FlSZe޵bx6kZLHԊR@k]BͯB2ۼ\,F|IC>f)`5eଃR]8Yf&f}p]ua מ1·JH)B%$jCgLJߴc}1pukKX!&}f{'Dl}S Ar$&,b㝓Wp7܄1+xT` $IP2۝.]ڊk2cK;o$T)Gm%#Ű"\ІZcoAt(ϔd$@%d];z}4$<;̈́;́_]̞J'L*OI/,# {vHšwspuNqr$ͨjp[q?::X=0/v\1 `.[D> }%@u;zIx-ؘX <'PzAoT:PcnUAng:Ir@0EKKFxh@(" WjB\u*J#n[=Ǧe!0 )^ T%U1YPA/^,NykX {3|0IŢf+κGI7!`*1ٶ]nD \f<5\w%RlVTYҷX+f#VAwn.; Ks*X&pBD&%D放MNwLjGat)sPu`V<ľ>1yXgl yfN}Eo{NQdvX<;?o8|~Dk[..{7Q;dOfS{j>{z݄cUecAt=*7vno vkTE8'fUceul낕f!1&E'GjWdZ͉2GL_7\7 [>;9,zG6YPr<y?=YM0{2JHsHa~ia\y.˽$)!Q 7mE*š޻/(c;9I03w[U0?reuƈ4i}wpVDeyD'q/fYf+ Yz ;`S`/&w6*T] s!az0)|x)6z/V70*mlRn. #Kϋ~0lgR@Uܰc >< ^bгo<֙w `&Z󭵁Bb Cz15f 95e!5+2= H2@XEWsլ" XɽjeH]|h:L1].6l]Uʗ̣}Z{ "QA^0kZCoG $ dz)pmWZ= YeY暷^);}~\ta={sin~&{ji>:~[=ra#\=(Jodְ͑Zg \oB ^ ˑ㇓,ᒓI}`f6[;3NZmdH IDAT5!5,& O@u^h}34vSj1,]d~6C/xR,]/=J~I<&SI.tAOSAG3{7?3!*mvTb mvC״T/% d)C`\ w\1t"EМ9y .rX=ܢ|iw}ڼ.meϠ0A;A/mBF*muήL񨓚mǴQvxɹBHxH2В\~@2?Jq/p]6bo;>$%wH2t[_rk0.)2WEOR5C `6)& ]uDOiu?*s*;l SMUsr/|/|織ZƆ2,}l$K3>e=J2."tH7Alqv?{<{>':{/l'{@Iٳ^@붑%~ |6REb6 zL ١!c`X"0v1Hbelwzy u_FWS,2Lg}t}.jVR A%+aLYKZblX|404mNLt[95VNcjՌ6cLQM8$8\o8=e}9b`Tv [4egsMK6c6ü)Y7LY/g@/ʨ2]<.%՚٬@xn>Lx\oN_$^Ly8ЧaPՌRMЇWk&̍ Lz|V0Qaglm@xx6863Bšժ8.9=3|o''C6bIwv)9K&Ȕzm3]in#EIk;L\ uk =@R)jm6wNTX]cHsu覠1Y̕Tn$C wmNKVbl.Y#Dm{b#y'j4?"딖PAΌFd|mPd"*}`w[BwOԬUYn q|ב:xQ)}pd=7= != A0vUBdvTK~:ԑy#߸8ypO 6mΕXʑ?[}vuxYJ3Ztd#yEIb9`~aKW!Zk{+ a|/3-llcذUc5q2$0X1鼠t3ղ:Pda1%f!4Rn׬ EB P n$0^I .e‹\hZ)()0]IIvS?9^@0;Q9Dd[T8Ľ5nYGGmK61Q˪Ya Jx_Sֱ=U3ܓRN,>SV̴7ܧv:>mضx1GˤEl:߽T]Cwf$IOD☄Vzs’L>ࢨ„4J5R6E 5-DtGɆ y/Gt6z5(#m,8yB cW:wdiMMOu4#i f:Zö;1322 _k3d7Xlm${@nCL}[xqWle=nJ}xJ On`IjFLqj+=2\z{Cri{mhfy$So*^7b{ھug SEi=rGn 4O*2c?e~,`nn睭0͹ꌓs>v9* l~>Rxʼlw&Va2dx!$OSȃ&Df ' 0jbl <5Rl ރ,2]YZJst(֛5Fj&%%lPPn2XIQglVvӒ!$supJs mׄVLupǐsFp4 ,1J66X{ !_ٔ:צsc2Lǒ;D6)Ro0E{Xt`ۏA ^6Oto\,wbc ¹oI2'mz}w qr簚}CDY; ̰s)!M\5g*‚Y&$snEdI1BᵅMd(F/˻ g-'v̓SVq1"F3e Y(NuMsxu9L%}F,\kSP J-xV!v;-cKfD O,`9%k l7>2.ݣU}Itۻ.﵇KϽYv ~<˹Y]YtZ\K{rJ ]j{w;9k=eyoHll^:K7mkK*`k :[}vX5kDޔ ~~j aPgG:;U D2 BNf eͬ [ g(c*H4 5ݤt0 Fn̒c3E3N,ìq<@ޤÏ z\Mf,FEV LJQIJU%-}`NƮ;M .VLZsPB[DMY'c2㺊*:*Nb: Ӽ~C`ʣǷoC?lUdrs?vi<9W'w%Ԝȴ^9ߟ|~Nj9߽",N^8sGfK^|53 LD({c;ٔ-46WCZP*66.!uzcYxȦ&` 2 |g|E&Yb4nR[J>Gcו]e:߃#98E LFF?d}J3( 4c0 |tZ4%&+j# zp=]'ڢ5PmΒf0#,#[S.v]v,h+,>h|<,9pϱsb`5F̀G9Ea'eXQTQbOW@ykzS!X7{Cׂo |d#x;ǿ8'pRgٗ C9}[AyLGmIeD5!]pqTw h1e^ if"4 y^+Ւ2ouZl uhqg:/wGGsLb }2o:z>>$1(JרVĠժf5Sq2hm҃M5ь+ N:!;ˊ&fy4tb1C v.'^mVBr4߭zw89p:q߉3jZm͛WͦR:q) XXZ8GhG A{yŹo0KT15Ʉׯ-zMMsnZw̼~#Qy朷'3p o~wE+G3Lsh?zr`u ZIγwX Z=RX4.̣̋l(V}}}Я Ҍ/K~N %@Q2S1V9eCllJHCJ1`DǑ>%;Y=]酼o>` "X3ХY?)dc ) yuUT$o%YTQgfxFŋĈmӧw'|b0ϕJ:KGe8Bjצ4C ZG9?CNgA\=j72'@<.ϟ;Jvt`(p `!IF1ˏʟ@$ں jU%{d_Mgi]pݾ{X]Yq>Q.4 @o-6 qaL0!@Yksufefe6KޤYI=)X/nJ=Ә|.[Kƻ,X(Zk,K]-9;s\r20@9MsmW\\gBE"MR~]ahJZc2XmJELeMִFvnM'1/Լ>=G/JfO_%ޜ#; W 8#Ò5wَj$歽hrc͛h햫:3Z!"{ WbnFyx*BB%`c޾23= mcˎ@}hy^i6KJ"xuŒŊx\,'[audOLLvs 9cJls⚾40^K4VJBs1tkRxׯto`| nd,D`wHTޙ7?s'pp[ e>Ao9 2ƞnrv0scn~ҁJ{>MHn@>9@>+.Xv7f /1߸&sŷ ?O [Oώ= VۧXo8@s@p?: nn=Ɵd2xz)On7O9azh='o%[<:'--p;^G?=78o'OB7lKnn[rSm p-q]mPvDSPf#3{ec)#=}߄Ko7{//m[ϓ'{rp@RU'O*msJy)|sYۛWxn]L oTR> 7''Or9ݠ}8p{=7*o=[UQ-<on)Do+rކ;noxZ>O5o o( n /YYc eYs!9'Nۦv0V#y53?}z'p47+$ <{H<<<|00:0 ; =ec`..4` Y}\po~/$bD,˳1[ۿ'lmǿ9[[o{[rU¼/?&h:5 ӄg&loEtf O`)bb<d6s8 ϯЯ>+u~?eGW HBR駃37gsv/H>?cwg[^_?ybvE/| p׵ b1c{gm!vpg̫0vf3va{Kf+}ݏ<' A-ypZgZ[fV\ylXqFg7 n1LmC9g>"a7GGpןfΟy fNۉg>Eȷ;\% X3iV7k4õAxxOya3hXu-[;`n%Evm*z3 y yHc6[cK\.xm̢טWO{zYu6g.ۂd,"fc)cLf8ׅ#(ю V6]1[ [*kE|D~Em6:N#O/`\nzb|,$Iݝ]R(g䓏w F_>=RAAllJ ?ǚ¿&~oPX;3k@Cc ?Rdj}%xkvd]W8_|C>٠d1)lk5Q8O~O,T{_IÚ{?{q7$~Vzv>&rzohpa s蓺DۤܤuU852 hFT&훂%kIՏ021 .֛>)Wiҫ wq {(wN4cqP_\Rz.6q[\ ]!(}_(%%'`TRΉ$"o9S;=9~潧k}T6Gkyz皽lPg'>'<_Vhweb,H`^dJ˖=Z+嚮Wʌy9f%'<<>~vM Bks Q5xŰ`}t{]CkxKT/*dWN!GG?}S|4/'n\7`iZ)$r0@_= ~k!=D/H1[]X]kڳMT eAK3)dtVCLtNu^g\"b)I/*0CP%BR01ż$hJ-Id Lt^yÊB@څΛgSZJ 1$NDT7`ɸG{k F!h#7q\wGi 6[k -VQ\U4|w7?XG < 'B{@^fgr%%gAl(aվlt^3C; #MR"S/GћehCU_0[>K&:w]HTEtD(CH7ܚ7!1rnV f!4L_)$0if\њS23`~#Aes+ NޥX0mXUs ѢX 2Hn@u%%eA(CKw^5Rǘ KA Ks"l.kgcTm63 U9h UဓoѴ.QO) <::2mZ[,$5*tzNi@935npuv:lLa[]VhnK}UXX73Kc+ sܳjYl [4ǎMQݚiNNK0Y$~cf,XnnPmlkB%:-۹Y$ԁqޤ~=۩ __z޶c1dYϟ‚Y6y_]‘ʘ1s3X0/萰#F&v8 ~y][fuqfv.*v[PkK$?x+U>_|V'a[v2W܌i~]o^_JǖN#L m=s]ӜUg{[jf-~ }B/Z"5Z;s_wm$)Npn?&ܻT)o낷OsԎv~W3RY+mBuKg?D:Гߡ9SuNy~7^w,N#m#N+f!wm^:_~ŶW|\qo8-'bK/W73S7rf1%~l6E>)khi8i3Qǯ2 +UNu#fJ2.~ fpnYX_#!NpNBq5#[,:[̼q-Z-8ߏՂdwW߼"ڶ,>e[K}?Ayج۽0 L&=p,@ZVmtb%E1}Qڵ-a}V^!rEbn3n8nߩ"ng]=뺫eፅs-ƹb%*& ŭfvXn%K*93Y9e=mfʒ9,>I(q+XnvBX/ohjC7I7dhVjw33ޔbQF'0j, iktxeVf[Nrj&0ݒsB x̼t@*uua L'DTx2`أlVk ݊)2H% ]>c\ID.F!3""[<~i}=; 3Bk%gKjxb 0W>23/68\4B5~篩3UA, 0_pBP^_{D {<O8L<ON-^-5Nٳp> IOHOjH$P=ҎLyz| 5+Gn*}:'?)jKuϏ :%hAUc c;k,˯z˳1މP!ma? ȩ/^^(#mwF;4@b^A:'^N8^WR)]!h/J"CL4d*r &bO4eĊ|C87~(CȽ')52 I8O (2 K|Ȕ> A^FoW{9h]Pk`y&#ws%ըn;nI[O,%. asQ2Z.'{Uɸ.8=90 bq PBq>!F 7izkc;wkۥw}#]^V&(nY7 \Jkp 9ő9:*]wwՄ& +F u^^ésZsv`Z҄СSiP92}Q^u#|4*A-M,ɴ.Zg)SH=OXU7$J d!$knMGO6.5(j N!|`!8ƚAOZ/_M0,Օ4/^kIt: 7M(FkA4nf8z/w9xdL&99ǧd"1Ǐi)&^K 勖9J# oX{QD!\er&>&FwݼƘm%Ϩ$6XHn^IiN =TaO@jLI?g^mِ^vM oP=p 0 c10u~3cw @I^6!>P)e6Hucr3Db5x5z{>qSKVW,Ye`Yb>@L@*bQ`!J0̑"¾bPÿù D,!qcD{rh.J%1ڄ€(naX9MRS8 fQ2tcbcEW "bi5tk&7߄&9/mnba0,Wfc.eekSt7MW. w^lTŁ,,m-v#=4Wۅ(k<#P#-12Ƅp$! ɵ.ɺseB$çbK-馆,K'cJq92'cHJ cC( L &y92&2ܼ@ȴŘ6fk,IML5 %剢F}r|9ǖ1{ RŸOa"<ӭFA!Z epIp8-Zscc lG''^[$l+x9~(6ny3)EcThjJ/8&9Bzf{4WEdh2*0O1&ig9njUL2R1ys~)@&JXk="Q;Ɛuh "c\LA"on&~j0pTx[X05LqetAy;^[5݆D][ WMݱXh CY*Jpe}Qz,U09qVWO2&إB)ŋc9OBDe:caV v6[9TRC!Xs3"GHY1Ϲx?o'(gj6ΰ!y4.Ĕ߷ʦQ:Tw[Y9h/s'#SD^P ?L%?X)A 0Eo[foh嶃"nXl#u`ۊ\J8۶~Că7¹]=x4: ji1qM5u@7Xfg7\'DJ2)> \$Œ >:]6\,詘+`z49Oc.`^ŠjVY|6wϕ `FT:@n:f,Fi&]s%Kۀ޿ ߃]Nq Nk`mN@7>.q`5 *ؿ%hS\6Jչ;C9@Lj,E!B-D lnhdz1f#k*G9Jd#klYk!E"$F*xMٓ쒘4Rx&|qiTuZ_ *6lɡe jF* JjW~rb8Ddߧ$gzs]"B^mj 0Cu2g}by^,)̔{O&yNm! SLjْg\{#AʊiJ:褏qYZ.KjBP~q-ѩum 3"Hܼ@i˛ 0Qc0/罗y-),BX8 EXf@14F=" oػcVI EeL?ah  ?h*hQRW+îӕ R+Y bj߹#L駂pY2n (X u!nOz[EZ/=c}W qh2>d@{8qOqk<6Z~:r7͋ULoZvb-f'v\ = K(q G: <[7u^H /FrY3l2W,mQkgkq`ofvy`^;\v`)fc`. Z43>YX-6ƕ /ݘy;w[u !R%Biso3[:$؝ {iadK, +\a%N#"I.Ǧ^i$KPd)\B7nḷ=ml ] Ӽ ɚkk9լD ~nc=pnau/(F^E1\ }qFBx)^MY¦p9t [2/u&Ry1\<+'mV5`aAWK*kdRj]G7 +0r[@>m [ۿ| W\}RfV!+ qza^J!Ul(FOY%LS(zaYX؏:F0՚X&Z1154N,6 ۪op=V|el`K] =KR 31]A\'R IDATo l\ӸF;8l7TF9e{Ib/ ǨE\)hJM=  |kLe]`e3E 7ԅQ`pNZK>20l<o`ocW%(ŨIS5%M{ 8MAesޤwaXXO qq q9bydœ+,(y_P0~HS:T!$("r]/K,LBiI7dA]S@19JemsC"3tA I9Ȱt)A& 01;)J QFO^yAd!j^j5jx6W6'eDivS19Ɩ  cx bARpx4e##y^fq>I^6c$qt7ߊ >ԏM9׋kMb.K[.*2TI.U;&ԡb-~8ΚU{[WL8a.XbBHْVI8Gl"[w5X&E:04u,XTWa&%$IB'gR$K($EBYb'!ˠt”cJo/(V*uGCxK g`é.~hмUgo-f-s4ΉQuE r?楿.sQQ :c{WYjomẉxbK[eX4i@OQ;c`>҂ˀw)~KMv/јV\9ȹn .$DؤQ\gQ!e;Kd>Yn7zqN!О9Tv=g\22q~82f'~Yr9cfV:x`y5ԣ\<~ư_Bvʁd32!79 ֵ$oI:{ιbŜҰk.XU.BT=Iq~YհnS!"`W#V"DZV=RX0 Θ0(Rp6G -bFa%X,ha@*KAxXviIaF ;!Z١Q/՗~5Hq8yC4Wl-̔HZҍs\eB,J*WͰDԞp5qТy6UmNQ{n{ ۘʇacb1ĺ0`%(*)2 PQu{Od?HyjKZm7Jm4a%$ddqTP-%Šyz-xhsnU|Em[zoFtcbo=ߢoN!@ `͜.'Xn\7Eb0!87}ۀ @pC*F8ڟ݁+'ۏgkTŀ@;Pf0tjJZc4Ѿk(IDV;ԅM2# z>$%yF;,$$ D!{S15:[h\'rn.ʈtSNNz޷ᕫE)E/YM}㜮\Ʊ xI9'􏟑VlFVl\.5,l+Oyv/*1 ҊyHrFc~ Hc^ ZQU(jǒ 0W,ƕgѐU>9^e\a_j %׀x]XW\\iJT+Hq[9Y%POkVNhD! CUKbeI9aśd*#\Sd*Ѯf 3:?A<; #xxp?~|ǐg]PEƹf-q]0hk7b>u3pa]m@pitqA?XNAP`UPk9;09)kFDe),hJcK>/q@w3Ry+Jvvoc&!2-=)67ո_e͕M_dځ&waP}y U!Ѿ Um^*pI±6ab겱"lz7ge, ^Kء׃*jux_ci {10 . i{P p(c (A˱:\e! >J-XC,bLI6_=ԣCRg'<)^ J%{ J^reࠛ %XpCZ e4|L;3\334M&[i^tiۭU`9 |L k'ٗ"/5nazvу&Iߨ3`pYg&#cK6YONG9zx8l88_nj./MQ95d:l2b =ϭJ-eEKaBb]M6s584Ne/k2ԥT#(Ysh=g0{͟#Uqwo,IUyU,Z[e2H!0"6?TSGd-.@P,$ވ`my2~/,yY5n[5)dR?ӍVܰZO>8pnetb*@a.nIcE B*ןzxˆmhx ],i:m hѷ &eDa@K N&ind q[2>,+PVSWϽﭒ 3Nߐ*pM\ NI*F{[)k0]hEZO`cEdS4v$!2:}Eƹa8=Tm,cCw  / ?+F TN}C]7F(ȵ8A(btg(1''/8yttȃĸ/xL>ViKJ?I(s7S}ή2ZG04^F}s,Wi\ a@t^d¿ "qFSihD&JYg B*aeQ1 }%0Jt4n) fv7j_[ڕPhv"TTwDsg<멢 pFo>P4ӏNPܧ4[Pi/TvJ+?#ǵ#@;#hR`#D/~7(KH,Iۢdd]?i9l ,s/vzs[6m۱F:21GP/) &o464#Wd1wW7虗Y޾dGˇNmuyu9`@ߑ^=3p7 .nn:ަY}\O7U"-]]GD&D)J}1`'~oY ;9fº)8z=jvN~QbJWD"@O'_cB{=ZUa 'h91'_>EKvdJqv>i s'H줞tA2Rb"N^A'S3^N)/Oh!ϭPy:7h{= !4{F挽d>Ou4z  }ASN9''M(I{^Q=E7L\|R196X=Vs\4WDc4 l k;*R툺@C%\oL}cn`,s~P^^qQ.s[ D ,q3jK*b/9WXo7`B"DP>0%t3"0dLɏu+PeIskFi%y_|$c0ww6]t7k ii9wʐ \Ji(qi+;W0(!Q%LJ@6_~*E&獐%X NxgDJq,(`b˲\$+F1 RUv;R1tNFWϞ15zd0HOqrF@ߎ8yc shpakTDC`zOO;ŗ/@H<,{0@@_TJQݺpr59.ݮLkvs-\VZfW4cy'}$9z݆ :%@G>/WUNsuFGmjpbKSr߮:@B@4BK0X׃pz Bpw֘?7Hs"`eA;|5+WOF԰u^!B%wk6IwYu8lRVN`}=K&w~0tnS-IF27~suUH|yDL2cƯw z~iļ$oBW۴s ۳ҩl*(Ǿ/Z2ms,o+޻HnFD,nߖ&Z0^slkjt 7s5`nN1)nXȄȅγyL@e(26L.@KAtCĪۉt@xb|1K2Ns\<T&9ͣvdp D c[·|KPƒPp.u11{n§WC@73hmOQ1MOHbЇ \4s0UB˹#yeǏj ,W SP Ӥ;>|q|\'Ѕ/C(ѣ'ir°>~YK261b c`Aq-`K҇ysT@;L`PUR:dxX9 WQwjqBxwHS3FJm5`(sCl5N+Hg6 )9qnjԑJo)WhM怂GCr]r96 JeRK켤O<0sz98% I6q(NVɹ QfCyNh^CЊeh7gW,Xb[F@z`6/ܹR ɗ]٤ qJ,<ύü`%!=bԧ"€]F.eo%prI¦B}QhԤu-6f,mQWY8ˋ1(?L6{$X,\yNB<:K74A( o$!֭ $c8t9iu4=B呧`mꬮ!9Ll+ Ht(vOb@kKyH2O*Mo(n DkQ 6!:ݓl?\2K]s6yQ)/ ,o[1]cM T\4Jm^˨9JӴjEսhP?ؔE.mtBCަ\s@+j`u\UU$.2;58B.͐tB`#.(FtIgU!=K"l9~T!aTlifӷ>9AsRX&QԚ)b:aN3 ,XӢUb?vP+ >>'KaJp_N0n(7LF`H+c"˲pNd\G(U1͕<|VU\2yNDR#Z,=?SFмg'#Ct\,eY)-ๅe4}Za+mxRCv%6U80gM REk!ZR S#8~ג`K5`'opsܚ zo`cv]"[S&B3A!m(6dv׸>5+RaM`}?+ɩ|Q`y t덂8ه(p~ /=9RW[A$ћdp q *W!gͯQ$WeAQl_죵zB5]ciQ8i67%F\u쫅YI6+m!^r @m\i^tbA}klĂ~T' ƺ1W쾄,!(B1p"hHm1/!$s˿a)ĺVʋzE'Xj!crV#b lKt[S,v[䒑0"څnr5`$x{.NSq-حt2J"(XזRVa0 |hMVR4)1z+Yƽܒe %v`yWn}rtaXK8oCg!6biXcJ2+m垗+ EaHR>ʫQ |INǜNsDag<]Dw@u̜_;upLSC0'BhiQ&o\d0*5/2z@~an[B9ta伇E+:dYyq.[pYx,~Ct~'9XN3n±cCqB5`pIldH g+iQ&W& 1Wd 1~鲗9Qe>zyF$RWo@c7r1dc?l;ǔ9_`E͓{E|uQ=X^@=SmiIJcQ/bp8ڤ"\C)I/ qKVYEy LŧM݆0,5 ׁ8[,/3_c5\(h@hݺPfmfYgms04#2*˸>|?|k[RWV:_JeV ?/P9RjgC=VуAo+%אAaIz%\V?(ȉ\01۫}>L_3U^Y.,h 5L=,M]%H1`i`H̚A/- k<5EH)P͐dӊ\d%i2! Q#H\Oc 4i8@90l bMUdF#{]hWV`)kQYn\QH<##vav3&IL VSLInQ8+8esj7$CN;qhsn)XD-6[5=G'+!1o!ݣebI)EY^_}lk8՗ =N*tՃG9)b<|{ YhAmg |bYqPE׈, ddb^AYl{7^aj+y<r1ΥVǽNm]vFb[06u.1%p]#`Zs=`D* O `rBuTylxObܶ؞m([m7l/:kTR ]RW nӘ MMskIk9NfIrIjlX޿tyTO6դ94 ̐f=Eu[!;Y/}x[Qqi*vryf@yS˩p:*WTzoVxQsN'%\ۚrv֠}m!8-~:j>Dx$@?EFI:Ei̍zUQY3HaȸH.]PMI *:'!k ,[Rb0t@uRs[`wO3$KJY4)&M Ð4q؁s\I&(}#c F#,Nv\,iu -ifnsA`%Ho4| A8 \bl?#Ӽ6܄ 2p^a^[fe*qDYxH]*kv"~f6'XdBAfٗ>ͶT2xC/lI#Ӛ_Ј̦k-.ɂdxM)qv)7iJmRLjs[$@/dvڝ{mԟ.{9+M{=-cKTd m_s PI4 $#o+>zm^e} ZN +Xr Br 2HmǾ OoHG2ѕE#P$S5ZRrW_cݜ 5.B-qAv2V zWX뒆:7V%L` 2n8)$d=КvFdN{`pIsA&4!=EJJԶԣUi 7фfS`eiګ`jDu f㱍Nqqo^Ю/k,u=* \|݁PadWKg {]%[J빍]!ZVX?^I@mD&97F CA(`眱_@??[غ{sw]gfDo{{g{ϰ_{3ww{끸-8c;gx/A[ ︻apɆ!^o=~Ikҿ h480ۋ -|oyxZk/<{F7L0/K_۷ٿk^<ݻ ;_v;{}6˿W_M컍~ʿuoygy] d #O { 0V/c{՟;p~}[}gYs[sk^6|̺'2{{ܟj`P5U_w<{dzg˟]AϽ=,{)xO7{Կ\B}̠3Ͽ_Ex_GU7"e[0 ؃=μ#liQ4f2訍gZ*s~$ffxgNg :~,_=얯}_M}͞ wfE%geoo;Z7|`Ϧw_-n@+s!n@s9#~Rރob7d/֣9>4ߪdŸ> PA@Hӌk1=Q_˟~[C}b {}$s[>w_{Ѫ wb3SLwY{P g7#wNOw?Nyu.U~S6I?,<o ɟᗕul{{w_;!wwwXks8VckvO?xGf~Y7O<\yĞ;qC{; Ks2Wޟ>;?xwi {x{{\{`@j8GAwЕpx 0.vO w>wu\xz|2TQ~ .ڙm?^q^s IDATy{$Zkw+򏷎v!]VZOcc%A~RJgw_|a0[kc'=ƹ͸~?ghwdFFNrvڧu}S`pAͥ9֜2ӼرG)xmqEc*}ZAJ @*76xޕa r/9e-zrE6%MMIu{A>%D@X! 8&ٮ"]kCQ.70m3^CdsY,~5U4o2䨱RQ&I#*`8W]tf٫:wrpYIO>wOx}YE@nRy4? 7Mv fv!OZ(mTGN\`ԟ YoFQ0o#@yrjHI'c h;/~e죬F*j74ڏ혬uYּ%}r i!AL 4/fO20Ն\_&dk6۾B ,dƀC7?+[4!xlEdZiM2^C! *Ibj*P^$`(~{r@f@mwb04}Ó%&z 4 /⪢_YYeu ڵFr@)ZrOP+¼L@8w=%G49l9w*Ry<)و0C "B'aܨ>i'%ɩjsg81RJ =OhG-Ʉ@ELƃ*P Mƣ B$ g'D,k}1lH?vk@tQzs\|qvjwLxiBttO㪯ELn݄'5²~hvK,^/Bр@\V[c!OT1&`EQf:鹍/F(Lw NEӼ]G__Hꉓcd Z7.nW[r(}<\l y~mK㑑Ϗ?hno?D'Jh0Lhp^b]nί֜|߹^?^ҍ626k F5'v  gU$"Rm\}?ӋX9o!͕ƫO [gĉ{C˷4U^HZi63tmB̼xr p6a 6Qg 8G'Rq2t͋}]rD`fK9kEUrߢ _H^˓>ewQ "u!Aſ5[jɠad0 $E[بBO$@:,{UA0mrdY07Fe>#u60|ǀȌ|Ā+Um& avx?MC 8ث 47Lg` d(k2^Xl-,7K;߼tŋ@|BY+&|n5(4F'k9ߟCKctG蟮٠.ݓs'h~Em"uŘW=Nk=@6dakv~VptZ:."޼WNqj:U͝N^ykr /f@ o?ۦ]~$/25ĪH/y"̟L<䤇NT}D6m_k5rq`mysu_xտw7:2̼p(ai'׵o]۪4} hy6Y$$0]NU4 w2Y jrbc#̚t؄pJX"#A˟"$_Xt1YX heXU9h LL[2qGAsWBg\ZI*U4BpZshἊƁn@'N?1`V!Zwwfqg~ м}im+hUk秭@y<.'ɯ'/.S@XdZGCw9fb)utJ8PD2=֚tH}~<Ÿb}9VY `C][xm<r6 &ˬK͈ nYi[8kApag'XYu} bw=$K 8 hqRd\Oct4(jm@lRRvV,C5Crggi3=2qR]d=ٸ?.w'n4V)Ә$eisMs@`Ia~Q༚ѣl2hToQ3U l|YGS0EĸlU8 @[J,Bj\ EѠwqu<:@,мQFfWgm^h<4k%ǯQbt5|pf!Zu1Uw.`+~o#|kM 8S QD)_Vr_^,I1@p},{c;oMVfZ\Q|]9?"Ӹ'xu"h}LZko*q|eO[:_yM_y!TmL W$Uk&(I^3O<4]cvb#Q*2i.NQu`#^(uB&ϣ{I:h6Ox`sihMC bc9q[e:Iܩce㇕x / ^lQ-t@LkYt2d'6~Ukg䍵xEe{>K!vA0~ Wzs!ѽ&_IN).MJrsqo-]$v\c _[W-b91`i#p^+Yz`PHh ;a7]xuomZ5 nE{aWryʵM-;1v$Sx4a$}PGm< oGC1Zp1V)/h[%^\]N50kU%WH$a), ZE=l¹uQ۹!,nȟy6<^W:Q2[/GKU4sqakVR;]ƆD@28>9юZ=%1ITM"ǵ^nm1fsyk͉<4 !I0fJ~fs=_k[˞ ~O C^Q]~T.q` `p} ~Zm2m@?|!`mR;i̜=CXϲZWɄVy+Ɇf{~ßsYk<>pްA{j{|4! K~Eƒs~@\amtJXP0<rC"*k3%0-[16ɭ%jq A4!(\Z[gzzfta ӼуE60n%}O1ڢ(@+ * !A9|#ՠ$cPh/4e {~;|$MýwRֺ@$ԷK-&0hYgN>I彂PB{=`vEg#ڍG=cl$u':uq+ޗ] T~B)E%E?%$;8Mև ѓBqm(|%9UGN&iA3o׶ɺv !JD{6R [Ǡ"FzZ& 1>?l;W Ym/\FԨ;Ջ,hX-کN_* T#z ՈQv_ w°%EвTK2Mg]J1C-~d(HL-z~}^`0֛]M\hFJum >=4,5VhNN5*Ł7417%BΣA [8ǯ9i~!\H ,Z"+։7;\ۆگʯ7`s`xqf[1z;tJD͓.t㴓кnݚmNr,>J`#h2b䫀< rN& NcWeq1K3Ro+jD5~K~k,O `="OZ'FiBB!`۔9XP#Frc2}N<8\^s87_ hE!/kt{N$L/f#^c6Ͳl׌MZd<`OI&m1%}ꭀΣ&$26ۥ}cC|N!'$IS8bai-#IdJ< yίlӋ`pEjh>i"SGSˑF&؄Fŀg4uOHwni=k@4L,>La6kthf栿A9f;5I,?(ٖo'ͳVn/ڵ$σy]p;{R=O1L%D~j-EA@)ǐe G:+ l0Հ L'XӀ|ßWeU^g7'dÖ,z&WP[S IDATdOxUϻ.7XmP8h)ǁc`P k3"jlc)#bOvgtM3E贺ya AzgjAvՆhW[_orK:!fc4'gdl}7Ie4fx#t`7]9!,}UGKm\.u826Rp|X(xvrງ).qC'Ӏ9 gt'0S*OV<}{`#RDYLgZ6٣ULt[ͽm3 1VI8PIXU 6۶)ր?lm@${e{r@;3[@U2}HfA"h6=S%׶1꜏!q\^!|&t{\Ue240zr>xVs>QD\5Yk~x۬"S! r h~2` 4E 甉!BӒ[WFRjR(l0JJ;Y MFXgD 2O“d2͸4L{B=@BYHyXJ1qg%6YE۹2EVT|oU6"_TY1p.fVz,{Q58H#ϗ-*Z.)}yp ^-J"d|P5h@i~my7&J`ۮ蹏,ȼ8 ttm ,5zFv{鄔rU@bJ 5Dh6\F}pu $;j\ ޞ5|t/:ŸGu)%{scU{x?d8B)KلqJϢ{@}&40lrXs:q܌X_8eRR)g*6 C߭k9U,xnP6MA(HA/?м @;C3Ι;G]?>+4o茝;fӖ;gS,0߰vX _Ԅ79ה&^f˫9eYFm{`GT 6EY>|A^8OQ1i?G7LۦcQ88&h^VRMAzX`pX+ni ln5T7\1hԨ/җpvx:b8u8fOG\ftMgǭn,O{Fɓ؊ jG[-[>f)8h颥H. PQTdž0ҕ*Ud61Xc9!AUH$WrL:.XD g(uӇ6Abޒ(8Mί Y.1͋%!sw{7ȉ3R:뫾s(4ܪu4`. ?s^n_l~yHyP寺8hc EɰqJRK a,r|e{RkCj(|U8lK#$6PBH0 dmRH# ΄NH,\R 8 s+De"}i?^yÃ;d=-M.1tԺ{Jn7{P%jb;MHilRO,"}e Z5SIR@>ٿZ6-TEJ6zmS@^̦-7ۋ;EsOXi_,hƻ:l# i(? Sn4Ar\6|$*K7Ffmb6? }ڝM`#h5t.Y3.r'怺'ONr'׌ymoz/>TJ g#x k!@Ny*?=]ץZRϻ`u^NKO2Yƣ8^cc[;o66h6\o*ٹretL#:[3i]}8ë *oɄ8VMR&hlR1׉Bbi;ıbR]p8CtT+yU%Дs@FrKU$QXc0CXKH@0Am2gyj#RΥeJ@Y'#8o? <)Ka)X,**Rf͍QK@rK\m׿_%V5M K?K! 9o ӭw/rf\Hk60ip_&0Ya`c`"H׻?_&#x$!n w!SmlÌ=6GPK3G%0wv{jmo&/.%>g۠O4sY%'<^0a])q}ܯU:=7o.p.a轳,cpDymR87sqn:!Oǿz$ Vc~|ق.'9Y7C^9y(c=eI" Ӿi8Zqmps5̆ gQޯTaSb9eɁd2$:&Sdv3+eBDdUhؖ}nOwͪZ( l3, 4g-±lHRB˶HV`d%QB!"C 9,\޸lMZZWzώm^c=Ce'2τd6ټZmбSi˼܍~KygFm,mV"SkiƢv~w9րw]؋ 6dPSWF8zШV^Eb6f #+wٿ]`ΛQ)%D}Q׶@,ӪWIx0d6zZYt5Z֡~uL:d0=ҥ6lYTaNp0/>EXA[ϩcYb6  r#&R#ݷT%I>D[C'kwYJOW2Ž !%BDDDOc;v8T(TN5@tԠNǬoۏY*]͉nRX0'/kM[D{Bl]_ iv7xy7Zlf0ܮ#ua6-cFܨU'٘FW'(Q̔frh IdS_WDĎ.}:Gz `2so{ n^Y+($j#ݎfTJlcw$õa-|347Zb\u&I'7WsH!)) -O)Ra#+bY]d6^8=,^\fRe! aئeJ! ~$  >P@,"˳pC6,`?v>?7C ,Ab]^ Y(ˏ._9c9` Qpd깤kh`v|z44^@}mF"b?K)LuX9<$L)%7._ FmIL0S -H#Eh1d Gpd{$Ygw^ã"hZyeujw *_.VIESoej÷9 r=ss|{a/A(IM}BH[NB_@B铴kicKHnD*_.f6mzFYba aZhDeoG^эF !}2a8 LeHu?.f <@a52t '1NbzoQP615,A*$L"7_Ϸ^ [xk0'ȫуB1BY.LD+4R "B-PEX,`/B ֺ?u λ3V6i;:+U$i) LKl跣V躘-20(+؋ m@Ώ Xӳkk<=ݑs[Iө5q[tj ;fsǁDYepý Amwu8\^9 gkt=龻6ixՍϴbs%z_'tNc67Y\&`.ru;E (rAz\~۝?hx!+  q7w#f<6hl3l[<-ZqYWsx~ $G0N{<Q4 d @c uPp=lR0ϠH*{h`*=E~K얻/8,&DV!4Pp_ ֹݼ-8Aʁң;}I:}rSwWSU3O趚 +YR 9F$[kKƜ7*bW{ ZwV{_NEFZȖfUZ.5]fTo8/8Wd_}+*_?zE? ֬Dtӿ{ئM魊,]E : '7\/HJH *kݽhu+{i?QUBd0Is<(qH#Ë5gfpo_24Ȣ\dw|U>+`(jk+8DŽ>}էϦ_?h@Ӡb vDhTŒ!Oj9i]3}%e^90} ^Χ94EVɍ;|qm4udM܋^KPM!Sk{aۗW.ͳL#vf썖!R$=M7 qݛ[*q17XdT!sWDtKWқO.Apv$Tܔ,O`6)b%i\eaWdsڇqZ7Z?G$0mIf1%nA8vy.AEKQ>1 qǙM_mmrpt?#=vht(ȶ"L1PB&` SQLҞgL$K%``WP0O1^ &rІUJ_G ɣu C %IT~q7l"PY(; 7U||:Z>'c 8$i?"Zg3=b/)%faDiܭTlp؏W^1 ۻaWZ`,ezcl{?w,POR{DM_%6ɒ E8˰21ru]$Ҍv|C!6VlIIi[V̒AcU8/iON3~xG>hVk/~$WD_ѽ-JP˩(ve7dPx5p&(,2~P%4\{h6.Ef 2Gm+IfUAE,SDXarI ԓ,\A$((z.B6ЖpS* -/ڠ&AJwHw2 `ǢgD47 IDATIhA 脺lկp46# ,)ץjNIEF|q2ɑP3|=huߩ% |(ƫSUn\$3vv@z"/@>)˓@*O>(_>"[ը "&8o*EŲ/Ύ~bO ϰ"vr t$ 5X R&ֳ GU Jq读kkNS0%_nX` `aJMEd;bs ~'`*Xr.3U\悭"v2e0{f 8+k~YR%Se'; ϻع*wu5*f^x۹Ÿc`<F a;ݼt{m4[DQrب=l:|o̖UEk-~DS,4<Id/7zfgs'l2yk=)i6DIxq7{*(~17$+o3Ka/?h{fi$J<.ih Sc8tg?wv!S8Os'' #ÌsK1fYJ_b깟Rp7TВ$l ⡁S;@?8|URk\l^u+376ß̿ (ERcV9G >od!k5L:$I=mNl5/Hi@Md a\ ^ȗ6jң N-/'[h#m̧Ev< x]^C:ᱬ@V~ ȕJI6*辜thK?#LsN*c1VDAFZL=4]rDqކa ~}e,"- @˔>i (Q(Ά g9>Wp词H=dlS =zR'IwuDE$eXDyߠ_dz{5~#K"Jm \oq=nHw}9]}Lq\&#t] {=[]/t:m nw^G$vsú/'΢V?A"K-<>~M8GV2{?Fjy_Bn9ō$O1K(DCoߙ ߟ9cxXhM2JQf9V2' E@' .Kf)o >$e9C2;#풖ϙ$sbDd_4Ӎ !3W6XI2DDcP4[ F[π YFV~fsyB`b]P2a{ y"f6?+>SZfӶq 0$I:ܸ}m^Un~I"~%Vg|j7 +\f8Uϛ V>Nx| *;M@:v"ӡ'=Q|gc)U*6.O,I Pq%>+R2, _s_!%-\NȢ>e\`yC(ݒE}? ܓdpO$64^X0kޏ*=RqH[ L̓_l"u w4P%6δ,2XnM|OCoKU;ȂFxa 짍^&Ռx%þ5Z^܍ޞas]wu~qv YԽ'8\V8~ooz-ΟI-N9%dE=9\luS]5{:ljF,ŦDիB A4ص. 脊PAi/dܩX!\F e5 -M_'ZP0ZoHH?}w~WtDe]v2RJň O~dʗgPoxX{hE,|Oo̢%>{f4MjrRv'|X!g 5n\U HET]Lfz{p9:rǏ*Mō}WK'8*-2*ҟі|mXkMjA*_Zd9@cO=6NY]^!2_<Lp7ٜH0:bim1,ڒ.WS0t(2^7_>\׀y`}͠h238_[.NA0c6WKi99m;XJ鑧Q9(^^KSy# q^JZU zo7di9>92{H)LwAE8eWm`rϜ+(N6 ݏ QtS|&^Wϩ~̩Xt#(>Ց+Go?5XF .}@/ U;m'4P=  | [.ehi !?0 _3(7+R,woՂ  p4 lFJX6mV~r'X2EY:1p2'=+m }&1v׶\5I* Aƹ:RCw荇:)VYJn]D>NNW5s\RX-5XU#,a%ōV21q!U`e>lFڂw t4غV+!# j0h n^IVñg-ac4g0||"k qy !$N1ΰe:BE_Z~ljTg3N@ˁ&ۻM h\E}ӛ5{lSߢ}۶d#^?F\N9 wGݭ!_Zawui9tteMD10~J6:4[6\i|\۱ 'O5=jz303*ٔGG1IѮ5+ozwiOf_; Xʆ?D#6co%W?S.}˟I!7k٣'YiC1l/)E#b4s8"bz ~i_W1YquGnz]|uեo۾K73˘ϟSį&fkiWhz !4wJ{T~QLʂ!|bמ0>%f53KB#Ne&:,Q4}֖&vYo^3WL2-OWh=hl-h*k7sgjgo9`6tu[ 0@%\$Etg'> ϻXv(/{~x^f\5RMpL{5Y)U;Of _4O^*tג{c}u˷ꍏI#?u*+ "Bl,LYipj Jղ:B1hi|p'GsP[+}1VZj䲍.P'ST |@i6ѥ_G42@KX86<$'/ LXϗȵU-l L5ۅN>fCJ)n$lldrF`5T b@=c3MZ16sëD)EEڂ^7mEXsKz`y,#ön|LD֬r=Yp򓽥[S"7~Jxnqxvϫ4x{}y~x L1t2 f$ګﳸIXJrd)2w]ɥ=vU3I^[}c{FQǼX2tRʕ%e3p+wrvT^3?D5B(j5tYaXuќuw , Sn:5o}鈫vdx4-<; |m3>9ܛ{\&}$1@nM<-׉Zێ"t⏤x0)O|b8'}۴n{ ]D ({<_h_uf4YUIjc/{;ti:*%LS`+Xk24$}aCyN%iv x :S풱4XI6P9xV|v$q2N?h#%SaZn7!)sČb,̅*dTn#HW[ҩ .Y,<#"+!h5t-"@)R?īmD7]Y)|9rMI$~sӌvZxT*]Ǡ>]i*pHT""FpH:E_ը! 3[l6'g9=UF4cocz=ex7c: \7iϞ/ 7x65IkM[E Q>-~&#?:ݟ4?+d%T6R8O/AɫڇpEUW-|L9H 'Q[>|U,w&uH:I堬0eSa[ͺj߰IցU5Sci۩֞ʼnmsfw4 %`ǒ>)=@=`kfוKm>3{&_ #ήU\ijyFӉ 2u;p0l)T PsސJxGEc4;jVk|QZT*3uSvh> }O{GgL a2Xs$4B2 (NC[Y,LjT`c4wYLO7ҝ;UHۡ\k at9aN&[%S=Pm2UYm=&t[% V~3@ 9Wu]fܞm2fZ eԾgj\ܓ4SZ]REsu~Q.5 Ne~hֹ}pV8 p0I025.ozYƹ}ZVs~0Ԏ#V2E4gLke&g>-Q&M"\n?/Qrv/)lj9UfU4`P J|zOj}OkyئM)c$SţRyvyΗRXzR@*2()@ÿ8=c`l@@{A'PO+`’y t a=LedRxNx\lm0},H*Ze[^χgi誆>g@vmnU|8.2q~ʯ&,'Yʝ1\7g>Z3ꁡuظӞ86#.q].aܕ<pK%Y5cv]2 &úbTN^һ1o-MgYN]0g8x;j|!\,¡R JiHkP4Toag+{] soj=fD*lOK=CA\*E;f3: fpzCÁ!ڒe4zm1g)Ip5뜔Au hvU>׶-ݶZ>.#b]@-ڲ1DjlvӶ 0'6iX$@ )g1/Y}$|hֹk9)JtW: v\^U?fWɐ;ǿ,sO*bf^aIɽŬu{_Lok)ۻaΙR9s"`RܻY. FxHmku#;YH)"'cB 漢Q>L?t%I|s)&ilhAo~.B3Rx ʿYߖ?#5k]x9Kp?9r O4ֻ։4yxi@3&hXI,SWlQ1k y<\o: ̦z<خ1 cعq.ĦWq p^ťV=*ڦl6٨s` l擬=:a=u&lXgp:R GI4Rq +ԨBڠ1lZN3n][;v@&H{ϙC2UGfULګ*֬jzZ!98pԵtx1{y?8̈́ϮD7i<"gɀZ>QX51ր7=(Z:VJkМe٪p2^@RF)܋{wڂìy2Ŷm:%?z+gzę0\AϏɐqĆp.Aw7Jh:>_pŏ>,;lMm_*F(Q趚oQM?T*eo&qbx Oo꜡9&ITEWɭAsC^} wo.@XW#f>Z;L82mHE]epL fe l00 Kngma vUm9φ=-G2|HY0O7)_z,Ê.#Ju-~vY"%ѰOns!=0 :-`β^*qL|w o{ IDATXׄ?^=9eF2E*ul˷VVǣpn$5Yp|%"p==ׄ dO7;ow, JaJ.:{a ,L]CrIFEҙEE]fq$UT˵iK\FPO9#i-?xmKfӖ8B&Svg1?Q'9?O{cĕ/wzk"4Ӊ"̄88ÙɆgE;8oLܙDp2kS/Kʨ 6^˧%^jbk4wj1'?@Kw E rP3~m}ehE=f50O9ޞƟSWC>Ydƒntg7W77COzh]c| eٟo>~q~G;g7v àZ?E7_M>,|CUи눭3qP6h0 bL@ n+VS9ew&y]0,Fm#lq^5_ĀYc߱݁BkRui$_mw BZsKp C\+!k+ׂΗ x r?)e.U;۵4nOu\:tbnŠeCp> o5eO|YAnmwRvh_bCIfua:u 00gO4+KhRPXwvi͍^coYXn7,o 4}=;tY@PMچ2dO}9>0 \c1Clr^ڙq$:'s9` c'`Oۏ[%9z ,fPC2 7̃b k `;mM;a]6&{(2̭kV9qn 78[ι]CO=(E[R+ 75)$b7cF;ZYo2)&fi1X8Gp9ibFC~p6ė/y3bi<ҜÉbBrc;'=Qlp)brO<jbޯ!r)08 D;\ {^pȿ<>״tv羾zԛI4x-]lk'h~7EPY>92>sDF0x;_ugVggT Bpg 07nAfN[𰭥[~(C[՚hv?Q Zf eȦ({M]LŒ"Z0Bp3Kb/+ŻP3ek?-G ʯYGcO}el{i4 x(,fCKK7~<ޮ\^R-:4vk[!ox,<&n@l}@\jԝä_^uRF_Ϫ웅RFӟQ f}i> $O(3w  ]rƒ]Nj͎4"x :啇2 |fPyqM]$`UګXR6hU_`8rwWe2Qe'ܟeg깮 5ٯڄR$]z!YWME{Joā=KA7*vYf46X,͡:Jx<9^5=d>f?}~yu,l")|qhd Wc_bhf4wdiJ!|YV|qڧt%+:FS3T+t>m+ռCII֌7i_c'>2WY]O q _ [zlU=HĚ g֚*3o GٕpRAρCLJׂ޼8};B9[bF'h1e.;IW~ެ vaq+,L`㺛۽kڤb6FA%Ae+ςިwgE%%+Pm;DOѰO:̛8 O@:X`+KJEJ2י:`qrN'.2 -şO/S4b n o$^9д i }r0~o,>Z~A,s7=o<SA )^Hs9kzP}U5;J`gŠun^dtT)9A;S6:>,slYf鉩|~~9Ӏ'8id=il|/0mAрf@- ݖN j}/3L;|0{IZdR!* dgT1pr 5>`̊Nc3(M\#E`&y5̖*TL&;/?OxՊ}E)T03Ʀ-Y78𥪾܁`1V';})%9" ^L)FQ[(dX.Tg`MEY{4./At~ׁtwbs7pCPu]ݢ{>l} \yޜ쩒f9P)WŏdU_w=TP0J:,#4a~Z`j?ڻ]TY x>j;չVG 8Pku}dvJ* 0"z3~ 3rjJ?|D-jkEh6ЮH:.Fu;!t==lNxC8ˮy;hI uSaP=}@ 5S =; ): .s2 39ufsYn[,-~گgSH)M3l;pݏ5ЫXr$kGT'$9JW(׻PE\=63^uEhW3`P`)@s ܙvG (EPpD#5Ë60ϖ"2üSt0;^ƋyjG8{GZOlQy#E]֚c8rz~w˗bY^*;izy$t[+PJ {ܴlmw& Foo FױiI޹RsoI:Nfo00&ܚ  _~@sg}a8@!B)n P"88v'(m}}޳Wvj.!}ƩT3juEiƒl ՜8V_^B(ٌs;G%Y] { L\7+QQ3S Z̽}s/E9pEfgXe-S|/>YvsdF(%ם&v}.(N2.\m|%"ΛWi\_e>}/y,o3|)}g?5m `'h^^[ɽ/s\ Fh܉;6Ќv Ǒ:mAc NAJIZw{4RpݹasSn)oTh NUd3[,j2P) K|%R99RJ暬ry$b1[tZQ :Խ`~bw !Qk{ޥw{@w;w.훤'.$aU=Zs+qtEr…~,v,۵@0z ˄\!40'hV K|ov6f g*[\|-pcviڢkFxflJ)\v 3vϕt]l{8m+m񟗟{weyT*./ߏa<ӳ ggLt ̘B*q-n6Tʻ32Ԫե!&;̙LJoie;YM֣ǩ +zv&~-pΒ][AD:]F> Dg+G'c}o$y֭.KێLshn?kLZ|7ݣ"S_/N4<S)JA59c[ܦvSv5gUNv -QJ_8*յ p//su pѲXyu9Y8dN*T*L`8 =y:+~]Z}ֺDQiJig^K+?U.6I=֜p(3xw tI^4Ñۅl}ܞZ.#i"l\n/er$$^nǘ){|ٶ3g؎AdFt+9o]*&6e=َ? :T8ZCGxи{^dGWGی6lsa7]p3'U57Ki U\{# <;XV/~j/؟S6<_gwݛ}MR߻T*?亣}-Wۆa}eL筓h۩}ض6Y)n{?K岳Rn2;lb%û} CϜWfiTARP;/ !}]\oַ{g>)`6m;;\J,B-[47K=u0/9=ryynTa &Ơ"3D>}^Je ƒIk+Fʉ-Ccϋ|[Fc""uS0gQon ǽp8*xu*voV) SIBVr\yaEQ %[oБ B? _G 8ΈXgsYv]a،hb.Y?$͘{W9/)^1]-{oBjUWD<{1o2kC(϶kR.Vܱm ˠ(K`!"j| ȁ˳?d4C^ &XՠYƭ%{q?\۵$yږ >rkbG5nM=NqVh{z:jwMUS<ϣ~~@復1W^\3G0Aդչ6f<.% 2l%D,2}Xuj&jyo#=c4t%!Bp׽ˊz;[:CP{x@踑ǚU 8jVƏybAs#CH*?xS!= fݾ8B=dVV4^vvxo0xne{ߢ><%]{oWՠӓdk'vV^nRn[%iǧ]dMM<7mAU Fg3='p0 fSRa )Qr\۽_ato9oϞuwWC7w`)s,h YN1Ϲ{\߶2 9 %c;δmnwW51ҝ.nPwA&}#q*mc5,Kw)GNvn [kg5'nřIS=.r@E\\A#MR!' lCPḋ޼D>ӿ4M|zT)!pATu.1N^VQvl6o[Up߹9>0X.^Am^~U[u|]ZX,73ۨe9C45,z"ܕ>s3060d IDAT],cp< JXI;vabx n-+#KC0h8't|kj,RJp,O<6L}fL} r63 ˽^mpcgg.3kG~~<}SA.hxY'h榬iJAXHz̜׍U{}_0zrv6 22/"Zuɋu&.͉9<@:Y"sT;Xz{A*6;ɀ*L >AcnfxHasAf7N"u1m^Ezx b6þږmF?rz9pN&.gKHη  )m&Fe]-&Vy5`^IRZb#Wj>ZZfFהQDDV`Is%4 lI~N <_s{|MQ\֠ԭ.}RUIw>W3gu=_Nv>{8YK<7`60̒fn?z%̵n*ћ@7>D=(5AhD92<6!?XNvKneKcl` nIEdjg/2o[%w[: T]VIÏUC]& ۃpŌi|d ;K IT,P/sLyuAuc O:͟?VQ뫵eJ;QA: .}bރy,CvisےZW8`Wk\҉}Kʑpbv$k{`m"]YUrt7&?54POw&]̢3Ћyqf_"X L@H"4pӐoo xNed?u*mͰZrJڢsYR]. P9WWS-xN[-SX,]ǿ2hX(3{hmG5}yb"-C{FG*>Oe2-r?'V6jsMgg>n(,];/gm.Y{6$zׯ.0@ZC3(;W|ɯ[bnND7sqr;.vŁ3hQe6m!cԉaeo6im >2yY}qj3> ڙ~MͰV) CjlhXou`)-hC۬˃9" "ԠA$AI0NbW;mqx$`dI@tА>g×` ZI4>"hNV٩_bi@OaSDbW܀p}-81mC(PȪ, |v~ "`Ke#ƺzݜ>WA$(yT%ڤƖF '-߈feh7VZ~) cw_=f_|7qֽqg_4D?5tQ7%-$3Kq:aiOqU]l\+w:9Rm<tP؞Eڔ`.0}Bn9,nH  .ע@Z ۼ8 "E#e=C K_P:~8>VǎRcy6jفX>/k@ P|e?sfZiչMՓ~KªeY@Ś^c;4h~8cP+;s  d3YNyZ8x[ʯ^Ŏq|s$I5F{)pP gt~m?iIz?@؀kI4%t( "gh;21"L t&_xdV0I uo?ȷĨslO]0qT޵[7O`MtU%l` M / 'jb(by#pfaT]X:١$ ElO!ZD >j3ώۜ>^fAD{Nk["i_y{As *v i,VKA?}02|4zRvD a $>޼r=eWn3;>Є-/`^a⮋!}]nG擧Jf9f͛GԎ4' '`4 VT_G+V "ݲۅ-C ^?h/G- |TS9qI+B ,HߣUn8ʈ24nmYm`+:znt>~E2/fǦ}9qtF mWLiP˜t2#ہCg$"+f,'``m?g_sӒ\q&{2Y^HY{wmΛs5gQdyuqUsxNjfxrD5PNs rf4m: hN0V11)vc(VJ:3e~YOaadcQ^<.71̫.gCȟ^.Y$?ӕ_B{EUqi(Xo2!1B3k+/ vd!ca{A S`rDrR"N=,h1MG8"AeY4f4PE_ՖS}JQ?鵌{g3ּ8O3H/O?} iMZ\(|*E}y>e0 bٔME_ s1&*@lf1 >7M Q#vygv gq[: ]2j9mZR`He%S]XJ DVѸyγnW_uOмhnw7cXb>sJmAN޸-[+.tR5(]uCPai@5ghH`A?#+}NS;!:+#Wxb ^{0;ykїoV߉O|6sOOyi'36Akzf)B HbSb:fo# 1P x(:q CoNsb6!lP@ Psyc٠Y"{R)|(˜{2.3Dz։A54!tɝtm c?ˆ 3q.6#YmRu) c 1 A0۴ QܚR@ZL"ashN+5Mm%׾`qo&)͢=yFsFv^y@\瘞1;*lú'hh ܟ|=T \ʉ`,5hdϊ קe;m0 -t38 Q|o h*–M]ߙݎYA{ ~IpxՋhy˷O|J hAp)R7 Y9~ jq16]{{V:\_ށ7#%Ug )fm*j7$9V%cS4 E6,P3@\d81#}>;o6uଯ;V~y[x-%vLҌms^_4O]`4_T $h36f[q=k΃Pa"5$]INa!+zZ]t0ଦY׬K?HZSg'~tA"8 *8e@ "?gb =0f,t&=8AcB `EGШx7wCg:3 OPt<^]1/3⾀)$eg.Z'`>~T {M:D pll=e8O(aXЖYϊ6Ə+ "T=ҿ׺x2Zd;iR5kxi۩\n>w!2r#S1`sI" HjJ{J$ֲbۂ`Š?G,RJ͉US@PA1Bp3zsѾ!H 19t0!`׋rm͚MH=;$ *!#` i5hb>)Y>`<j U#R셡Y}ڗiqY{`Q01QkA-tEy@O$k-s !sMۦv |lWMtqyz+.@n Mk^4Z[P M׏H(P$5|EG`L NOyR LO([2Y0:Ҁ(/! `X"^;Q"ʟ`uʆEZ>IfV3}I[ - J:/ ( @z1 S0tM_"iVLH!5"/tylH8p=ȇ}̒nHO (m8͚PP\B~atHOf>w1 'C` 7&Mwx{/W~lЦsE Ѐ8lL-xyeMwH@yӝgVc`RS /l&%ЅY#u"݅D4^\x.knfku|KAi9XTбC(FK{'Y ˁ hRE=%BÉSRQ OآG12uۆM!`*Zы֩z땊+jeiѬ0rU#G7C<[@zр>c) li`me5qj5n}c 4'.ẀqTb4)PӠQe>7Xʆ킚2֊}Ӷ 0'?0ΣJG W# ^_ %;Zu!Z!^ => F_ts0*xr?\/n_arPW1 KJcjhÃ+M4QЭJ~NI0+Ko.DbNo'izΗ+ ՚P л׏=[> I%Ӊ`/Z1piR̆fiSX=5#P}g8qt%dJ@TJ"`y\iA1Ug #v߻V21NDG! "3s8Ԉ=K#5lѐ@Bqhp쏆CEX~ SX  "PTLT,ivYbTIDAT5+*0pގz+' |p<[v:XNC_HkzFcB7 PܡRHIccN鏥ي废4C1mYOX}$檜_B*Usp|ǼCDLOX@!V[@rq?:+ B0  V<(FPeEnL݄0X"f3v8?̮UX;˱fQq8%\NZր-z: {{yDc˝mu6hfOeYb5}KK9֙ P~!Z ~wPv u]4ѕ%>jR1dMVa`u_Xk<bԱ]ɳgQn&n;tok:A؏@W[8 &e(`6Af H`6o9a,\3yBHN^76?0xNΏZ΁f(q sؖj!AK̗bIѥ^;9ԫb xBȮ&4JLs0\-s/0Ax^1<(R Ab`;+4&7{SFES3Ҍakjb\;"FU:~/&~lW,[oۦOD C_{-t>DMO ue_~w'+C/0AR-a@^k&eyeԴ N*Aq)Sο(tjh6#լe*o*B$/U?'(y T$bm n1=mƁj(;b Aj1E9{Ә^rڄ?[CaED!m;QE4xZB ks E0z, }^ ,$ojl)M| /O1ۂJ1YSGKTUNC=dZ秺`b+մ &9 D[RK49f$ 0x[6Nn镳,+z- Vܽvyw831 ͊F!LPMC@]/ '0c:rgF|9l*DғMZ6tmENJބZ**sx cw^cVl5A {'Џ)?fzCzԳ&mcS zHjG#o}bhPTSpj=;C-c9€W$,EQ_?h S(jb#P1V,>dj2$GX6EKL'%Z^ER;r_1 =9^Ptp"r0&(*E#IDid"%;[fm!#. dQ(8ä%9&z(0 ,t B7R:0"c>A lAvGa"_8bü6yyPBs8.y|F9 ؀0P%E_}-Fa *z$c܎DJ/3`zH$_,OϟD7tnhnܪv4iqҸBӄnɶ-n|"ZШj:*k!O+ =Ā uJ+8_l N4`N}•>,ۡj\j[3uG\}+Iš(: !DH@Qo`+LZMj|(y]GPWPS_3gc̲gr M^bT Vi!܌{; P|ۄ+F xY͂Mx?_v AXgp䥭e&׾/#8ė(S<ĿEݴ@(H-M=#cC AQD`ĎЊ,81m# :WZӿ#(قxH*9KpiIk 3Ь8jk6`+ދ^c{/М{ƚYY<A ͪ P^@m.^+w3NuӘȋAp^,[eto1[,1KkP͘ ǜb` Ъtww? -] ;Xd۹ɓqO 8I[d(s B]KOhgkFɁҁ. ,1xqʊ?+;Vl>3_lEܠAgї@auWS}t8cJ{ǻ.v;,`^?2~=OB-;4 CbNXvGe'<;8/!HD(1&XQ\,AI#" >QJ(ľ7E9.T3[L0l* c3e۰@t<0 >7gAZi?ߟcI3zElTzH\d,G8(T3L/STJJO J<k`dLf Z懺S-q~9`> K>>J_q;F)^ত5εot}hdɼ Y 9aZ 6Yֈ.UANo?@M{rY*i\AuC`+(ָJ>:RgY4U8RFb;[6z, ?l)sYjmjafYlf6bW㟸q6m9n?3#{Ne&F >k{8fn1a:q}=sU^Ɇx0hiFy ?Gc wP`&~?Ȣjc9b!XD4_EC-φm\NiICmi/PYĥ V{rs)4Stkې}s~q>,$H\@(E~czRbɝυXo iyL{T]sPՈU :a{09_?~M̀ѲCmW0>nI 0+c6…)R OR]])ߔG~)4\ыyR%2@U @0Z=HU@|-BER G$r8NMGa`K^Ȫ%1pҨ^wЂ(B(m 3غQ=\vQDk5]jڄv[[l?SfmGw7J}Y-hpހvo{ S6yGann I>A'Ks'ɡAqCήK2G E^(!h$A*VY( 8Њ*L!$c5du^Ai )%E#D3[!` |*0ِ#d0 EjcZhd27R)`DB}Ѿ6oĈ{[`haW/UT& gNegf)SM0KF.@`/fA3vpi3; 2ˠJXwi( EA7רiR`p"W -[C(s,T hƆv#7VpJ;JYٷC}o S갲V' K 0C07>03@3Q[/5 o;sj4XUOK@Nx248N ޝ<,M6$S =,|m֍+U`u Q\\ gB}wb]enhʅwN!_f74`Kʐb_-0vzM|7 odY,GF]U\q4h- |.e<2 Bo<3Z >hHy,Zͮ:YF *t )@p`*0װ;sLk Src/_<1BY!G%; *#n[Aℶj}km1#P8B4c`HlerIdl bIBmq 8k@baV^UY{ hP~sT_B>"sQL:D. \ ?YSeq;3-G`l5(5O )7- BJ)\ ",kF`BTat!atɽvY){ ]4n׳:eVyf nɝVD΅T?{~ă\o!Qeɋ֧sFcG@%@d.B@j h([V~4 :0So>ej֬#K/<]A3!ŸY(̀?(Bf?{(-mnI 2Q-sGz}?R=Mi$j1eLk97E:BA5EfB ;L}bQޮR,x~/%p֙<g7οW_xrw?]]4{Hr5I)*5.W ӯ';QTSx7-1,6E)Io.w Wv53{l0Zs`-&'6P3Wly{nn2MXv ,IENDB`mudlet-2.1/src/icons/filter-grey-locked.png0000644000175000017500000000765512070466512020276 0ustar csmallcsmallPNG  IHDR00WtIDAThZ[]Yk}9יs<3ljƗq̔TB-B-!>Q% T!<$T)MjR;x|fΙ9}}ugN}x~{}{kСCKLeu xfjj걉Si pBy8"C :RJT)I)!D& c,Ͳ,<β,au, ,,SB8~e̙3^ >LR}~~^V^gq B 2Zk>:N Z)cYe?jFϓ ѣO8RivnY8MSu])q(vM>* B$"s^Dq24,+r* FTqe۶طoڄy5 a!vtOxB`Pe{4Mv}A)5/`mΝ(R\eYF1f !0 J)F )%hA)# 4Bh1cQJq%!De٠h%IӧOo-//<}'nٜz^Wv$Il)%ގ95p΁s1PJ( DQ8uW(6+%uw}}ym֨";M1 VM۶]˲bY\\4 8Nuݢi4MdRjιKy9Ocld\tcYVU*q~#IsܹsYTҜ)˲\4m0֔b[e[eQJ 4d5hȤ%Iyf8$ItF`0Hh4IfS<''Nõi 9"\kF}|~c$$ UJ(`0 лx"{P2GO^*._5 c\.+0 z.ks(GVXJiDQd%I)$I:/^qA@lòR)Yir˲i!#ߎ{9 P)孮<&IꇡoW [(&+*heܶm16B8 4\yiqw666Qa#5.ka:cN)eQ cT! !lkk2 c<3vԩSzyyI)ic׶) 0DZBpy$IK}Z<|wR(9RC}X,^WVV:7nn !V!B9o/|iiii¶m{=_vϞ=jF@WcX,>gϞ( gײ,{]_tIcBPJAe'᳭Vk:B>0w!B'''0 7֞K.]կ~t$z^BңBhff<I(wTގjG17qtfAke=AMJ sHC]հ8nZ(^}+ۓuO[E8fy- ]YY^σ oMY鵵a蛦rlJ#Ň1Pҏa}?^xq0|e}}e3}ƍvOa~ʲ,0iX|ObtJeDZ|/| :_t:4MoFqjssDz^{!čjGJeNs\nZhNZ 4M]*f\lT|Xfjz{3:Suo߹9vM[`t9#EN(žxY'Rs:8jȨGuC\TsRwq}Bʫ Y\hR~G[Ba!ؑvQ@HhKO@/WD`WN:GM#yٌyDQ0Jaa%򖉜 E4NBB? O(-84S{3[6<HA I JI6؎, :7A4H \:,ciqUE@JZ@*How/D}6ݜT2K/Tm6 ǔVYA$~7ԁ!!%u񫰌NS 2u;^|62)\ [Y\=("@>_S)(,PJ;"qH)m1Hs@INJ3reeQ-{:Q]s+h>%c;L^I|drT<XҨ( % Q v,I: ]i G^2iMMb.PG+zaZY ^߮T:] \$.E b["%LPQ@uu%-ǾV$UTǓț`6$&$ɝ>҃0TDTgS4R)O>AKG8;L2Jx8M4yu\GfPԡKĒnꚻJ:'+].&KXs-J۱ 23zd3fkvC!D ,XTC|jWvm %^GRM96$_"ndt4LD)xZR2I&,By2l}n~CBN|>p5,ev29e-h6@*$%ַ%vAws2􌅎]G\j3WVQJTh ?14}~<M!WnE\J!jBKxzt<4XѬ.W'յ+M׿%=7B!BPk (mÓh֪0Ƈ(qS'9IaZC՗A%Bi}w/|TzzS.8VxI4U1aCAdؕs&7|dTWjIWo#vcǔ'4>z>e_YWL掕K^FNw0ZLW u3ڰ]b-'V?W.V ?>~#Y߸]7֡u IǙAe]_8.pſVo>wK#cD6*2ٯrF FlDl]3PkU/ 3籠Efoh=8X|=aͼt>o0E4IrH!%7NU?*O<-NO򘕄f27G a3g=U H Q0ְѱkD*x>28 GYp[M_Z!}*;NLm.5,jzܹMZ+^ z/r̷"nȗccZ? 4жۭ5_=[gzi`&J&PVqo?7yIL#Xf}ͥh7F<3IENDB`mudlet-2.1/src/icons/applications-internet.png0000644000175000017500000002021211513237311021074 0ustar csmallcsmallPNG  IHDR@@iqsBIT|d pHYsu85tEXtSoftwarewww.inkscape.org< IDATx{{%y59ϝ' 1BRE*+IEqX"TEBplǑq,J) ˩ }yܹ~ ޅ(}pt=4鏂zh'=O3P5RM>(zv x=Yc@2,ã6|{w`5s%5[=܀ Zm75"&<&DpV+u8W|0/lߙ+d?J'n3LȎ]hA2L]}@$`&Mҭ=mjԬT4ha\_=;·ouV)@Q7oeJ~n۶ԇ?&& tԅ-(@UUʤToti~A%L]*^.PeN/|m_"õo+@QRo _rލ;)hdjmMkxH ޤFO펃Z@D pn44Q&3aPi̩=rsXYm!{Q@.śvN'zɃ&^RUJB jsCFH^]\"4 I`('?LqB JΜE4w_X_| 0G'?r];ځc $ O>{sdwXeJ9yz4MAk* wH XTQҢp| tBg.UJkJUdW+ ~vd2,ܢ b̰7 QG_ 8!BX4XZz!ACd2AÓDbCI=kT]#DeJdD.UXq+;l}?{ZHSSw"CVH = J.\^*9|0L=Q &] :Yi ҡ@\҉B*DZo Oy"VS]i|A7MQ§|lؗӇ 4 EapLHe.ޑÛX&2QRiz*Oe 9dsǯfDOπ2 VYfw8MjUgj>Y{ΞYt`;̙3?}[Unyhml445(\g7`m:+F<;R4.}+2o-޲yΞ[Q*`~F=?`PYVk*@RFdYz? C-[)u[3/} =V0o#_{ЄEtƨ>ޗ8eKh*4ͱ5܇>gi 6Bh^CyUSe`LCAEYx%tƁ]''(Ȗ-hYZ:q0!4y$jo(?ޒ ޟVuWn}߶a v}>er.}jS ++:ާf/8,G$N0ӆ ,vep`,"b[YṔFHl|`Μ[øGa$nLсtyo: "Iz;N`i) @ZPJà [q` p>Cw!,,~ -"lT@wӆͯ>P WG&Yb0|AId~Î]PqX5%{n_ Up{޿pj8%#$Zk#wOs 㐅ǂHMo 2Pl7`.`Z+WiҁPZ<Ĉ8#-'tU k$EoLzNy   je}tr,tsOH%XqqN(fNe,?Gm5ujT29  B0DK d ʲ72$pB[vS<]P>-W@zwg0)!̈i)(!ίq…+?&4  { @3FHLE-/c=B!nYa/iiBX}x@*Q H>d &G>F!?2Tup(9pD:J,,bψbenu}܄92$҆|)'8<}Ju ʳK#!T:tRfDd*{ޑm>}xPIe?:v|μm"v]%d_Ze{Ȥy&ᬲa-^Xڮ>" N UMN]Ng.]miR,4 L@}]&Zi"x! ?O? )CCACãC\gġq)]_j6Pu[AU,3'fUP!D+B74 ,0(.f y9Bm%* X{4!UGϬC~)=ۥj"pË. e2 uPJ\ `z}bdL8f֗c`kE$u2w0bwrChAV)<{{P n"A״hT lX %P"Hb_-NMXǚ$ TߐN@Df[8Q^򞛆#Ų9\#HP^Sq.MP@,L1qR^ ^ o5Q}~fYLdVάx[߄ MNa@m8ύ˨}|b ' Ϟ]nE2co :5Zy!b\G)k QݦyZw(Hea謀kB!]ROJ{{?nvN p+AN౗i|8CBvˋH0)FqH4~y=:Vu,0!bh1)8` ZŞI‡L&ߓ@oXz}=JiNarT[\Zp妬8=8B'r)-#=E "rԁJl=b^'{ B@0נ8c5P9$<_>s2+k֧+m>J !cg@5y^j f})<5>5ٺ|m_h}ӽ֋IOX=_1C2jQ#ZP=%f=p{nsH,HG8b@d ~> &(&@JkVLB/&B;PX>T;Ni0R>xQh 锁<, Ja8ʿ%-]iqnW|6$\=QUشQ4-=r[tbM?P/58FlSj1B9+#X\qW`s y+1M!#tcg>6Mg;Q74 O#lRxTBk!,<ƃT/!k8*n\OE\7CÈD)=DO\HIŤQ4^Vc Y? $ׄp\ u|Qz t8.(ʝ;T-/C&zZom7r{NWSM̜dJ^Zm~!Eu(Ep2NϜҽGb*4f\DBDZX 1ۦ>.K7U2sN(I/T1os>AB oȽAkܯgǶn,VlPcdwPPyF!:96Ц<];e(MFl=FؓW:q 2;BbpÂfX>RB~xJO]lAF|C,|?{=)ᕋ?s)t/An_׳FWZwz Àͳ7' =,)-MeM`C-YCa1:z&ݾ@J.3S!qs?dvKc`*IU?‡Goz{VjűMt`է~dG*eL{/ ,g),*cp4^\G,= r}Ɲg=wvN&G>oZf5d|(=C.KSrݙc[tڍ0ƹWp =f|8M;0ztr5@l<քϊ&nKV^_+Y.Ng!7@ͨl3m^/8]rWxy\?i4c38N4YC ٤[7Y&epzV0Dx5n SL}j?nϏXKKON`yV81e 2I !ݒwNӇw/0Mh i쌳]=WTW6 Z}9nbA"{Xp;B3BSP~-}^59Oȓ/}fFw\CQ:ki/;e`~r?0z痕ܼ`^YF q2TP - f0:Nu9o n}CYOscz]03줒 V*Zټ1X|? t CEصq@cVd9Eu($|Ŏ5 X8a].tW~224MQ0Y} _Xr˿+@>Ҩ6^/-j%_ّ̎t[F&Q~F9bj p4(D;u-j,ThlQ-aCy252Du, edE((!wy=t+~uO·OI^WqQ?kW˧b&IENDB`mudlet-2.1/src/icons/achaea_120_30.png0000755000175000017500000000546111513237311016662 0ustar csmallcsmallPNG  IHDRx*tEXtSoftwareAdobe ImageReadyqe<PLTEL{0zۆ;ޕJ+sYGv4um͖"[O#tƘt֋d]j3v(m-xG'm6kĥ%jXCRXæj5:3)ov(2w,k-qTh)VB2sԄ/d*9|#bd8K׬>**`j&h-|d<0nY;{Ϋ5z2!a"l {+e?"u1(f2'b`/jbN{T߶B)rٜ>tBz؈"~2~*hArQQQ& GIDATxĖCI 2#C& #rD\a_53~ot 骮/I ڮT:ίFɫ,_J%)uD*V7M&ЀU9Fp:/y ǹ(ídMw~ 60a,5gMsrctlh\!4N|E&JmQXj0,t82!~%Ç7Sm\"!i `t«~iqie A D q.pτf  xE}c1'*<,GGc8ɕ=hf. q5Egef,VP5O\S1#zmx畁͕ۄ8-{f3V@O*2`!Vaf{Bmተ2.kDVٚ9:MENhIyU Z@%С9%HaU (ri "w[H#҈lגF~–~b䵁k\\:@p 7Q?$Ga,_DuX*2&]ea "$]qy%\p:KU6u'$:'9H %?[0[{KY2Rod=WX, 8䲷\. )zZDPΆU}7`7,p\+~>)Lj QG'8e܍)F\uB)|2h5_yI\Bxs<ܑ,_raCY)mSӑ6j0,x $(l;6ҥ1iXFQT jƗ2Ù5'1녬?\//Ggdz~1#0L neHxR)f3F2J[e2JwJcxH_2'ɵ-Y);3N! +9*Xr* uƊk?1rkt8NX cVWj:}mSUjX|J[.bBiy^B?]>|44ƖFR)([e%_ZʐSUK]͏ҊRTۥJNK-.zv[wI~}'hvqqqap)h kj6'E dN`~2NKcD7*Wmzj%>p_%:>m/t3|5x,f;Eg"LT4Mb^׏F4A1k%+>62mEw'Fwf14kf -tCT+Wh`Hc$ Eob}]EyssL6#e2nlldd ɈA`-=Ryz""GGeg*ۯ-P)bʷov~G|0IVۮog|GZ^kҏP=lZWYH|z +y<Ӈlwz{ wTj)P4 ~RT<'/ Ra.!5 `{ۆBnQz#FˁmG4p! |=5tggާOOOj Ņ>r^#YouIENDB`mudlet-2.1/src/icons/applications-engineering.png0000755000175000017500000003016011513237311021544 0ustar csmallcsmallPNG  IHDR>asBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org</IDATx} GyWuzŒ[؀m 1xa $s2L2s2@&fa2L’`fBN ;bz#wٲtw?WUS}q% ٖ<㯮Zkߦo ڪFc6~mmpzIkxN>;4ƚbXDz&~GÚN<k@9ۼg4vmE?Jkxo?ɩ{'yY-Y No[pקJC6h aM=\Ux۞gIN{)tٕM 6+B6AwvC7u}X`8ؾu2g_wxggb MmKZ(PIX 05ޚBJBiH/4üsgo ~_?cš*yn}oo*"(]3NAi@!`{YlS \ &f0[xuPtM;nO]AX-5K[C#>bu>ug^fٝ64"g%`3c,1,[(ea '@{n1___͈"#|6@+@'l۝|,:ID<ץ}6ox_/yB)P鬻:D`*ّx>!^ }ac9$[("6Pݩ>Oo ֭&o~o}v9Cv}4Dp{$_u/\:3/'cS j4<@oA|C][06CƠcx@?("}M I4%mI(KyS ىlEClS3$k]_7}sQ<"xos\m;>iHƀdr||䡿 o(xEo3\>ouvZ-/M XÊe#J@8dB 3 /,,37xfMG䏜NV9^mgLa_b}9Hփ/Z:yJ ACJFo9sw Y+nwݒnxy4F,+pX|40 Brl=_md{7^W^{oE旅NAIJ~$:ͼiB'¸YCu ˅ x=Ogz>މ2Ύ0>mGD$`C:@Ic Z`erR " aYsXm3~O⣟[ʃGv#! 8|vtVUv%?v)jvR`ӿZHZ rd!@ LN򥟦N|P\c+@k9h' '`(D~_" qư(\4 ;Xmgoͷ`yM7tX@`ן2soL7{F s.BnE:PD"{/xvO`A/~y~ˇ51`bJiIP)PJX"0eJ K"af ;Ljx5-p*pm{CX>xܑ;6.O&}H[~rCiO`?Jbj+/LPe'! Eh9("T n^>~eO\.o&X&i#H{wmn}@6@2I6P<PS>@"q-Ha7̰0ƒr.:'q*Hѕ+>3 j 6AA̾2.Ҳuo(`LkW0#v-3^p;7k`k/+fwsOIj?gϖ'+S{F jEn9b`8|sa;`uz`): * HfK }+eZ|Ԋ_&NZ$2q7߼It mugzM_Ͽa 7nMJPŒ~lv ._Y>OO|: ĩz\zGDzå D75 ծ054vS )L#-dŰ~څ/o=H.߹wEA-]ܦA|ؖ%{b~lo"eR=XZ>O| tS ࡞ dwk cJ %.54x+QHYa|I)`tѧ]21| 5=`@ %L^^1w./;'u] ZmFя!:, AYJ 젤EREb$_jjeAh"K+^'Tv*KCn*IWVAX-gX]Ăx~ I}ƦS*HVHs.ܓavq b} }m@_ tbȸea-QH,f3U?Ό@Я>{{k_@hH&y|d`ȃ3X3PB ׊] 7[/ɿ Ji=~F@ Z㥇zD$QyP/6 ^+JNšucJ(@p6Mewv XN\MrPv;OAvb2.la=[ceNr}$/zҥv \G9c?z$@ cT0= 4 Z \^ He`# Uii@|+E*nx#/'_ X,{U_i4*BD`pi@>m6)rycnB{ø#ئ0CA!,zb}My+"IJr ׌O^Zz~X׏7|,(E*o_!(AP]$BD j$cu',@詮~6ؽ)XpiFQlx JDa0 ;IYO"Àe3>E3{@$ҪF#~EϽׯ&am ٪P&xAkc$}q@hnҹ\^LNph`4Ia }Uer1,k`qR:!~F[ѣ(6MD4%*Z|fjho%aN(὾|BGsWQ']FKj-)0 A .a[xm\+6G،d0]d~< ^GsB('TS-L`HC-DP@j/]@ĮV`<#QȦ$" BZNʵu]Wƿ89"^7͢5e0+(\? ņ@c dY$ 'vZ{\Pؖ3B@=<"FxA~A͜$X"\5cz"YHg]h-GBlx.7. ( ܎1ѧ|qdjMo_-\U ّ֩I5 D)4ަdIgM]`d-d|H? bKx£RH .*/qN~S3v@Ozn_U:ɵ1TmGR1[$~4#V_p+"8NZ1f"pp"ls[`,9+6/ïP7阌{#/{D||7m˫VXj 7 dYp2J`0YK *M霓%4MܒXo-#iy,0`s@!ku5B$)+vFNK9č#m)c]Qզh-̪$R20GSEYO:kBVNi*mKlsx\Z4T|.}<)Щ|=kGO@b5ԄGnf\|EPa`إQ}m~E mC ډ@ * o\qXFEbj7"9Ȩp{#j#(Ӷ‹p}$h+vϽ򿜾DTǩ;6֮c tšˁ[~I/ 8+yJa_ Ac~Qď$_4p~6N< [(ՌEE? ?j&h{?5&,:}j'.uaH`{X+ȴ+TEnUDER"T=d9܏{c_yDtt}ŏ8*R 03Ę~|7sNn{6-|ў-'O!FRs'R@y+h.嵫5T5_Qt@ڱ/qoXmT-;ۨh>T<^Ow-x7<*lg\.sG#v 35EzDb-=N@\G݃TB.0nw'/T 9DKhgΚ؋^!?x}Ї|#0E[dJ򩢥sC;?h xX+!aQX\~}>@S+*5{<liP.8f Nch},ad(Ziˠ͍X>p ? fdxW;huFhaMI\<\W P[pzWz" /@o*0X(9~+󑽟˟(+~>ӭB@b`σxql-XebQ)N|%(]@[%yG[J???q>M $b)ZXxWC 8\CA?̣̓6rm+ޢz?Ivh U!p (@ `C/`I`(z,ua_a2NB>j2y}[Զbb x_/>8}WkF swySf>diC(Pyw]'=qD៓͠ jlu#p}郅|3PE#g1+@?Ә9' /kIHSfq鿝wܱ|Ir}F緛hx?\?a(iPxo, [Oudlz’*l!0 (c,* Ĉ zhmS`Y7* c |m^/KbR)vLc, <\7w?z*_ |tY!@;Z}%af3HP:DԚ]nцB*ج{Z-Cm@ՍV6P*>}8K X.{3+ز b=6[t[ A\vT!=E`kuqS<|C $ՂI /Uf0(guIKc?(?AZ@uRn`]0 ԛ=>G:-:n5Z w$] DKڒ ~h`y!]ϋXwǧp?Svlܱ vwR>\܍w6~`0d1BpL{bG1NWP-$/xr X%؃NA6fikC"N Bw[hM_*v EII6i J4(W:uj$p~/3P<7/]8 'T#Ƿ1Ļ~qQH_ݚ3)/ }phATО| ooKvP WRa|-YMhePbK&7] ryz}c@+"oQ#!\$h'>R Bl;t(`u[Ǐ{pLolofrr?܌T. +!`h=F߹w;Dz,e} Sc!F1cH$_& *&jD 0!%-6Gv<{̽gkOzfv\;9{;瞙wd|5.vo{ͩ0W:W7?[}Z4 PI"ïc;±ʟ֕,<yi?(?r+ zZ Q=7(UJ*Hy/D/5xVJP H@g}?yHc{I^* p>QidI e[ t)5WulJQ\݀~r-BTnn7UW/`Z5 xY^ppO6 !q]>NᓑM{f/`QN (OO<6OY@) y#Dy@"|oAAd"c:$=[yN &Ah/U)Ӹ z# &w=oC$(ݮ=XeY5Xs+6mo]~* Ĵa_XCiɨ9?9ITv@A֫2AdWD<;#*Z1 ӨLv.z270+HKW~KPM,T\PJK<KA~fU7Y\3>$%m1"RHٙ`cYxf b6@3Hv@ix+oԺ:cj1H)j[߼#HxVoL0xG!ܞB__ 8Z/D]!IF@@5)^BǬ17o(|tce$2+FC>|zs%ȼ+(b1fzSOОILIuJ}6~zK0C3t^qlp>ewV{[!A\ Xm|(? OdA~jSeuBфPZIcF1{h4$|/&ol;=-/i+C:ϊL pWD|VwW ]Cx3>7MWuСE&kyٮ[TGɔ25Nh^[,d*@$Q"2 MT1B =.`0ժYG0;㈑oOK \z2F|}R:Ѝ|wd ZE_O~&[\& ű/~|껠il:(IL-|,L̇1qRfC(Bj%M)3 B\EXF8?jTj<{?+ob üް(6Y߫Y 0555m888/]|3rKni@6klҟ! $xT+crhM\=hT$qRh#OUX^׹xvx" ;L莛?F7 fX&묗H(Ov0΀;qyI! lV#'Wl#;c®G7@e@^Gh6 9ġ#|Pcv[ 4Su 1 B6P}~^okri `p ކxm 8BUJ?4[.(4sstXAA%&eu}aU 91|[ ^ѳc|gVˌi[#׮K/0 d>Y>^آvf;fլi8cv6Wwn;ܱ_4< /`?GWӒ{Bׯ[e *D3 P&T zȹZ>wIRmۺm[C}#3Z `ds?mX{ T( [(R+k(|Ep $[QEh"#:f egu1yӷ1f-b~_ӀZ lU 7%4zuXfFƖbhB!YQ輕,A(5DDj̋0M;: 5۲3ަug,>ˮB>7wK|k΂oY]7Ka@Ƃ.Dp^޲>vޱlj q63%~G0n)M`t|mq eg} 縠i@M;٦pgE`Z/lc0l٘Z,uPSЕ㫗n8{j[ozgC|\XH`K.Hۼ|($"Vx%!M!UG:;yp vqF$.򝼑00C D  b~FddD),i4/kbW}`!MpcǏԟYcRĤi1~^cy>#D|ծssv&)̛E(ͤ4,.֎P\I5t9x4K3bfR111rQ(`&fFsP{)bXi'+S? y@@f=#"DBÕ)D@ #!Cg} Rw&@V220"ǮD߶^5O!"ڵ^/2E겻IPuDqSiݎRHiڈ(Y $IE Df_PEPI@VLz*hΠ"sdr;A!@}n8D-JJ22#GW$<@RJ} APpZ X !< W^P^Y%Po3QÙWZ6 33re@D`-(u9A(DTw Z8ŢD~CY|g#D9L)020瑢ERI-bK2_ղ.PFF6`E@0 aAfv:F }\+z@!m%&`"VZKT^M֮#RR(m`fD_O~ S_ʹNL;k%kT};??b%Ұu Af唖d1[fbeJ[ɚd:DgRL2D!b򙹰+` %X-Xˁ#(7ĕIg\|7|k6}N>7vT}Cp'4͊C^;X;8׶uo]W^ a|773QRZ\Y8 b=w na)3=%/Ϭ«..4+bɘ3qg`!H)Nz{aav'^gղU2p:|Y?RמkcQ 3i671v!۲Ni$a 3!QZ./O;p~bn/.ezw-/9KPX)wY]&sC/fd1 ydB'+/j97;mi!<39+L̊5lB&\b5XҶ=LfTi'!L K;7wn;?K>T}sH`ʁ @ؔL K Lƨhi*ِ!ʎKB$zx"{N9'P*EdX_ a/Ov)oy-.Gk{a&/ddڵkgj-gG^Oִ6v︢0R^<7X%xN Ε\a}l;>>U"#\yP{ꑿ?_BKPY! U4|p\TL#D *xNF^Vpp$ zN)L!L _ \y°NO^]wkn 0NR~fTmK2۔_Dƺ-4m;WٖD>h|aXcB/s=DBJֆ )ƃdx\"B Ė~wѓ/ڈO]K?V8wS ÊXDPDѳ7ΐRd* z=Kh+YP2j`8ť1)MD!Mģ )6BF2k~rc+Y7Ara;;]L;ˉM?<棅 @X" _a}Ѻ` aBpVRE0h je``+!^{DjkSɺҼ?]W]q9c箖 \EWKuV 4eJ5T1wG))T(s[rJNZi'A ?U4D6]:-)߱ ̜_ {z)HaW` 4S\9]\ZuI4o0ZE~fTF+|"Uܵ;n`).rc-׻eiXBDL^y%Y" ;uStJKE4!oP3"i13t6z醖Tm3[L:a"fD ] zҲV{-y,bN.W;+D hTS1NFDJX;*d }cp+?'ri='~>&aҨ_w M;^~߫v_q;8yq,[7_ 1\WCy?,柪oiڭK|#瞜)mol p +Y㖗 + k  0!;;p&:0Ԋ , 5"Ev10ײeBլ(v+k7S.Cข1,;vH *b+,x8XHSTY-a%S1"&@D1WMgraA+m{[j(|Sy[1e_f>g/^d!7V{ 9|ra @Ơz !Qj, sTeM+HyV4P(BD"~]ᒍ*BOb|E*T>R [ #fU;q }@%z 0 $35|q}fSou\EϠ6`X[23igt)RgY)\C( &_ku``gI>D6"qIˎCDXU3+\5 +ƌPrxrER̬C,z(0bTeiD Xsh:}#n`LCG  ;vvf.]x镚 ~闑oOo.{k۵gHũv.S۾*(??~}Tg^ )  D,$jaD=WQaC3"UΈ ]$&Rٍi'3]{Œm[l>tc " ;X}ò[iټ#&QL8ϊ @}5ʓOfmꚺ㊫-QT챰BDfdE([cf( )c{%=BimWHF( fڥz+u)NX#3AxCc :T`Rb+\վ:MGnpD (%(sUص)ƣ],Ħ"9;6X,֎]7֖`X~HHBɠ-r]Lm2SFzf]@`^eC/8 !?# i/N=嶵_HKS Ӄt1/!9?-Rbnrai겾1xc聺'lcK%5':-K1ںtm}'ƣ]Ɩ0.B>E}NGۛzb5U.\(jFەH.XLR#)u/~GV}:(r5k3Ds>t=+mZ;yZ\5Eú ٷ50gX eeC輰`̀"V;YXAnh+M*505^(+jcx̥Lc+"B.D{]EQv5u}Ź$kꢳrK35<mO>S)_tߺs['$2q ȋRD̤DJfD6rvR0j埘F%Yr3^p/ dNg2'u(cqg#3Bs׆ExՃ9 2+a/r [BӁ44*lsʘ(*" * [ofDbV&Guёf6ڷuWOfkCr33>0Tn!bY&_J)rL=3Q/|XHި!jFW2D_%E?/ TrHKTɴ_,,MNayfX ʊ5$:A0Akp@ň 1%(?`ރNL7Mr%]X^\NffܹHs/ = R0`2nl%S_?e>+\ cL\&5 5׷m" +H+Edt(PP4纋+O])o_Dޢ/; .!.vʅ^a%L}VFmRp&r0H"PX &qq_- GpWu(.(C'Ƨ/G{umhl[eZfgb ϜCT3:]Uh/#ށ-]=v >̓n7Э:6mjz[^v٥gZ#"JbP0y*;TpP1|.BK9Sz$xaͅW_}oD/qTW  Jif´SV"ki! 3N +#eZ)SP <Xls@qKE])_Nn?pM \MӺhtS:?#8?[7Fϟ8ګz?e`DrhSKM[Xן~2 ؃_[jmr|ٲa|سbQCEW.T\FO)K ̾0ZrB/n~iv8m_uC{3sL 2y_z;O臞DD]_~:}#LCo:Agj4N9q4QR(KBD@)+R}bH+ҥ15G׺䔇z&.^`ô۷dDcM8@s^e'\c7~?Ecl7_~74|_uæWo򪵦a{>3gf&.@P6OJqI\״,7΍Rw ]xJ] @B Ph S/=S2b؏䃁ڟmy4^H",,;ILLF3 0 Yg`sD6x_ =3;98?yӝǮ?/,^uto/q_63َ uM7uwCSK(Wk81< #[lT[W_+SW840HſVrk/ܺ}ȿO(:Ξ?l[ϭ-JtGsiZ㔯T:MS*9p;[k\cGn[w_) ?PS_߻J?FBFG =kZ PJ @D!^ly$Y'+TIDATZ QlVX\g03QsfB`R$,"]*MXE1 +e1^z"\OU$W0XmʀkJ:CKq%"QCV33U~cA{(r 2rqb"]UdP.G cF @"HD,ȔjfMu=I4`K9tC>}{J)JU4|"XE\Jz1P *x ^ulWʍRAY~0[  9*~G)nօׂ)HJFRxY yު#cqUa T u~ $FgJC Rw{ms渦W(F0(D31`Cl{ $:Oh2C\הٰ[ǓfFNsөƨ% ))j[,&ED@3(0e LMNx;oyg"ֺ,_ 1\&d@ J6D jY34|@ uH)<ɻ?xo8:$@:'!AKHTM_?t48̇'Eaf#f$8". *4C |@L#:R"J&dPK ,`dF3u aةl%1sJDd>^QdTY}@hGDda @WΜɏ=x`"`q@UB@`b¨V^R9*BJ=xJDMaj0E|!%cutTm/J~?].擩t6BϭJGadUSTaQB̢JTo%:EEP̌ qٸ3ѓ4 dd|$a&Xd lUʃX>kA &;3˞ҿJk^{?01Aip?LtK䑡i:z48[u xRлck׆ ڋ,-,+vwbɶ#TU0J|SKs]C]`abzł(  @i 6+I11S-&oޛܒBB-W)||ZE{r^bQ/f)@<|?Ȥ|';;/9V[g{GG+/N(Wȇ"&Ŋ1Ϥ|R;7t߽g8|8o?{cG>|Kwڽw&찬X~OkvCJXzW/;|}`t`WDz6n&kc((}K(D/ 07eV"~B,;2).Gb , HU̓7ڭWz-4$HR mm6cնMfLP(q"_^^4! w=wuۏفB|dPڴ@~mekH)Jd&("rWSvLAhv}C?}lǮ_~t&-@ J-ˮkJјdk-Ns+itt'>~OJ&.~W-6=BD4pD=(3|޲-ӴC@ b0tH=(RD(*2`dM:IXҙRkuP*jz>AHR'6!Wȋ-ax] vbeqo)dwfvK H S0 ŦJXv{Y B+M[6r_IY)`HmvDCa@).]"(3~ȡU^9DNmZIJXɴaZ(6+@,NLT=y)pDď q? 4?6'fR*Sh?B_cSc}c=bпUOcBǁ{̜Φ&/MR,zoc&MJc{pW y_{>/of7n޴cw{e'_??O _?|NqBD*{'67>)fFڣfDiHR0 !4f="Ir H ` !†E 7lns5̊5@b6$w\w<f幏-=ÍM ]7^ D8zHDX/֊8آ9LZ7l&S.'/M$i=(tpRꋤ+ϽJ'˅Ѕr.I_8sl>{ͯoG Ts33{7>y13 RP~Lw2ĒivvH}3) K- `NZ~={iݏ;}偽m۹9U^x'P!噙1*lp Vr:m75DХiJ&V`Gtidrm Z驑-rQVnI2(eFyԙBHt.uYC)@\ B,f#G٨ɓ|"Ff|k1AB]} Eis3MӳDAS*bF!^??˶T8@JEBf' wX4H**¾D@3ֶ7m)=wv77\/j  k'VNv;S.`Iֶd?7:l)NG DB~!i5Yb$` F)PC!C5!#3PZ8l Lw۶cxpdW씆3/|OL׽X7n~o,;}i66516`,?n.[eb&O~?>ad`T.oߵY/p6n>OLJG;Șe[-mTH4EbFD!1J Ӑ' BgYPhCƣ"*t/flJ+OYZ+zsk2$ KHC9ׄc)Q335;11픝ѱN@}ྫ  {}ֶ֙c?`+E0>v)[ٹkG:kM*@``Wn>?׮:N8>K3xX>+嶛Ni7?W#;bzju vۺk@PTpaӖ{w?;t6~(4<4<;=;yi`ÇjkZZttolj;Y)B5{_۴y# ##ceW;?-Q1hAv_lOefۺqp HM]0--A/吗w. (:7GR42<׷{?3=  q~~BiܕIV@1?;_()@lljlhwU:^Z\ӕws;qfj&[ݲmk:4&4YX)۲luR-j- Ϟ[YZ۱WV cz/>F"'M#oNOvm޺c @:3<8X.i]sSsOܽwʾ[FZ@?}swox1e.8J[fү.nkm~vّk ˆ \j!}hso2Yz B%A!6رhRBX*xJXRAGD 5fAB`mkD:X oPƢ6df¤0,NpÀ3\rd<޸UO3VlLzD1ڬCE SF .EXa0m\iDc>X` EAB:o IXXƪ(1gr9,~J$.&&f:"=:!9io88vz|e=R:O!p2BA 7oز_д4_౔ 9iRBx~3<)؉eP #J~Pug:#LÅA1isCB*ŽA;8jA?EBBȈ8Gp?8HY!A?T&Rz6DpBH6~X?弫ChXJJCJCJӬM&rr[ΕXrUTJnokm'Ǡ^j˪ ~ [0a%7" <* Ƛ)fa4uYV1pU߸G^1+ʏzHBMBE+! yNЍJ0=y Ȭ|բ. S_E7*ӃCIENDB`mudlet-2.1/src/dlgColorTrigger.cpp0000644000175000017500000003522011513237311016541 0ustar csmallcsmall#include "dlgColorTrigger.h" /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "TTrigger.h" #include "dlgColorTrigger.h" #include "Host.h" #include "mudlet.h" #include "TTextEdit.h" dlgColorTrigger::dlgColorTrigger( QWidget * pF, TTrigger * pT, int mode ) : QDialog( pF ) , mpTrigger( pT ) , mMode( mode ) { // init generated dialog setupUi(this); connect(closeButton, SIGNAL(pressed()), this, SLOT(slot_save_and_exit())); connect(pushButton_black, SIGNAL(clicked()), this, SLOT(setColorBlack())); QPalette palette; QString styleSheet; QColor color; color = mpTrigger->mpHost->mBlack; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_black->setStyleSheet( styleSheet ); connect(pushButton_Lblack, SIGNAL(clicked()), this, SLOT(setColorLightBlack())); color = mpTrigger->mpHost->mLightBlack; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblack->setStyleSheet( styleSheet ); connect(pushButton_green, SIGNAL(clicked()), this, SLOT(setColorGreen())); color = mpTrigger->mpHost->mGreen; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_green->setStyleSheet( styleSheet ); connect(pushButton_Lgreen, SIGNAL(clicked()), this, SLOT(setColorLightGreen())); color = mpTrigger->mpHost->mLightGreen; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lgreen->setStyleSheet( styleSheet ); connect(pushButton_red, SIGNAL(clicked()), this, SLOT(setColorRed())); color = mpTrigger->mpHost->mRed; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_red->setStyleSheet( styleSheet ); connect(pushButton_Lred, SIGNAL(clicked()), this, SLOT(setColorLightRed())); color = mpTrigger->mpHost->mLightRed; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lred->setStyleSheet( styleSheet ); connect(pushButton_blue, SIGNAL(clicked()), this, SLOT(setColorBlue())); color = mpTrigger->mpHost->mBlue; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_blue->setStyleSheet( styleSheet ); connect(pushButton_Lblue, SIGNAL(clicked()), this, SLOT(setColorLightBlue())); color = mpTrigger->mpHost->mLightBlue; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblue->setStyleSheet( styleSheet ); connect(pushButton_yellow, SIGNAL(clicked()), this, SLOT(setColorYellow())); color = mpTrigger->mpHost->mYellow; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_yellow->setStyleSheet( styleSheet ); connect(pushButton_Lyellow, SIGNAL(clicked()), this, SLOT(setColorLightYellow())); color = mpTrigger->mpHost->mLightYellow; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lyellow->setStyleSheet( styleSheet ); connect(pushButton_cyan, SIGNAL(clicked()), this, SLOT(setColorCyan())); color = mpTrigger->mpHost->mCyan; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_cyan->setStyleSheet( styleSheet ); connect(pushButton_Lcyan, SIGNAL(clicked()), this, SLOT(setColorLightCyan())); color = mpTrigger->mpHost->mLightCyan; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lcyan->setStyleSheet( styleSheet ); connect(pushButton_magenta, SIGNAL(clicked()), this, SLOT(setColorMagenta())); color = mpTrigger->mpHost->mMagenta; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_magenta->setStyleSheet( styleSheet ); connect(pushButton_Lmagenta, SIGNAL(clicked()), this, SLOT(setColorLightMagenta())); color = mpTrigger->mpHost->mLightMagenta; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lmagenta->setStyleSheet( styleSheet ); connect(pushButton_white, SIGNAL(clicked()), this, SLOT(setColorWhite())); color = mpTrigger->mpHost->mWhite; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_white->setStyleSheet( styleSheet ); connect(pushButton_Lwhite, SIGNAL(clicked()), this, SLOT(setColorLightWhite())); color = mpTrigger->mpHost->mLightWhite; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lwhite->setStyleSheet( styleSheet ); } void dlgColorTrigger::setColorBlack() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 2; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mBlack; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 2; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mBlack; } close(); } void dlgColorTrigger::setColorLightBlack() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 1; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mLightBlack; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 1; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mLightBlack; } close(); } void dlgColorTrigger::setColorRed() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 4; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mRed; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 4; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mRed; } close(); } void dlgColorTrigger::setColorLightRed() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 3; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mLightRed; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 3; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mLightRed; } close(); } void dlgColorTrigger::setColorGreen() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 6; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mGreen; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 6; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mGreen; } close(); } void dlgColorTrigger::setColorLightGreen() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 5; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mLightGreen; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 5; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mLightGreen; } close(); } void dlgColorTrigger::setColorBlue() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 10; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mBlue; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 10; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mBlue; } close(); } void dlgColorTrigger::setColorLightBlue() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 9; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mLightBlue; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 9; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mLightBlue; } close(); } void dlgColorTrigger::setColorYellow() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 8; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mYellow; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 8; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mYellow; } close(); } void dlgColorTrigger::setColorLightYellow() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 7; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mLightYellow; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 7; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mLightYellow; } close(); } void dlgColorTrigger::setColorCyan() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 14; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mCyan; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 14; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mCyan; } close(); } void dlgColorTrigger::setColorLightCyan() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 13; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mLightCyan; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 13; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mLightCyan; } close(); } void dlgColorTrigger::setColorMagenta() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 12; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mMagenta; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 12; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mMagenta; } close(); } void dlgColorTrigger::setColorLightMagenta() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 11; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mLightMagenta; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 11; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mLightMagenta; } close(); } void dlgColorTrigger::setColorWhite() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 16; mpTrigger->mColorTriggerFgColor = mpTrigger->mpHost->mWhite; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 16; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mWhite; } close(); } void dlgColorTrigger::setColorLightWhite() { if( ! mpTrigger ) return; mpTrigger->mColorTrigger = true; if( mMode == 0 ) { mpTrigger->mColorTriggerFg = true; mpTrigger->mColorTriggerFgAnsi = 15; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mLightWhite; } else { mpTrigger->mColorTriggerBg = true; mpTrigger->mColorTriggerBgAnsi = 15; mpTrigger->mColorTriggerBgColor = mpTrigger->mpHost->mLightWhite; } close(); } void dlgColorTrigger::slot_save_and_exit() { if( mMode == 0 ) { mpTrigger->mColorTriggerBg = false; } else { mpTrigger->mColorTriggerFg = false; } close(); } mudlet-2.1/src/dlgMapper.cpp0000644000175000017500000003021012070466512015363 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn - KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "dlgMapper.h" #include "TDebug.h" #include "Host.h" #include #include #include #include dlgMapper::dlgMapper( QWidget * parent, Host * pH, TMap * pM ) : QWidget( parent ) , mpMap( pM ) , mpHost( pH ) { setupUi(this); glWidget->mpMap = pM; mp2dMap->mpMap = pM; mp2dMap->mpHost = pH; QMapIterator it( mpMap->areaNamesMap ); //sort them alphabetically (case sensitive) QMap areaNames; while( it.hasNext() ) { it.next(); QString name = it.value(); areaNames.insert(name.toLower(), name); } //areaNames.sort(); QMapIterator areaIt( areaNames ); while( areaIt.hasNext() ) { areaIt.next(); showArea->addItem( areaIt.value() ); } bubbles->setChecked( mpHost->mBubbleMode ); mp2dMap->mBubbleMode = mpHost->mBubbleMode; d3buttons->setVisible(false); roomSize->setValue(mpHost->mRoomSize*10); lineSize->setValue(mpHost->mLineSize); showInfo->setChecked( mpHost->mShowInfo ); mp2dMap->mShowInfo = mpHost->mShowInfo; showRoomIDs->setChecked( mpHost->mShowRoomID ); mp2dMap->mShowRoomID = mpHost->mShowRoomID; panel->setVisible(mpHost->mShowPanel); //searchList->setSelectionMode( QAbstractItemView::SingleSelection ); //connect(roomID, SIGNAL(returnPressed()), this, SLOT(goRoom())); connect(bubbles, SIGNAL(clicked()), this, SLOT(slot_bubbles())); connect(showInfo, SIGNAL(clicked()), this, SLOT(slot_info())); connect(ortho, SIGNAL(pressed()), glWidget, SLOT(fullView())); connect(singleLevel, SIGNAL(pressed()), glWidget, SLOT(singleView())); connect(increaseTop, SIGNAL(pressed()), glWidget, SLOT(increaseTop())); connect(increaseBottom, SIGNAL(pressed()), glWidget, SLOT(increaseBottom())); connect(reduceTop, SIGNAL(pressed()), glWidget, SLOT(reduceTop())); connect(reduceBottom, SIGNAL(pressed()), glWidget, SLOT(reduceBottom())); //connect(searchList, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(choseRoom(QListWidgetItem*))); connect(shiftZup, SIGNAL(pressed()), mp2dMap, SLOT(shiftZup())); connect(shiftZdown, SIGNAL(pressed()), mp2dMap, SLOT(shiftZdown())); connect(shiftLeft, SIGNAL(pressed()), mp2dMap, SLOT(shiftLeft())); connect(shiftRight, SIGNAL(pressed()), mp2dMap, SLOT(shiftRight())); connect(shiftUp, SIGNAL(pressed()), mp2dMap, SLOT(shiftUp())); connect(shiftDown, SIGNAL(pressed()), mp2dMap, SLOT(shiftDown())); connect(shiftZup, SIGNAL(pressed()), glWidget, SLOT(shiftZup())); connect(shiftZdown, SIGNAL(pressed()), glWidget, SLOT(shiftZdown())); connect(shiftLeft, SIGNAL(pressed()), glWidget, SLOT(shiftLeft())); connect(shiftRight, SIGNAL(pressed()), glWidget, SLOT(shiftRight())); connect(shiftUp, SIGNAL(pressed()), glWidget, SLOT(shiftUp())); connect(shiftDown, SIGNAL(pressed()), glWidget, SLOT(shiftDown())); connect(showInfo, SIGNAL(clicked()), glWidget, SLOT(showInfo())); connect(showArea, SIGNAL(activated(QString)), mp2dMap, SLOT(switchArea(QString))); connect(showArea, SIGNAL(activated(QString)), glWidget, SLOT(showArea(QString))); connect(defaultView, SIGNAL(pressed()), glWidget, SLOT(defaultView())); connect(dim2,SIGNAL(pressed()), this, SLOT(show2dView())); connect(sideView, SIGNAL(pressed()), glWidget, SLOT(sideView())); connect(topView, SIGNAL(pressed()), glWidget, SLOT(topView())); connect(togglePanel, SIGNAL(pressed()), this, SLOT(slot_togglePanel())); connect(lineSize, SIGNAL(valueChanged(int)), this, SLOT(slot_lineSize(int))); connect(roomSize, SIGNAL(valueChanged(int)), this, SLOT(slot_roomSize(int))); connect(scale, SIGNAL(valueChanged(int)), glWidget, SLOT(setScale(int))); connect(xRot, SIGNAL(valueChanged(int)), glWidget, SLOT(setXRotation(int))); connect(yRot, SIGNAL(valueChanged(int)), glWidget, SLOT(setYRotation(int))); connect(zRot, SIGNAL(valueChanged(int)), glWidget, SLOT(setZRotation(int))); mpDownloader = new QNetworkAccessManager( this ); connect(mpDownloader, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*))); connect(showRoomIDs, SIGNAL(stateChanged(int)), this, SLOT(slot_toggleShowRoomIDs(int))); mp2dMap->mFontHeight = QFontMetrics( mpHost->mDisplayFont ).height(); glWidget->hide(); mpMap->customEnvColors[257] = mpHost->mRed_2; mpMap->customEnvColors[258] = mpHost->mGreen_2; mpMap->customEnvColors[259] = mpHost->mYellow_2; mpMap->customEnvColors[260] = mpHost->mBlue_2; mpMap->customEnvColors[261] = mpHost->mMagenta_2; mpMap->customEnvColors[262] = mpHost->mCyan_2; mpMap->customEnvColors[263] = mpHost->mWhite_2; mpMap->customEnvColors[264] = mpHost->mBlack_2; mpMap->customEnvColors[265] = mpHost->mLightRed_2; mpMap->customEnvColors[266] = mpHost->mLightGreen_2; mpMap->customEnvColors[267] = mpHost->mLightYellow_2; mpMap->customEnvColors[268] = mpHost->mLightBlue_2; mpMap->customEnvColors[269] = mpHost->mLightMagenta_2; mpMap->customEnvColors[270] = mpHost->mLightCyan_2; mpMap->customEnvColors[271] = mpHost->mLightWhite_2; mpMap->customEnvColors[272] = mpHost->mLightBlack_2; qDebug()<<"dlgMapper constructor -> call T2DMap::init()"; mp2dMap->init(); } void dlgMapper::updateAreaComboBox() { QMapIterator it( mpMap->areaNamesMap ); //sort them alphabetically (case sensitive) QMap areaNames; while( it.hasNext() ) { it.next(); QString name = it.value(); areaNames.insert(name.toLower(), name); } //areaNames.sort(); QMapIterator areaIt( areaNames ); showArea->clear(); while( areaIt.hasNext() ) { areaIt.next(); showArea->addItem( areaIt.value() ); } } void dlgMapper::slot_toggleShowRoomIDs(int s) { if( s == Qt::Checked ) mp2dMap->mShowRoomID = true; else mp2dMap->mShowRoomID = false; mp2dMap->mpHost->mShowRoomID = mp2dMap->mShowRoomID; mp2dMap->update(); } void dlgMapper::slot_toggleStrongHighlight( int v ) { mpHost->mMapStrongHighlight = v == Qt::Checked ? true : false; mp2dMap->update(); } void dlgMapper::slot_togglePanel() { panel->setVisible(!panel->isVisible()); mpHost->mShowPanel = panel->isVisible(); } void dlgMapper::show2dView() { glWidget->setVisible(!glWidget->isVisible()); mp2dMap->setVisible(!mp2dMap->isVisible()); if(glWidget->isVisible()) d3buttons->setVisible(true); else d3buttons->setVisible(false); } void dlgMapper::downloadMap() { QString url = mpHost->mUrl; url.prepend("http://www."); url.append("/maps/map.xml"); //qDebug()<<"DOWNLOADING:"<get( QNetworkRequest( QUrl( url ) ) ); mpProgressDialog = new QProgressDialog("Downloading the map ...", "Abort", 0, 4000000, this); connect(mpReply, SIGNAL(downloadProgress( qint64, qint64 )), this, SLOT(setDownloadProgress(qint64,qint64))); connect(mpProgressDialog, SIGNAL(canceled()), this, SLOT(cancel())); mpProgressDialog->show(); } void dlgMapper::setDownloadProgress( qint64 got, qint64 tot ) { mpProgressDialog->setRange(0, static_cast(tot) ); mpProgressDialog->setValue(static_cast(got)); } void dlgMapper::cancel() { qDebug()<<"download was cancalled"; mpProgressDialog->close(); mpReply->abort(); mpHost->mpMap->init( mpHost ); glWidget->updateGL(); } #include "XMLimport.h" void dlgMapper::replyFinished( QNetworkReply * reply ) { //qDebug()<<"download complete!"; mpProgressDialog->close(); QString name = QDir::homePath()+"/.config/mudlet/profiles/"+mpHost->getName()+"/map.xml"; QFile file(name); file.open( QFile::WriteOnly ); file.write( reply->readAll() ); file.flush(); file.close(); if( ! file.open(QFile::ReadOnly | QFile::Text) ) { QMessageBox::warning(this, tr("Import Map Package:"), tr("Cannot read file %1:\n%2.") .arg(name) .arg(file.errorString())); return; } XMLimport reader( mpHost ); reader.importPackage( & file ); mpHost->mpMap->init( mpHost ); glWidget->updateGL(); if( mpHost->mpMap ) if( mpHost->mpMap->mpMapper ) mpHost->mpMap->mpMapper->updateAreaComboBox(); TEvent mapDownloadEvent; mapDownloadEvent.mArgumentList.append( "sysMapDownloadEvent" ); mapDownloadEvent.mArgumentTypeList.append(ARGUMENT_TYPE_STRING); mpHost->raiseEvent( & mapDownloadEvent ); } void dlgMapper::choseRoom(QListWidgetItem * pT ) { QString txt = pT->text(); QMapIterator it( mpMap->rooms ); while( it.hasNext() ) { it.next(); int i = it.key(); if( mpMap->rooms[i]->name == txt ) { qDebug()<<"found room id="<mTargetID = i; if( ! mpMap->findPath( mpMap->mRoomId, i ) ) { QString msg = "Cannot find a path to this room.\n"; mpHost->mpConsole->printSystemMessage(msg); } else mpMap->mpHost->startSpeedWalk(); break; } } mpHost->mpConsole->setFocus(); } void dlgMapper::goRoom() { // QString txt = roomID->text(); // searchList->clear(); // int id = txt.toInt(); // if( id != 0 && mpMap->rooms.contains( id ) ) // { // mpMap->mTargetID = id; // if( mpMap->findPath(0,0) ) // { // qDebug()<<"glwidget: starting speedwalk path length="<mPathList.size(); // mpMap->mpHost->startSpeedWalk(); // } // else // { // QString msg = "Cannot find a path to this room.\n"; // mpHost->mpConsole->printSystemMessage(msg); // } // } // else // { // QMapIterator it( mpMap->rooms ); // while( it.hasNext() ) // { // it.next(); // int i = it.key(); // if( mpMap->rooms[i]->name.contains( txt, Qt::CaseInsensitive ) ) // { // qDebug()<<"inserting match:"<addItem( mpMap->rooms[i]->name ); // } // } // } // mpHost->mpConsole->setFocus(); } void dlgMapper::slot_roomSize(int d) { float s = (float)d/10.0; mp2dMap->setRoomSize( s ); mp2dMap->update(); } void dlgMapper::slot_lineSize(int d) { mp2dMap->setExitSize( d ); mp2dMap->update(); } void dlgMapper::slot_bubbles() { mp2dMap->mBubbleMode = bubbles->isChecked(); mp2dMap->mpHost->mBubbleMode = mp2dMap->mBubbleMode; mp2dMap->update(); } void dlgMapper::slot_info() { mp2dMap->mShowInfo = showInfo->isChecked(); mp2dMap->mpHost->mShowInfo = mp2dMap->mShowInfo; mp2dMap->update(); } mudlet-2.1/src/TLabel.h0000644000175000017500000000456611647202526014301 0ustar csmallcsmall#ifndef TLABEL_H #define TLABEL_H /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "mudlet.h" #include "Host.h" #include #include "TEvent.h" class TEvent; class TLabel : public QLabel { Q_OBJECT public: TLabel( QWidget * pW=0 ); void setScript( Host * pHost, QString & func, TEvent * args ){ mpHost = pHost; mScript = func; mpParameters = args; } void setEnter( Host * pHost, QString & func, TEvent * args ){ mpHost = pHost; mEnter = func; mEnterParams = args; } void setLeave( Host * pHost, QString & func, TEvent * args ){ mpHost = pHost; mLeave = func; mLeaveParams = args; } void mousePressEvent( QMouseEvent * ); void leaveEvent(QEvent *); void enterEvent(QEvent *); Host * mpHost; QString mScript; QString mEnter; QString mLeave; TEvent * mpParameters; TEvent * mLeaveParams; TEvent * mEnterParams; bool mouseInside; public slots: signals: }; #endif // TLABEL_H mudlet-2.1/src/quazip/0000755000175000017500000000000012070466513014262 5ustar csmallcsmallmudlet-2.1/src/quazip/quazip-0.4.4/0000755000175000017500000000000012070466513016234 5ustar csmallcsmallmudlet-2.1/src/quazip/quazip-0.4.4/quazip.sln0000644000175000017500000000244512070466513020270 0ustar csmallcsmall Microsoft Visual Studio Solution File, Format Version 10.00 # Visual C++ Express 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qztest", "test\qztest.vcproj", "{7632B767-D089-4F15-8B1E-C4B3F9EBF592}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "quazip", "quazip\quazip.vcproj", "{E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {7632B767-D089-4F15-8B1E-C4B3F9EBF592}.Debug|Win32.ActiveCfg = Debug|Win32 {7632B767-D089-4F15-8B1E-C4B3F9EBF592}.Debug|Win32.Build.0 = Debug|Win32 {7632B767-D089-4F15-8B1E-C4B3F9EBF592}.Release|Win32.ActiveCfg = Release|Win32 {7632B767-D089-4F15-8B1E-C4B3F9EBF592}.Release|Win32.Build.0 = Release|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Debug|Win32.ActiveCfg = Debug|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Debug|Win32.Build.0 = Debug|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Release|Win32.ActiveCfg = Release|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal mudlet-2.1/src/quazip/quazip-0.4.4/NEWS0000644000175000017500000000706212070466513016740 0ustar csmallcsmallQuaZIP changes * 2012-01-14 0.4.4 * Fixed isSequential() test that was causing open() failures on Unix. * Fixed sub-directory compressing in JlCompress. * Added MS VS 2008 solution, compatible with the binary Qt distribution (tested on MS VS 2008 Express, had to run MOC manually due to the lack of plugin in Express). * Fixed extracting directories in JlCompress. * Fixed JlCompress.h includes in the test suite, which used lowercase names thus breaking on case-sensitive systems. * Implemented missing QuaZipFile::getZip() that was only declared. * Fixed reopening closed files. * Fixed possible memory leak in case of open error. * 2011-09-09 0.4.3 * New test suite using QTestLib. * Fixed bytesAvailable(), pos() and atEnd(). * Added ZIP v1.0 support and disabling data descriptor for compatibility with some older software. * Fixed DLL export/import issues for some symbols. * Added QUAZIP_STATIC macro for compiling as a static library or directly including the source. * Added getFileNameList() and getFileInfoList() convenience functions. * Added some buffering to JlCompress to improve performance. * 2011-08-10 0.4.2 * Cmake patch (thanks to Bernhard Rosenkraenzer). * Symbian patch (thanks to Hamish Willee). * Documented the multiple files limitation of QuaZipFile. * Fixed relative paths handling in JlCompress. * Fixed linking to MinGW zlib. * 2011-05-26 0.4.1 * License statement updated to avoid confusion. GPL license removed for the very same reason. * Parts of original package are now clearly marked as modified, just as their license requires. * 2011-05-23 0.4 * QuaZip and QuaZipFile classes now use the Pimpl idiom. This means that future releases will probably be binary compatible with this one, but it also means that this one is binary incompatible with the old ones. * IO API has been rewritten using QIODevice instead of standard C library. Among other things it means that QuaZip now supports files up to 4 GB in size instead of 2 GB. * Added QuaZip methods allowing access to ZIP files represented by any seekable QIODevice implementation (QBuffer is a good example). * 2010-07-23 0.3 * Fixed getComment() for global comments. * Added some useful classes for calculating checksums (thanks to Adam Walczak). * Added some utility classes for working with whole directories (thanks to Roberto Pompermaier). It would be nice if someone documents these in English, though. * Probably fixed some problems with passwords (thanks to Vasiliy Sorokin). I didn't test it, though. * 2008-09-17 0.2.3 * Fixed license notices in sources. * SVN * Fixed a small bug in QuaZipFile::atEnd(). * 2007-01-16 0.2.2 * Added LGPL as alternative license. * Added FAQ documentation page. * 2006-03-21 0.2.1 * Fixed setCommentCodec() bug. * Fixed bug that set month 1-12 instead of 0-11, as specified in zip.h. * Added workaround for Qt's bug that caused wrong timestamps. * Few documentation fixes and cosmetic changes. * 2005-07-08 0.2 * Write support. * Extended QuaZipFile API, including size(), *pos() functions. * Support for comments encoding/decoding. * 2005-07-01 0.1 * Initial version. mudlet-2.1/src/quazip/quazip-0.4.4/FindQuaZip.cmake0000644000175000017500000000133212070466513021247 0ustar csmallcsmallfind_package(Qt4) find_path(QuaZip_INCLUDE_DIR quazip.h ${CMAKE_INSTALL_PREFIX}/include/quazip ${CMAKE_INSTALL_PREFIX}/include /usr/include/quazip /usr/local/include/quazip ${QT_INCLUDE_DIR}/quazip ${QT_INCLUDE_DIR} ${QUAZIP_DIR}/include/quazip ${QUAZIP_DIR}/quazip ${QUAZIP_DIR}/include) find_library(QuaZip_LIBRARY NAMES quazip PATHS ${CMAKE_INSTALL_PREFIX}/lib64 ${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/Library/Frameworks ${QUAZIP_DIR}/lib64 ${QUAZIP_DIR}/lib ${QUAZIP_DIR}/quazip ${QUAZIP_DIR}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(quazip DEFAULT_MSG QuaZip_LIBRARY QuaZip_INCLUDE_DIR) set(QuaZip_LIBRARIES ${QuaZip_LIBRARY}) mark_as_advanced(QuaZip_LIBRARY QuaZip_INCLUDE_DIR) mudlet-2.1/src/quazip/quazip-0.4.4/quazip/0000755000175000017500000000000012070466513017545 5ustar csmallcsmallmudlet-2.1/src/quazip/quazip-0.4.4/quazip/quaadler32.cpp0000644000175000017500000000072112070466513022214 0ustar csmallcsmall#include "quaadler32.h" #include "zlib.h" QuaAdler32::QuaAdler32() { reset(); } quint32 QuaAdler32::calculate(const QByteArray &data) { return adler32( adler32(0L, Z_NULL, 0), (const Bytef*)data.data(), data.size() ); } void QuaAdler32::reset() { checksum = adler32(0L, Z_NULL, 0); } void QuaAdler32::update(const QByteArray &buf) { checksum = adler32( checksum, (const Bytef*)buf.data(), buf.size() ); } quint32 QuaAdler32::value() { return checksum; } mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazip.sln0000644000175000017500000000153612070466513021601 0ustar csmallcsmall Microsoft Visual Studio Solution File, Format Version 10.00 # Visual C++ Express 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "quazip", "quazip.vcproj", "{E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Debug|Win32.ActiveCfg = Debug|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Debug|Win32.Build.0 = Debug|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Release|Win32.ActiveCfg = Release|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal mudlet-2.1/src/quazip/quazip-0.4.4/quazip/qioapi.cpp0000644000175000017500000000650212070466513021536 0ustar csmallcsmall/* ioapi.c -- IO base function header for compress/uncompress .zip files using zlib + zip or unzip API Version 1.01e, February 12th, 2005 Copyright (C) 1998-2005 Gilles Vollant Modified by Sergey A. Tachenov to integrate with Qt. */ #include #include #include #include "zlib.h" #include "ioapi.h" #include "quazip_global.h" #include /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ #ifndef SEEK_CUR #define SEEK_CUR 1 #endif #ifndef SEEK_END #define SEEK_END 2 #endif #ifndef SEEK_SET #define SEEK_SET 0 #endif voidpf ZCALLBACK qiodevice_open_file_func ( voidpf opaque UNUSED, voidpf file, int mode) { QIODevice *iodevice = reinterpret_cast(file); if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) iodevice->open(QIODevice::ReadOnly); else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) iodevice->open(QIODevice::ReadWrite); else if (mode & ZLIB_FILEFUNC_MODE_CREATE) iodevice->open(QIODevice::WriteOnly); if (iodevice->isOpen()) { if (iodevice->isSequential()) { iodevice->close(); return NULL; } else { return iodevice; } } else return NULL; } uLong ZCALLBACK qiodevice_read_file_func ( voidpf opaque UNUSED, voidpf stream, void* buf, uLong size) { uLong ret; ret = (uLong)((QIODevice*)stream)->read((char*)buf,size); return ret; } uLong ZCALLBACK qiodevice_write_file_func ( voidpf opaque UNUSED, voidpf stream, const void* buf, uLong size) { uLong ret; ret = (uLong)((QIODevice*)stream)->write((char*)buf,size); return ret; } uLong ZCALLBACK qiodevice_tell_file_func ( voidpf opaque UNUSED, voidpf stream) { uLong ret; ret = ((QIODevice*)stream)->pos(); return ret; } int ZCALLBACK qiodevice_seek_file_func ( voidpf opaque UNUSED, voidpf stream, uLong offset, int origin) { uLong qiodevice_seek_result=0; int ret; switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR : qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset; break; case ZLIB_FILEFUNC_SEEK_END : qiodevice_seek_result = ((QIODevice*)stream)->size() - offset; break; case ZLIB_FILEFUNC_SEEK_SET : qiodevice_seek_result = offset; break; default: return -1; } ret = !((QIODevice*)stream)->seek(qiodevice_seek_result); return ret; } int ZCALLBACK qiodevice_close_file_func ( voidpf opaque UNUSED, voidpf stream) { ((QIODevice*)stream)->close(); return 0; } int ZCALLBACK qiodevice_error_file_func ( voidpf opaque UNUSED, voidpf stream) { return !((QIODevice*)stream)->errorString().isEmpty(); } void fill_qiodevice_filefunc ( zlib_filefunc_def* pzlib_filefunc_def) { pzlib_filefunc_def->zopen_file = qiodevice_open_file_func; pzlib_filefunc_def->zread_file = qiodevice_read_file_func; pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func; pzlib_filefunc_def->ztell_file = qiodevice_tell_file_func; pzlib_filefunc_def->zseek_file = qiodevice_seek_file_func; pzlib_filefunc_def->zclose_file = qiodevice_close_file_func; pzlib_filefunc_def->zerror_file = qiodevice_error_file_func; pzlib_filefunc_def->opaque = NULL; } mudlet-2.1/src/quazip/quazip-0.4.4/quazip/Makefile.Debug0000644000175000017500000002464212070466513022242 0ustar csmallcsmall############################################################################# # Makefile for building: quazip # Generated by qmake (2.01a) (Qt 4.7.4) on: So 24. Jun 14:17:20 2012 # Project: quazip.pro # Template: lib ############################################################################# ####### Compiler, tools and options CC = gcc CXX = g++ DEFINES = -DUNICODE -DQT_LARGEFILE_SUPPORT -DQUAZIP_BUILD -DQT_DLL -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT CFLAGS = -g -Wall $(DEFINES) CXXFLAGS = -g -Wall -frtti -fexceptions -mthreads $(DEFINES) INCPATH = -I"c:\QtSDK\Desktop\Qt\4.7.4\mingw\include\QtCore" -I"c:\QtSDK\Desktop\Qt\4.7.4\mingw\include" -I"." -I"c:\mudlet_package_MINGW\zlib-1.2.5" -I"c:\QtSDK\Desktop\Qt\4.7.4\mingw\include\ActiveQt" -I"debug" -I"c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\default" LINK = g++ LFLAGS = -mthreads -shared -Wl,--out-implib,debug\libquazip.a LIBS = -L"c:\QtSDK\Desktop\Qt\4.7.4\mingw\lib" -lQtCored4 QMAKE = c:\QtSDK\Desktop\Qt\4.7.4\mingw\bin\qmake.exe IDC = c:\QtSDK\Desktop\Qt\4.7.4\mingw\bin\idc.exe IDL = midl ZIP = zip -r -9 DEF_FILE = RES_FILE = COPY = copy /y COPY_FILE = $(COPY) COPY_DIR = xcopy /s /q /y /i DEL_FILE = del DEL_DIR = rmdir MOVE = move CHK_DIR_EXISTS= if not exist MKDIR = mkdir INSTALL_FILE = $(COPY_FILE) INSTALL_PROGRAM = $(COPY_FILE) INSTALL_DIR = $(COPY_DIR) ####### Output directory OBJECTS_DIR = debug ####### Files SOURCES = unzip.c \ zip.c \ JlCompress.cpp \ qioapi.cpp \ quaadler32.cpp \ quacrc32.cpp \ quazip.cpp \ quazipfile.cpp \ quazipnewinfo.cpp debug\moc_quazipfile.cpp OBJECTS = debug/unzip.o \ debug/zip.o \ debug/JlCompress.o \ debug/qioapi.o \ debug/quaadler32.o \ debug/quacrc32.o \ debug/quazip.o \ debug/quazipfile.o \ debug/quazipnewinfo.o \ debug/moc_quazipfile.o DIST = QMAKE_TARGET = quazip DESTDIR = debug\ #avoid trailing-slash linebreak TARGET = quazip.dll DESTDIR_TARGET = debug\quazip.dll ####### Implicit rules .SUFFIXES: .cpp .cc .cxx .c .cpp.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< .cc.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< .cxx.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< .c.o: $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< ####### Build rules first: all all: Makefile.Debug $(DESTDIR_TARGET) $(DESTDIR_TARGET): $(OBJECTS) $(LINK) $(LFLAGS) -o $(DESTDIR_TARGET) object_script.quazip.Debug $(LIBS) qmake: FORCE @$(QMAKE) -o Makefile.Debug quazip.pro dist: $(ZIP) quazip.zip $(SOURCES) $(DIST) quazip.pro c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\qconfig.pri c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\modules\qt_webkit_version.pri c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\qt_functions.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\qt_config.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\exclusive_builds.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\default_pre.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\default_pre.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\debug.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\debug_and_release.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\default_post.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\default_post.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\build_pass.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\warn_on.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\qt.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\thread.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\moc.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\rtti.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\exceptions.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\stl.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\shared.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\dll.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\windows.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\resources.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\uic.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\yacc.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\lex.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\include_source_dir.prf HEADERS RESOURCES IMAGES SOURCES OBJECTIVE_SOURCES FORMS YACCSOURCES YACCSOURCES LEXSOURCES clean: compiler_clean -$(DEL_FILE) debug\unzip.o debug\zip.o debug\JlCompress.o debug\qioapi.o debug\quaadler32.o debug\quacrc32.o debug\quazip.o debug\quazipfile.o debug\quazipnewinfo.o debug\moc_quazipfile.o -$(DEL_FILE) debug\libquazip.a distclean: clean -$(DEL_FILE) $(DESTDIR_TARGET) -$(DEL_FILE) Makefile.Debug check: first mocclean: compiler_moc_header_clean compiler_moc_source_clean mocables: compiler_moc_header_make_all compiler_moc_source_make_all compiler_moc_header_make_all: debug/moc_quazipfile.cpp compiler_moc_header_clean: -$(DEL_FILE) debug\moc_quazipfile.cpp debug/moc_quazipfile.cpp: quazip_global.h \ quazip.h \ zip.h \ ioapi.h \ unzip.h \ quazipfileinfo.h \ quazipnewinfo.h \ quazipfile.h C:\QtSDK\Desktop\Qt\4.7.4\mingw\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 quazipfile.h -o debug\moc_quazipfile.cpp compiler_rcc_make_all: compiler_rcc_clean: compiler_image_collection_make_all: qmake_image_collection.cpp compiler_image_collection_clean: -$(DEL_FILE) qmake_image_collection.cpp compiler_moc_source_make_all: compiler_moc_source_clean: compiler_uic_make_all: compiler_uic_clean: compiler_yacc_decl_make_all: compiler_yacc_decl_clean: compiler_yacc_impl_make_all: compiler_yacc_impl_clean: compiler_lex_make_all: compiler_lex_clean: compiler_clean: compiler_moc_header_clean ####### Compile debug/unzip.o: unzip.c unzip.h \ ioapi.h \ crypt.h \ quazip_global.h $(CC) -c $(CFLAGS) $(INCPATH) -o debug\unzip.o unzip.c debug/zip.o: zip.c zip.h \ ioapi.h \ quazip_global.h \ crypt.h $(CC) -c $(CFLAGS) $(INCPATH) -o debug\zip.o zip.c debug/JlCompress.o: JlCompress.cpp JlCompress.h \ quazip.h \ zip.h \ ioapi.h \ unzip.h \ quazip_global.h \ quazipfileinfo.h \ quazipfile.h \ quazipnewinfo.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug\JlCompress.o JlCompress.cpp debug/qioapi.o: qioapi.cpp ioapi.h \ quazip_global.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug\qioapi.o qioapi.cpp debug/quaadler32.o: quaadler32.cpp quaadler32.h \ quachecksum32.h \ quazip_global.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug\quaadler32.o quaadler32.cpp debug/quacrc32.o: quacrc32.cpp quacrc32.h \ quachecksum32.h \ quazip_global.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug\quacrc32.o quacrc32.cpp debug/quazip.o: quazip.cpp quazip.h \ zip.h \ ioapi.h \ unzip.h \ quazip_global.h \ quazipfileinfo.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug\quazip.o quazip.cpp debug/quazipfile.o: quazipfile.cpp quazipfile.h \ quazip_global.h \ quazip.h \ zip.h \ ioapi.h \ unzip.h \ quazipfileinfo.h \ quazipnewinfo.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug\quazipfile.o quazipfile.cpp debug/quazipnewinfo.o: quazipnewinfo.cpp quazipnewinfo.h \ quazip_global.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug\quazipnewinfo.o quazipnewinfo.cpp debug/moc_quazipfile.o: debug/moc_quazipfile.cpp $(CXX) -c $(CXXFLAGS) $(INCPATH) -o debug\moc_quazipfile.o debug\moc_quazipfile.cpp ####### Install install_headers: first FORCE @$(CHK_DIR_EXISTS) $(INSTALL_ROOT)\include\quazip $(MKDIR) $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\crypt.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\ioapi.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\JlCompress.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quaadler32.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quachecksum32.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quacrc32.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quazip.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quazipfile.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quazipfileinfo.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quazipnewinfo.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quazip_global.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\unzip.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\zip.h $(INSTALL_ROOT)\include\quazip uninstall_headers: FORCE -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\crypt.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\ioapi.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\JlCompress.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quaadler32.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quachecksum32.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quacrc32.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quazip.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quazipfile.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quazipfileinfo.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quazipnewinfo.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quazip_global.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\unzip.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\zip.h -$(DEL_DIR) $(INSTALL_ROOT)\include\quazip install_target: first FORCE @$(CHK_DIR_EXISTS) $(INSTALL_ROOT)\lib $(MKDIR) $(INSTALL_ROOT)\lib -$(INSTALL_FILE) "debug\libquazip.a" "$(INSTALL_ROOT)\lib\libquazip.a" -$(INSTALL_FILE) "debug\quazip.pdb" "$(INSTALL_ROOT)\lib\quazip.pdb" -$(INSTALL_FILE) "$(DESTDIR_TARGET)" "$(INSTALL_ROOT)\lib\$(TARGET)" uninstall_target: FORCE -$(DEL_FILE) "$(INSTALL_ROOT)\lib\libquazip.a" -$(DEL_FILE) "$(INSTALL_ROOT)\lib\quazip.pdb" -$(DEL_FILE) "$(INSTALL_ROOT)\lib\$(TARGET)" -$(DEL_DIR) $(INSTALL_ROOT)\lib install: install_headers install_target FORCE uninstall: uninstall_headers uninstall_target FORCE FORCE: mudlet-2.1/src/quazip/quazip-0.4.4/quazip/object_script.quazip.Debug0000644000175000017500000000031512070466513024656 0ustar csmallcsmallINPUT( ./debug\unzip.o ./debug\zip.o ./debug\JlCompress.o ./debug\qioapi.o ./debug\quaadler32.o ./debug\quacrc32.o ./debug\quazip.o ./debug\quazipfile.o ./debug\quazipnewinfo.o ./debug\moc_quazipfile.o ); mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazipnewinfo.cpp0000644000175000017500000000301412070466513023146 0ustar csmallcsmall/* Copyright (C) 2005-2011 Sergey A. Tachenov This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant, see quazip/(un)zip.h files for details, basically it's zlib license. */ #include #include "quazipnewinfo.h" QuaZipNewInfo::QuaZipNewInfo(const QString& name): name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0) { } QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file): name(name), internalAttr(0), externalAttr(0) { QFileInfo info(file); QDateTime lm = info.lastModified(); if (!info.exists()) dateTime = QDateTime::currentDateTime(); else dateTime = lm; } void QuaZipNewInfo::setFileDateTime(const QString& file) { QFileInfo info(file); QDateTime lm = info.lastModified(); if (info.exists()) dateTime = lm; } mudlet-2.1/src/quazip/quazip-0.4.4/quazip/zip.c0000644000175000017500000011445412070466513020524 0ustar csmallcsmall/* zip.c -- IO on .zip files using zlib Version 1.01e, February 12th, 2005 27 Dec 2004 Rolf Kalbermatter Modification to zipOpen2 to support globalComment retrieval. Copyright (C) 1998-2005 Gilles Vollant Read zip.h for more info Modified by Sergey A. Tachenov to integrate with Qt. */ #include #include #include #include #include "zlib.h" #include "zip.h" #include "quazip_global.h" #ifdef STDC # include # include # include #endif #ifdef NO_ERRNO_H extern int errno; #else # include #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ #ifndef VERSIONMADEBY # define VERSIONMADEBY (0x031e) /* best for standard pkware crypt */ #endif #ifndef Z_BUFSIZE #define Z_BUFSIZE (16384) #endif #ifndef Z_MAXFILENAMEINZIP #define Z_MAXFILENAMEINZIP (256) #endif #ifndef ALLOC # define ALLOC(size) (malloc(size)) #endif #ifndef TRYFREE # define TRYFREE(p) {if (p) free(p);} #endif /* #define SIZECENTRALDIRITEM (0x2e) #define SIZEZIPLOCALHEADER (0x1e) */ /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ #ifndef SEEK_CUR #define SEEK_CUR 1 #endif #ifndef SEEK_END #define SEEK_END 2 #endif #ifndef SEEK_SET #define SEEK_SET 0 #endif #ifndef DEF_MEM_LEVEL #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif #endif const char zip_copyright[] = " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; #define SIZEDATA_INDATABLOCK (4096-(4*4)) #define LOCALHEADERMAGIC (0x04034b50) #define DESCRIPTORHEADERMAGIC (0x08074b50) #define CENTRALHEADERMAGIC (0x02014b50) #define ENDHEADERMAGIC (0x06054b50) #define FLAG_LOCALHEADER_OFFSET (0x06) #define CRC_LOCALHEADER_OFFSET (0x0e) #define SIZECENTRALHEADER (0x2e) /* 46 */ typedef struct linkedlist_datablock_internal_s { struct linkedlist_datablock_internal_s* next_datablock; uLong avail_in_this_block; uLong filled_in_this_block; uLong unused; /* for future use and alignement */ unsigned char data[SIZEDATA_INDATABLOCK]; } linkedlist_datablock_internal; typedef struct linkedlist_data_s { linkedlist_datablock_internal* first_block; linkedlist_datablock_internal* last_block; } linkedlist_data; typedef struct { z_stream stream; /* zLib stream structure for inflate */ int stream_initialised; /* 1 is stream is initialised */ uInt pos_in_buffered_data; /* last written byte in buffered_data */ uLong pos_local_header; /* offset of the local header of the file currenty writing */ char* central_header; /* central header data for the current file */ uLong size_centralheader; /* size of the central header for cur file */ uLong flag; /* flag of the file currently writing */ int method; /* compression method of file currenty wr.*/ int raw; /* 1 for directly writing raw data */ Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ uLong dosDate; uLong crc32; int encrypt; #ifndef NOCRYPT unsigned long keys[3]; /* keys defining the pseudo-random sequence */ const unsigned long* pcrc_32_tab; int crypt_header_size; #endif } curfile_info; typedef struct { zlib_filefunc_def z_filefunc; voidpf filestream; /* io structore of the zipfile */ linkedlist_data central_dir;/* datablock with central dir in construction*/ int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ curfile_info ci; /* info on the file curretly writing */ uLong begin_pos; /* position of the beginning of the zipfile */ uLong add_position_when_writting_offset; uLong number_entry; #ifndef NO_ADDFILEINEXISTINGZIP char *globalcomment; #endif unsigned flags; } zip_internal; #ifndef NOCRYPT #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED #include "crypt.h" #endif local linkedlist_datablock_internal* allocate_new_datablock() { linkedlist_datablock_internal* ldi; ldi = (linkedlist_datablock_internal*) ALLOC(sizeof(linkedlist_datablock_internal)); if (ldi!=NULL) { ldi->next_datablock = NULL ; ldi->filled_in_this_block = 0 ; ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; } return ldi; } local void free_datablock(ldi) linkedlist_datablock_internal* ldi; { while (ldi!=NULL) { linkedlist_datablock_internal* ldinext = ldi->next_datablock; TRYFREE(ldi); ldi = ldinext; } } local void init_linkedlist(ll) linkedlist_data* ll; { ll->first_block = ll->last_block = NULL; } #if 0 // unused local void free_linkedlist(ll) linkedlist_data* ll; { free_datablock(ll->first_block); ll->first_block = ll->last_block = NULL; } #endif local int add_data_in_datablock(ll,buf,len) linkedlist_data* ll; const void* buf; uLong len; { linkedlist_datablock_internal* ldi; const unsigned char* from_copy; if (ll==NULL) return ZIP_INTERNALERROR; if (ll->last_block == NULL) { ll->first_block = ll->last_block = allocate_new_datablock(); if (ll->first_block == NULL) return ZIP_INTERNALERROR; } ldi = ll->last_block; from_copy = (unsigned char*)buf; while (len>0) { uInt copy_this; uInt i; unsigned char* to_copy; if (ldi->avail_in_this_block==0) { ldi->next_datablock = allocate_new_datablock(); if (ldi->next_datablock == NULL) return ZIP_INTERNALERROR; ldi = ldi->next_datablock ; ll->last_block = ldi; } if (ldi->avail_in_this_block < len) copy_this = (uInt)ldi->avail_in_this_block; else copy_this = (uInt)len; to_copy = &(ldi->data[ldi->filled_in_this_block]); for (i=0;ifilled_in_this_block += copy_this; ldi->avail_in_this_block -= copy_this; from_copy += copy_this ; len -= copy_this; } return ZIP_OK; } /****************************************************************************/ #ifndef NO_ADDFILEINEXISTINGZIP /* =========================================================================== Inputs a long in LSB order to the given file nbByte == 1, 2 or 4 (byte, short or long) */ local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream, uLong x, int nbByte)); local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte) const zlib_filefunc_def* pzlib_filefunc_def; voidpf filestream; uLong x; int nbByte; { unsigned char buf[4]; int n; for (n = 0; n < nbByte; n++) { buf[n] = (unsigned char)(x & 0xff); x >>= 8; } if (x != 0) { /* data overflow - hack for ZIP64 (X Roche) */ for (n = 0; n < nbByte; n++) { buf[n] = 0xff; } } if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) return ZIP_ERRNO; else return ZIP_OK; } local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte)); local void ziplocal_putValue_inmemory (dest, x, nbByte) void* dest; uLong x; int nbByte; { unsigned char* buf=(unsigned char*)dest; int n; for (n = 0; n < nbByte; n++) { buf[n] = (unsigned char)(x & 0xff); x >>= 8; } if (x != 0) { /* data overflow - hack for ZIP64 */ for (n = 0; n < nbByte; n++) { buf[n] = 0xff; } } } /****************************************************************************/ local uLong ziplocal_TmzDateToDosDate(ptm,dosDate) const tm_zip* ptm; uLong dosDate UNUSED; { uLong year = (uLong)ptm->tm_year; if (year>1980) year-=1980; else if (year>80) year-=80; return (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); } /****************************************************************************/ local int ziplocal_getByte OF(( const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream, int *pi)); local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi) const zlib_filefunc_def* pzlib_filefunc_def; voidpf filestream; int *pi; { unsigned char c; int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); if (err==1) { *pi = (int)c; return ZIP_OK; } else { if (ZERROR(*pzlib_filefunc_def,filestream)) return ZIP_ERRNO; else return ZIP_EOF; } } /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ local int ziplocal_getShort OF(( const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX) const zlib_filefunc_def* pzlib_filefunc_def; voidpf filestream; uLong *pX; { uLong x ; int i; int err; err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); x = (uLong)i; if (err==ZIP_OK) err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<8; if (err==ZIP_OK) *pX = x; else *pX = 0; return err; } local int ziplocal_getLong OF(( const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX) const zlib_filefunc_def* pzlib_filefunc_def; voidpf filestream; uLong *pX; { uLong x ; int i; int err; err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); x = (uLong)i; if (err==ZIP_OK) err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<8; if (err==ZIP_OK) err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<16; if (err==ZIP_OK) err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<24; if (err==ZIP_OK) *pX = x; else *pX = 0; return err; } #ifndef BUFREADCOMMENT #define BUFREADCOMMENT (0x400) #endif /* Locate the Central directory of a zipfile (at the end, just before the global comment) */ local uLong ziplocal_SearchCentralDir OF(( const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream)); local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream) const zlib_filefunc_def* pzlib_filefunc_def; voidpf filestream; { unsigned char* buf; uLong uSizeFile; uLong uBackRead; uLong uMaxBack=0xffff; /* maximum size of global comment */ uLong uPosFound=0; if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0; uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) return 0; uBackRead = 4; while (uBackReaduMaxBack) uBackRead = uMaxBack; else uBackRead+=BUFREADCOMMENT; uReadPos = uSizeFile-uBackRead ; uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) break; if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; for (i=(int)uReadSize-3; (i--)>0;) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { uPosFound = uReadPos+i; break; } if (uPosFound!=0) break; } TRYFREE(buf); return uPosFound; } #endif /* !NO_ADDFILEINEXISTINGZIP*/ /************************************************************/ extern zipFile ZEXPORT zipOpen2 (file, append, globalcomment, pzlib_filefunc_def) voidpf file; int append; zipcharpc* globalcomment; zlib_filefunc_def* pzlib_filefunc_def; { zip_internal ziinit; zip_internal* zi; int err=ZIP_OK; if (pzlib_filefunc_def==NULL) fill_qiodevice_filefunc(&ziinit.z_filefunc); else ziinit.z_filefunc = *pzlib_filefunc_def; ziinit.filestream = (*(ziinit.z_filefunc.zopen_file)) (ziinit.z_filefunc.opaque, file, (append == APPEND_STATUS_CREATE) ? (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); if (ziinit.filestream == NULL) return NULL; ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream); ziinit.in_opened_file_inzip = 0; ziinit.ci.stream_initialised = 0; ziinit.number_entry = 0; ziinit.add_position_when_writting_offset = 0; ziinit.flags = ZIP_WRITE_DATA_DESCRIPTOR; init_linkedlist(&(ziinit.central_dir)); zi = (zip_internal*)ALLOC(sizeof(zip_internal)); if (zi==NULL) { ZCLOSE(ziinit.z_filefunc,ziinit.filestream); return NULL; } /* now we add file in a zipfile */ # ifndef NO_ADDFILEINEXISTINGZIP ziinit.globalcomment = NULL; if (append == APPEND_STATUS_ADDINZIP) { uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ uLong size_central_dir; /* size of the central directory */ uLong offset_central_dir; /* offset of start of central directory */ uLong central_pos,uL; uLong number_disk; /* number of the current dist, used for spaning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used for spaning ZIP, unsupported, always 0*/ uLong number_entry; uLong number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ uLong size_comment; central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream); if (central_pos==0) err=ZIP_ERRNO; if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) err=ZIP_ERRNO; /* the signature, already checked */ if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK) err=ZIP_ERRNO; /* number of this disk */ if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK) err=ZIP_ERRNO; /* number of the disk with the start of the central directory */ if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK) err=ZIP_ERRNO; /* total number of entries in the central dir on this disk */ if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK) err=ZIP_ERRNO; /* total number of entries in the central dir */ if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK) err=ZIP_ERRNO; if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=ZIP_BADZIPFILE; /* size of the central directory */ if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK) err=ZIP_ERRNO; /* offset of start of central directory with respect to the starting disk number */ if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK) err=ZIP_ERRNO; /* zipfile global comment length */ if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK) err=ZIP_ERRNO; if ((central_pos0) { ziinit.globalcomment = ALLOC(size_comment+1); if (ziinit.globalcomment) { size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment); ziinit.globalcomment[size_comment]=0; } } byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); ziinit.add_position_when_writting_offset = byte_before_the_zipfile; { uLong size_central_dir_to_read = size_central_dir; size_t buf_size = SIZEDATA_INDATABLOCK; void* buf_read = (void*)ALLOC(buf_size); if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) err=ZIP_ERRNO; while ((size_central_dir_to_read>0) && (err==ZIP_OK)) { uLong read_this = SIZEDATA_INDATABLOCK; if (read_this > size_central_dir_to_read) read_this = size_central_dir_to_read; if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this) err=ZIP_ERRNO; if (err==ZIP_OK) err = add_data_in_datablock(&ziinit.central_dir,buf_read, (uLong)read_this); size_central_dir_to_read-=read_this; } TRYFREE(buf_read); } ziinit.begin_pos = byte_before_the_zipfile; ziinit.number_entry = number_entry_CD; if (ZSEEK(ziinit.z_filefunc, ziinit.filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) err=ZIP_ERRNO; } if (globalcomment) { *globalcomment = ziinit.globalcomment; } # endif /* !NO_ADDFILEINEXISTINGZIP*/ if (err != ZIP_OK) { # ifndef NO_ADDFILEINEXISTINGZIP TRYFREE(ziinit.globalcomment); # endif /* !NO_ADDFILEINEXISTINGZIP*/ TRYFREE(zi); return NULL; } else { *zi = ziinit; return (zipFile)zi; } } extern zipFile ZEXPORT zipOpen (file, append) voidpf file; int append; { return zipOpen2(file,append,NULL,NULL); } extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, strategy, password, crcForCrypting) zipFile file; const char* filename; const zip_fileinfo* zipfi; const void* extrafield_local; uInt size_extrafield_local; const void* extrafield_global; uInt size_extrafield_global; const char* comment; int method; int level; int raw; int windowBits; int memLevel; int strategy; const char* password; uLong crcForCrypting; { zip_internal* zi; uInt size_filename; uInt size_comment; uInt i; int err = ZIP_OK; uLong version_to_extract; # ifdef NOCRYPT if (password != NULL) return ZIP_PARAMERROR; # endif if (file == NULL) return ZIP_PARAMERROR; if ((method!=0) && (method!=Z_DEFLATED)) return ZIP_PARAMERROR; zi = (zip_internal*)file; if (zi->in_opened_file_inzip == 1) { err = zipCloseFileInZip (file); if (err != ZIP_OK) return err; } if (method == 0 && (level == 0 || (zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) == 0)) { version_to_extract = 10; } else { version_to_extract = 20; } if (filename==NULL) filename="-"; if (comment==NULL) size_comment = 0; else size_comment = (uInt)strlen(comment); size_filename = (uInt)strlen(filename); if (zipfi == NULL) zi->ci.dosDate = 0; else { if (zipfi->dosDate != 0) zi->ci.dosDate = zipfi->dosDate; else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate); } zi->ci.flag = 0; if ((level==8) || (level==9)) zi->ci.flag |= 2; if ((level==2)) zi->ci.flag |= 4; if ((level==1)) zi->ci.flag |= 6; if (password != NULL) { zi->ci.flag |= 1; } if (version_to_extract >= 20 && (zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) != 0) zi->ci.flag |= 8; zi->ci.crc32 = 0; zi->ci.method = method; zi->ci.encrypt = 0; zi->ci.stream_initialised = 0; zi->ci.pos_in_buffered_data = 0; zi->ci.raw = raw; zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ; zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader); ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); /* version info */ ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2); ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)version_to_extract,2); ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ if (zipfi==NULL) ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); else ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); if (zipfi==NULL) ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); else ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4); for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = *(((const char*)extrafield_global)+i); for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ size_extrafield_global+i) = *(comment+i); if (zi->ci.central_header == NULL) return ZIP_INTERNALERROR; /* write the local header */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4); if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)version_to_extract,2); if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2); if ((err==ZIP_OK) && (size_filename>0)) if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) err = ZIP_ERRNO; if ((err==ZIP_OK) && (size_extrafield_local>0)) if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local) !=size_extrafield_local) err = ZIP_ERRNO; zi->ci.stream.avail_in = (uInt)0; zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; zi->ci.stream.next_out = zi->ci.buffered_data; zi->ci.stream.total_in = 0; zi->ci.stream.total_out = 0; if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) { zi->ci.stream.zalloc = (alloc_func)0; zi->ci.stream.zfree = (free_func)0; zi->ci.stream.opaque = (voidpf)0; if (windowBits>0) windowBits = -windowBits; err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); if (err==Z_OK) zi->ci.stream_initialised = 1; } # ifndef NOCRYPT zi->ci.crypt_header_size = 0; if ((err==Z_OK) && (password != NULL)) { unsigned char bufHead[RAND_HEAD_LEN]; unsigned int sizeHead; zi->ci.encrypt = 1; zi->ci.pcrc_32_tab = get_crc_table(); /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ crcForCrypting = (uLong)zi->ci.dosDate << 16; // ATTANTION! Without this row, you don't unpack your password protected archive in other app. sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); zi->ci.crypt_header_size = sizeHead; if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) err = ZIP_ERRNO; } # endif if (err==Z_OK) zi->in_opened_file_inzip = 1; return err; } extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, raw) zipFile file; const char* filename; const zip_fileinfo* zipfi; const void* extrafield_local; uInt size_extrafield_local; const void* extrafield_global; uInt size_extrafield_global; const char* comment; int method; int level; int raw; { return zipOpenNewFileInZip3 (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0); } extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level) zipFile file; const char* filename; const zip_fileinfo* zipfi; const void* extrafield_local; uInt size_extrafield_local; const void* extrafield_global; uInt size_extrafield_global; const char* comment; int method; int level; { return zipOpenNewFileInZip2 (file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global, size_extrafield_global, comment, method, level, 0); } local int zipFlushWriteBuffer(zi) zip_internal* zi; { int err=ZIP_OK; if (zi->ci.encrypt != 0) { #ifndef NOCRYPT uInt i; int t; for (i=0;ici.pos_in_buffered_data;i++) zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); #endif } if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) !=zi->ci.pos_in_buffered_data) err = ZIP_ERRNO; zi->ci.pos_in_buffered_data = 0; return err; } extern int ZEXPORT zipWriteInFileInZip (file, buf, len) zipFile file; const void* buf; unsigned len; { zip_internal* zi; int err=ZIP_OK; if (file == NULL) return ZIP_PARAMERROR; zi = (zip_internal*)file; if (zi->in_opened_file_inzip == 0) return ZIP_PARAMERROR; zi->ci.stream.next_in = (void*)buf; zi->ci.stream.avail_in = len; zi->ci.crc32 = crc32(zi->ci.crc32,buf,len); while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) { if (zi->ci.stream.avail_out == 0) { if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) err = ZIP_ERRNO; zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; zi->ci.stream.next_out = zi->ci.buffered_data; } if(err != ZIP_OK) break; if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) { uLong uTotalOutBefore = zi->ci.stream.total_out; err=deflate(&zi->ci.stream, Z_NO_FLUSH); zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; } else { uInt copy_this,i; if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) copy_this = zi->ci.stream.avail_in; else copy_this = zi->ci.stream.avail_out; for (i=0;ici.stream.next_out)+i) = *(((const char*)zi->ci.stream.next_in)+i); { zi->ci.stream.avail_in -= copy_this; zi->ci.stream.avail_out-= copy_this; zi->ci.stream.next_in+= copy_this; zi->ci.stream.next_out+= copy_this; zi->ci.stream.total_in+= copy_this; zi->ci.stream.total_out+= copy_this; zi->ci.pos_in_buffered_data += copy_this; } } } return err; } extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32) zipFile file; uLong uncompressed_size; uLong crc32; { zip_internal* zi; uLong compressed_size; int err=ZIP_OK; if (file == NULL) return ZIP_PARAMERROR; zi = (zip_internal*)file; if (zi->in_opened_file_inzip == 0) return ZIP_PARAMERROR; zi->ci.stream.avail_in = 0; if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) while (err==ZIP_OK) { uLong uTotalOutBefore; if (zi->ci.stream.avail_out == 0) { if (zipFlushWriteBuffer(zi) == ZIP_ERRNO) err = ZIP_ERRNO; zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; zi->ci.stream.next_out = zi->ci.buffered_data; } uTotalOutBefore = zi->ci.stream.total_out; err=deflate(&zi->ci.stream, Z_FINISH); zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; } if (err==Z_STREAM_END) err=ZIP_OK; /* this is normal */ if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) if (zipFlushWriteBuffer(zi)==ZIP_ERRNO) err = ZIP_ERRNO; if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) { err=deflateEnd(&zi->ci.stream); zi->ci.stream_initialised = 0; } if (!zi->ci.raw) { crc32 = (uLong)zi->ci.crc32; uncompressed_size = (uLong)zi->ci.stream.total_in; } compressed_size = (uLong)zi->ci.stream.total_out; # ifndef NOCRYPT compressed_size += zi->ci.crypt_header_size; # endif ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ ziplocal_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ if (zi->ci.stream.data_type == Z_ASCII) ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); ziplocal_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ if (err==ZIP_OK) err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header, (uLong)zi->ci.size_centralheader); free(zi->ci.central_header); if (err==ZIP_OK) { uLong cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); if (ZSEEK(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) err = ZIP_ERRNO; if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ if (err==ZIP_OK) /* compressed size, unknown */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); if (err==ZIP_OK) /* uncompressed size, unknown */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); if (ZSEEK(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) err = ZIP_ERRNO; if ((zi->ci.flag & 8) != 0) { /* Write local Descriptor after file data */ if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)DESCRIPTORHEADERMAGIC,4); if (err==ZIP_OK) err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ if (err==ZIP_OK) /* compressed size, unknown */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); if (err==ZIP_OK) /* uncompressed size, unknown */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); } } zi->number_entry ++; zi->in_opened_file_inzip = 0; return err; } extern int ZEXPORT zipCloseFileInZip (file) zipFile file; { return zipCloseFileInZipRaw (file,0,0); } extern int ZEXPORT zipClose (file, global_comment) zipFile file; const char* global_comment; { zip_internal* zi; int err = 0; uLong size_centraldir = 0; uLong centraldir_pos_inzip; uInt size_global_comment; if (file == NULL) return ZIP_PARAMERROR; zi = (zip_internal*)file; if (zi->in_opened_file_inzip == 1) { err = zipCloseFileInZip (file); } #ifndef NO_ADDFILEINEXISTINGZIP if (global_comment==NULL) global_comment = zi->globalcomment; #endif if (global_comment==NULL) size_global_comment = 0; else size_global_comment = (uInt)strlen(global_comment); centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); if (err==ZIP_OK) { linkedlist_datablock_internal* ldi = zi->central_dir.first_block ; while (ldi!=NULL) { if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) if (ZWRITE(zi->z_filefunc,zi->filestream, ldi->data,ldi->filled_in_this_block) !=ldi->filled_in_this_block ) err = ZIP_ERRNO; size_centraldir += ldi->filled_in_this_block; ldi = ldi->next_datablock; } } free_datablock(zi->central_dir.first_block); if (err==ZIP_OK) /* Magic End */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); if (err==ZIP_OK) /* number of this disk */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); if (err==ZIP_OK) /* number of the disk with the start of the central directory */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); if (err==ZIP_OK) /* total number of entries in the central dir */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); if (err==ZIP_OK) /* size of the central directory */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); if (err==ZIP_OK) /* zipfile comment length */ err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); if ((err==ZIP_OK) && (size_global_comment>0)) if (ZWRITE(zi->z_filefunc,zi->filestream, global_comment,size_global_comment) != size_global_comment) err = ZIP_ERRNO; if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0) if (err == ZIP_OK) err = ZIP_ERRNO; #ifndef NO_ADDFILEINEXISTINGZIP TRYFREE(zi->globalcomment); #endif TRYFREE(zi); return err; } extern int ZEXPORT zipSetFlags(zipFile file, unsigned flags) { zip_internal* zi; if (file == NULL) return ZIP_PARAMERROR; zi = (zip_internal*)file; zi->flags |= flags; return ZIP_OK; } extern int ZEXPORT zipClearFlags(zipFile file, unsigned flags) { zip_internal* zi; if (file == NULL) return ZIP_PARAMERROR; zi = (zip_internal*)file; zi->flags &= ~flags; return ZIP_OK; } mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazip.h0000644000175000017500000004242012070466513021231 0ustar csmallcsmall#ifndef QUA_ZIP_H #define QUA_ZIP_H /* Copyright (C) 2005-2011 Sergey A. Tachenov This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant, see quazip/(un)zip.h files for details, basically it's zlib license. **/ #include #include #include #include "zip.h" #include "unzip.h" #include "quazip_global.h" #include "quazipfileinfo.h" // just in case it will be defined in the later versions of the ZIP/UNZIP #ifndef UNZ_OPENERROR // define additional error code #define UNZ_OPENERROR -1000 #endif class QuaZipPrivate; /// ZIP archive. /** \class QuaZip quazip.h * This class implements basic interface to the ZIP archive. It can be * used to read table contents of the ZIP archive and retreiving * information about the files inside it. * * You can also use this class to open files inside archive by passing * pointer to the instance of this class to the constructor of the * QuaZipFile class. But see QuaZipFile::QuaZipFile(QuaZip*, QObject*) * for the possible pitfalls. * * This class is indended to provide interface to the ZIP subpackage of * the ZIP/UNZIP package as well as to the UNZIP subpackage. But * currently it supports only UNZIP. * * The use of this class is simple - just create instance using * constructor, then set ZIP archive file name using setFile() function * (if you did not passed the name to the constructor), then open() and * then use different functions to work with it! Well, if you are * paranoid, you may also wish to call close before destructing the * instance, to check for errors on close. * * You may also use getUnzFile() and getZipFile() functions to get the * ZIP archive handle and use it with ZIP/UNZIP package API directly. * * This class supports localized file names inside ZIP archive, but you * have to set up proper codec with setCodec() function. By default, * locale codec will be used, which is probably ok for UNIX systems, but * will almost certainly fail with ZIP archives created in Windows. This * is because Windows ZIP programs have strange habit of using DOS * encoding for file names in ZIP archives. For example, ZIP archive * with cyrillic names created in Windows will have file names in \c * IBM866 encoding instead of \c WINDOWS-1251. I think that calling one * function is not much trouble, but for true platform independency it * would be nice to have some mechanism for file name encoding auto * detection using locale information. Does anyone know a good way to do * it? **/ class QUAZIP_EXPORT QuaZip { friend class QuaZipPrivate; public: /// Useful constants. enum Constants { MAX_FILE_NAME_LENGTH=256 /**< Maximum file name length. Taken from \c UNZ_MAXFILENAMEINZIP constant in unzip.c. */ }; /// Open mode of the ZIP file. enum Mode { mdNotOpen, ///< ZIP file is not open. This is the initial mode. mdUnzip, ///< ZIP file is open for reading files inside it. mdCreate, ///< ZIP file was created with open() call. mdAppend, /**< ZIP file was opened in append mode. This refers to * \c APPEND_STATUS_CREATEAFTER mode in ZIP/UNZIP package * and means that zip is appended to some existing file * what is useful when that file contains * self-extractor code. This is obviously \em not what * you whant to use to add files to the existing ZIP * archive. **/ mdAdd ///< ZIP file was opened for adding files in the archive. }; /// Case sensitivity for the file names. /** This is what you specify when accessing files in the archive. * Works perfectly fine with any characters thanks to Qt's great * unicode support. This is different from ZIP/UNZIP API, where * only US-ASCII characters was supported. **/ enum CaseSensitivity { csDefault=0, ///< Default for platform. Case sensitive for UNIX, not for Windows. csSensitive=1, ///< Case sensitive. csInsensitive=2 ///< Case insensitive. }; private: QuaZipPrivate *p; // not (and will not be) implemented QuaZip(const QuaZip& that); // not (and will not be) implemented QuaZip& operator=(const QuaZip& that); public: /// Constructs QuaZip object. /** Call setName() before opening constructed object. */ QuaZip(); /// Constructs QuaZip object associated with ZIP file \a zipName. QuaZip(const QString& zipName); /// Constructs QuaZip object associated with ZIP file represented by \a ioDevice. /** The IO device must be seekable, otherwise an error will occur when opening. */ QuaZip(QIODevice *ioDevice); /// Destroys QuaZip object. /** Calls close() if necessary. */ ~QuaZip(); /// Opens ZIP file. /** * Argument \a mode specifies open mode of the ZIP archive. See Mode * for details. Note that there is zipOpen2() function in the * ZIP/UNZIP API which accepts \a globalcomment argument, but it * does not use it anywhere, so this open() function does not have this * argument. See setComment() if you need to set global comment. * * If the ZIP file is accessed via explicitly set QIODevice, then * this device is opened in the necessary mode. If the device was * already opened by some other means, then the behaviour is defined by * the device implementation, but generally it is not a very good * idea. For example, QFile will at least issue a warning. * * \return \c true if successful, \c false otherwise. * * \note ZIP/UNZIP API open calls do not return error code - they * just return \c NULL indicating an error. But to make things * easier, quazip.h header defines additional error code \c * UNZ_ERROROPEN and getZipError() will return it if the open call * of the ZIP/UNZIP API returns \c NULL. * * Argument \a ioApi specifies IO function set for ZIP/UNZIP * package to use. See unzip.h, zip.h and ioapi.h for details. Note * that IO API for QuaZip is different from the original package. * The file path argument was changed to be of type \c voidpf, and * QuaZip passes a QIODevice pointer there. This QIODevice is either * set explicitly via setIoDevice() or the QuaZip(QIODevice*) * constructor, or it is created internally when opening the archive * by its file name. The default API (qioapi.cpp) just delegates * everything to the QIODevice API. Not only this allows to use a * QIODevice instead of file name, but also has a nice side effect * of raising the file size limit from 2G to 4G. * * In short: just forget about the \a ioApi argument and you'll be * fine. **/ bool open(Mode mode, zlib_filefunc_def *ioApi =NULL); /// Closes ZIP file. /** Call getZipError() to determine if the close was successful. The * underlying QIODevice is also closed, regardless of whether it was * set explicitly or not. */ void close(); /// Sets the codec used to encode/decode file names inside archive. /** This is necessary to access files in the ZIP archive created * under Windows with non-latin characters in file names. For * example, file names with cyrillic letters will be in \c IBM866 * encoding. **/ void setFileNameCodec(QTextCodec *fileNameCodec); /// Sets the codec used to encode/decode file names inside archive. /** \overload * Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName)); **/ void setFileNameCodec(const char *fileNameCodecName); /// Returns the codec used to encode/decode comments inside archive. QTextCodec* getFileNameCodec() const; /// Sets the codec used to encode/decode comments inside archive. /** This codec defaults to locale codec, which is probably ok. **/ void setCommentCodec(QTextCodec *commentCodec); /// Sets the codec used to encode/decode comments inside archive. /** \overload * Equivalent to calling setCommentCodec(QTextCodec::codecForName(codecName)); **/ void setCommentCodec(const char *commentCodecName); /// Returns the codec used to encode/decode comments inside archive. QTextCodec* getCommentCodec() const; /// Returns the name of the ZIP file. /** Returns null string if no ZIP file name has been set, for * example when the QuaZip instance is set up to use a QIODevice * instead. * \sa setZipName(), setIoDevice(), getIoDevice() **/ QString getZipName() const; /// Sets the name of the ZIP file. /** Does nothing if the ZIP file is open. * * Does not reset error code returned by getZipError(). * \sa setIoDevice(), getIoDevice(), getZipName() **/ void setZipName(const QString& zipName); /// Returns the device representing this ZIP file. /** Returns null string if no device has been set explicitly, for * example when opening a ZIP file by name. * \sa setIoDevice(), getZipName(), setZipName() **/ QIODevice *getIoDevice() const; /// Sets the device representing the ZIP file. /** Does nothing if the ZIP file is open. * * Does not reset error code returned by getZipError(). * \sa getIoDevice(), getZipName(), setZipName() **/ void setIoDevice(QIODevice *ioDevice); /// Returns the mode in which ZIP file was opened. Mode getMode() const; /// Returns \c true if ZIP file is open, \c false otherwise. bool isOpen() const; /// Returns the error code of the last operation. /** Returns \c UNZ_OK if the last operation was successful. * * Error code resets to \c UNZ_OK every time you call any function * that accesses something inside ZIP archive, even if it is \c * const (like getEntriesCount()). open() and close() calls reset * error code too. See documentation for the specific functions for * details on error detection. **/ int getZipError() const; /// Returns number of the entries in the ZIP central directory. /** Returns negative error code in the case of error. The same error * code will be returned by subsequent getZipError() call. **/ int getEntriesCount() const; /// Returns global comment in the ZIP file. QString getComment() const; /// Sets global comment in the ZIP file. /** Comment will be written to the archive on close operation. * * \sa open() **/ void setComment(const QString& comment); /// Sets the current file to the first file in the archive. /** Returns \c true on success, \c false otherwise. Call * getZipError() to get the error code. **/ bool goToFirstFile(); /// Sets the current file to the next file in the archive. /** Returns \c true on success, \c false otherwise. Call * getZipError() to determine if there was an error. * * Should be used only in QuaZip::mdUnzip mode. * * \note If the end of file was reached, getZipError() will return * \c UNZ_OK instead of \c UNZ_END_OF_LIST_OF_FILE. This is to make * things like this easier: * \code * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { * // do something * } * if(zip.getZipError()==UNZ_OK) { * // ok, there was no error * } * \endcode **/ bool goToNextFile(); /// Sets current file by its name. /** Returns \c true if successful, \c false otherwise. Argument \a * cs specifies case sensitivity of the file name. Call * getZipError() in the case of a failure to get error code. * * This is not a wrapper to unzLocateFile() function. That is * because I had to implement locale-specific case-insensitive * comparison. * * Here are the differences from the original implementation: * * - If the file was not found, error code is \c UNZ_OK, not \c * UNZ_END_OF_LIST_OF_FILE (see also goToNextFile()). * - If this function fails, it unsets the current file rather than * resetting it back to what it was before the call. * * If \a fileName is null string then this function unsets the * current file and return \c true. Note that you should close the * file first if it is open! See * QuaZipFile::QuaZipFile(QuaZip*,QObject*) for the details. * * Should be used only in QuaZip::mdUnzip mode. * * \sa setFileNameCodec(), CaseSensitivity **/ bool setCurrentFile(const QString& fileName, CaseSensitivity cs =csDefault); /// Returns \c true if the current file has been set. bool hasCurrentFile() const; /// Retrieves information about the current file. /** Fills the structure pointed by \a info. Returns \c true on * success, \c false otherwise. In the latter case structure pointed * by \a info remains untouched. If there was an error, * getZipError() returns error code. * * Should be used only in QuaZip::mdUnzip mode. * * Does nothing and returns \c false in any of the following cases. * - ZIP is not open; * - ZIP does not have current file; * - \a info is \c NULL; * * In all these cases getZipError() returns \c UNZ_OK since there * is no ZIP/UNZIP API call. **/ bool getCurrentFileInfo(QuaZipFileInfo* info)const; /// Returns the current file name. /** Equivalent to calling getCurrentFileInfo() and then getting \c * name field of the QuaZipFileInfo structure, but faster and more * convenient. * * Should be used only in QuaZip::mdUnzip mode. **/ QString getCurrentFileName()const; /// Returns \c unzFile handle. /** You can use this handle to directly call UNZIP part of the * ZIP/UNZIP package functions (see unzip.h). * * \warning When using the handle returned by this function, please * keep in mind that QuaZip class is unable to detect any changes * you make in the ZIP file state (e. g. changing current file, or * closing the handle). So please do not do anything with this * handle that is possible to do with the functions of this class. * Or at least return the handle in the original state before * calling some another function of this class (including implicit * destructor calls and calls from the QuaZipFile objects that refer * to this QuaZip instance!). So if you have changed the current * file in the ZIP archive - then change it back or you may * experience some strange behavior or even crashes. **/ unzFile getUnzFile(); /// Returns \c zipFile handle. /** You can use this handle to directly call ZIP part of the * ZIP/UNZIP package functions (see zip.h). Warnings about the * getUnzFile() function also apply to this function. **/ zipFile getZipFile(); /// Changes the data descriptor writing mode. /** According to the ZIP format specification, a file inside archive may have a data descriptor immediately following the file data. This is reflected by a special flag in the local file header and in the central directory. By default, QuaZIP sets this flag and writes the data descriptor unless both method and level were set to 0, in which case it operates in 1.0-compatible mode and never writes data descriptors. By setting this flag to false, it is possible to disable data descriptor writing, thus increasing compatibility with archive readers that don't understand this feature of the ZIP file format. Setting this flag affects all the QuaZipFile instances that are opened after this flag is set. The data descriptor writing mode is enabled by default. \param enabled If \c true, enable local descriptor writing, disable it otherwise. \sa QuaZipFile::setDataDescriptorWritingEnabled() */ void setDataDescriptorWritingEnabled(bool enabled); /// Returns the data descriptor default writing mode. /** \sa setDataDescriptorWritingEnabled() */ bool isDataDescriptorWritingEnabled() const; /// Returns a list of files inside the archive. /** \return A list of file names or an empty list if there was an error or if the archive is empty (call getZipError() to figure out which). \sa getFileInfoList() */ QStringList getFileNameList() const; /// Returns information list about all files inside the archive. /** \return A list of QuaZipFileInfo objects or an empty list if there was an error or if the archive is empty (call getZipError() to figure out which). \sa getFileNameList() */ QList getFileInfoList() const; }; #endif mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazip.cpp0000644000175000017500000003374112070466513021572 0ustar csmallcsmall/* Copyright (C) 2005-2011 Sergey A. Tachenov This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant, see quazip/(un)zip.h files for details, basically it's zlib license. **/ #include #include #include "quazip.h" /// All the internal stuff for the QuaZip class. /** \internal This class keeps all the private stuff for the QuaZip class so it can be changed without breaking binary compatibility, according to the Pimpl idiom. */ class QuaZipPrivate { friend class QuaZip; private: /// The pointer to the corresponding QuaZip instance. QuaZip *q; /// The codec for file names. QTextCodec *fileNameCodec; /// The codec for comments. QTextCodec *commentCodec; /// The archive file name. QString zipName; /// The device to access the archive. QIODevice *ioDevice; /// The global comment. QString comment; /// The open mode. QuaZip::Mode mode; union { /// The internal handle for UNZIP modes. unzFile unzFile_f; /// The internal handle for ZIP modes. zipFile zipFile_f; }; /// Whether a current file is set. bool hasCurrentFile_f; /// The last error. int zipError; /// Whether \ref QuaZip::setDataDescriptorWritingEnabled() "the data descriptor writing mode" is enabled. bool dataDescriptorWritingEnabled; /// The constructor for the corresponding QuaZip constructor. inline QuaZipPrivate(QuaZip *q): q(q), fileNameCodec(QTextCodec::codecForLocale()), commentCodec(QTextCodec::codecForLocale()), ioDevice(NULL), mode(QuaZip::mdNotOpen), hasCurrentFile_f(false), zipError(UNZ_OK), dataDescriptorWritingEnabled(true) {} /// The constructor for the corresponding QuaZip constructor. inline QuaZipPrivate(QuaZip *q, const QString &zipName): q(q), fileNameCodec(QTextCodec::codecForLocale()), commentCodec(QTextCodec::codecForLocale()), zipName(zipName), ioDevice(NULL), mode(QuaZip::mdNotOpen), hasCurrentFile_f(false), zipError(UNZ_OK), dataDescriptorWritingEnabled(true) {} /// The constructor for the corresponding QuaZip constructor. inline QuaZipPrivate(QuaZip *q, QIODevice *ioDevice): q(q), fileNameCodec(QTextCodec::codecForLocale()), commentCodec(QTextCodec::codecForLocale()), ioDevice(ioDevice), mode(QuaZip::mdNotOpen), hasCurrentFile_f(false), zipError(UNZ_OK), dataDescriptorWritingEnabled(true) {} /// Returns either a list of file names or a list of QuaZipFileInfo. template bool getFileInfoList(QList *result) const; }; QuaZip::QuaZip(): p(new QuaZipPrivate(this)) { } QuaZip::QuaZip(const QString& zipName): p(new QuaZipPrivate(this, zipName)) { } QuaZip::QuaZip(QIODevice *ioDevice): p(new QuaZipPrivate(this, ioDevice)) { } QuaZip::~QuaZip() { if(isOpen()) close(); delete p; } bool QuaZip::open(Mode mode, zlib_filefunc_def* ioApi) { p->zipError=UNZ_OK; if(isOpen()) { qWarning("QuaZip::open(): ZIP already opened"); return false; } QIODevice *ioDevice = p->ioDevice; if (ioDevice == NULL) { if (p->zipName.isEmpty()) { qWarning("QuaZip::open(): set either ZIP file name or IO device first"); return false; } else { ioDevice = new QFile(p->zipName); } } switch(mode) { case mdUnzip: p->unzFile_f=unzOpen2(ioDevice, ioApi); if(p->unzFile_f!=NULL) { p->mode=mode; p->ioDevice = ioDevice; return true; } else { p->zipError=UNZ_OPENERROR; if (!p->zipName.isEmpty()) delete ioDevice; return false; } case mdCreate: case mdAppend: case mdAdd: p->zipFile_f=zipOpen2(ioDevice, mode==mdCreate?APPEND_STATUS_CREATE: mode==mdAppend?APPEND_STATUS_CREATEAFTER: APPEND_STATUS_ADDINZIP, NULL, ioApi); if(p->zipFile_f!=NULL) { p->mode=mode; p->ioDevice = ioDevice; return true; } else { p->zipError=UNZ_OPENERROR; if (!p->zipName.isEmpty()) delete ioDevice; return false; } default: qWarning("QuaZip::open(): unknown mode: %d", (int)mode); if (!p->zipName.isEmpty()) delete ioDevice; return false; break; } } void QuaZip::close() { p->zipError=UNZ_OK; switch(p->mode) { case mdNotOpen: qWarning("QuaZip::close(): ZIP is not open"); return; case mdUnzip: p->zipError=unzClose(p->unzFile_f); break; case mdCreate: case mdAppend: case mdAdd: p->zipError=zipClose(p->zipFile_f, p->commentCodec->fromUnicode(p->comment).constData()); break; default: qWarning("QuaZip::close(): unknown mode: %d", (int)p->mode); return; } // opened by name, need to delete the internal IO device if (!p->zipName.isEmpty()) { delete p->ioDevice; p->ioDevice = NULL; } if(p->zipError==UNZ_OK) p->mode=mdNotOpen; } void QuaZip::setZipName(const QString& zipName) { if(isOpen()) { qWarning("QuaZip::setZipName(): ZIP is already open!"); return; } p->zipName=zipName; p->ioDevice = NULL; } void QuaZip::setIoDevice(QIODevice *ioDevice) { if(isOpen()) { qWarning("QuaZip::setIoDevice(): ZIP is already open!"); return; } p->ioDevice = ioDevice; p->zipName = QString(); } int QuaZip::getEntriesCount()const { QuaZip *fakeThis=(QuaZip*)this; // non-const fakeThis->p->zipError=UNZ_OK; if(p->mode!=mdUnzip) { qWarning("QuaZip::getEntriesCount(): ZIP is not open in mdUnzip mode"); return -1; } unz_global_info globalInfo; if((fakeThis->p->zipError=unzGetGlobalInfo(p->unzFile_f, &globalInfo))!=UNZ_OK) return p->zipError; return (int)globalInfo.number_entry; } QString QuaZip::getComment()const { QuaZip *fakeThis=(QuaZip*)this; // non-const fakeThis->p->zipError=UNZ_OK; if(p->mode!=mdUnzip) { qWarning("QuaZip::getComment(): ZIP is not open in mdUnzip mode"); return QString(); } unz_global_info globalInfo; QByteArray comment; if((fakeThis->p->zipError=unzGetGlobalInfo(p->unzFile_f, &globalInfo))!=UNZ_OK) return QString(); comment.resize(globalInfo.size_comment); if((fakeThis->p->zipError=unzGetGlobalComment(p->unzFile_f, comment.data(), comment.size())) < 0) return QString(); fakeThis->p->zipError = UNZ_OK; return p->commentCodec->toUnicode(comment); } bool QuaZip::setCurrentFile(const QString& fileName, CaseSensitivity cs) { p->zipError=UNZ_OK; if(p->mode!=mdUnzip) { qWarning("QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode"); return false; } if(fileName.isEmpty()) { p->hasCurrentFile_f=false; return true; } // Unicode-aware reimplementation of the unzLocateFile function if(p->unzFile_f==NULL) { p->zipError=UNZ_PARAMERROR; return false; } if(fileName.length()>MAX_FILE_NAME_LENGTH) { p->zipError=UNZ_PARAMERROR; return false; } bool sens; if(cs==csDefault) { #ifdef Q_WS_WIN sens=false; #else sens=true; #endif } else sens=cs==csSensitive; QString lower, current; if(!sens) lower=fileName.toLower(); p->hasCurrentFile_f=false; for(bool more=goToFirstFile(); more; more=goToNextFile()) { current=getCurrentFileName(); if(current.isEmpty()) return false; if(sens) { if(current==fileName) break; } else { if(current.toLower()==lower) break; } } return p->hasCurrentFile_f; } bool QuaZip::goToFirstFile() { p->zipError=UNZ_OK; if(p->mode!=mdUnzip) { qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode"); return false; } p->zipError=unzGoToFirstFile(p->unzFile_f); p->hasCurrentFile_f=p->zipError==UNZ_OK; return p->hasCurrentFile_f; } bool QuaZip::goToNextFile() { p->zipError=UNZ_OK; if(p->mode!=mdUnzip) { qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode"); return false; } p->zipError=unzGoToNextFile(p->unzFile_f); p->hasCurrentFile_f=p->zipError==UNZ_OK; if(p->zipError==UNZ_END_OF_LIST_OF_FILE) p->zipError=UNZ_OK; return p->hasCurrentFile_f; } bool QuaZip::getCurrentFileInfo(QuaZipFileInfo *info)const { QuaZip *fakeThis=(QuaZip*)this; // non-const fakeThis->p->zipError=UNZ_OK; if(p->mode!=mdUnzip) { qWarning("QuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip mode"); return false; } unz_file_info info_z; QByteArray fileName; QByteArray extra; QByteArray comment; if(info==NULL) return false; if(!isOpen()||!hasCurrentFile()) return false; if((fakeThis->p->zipError=unzGetCurrentFileInfo(p->unzFile_f, &info_z, NULL, 0, NULL, 0, NULL, 0))!=UNZ_OK) return false; fileName.resize(info_z.size_filename); extra.resize(info_z.size_file_extra); comment.resize(info_z.size_file_comment); if((fakeThis->p->zipError=unzGetCurrentFileInfo(p->unzFile_f, NULL, fileName.data(), fileName.size(), extra.data(), extra.size(), comment.data(), comment.size()))!=UNZ_OK) return false; info->versionCreated=info_z.version; info->versionNeeded=info_z.version_needed; info->flags=info_z.flag; info->method=info_z.compression_method; info->crc=info_z.crc; info->compressedSize=info_z.compressed_size; info->uncompressedSize=info_z.uncompressed_size; info->diskNumberStart=info_z.disk_num_start; info->internalAttr=info_z.internal_fa; info->externalAttr=info_z.external_fa; info->name=p->fileNameCodec->toUnicode(fileName); info->comment=p->commentCodec->toUnicode(comment); info->extra=extra; info->dateTime=QDateTime( QDate(info_z.tmu_date.tm_year, info_z.tmu_date.tm_mon+1, info_z.tmu_date.tm_mday), QTime(info_z.tmu_date.tm_hour, info_z.tmu_date.tm_min, info_z.tmu_date.tm_sec)); return true; } QString QuaZip::getCurrentFileName()const { QuaZip *fakeThis=(QuaZip*)this; // non-const fakeThis->p->zipError=UNZ_OK; if(p->mode!=mdUnzip) { qWarning("QuaZip::getCurrentFileName(): ZIP is not open in mdUnzip mode"); return QString(); } if(!isOpen()||!hasCurrentFile()) return QString(); QByteArray fileName(MAX_FILE_NAME_LENGTH, 0); if((fakeThis->p->zipError=unzGetCurrentFileInfo(p->unzFile_f, NULL, fileName.data(), fileName.size(), NULL, 0, NULL, 0))!=UNZ_OK) return QString(); return p->fileNameCodec->toUnicode(fileName.constData()); } void QuaZip::setFileNameCodec(QTextCodec *fileNameCodec) { p->fileNameCodec=fileNameCodec; } void QuaZip::setFileNameCodec(const char *fileNameCodecName) { p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName); } QTextCodec *QuaZip::getFileNameCodec()const { return p->fileNameCodec; } void QuaZip::setCommentCodec(QTextCodec *commentCodec) { p->commentCodec=commentCodec; } void QuaZip::setCommentCodec(const char *commentCodecName) { p->commentCodec=QTextCodec::codecForName(commentCodecName); } QTextCodec *QuaZip::getCommentCodec()const { return p->commentCodec; } QString QuaZip::getZipName() const { return p->zipName; } QIODevice *QuaZip::getIoDevice() const { if (!p->zipName.isEmpty()) // opened by name, using an internal QIODevice return NULL; return p->ioDevice; } QuaZip::Mode QuaZip::getMode()const { return p->mode; } bool QuaZip::isOpen()const { return p->mode!=mdNotOpen; } int QuaZip::getZipError() const { return p->zipError; } void QuaZip::setComment(const QString& comment) { p->comment=comment; } bool QuaZip::hasCurrentFile()const { return p->hasCurrentFile_f; } unzFile QuaZip::getUnzFile() { return p->unzFile_f; } zipFile QuaZip::getZipFile() { return p->zipFile_f; } void QuaZip::setDataDescriptorWritingEnabled(bool enabled) { p->dataDescriptorWritingEnabled = enabled; } bool QuaZip::isDataDescriptorWritingEnabled() const { return p->dataDescriptorWritingEnabled; } template static TFileInfo getFileInfo(QuaZip *zip, bool *ok); template<> QuaZipFileInfo getFileInfo(QuaZip *zip, bool *ok) { QuaZipFileInfo info; *ok = zip->getCurrentFileInfo(&info); return info; } template<> QString getFileInfo(QuaZip *zip, bool *ok) { QString name = zip->getCurrentFileName(); *ok = !name.isEmpty(); return name; } template bool QuaZipPrivate::getFileInfoList(QList *result) const { QuaZipPrivate *fakeThis=const_cast(this); fakeThis->zipError=UNZ_OK; if (mode!=QuaZip::mdUnzip) { qWarning("QuaZip::getFileNameList/getFileInfoList(): " "ZIP is not open in mdUnzip mode"); return false; } QString currentFile; if (q->hasCurrentFile()) { currentFile = q->getCurrentFileName(); } if (q->goToFirstFile()) { do { bool ok; result->append(getFileInfo(q, &ok)); if (!ok) return false; } while (q->goToNextFile()); } if (zipError != UNZ_OK) return false; if (currentFile.isEmpty()) { if (!q->setCurrentFile(currentFile)) return false; } else { if (!q->goToFirstFile()) return false; } return true; } QStringList QuaZip::getFileNameList() const { QStringList list; if (p->getFileInfoList(&list)) return list; else return QStringList(); } QList QuaZip::getFileInfoList() const { QList list; if (p->getFileInfoList(&list)) return list; else return QList(); } mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quaadler32.h0000644000175000017500000000103512070466513021660 0ustar csmallcsmall#ifndef QUAADLER32_H #define QUAADLER32_H #include #include "quachecksum32.h" /// Adler32 checksum /** \class QuaAdler32 quaadler32.h * This class wrappers the adler32 function with the QuaChecksum32 interface. * See QuaChecksum32 for more info. */ class QUAZIP_EXPORT QuaAdler32 : public QuaChecksum32 { public: QuaAdler32(); quint32 calculate(const QByteArray &data); void reset(); void update(const QByteArray &buf); quint32 value(); private: quint32 checksum; }; #endif //QUAADLER32_H mudlet-2.1/src/quazip/quazip-0.4.4/quazip/ioapi.h0000644000175000017500000000503312070466513021020 0ustar csmallcsmall/* ioapi.h -- IO base function header for compress/uncompress .zip files using zlib + zip or unzip API Version 1.01e, February 12th, 2005 Copyright (C) 1998-2005 Gilles Vollant Modified by Sergey A. Tachenov to integrate with Qt. */ #ifndef _ZLIBIOAPI_H #define _ZLIBIOAPI_H #define ZLIB_FILEFUNC_SEEK_CUR (1) #define ZLIB_FILEFUNC_SEEK_END (2) #define ZLIB_FILEFUNC_SEEK_SET (0) #define ZLIB_FILEFUNC_MODE_READ (1) #define ZLIB_FILEFUNC_MODE_WRITE (2) #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) #define ZLIB_FILEFUNC_MODE_EXISTING (4) #define ZLIB_FILEFUNC_MODE_CREATE (8) #ifndef ZCALLBACK #if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) #define ZCALLBACK CALLBACK #else #define ZCALLBACK #endif #endif #ifdef __cplusplus extern "C" { #endif typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, voidpf file, int mode)); typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); typedef uLong (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); typedef int (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); typedef struct zlib_filefunc_def_s { open_file_func zopen_file; read_file_func zread_file; write_file_func zwrite_file; tell_file_func ztell_file; seek_file_func zseek_file; close_file_func zclose_file; testerror_file_func zerror_file; voidpf opaque; } zlib_filefunc_def; void fill_qiodevice_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); #define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) #define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) #define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) #define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) #define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) #define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) #ifdef __cplusplus } #endif #endif mudlet-2.1/src/quazip/quazip-0.4.4/quazip/crypt.h0000644000175000017500000001131412070466513021057 0ustar csmallcsmall/* crypt.h -- base code for crypt/uncrypt ZIPfile Version 1.01e, February 12th, 2005 Copyright (C) 1998-2005 Gilles Vollant This code is a modified version of crypting code in Infozip distribution The encryption/decryption parts of this source code (as opposed to the non-echoing password parts) were originally written in Europe. The whole source package can be freely distributed, including from the USA. (Prior to January 2000, re-export from the US was a violation of US law.) This encryption code is a direct transcription of the algorithm from Roger Schlafly, described by Phil Katz in the file appnote.txt. This file (appnote.txt) is distributed with the PKZIP program (even in the version without encryption capabilities). If you don't need crypting in your application, just define symbols NOCRYPT and NOUNCRYPT. This code support the "Traditional PKWARE Encryption". The new AES encryption added on Zip format by Winzip (see the page http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong Encryption is not supported. */ #include "quazip_global.h" #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) /*********************************************************************** * Return the next byte in the pseudo-random sequence */ static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab UNUSED) { //(void) pcrc_32_tab; /* avoid "unused parameter" warning */ unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an * unpredictable manner on 16-bit systems; not a problem * with any known compiler so far, though */ temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); } /*********************************************************************** * Update the encryption keys with the next byte of plain text */ static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) { (*(pkeys+0)) = CRC32((*(pkeys+0)), c); (*(pkeys+1)) += (*(pkeys+0)) & 0xff; (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; { register int keyshift = (int)((*(pkeys+1)) >> 24); (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); } return c; } /*********************************************************************** * Initialize the encryption keys and the random header according to * the given password. */ static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) { *(pkeys+0) = 305419896L; *(pkeys+1) = 591751049L; *(pkeys+2) = 878082192L; while (*passwd != '\0') { update_keys(pkeys,pcrc_32_tab,(int)*passwd); passwd++; } } #define zdecode(pkeys,pcrc_32_tab,c) \ (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) #define zencode(pkeys,pcrc_32_tab,c,t) \ (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED #define RAND_HEAD_LEN 12 /* "last resort" source for second part of crypt seed pattern */ # ifndef ZCR_SEED2 # define ZCR_SEED2 3141592654UL /* use PI as default pattern */ # endif static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) const char *passwd; /* password string */ unsigned char *buf; /* where to write header */ int bufSize; unsigned long* pkeys; const unsigned long* pcrc_32_tab; unsigned long crcForCrypting; { int n; /* index in random header */ int t; /* temporary */ int c; /* random byte */ unsigned char header[RAND_HEAD_LEN-2]; /* random header */ static unsigned calls = 0; /* ensure different random header each time */ if (bufSize> 7) & 0xff; header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); } /* Encrypt random header (last two bytes is high word of crc) */ init_keys(passwd, pkeys, pcrc_32_tab); for (n = 0; n < RAND_HEAD_LEN-2; n++) { buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); } buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); return n; } #endif mudlet-2.1/src/quazip/quazip-0.4.4/quazip/doc/0000755000175000017500000000000012070466513020312 5ustar csmallcsmallmudlet-2.1/src/quazip/quazip-0.4.4/quazip/doc/usage.dox0000644000175000017500000000671612070466513022144 0ustar csmallcsmall/** \page usage Usage * * This page provides general information on QuaZIP usage. See classes * QuaZip and QuaZipFile for the detailed documentation on what can * QuaZIP do and what can not. Also, reading comments in the zip.h and * unzip.h files (taken from the original ZIP/UNZIP package) is always a * good idea too. After all, QuaZIP is just a wrapper with a few * convenience extensions and reimplementations. * * QuaZip is a class representing ZIP archive, QuaZipFile represents a * file inside archive and subclasses QIODevice as well. * * \section terminology Terminology * * "QuaZIP" means whole this library, while "QuaZip" (not case * difference) is just one class in it. * * "ZIP/UNZIP API" means the original API of the Gilles Vollant's * ZIP/UNZIP package. It was slightly modified to better integrate with * Qt. * * "ZIP", "ZIP archive" or "ZIP file" means any ZIP archive. Typically * this is a plain file with ".zip" (or ".ZIP") file name suffix. * * "A file inside archive", "a file inside ZIP" or something like that * means file either being read or written from/to some ZIP archive. * * \section error-handling Error handling * * Almost any call to ZIP/UNZIP API return some error code. Most of the * original API's error checking could be done in this wrapper as well, * but it would cause unnecessary code bloating without any benefit. So, * QuaZIP only checks for situations that ZIP/UNZIP API can not check * for. For example, ZIP/UNZIP API has no "ZIP open mode" concept * because read and write modes are completely separated. On the other * hand, to avoid creating classes like "QuaZipReader", "QuaZipWriter" * or something like that, QuaZIP introduces "ZIP open mode" concept * instead, thus making it possible to use one class (QuaZip) for both * reading and writing. But this leads to additional open mode checks * which are not done in ZIP/UNZIP package. * * Therefore, error checking is two-level (QuaZIP's level and ZIP/UNZIP * API level), which sometimes can be confusing, so here are some * advices on how the error checking should be properly done: * * - Both QuaZip and QuaZipFile have getZipError() function, which return * error code of the last ZIP/UNZIP API call. Most function calls * reset error code to UNZ_OK on success and set error code on * failure. Some functions do not reset error code. Most of them are * \c const and do not access ZIP archive in any way. Some, on the * other hand, \em do access ZIP archive, but do not reset or set * error code. For example, QuaZipFile::pos() function. Such functions * are explicitly marked in the documentation. * - Most functions have its own way to report errors, by returning a * null string, negative value or \c false. If such a function returns * error value, call getZipError() to get more information about * error. See "zip.h" and "unzip.h" of the ZIP/UNZIP package for error * codes. * - If the function returns error-stating value (like \c false), but * getZipError() returns UNZ_OK, it means that you did something * obviously wrong. For example, tried to write in the archive open * for reading or not open at all. You better just do not do that! * Most functions also issue a warning using qWarning() function in * such cases. See documentation for a specific function for details * on when it should not be called. * * I know that this is somewhat messy, but I could not find a better way * to do all the error handling. **/ mudlet-2.1/src/quazip/quazip-0.4.4/quazip/doc/faq.dox0000644000175000017500000000174212070466513021601 0ustar csmallcsmall/** * \page faq QuaZip FAQ * * * * \anchor faq-non-QIODevice Q. Is there any way to use QuaZipFile in Qt * where you are supposed to use normal (non-zipped) file, but not * through QIODevice API? * * A. Usually not. For example, if you are passing file name to some * database driver (like SQLite), Qt usually just passes this name down * to the 3rd-party library, which is usually does not know anything * about QIODevice and therefore there is no way to pass QuaZipFile as * normal file. However, if we are talking about some place where you * pass file name, and then indirectly use QFile to open it, then it is * a good idea to make overloaded method, which accepts QIODevice * pointer. Then you would be able to pass QuaZipFile as well as many * other nice things such as QBuffer or QProcess. **/ mudlet-2.1/src/quazip/quazip-0.4.4/quazip/doc/index.dox0000644000175000017500000001445012070466513022141 0ustar csmallcsmall/** * \mainpage QuaZIP - Qt/C++ wrapper for ZIP/UNZIP package * \htmlonly Powered by SourceForge.net \endhtmlonly * \section overview Overview * * QuaZIP is a simple C++ wrapper over Gilles Vollant's ZIP/UNZIP * package that can be used to access ZIP archives. It uses Trolltech's * Qt toolkit. * * If you do not know what Qt is, you have two options: * - Just forget about QuaZIP. * - Learn more about Qt by downloading it and/or reading excellent official Qt documentation * * The choice is yours, but if you are really interested in * cross-platform (Windows/Linux/BSD/UNIX/Mac/Others) software * development, I would definitely recommend you the second choice ^_^ * * QuaZIP allows you to access files inside ZIP archives using QIODevice * API, and - yes! - that means that you can also use QTextStream, * QDataStream or whatever you would like to use on your zipped files. * * QuaZIP provides complete abstraction of the ZIP/UNZIP API, for both * reading from and writing to ZIP archives. * * \section download Download QuaZIP * * Downloads are available from QuaZIP project's page * at SourceForge.net. * * \section platforms Platforms supported * * QuaZIP has been currently tested with Qt 4.0.0 on the following * platforms: * - linux-g++ * - freebsd-g++ * - hpux-acc * - win32-g++ (MinGW) * * No testing has been done on other systems. Of course, patches to * make it work on any platform that it currently does not work on are * always welcome! * * \section whats-new What is new in this version of QuaZIP? * * See the NEWS file supplied with the distribution. * * \section Requirements * * Just zlib and Qt 4. Well, Qt 4 * depends on zlib anyway. * * \section building Building, testing and installing * * \note Instructions given in this section assume that you are * using some UNIX dialect, but the build process should be very similar * on win32-g++ platform too. On other platforms it's essentially the * same process, maybe with some qmake adjustments not specific to * QuaZIP itself. * * To build the library, run: \verbatim $ cd /wherever/quazip/source/is/quazip-x.y.z/quazip $ qmake [PREFIX=where-to-install] $ make \endverbatim * * Make sure that you have Qt 4 installed with all required headers and * utilities (not just library) and that you run qmake utility of the Qt * 4, not some other version you may have already installed (you may * need to type full path to qmake like /usr/local/qt4/bin/qmake). * * To reconfigure (with another PREFIX, for example), just run qmake * with appropriate arguments again. * * If you need to specify additional include path or libraries, use * qmake features (see qmake reference in the Qt documentation). For * example: * \verbatim $ qmake LIBS+=-L/usr/local/zlib/lib INCLUDEPATH+=/usr/local/zlib/include \endverbatim * (note abscence of "-I" before include path) * * To check if QuaZIP's basic features work ok on your platform, you may * wish to compile simple test programs provided in test directory. * Look in the sources of the tests to find out about their * requirements. Typically, the test looks something like this: \verbatim $ cd /wherever/quazip/source/is/quazip-x.y.z/test/zip $ qmake $ make $ ./zip $ cd ../unzip $ cp ../zip/test.zip ./test.zip $ mkdir out $ qmake $ make $ ./unzip \endverbatim * * You should see the zip contents with details as the output of the * "./unzip". Ignore message saying you should check the file name for * testCase() if you do not want to test * \link QuaZip::CaseSensitivity locale-aware case-insensitivity\endlink. * Otherwise, see the sources. In any case, this message appearing means * that everything else was fine. Otherwise, you will get some other error * message instead. Investigate it or send bug report including message, * platform and QuaZIP version used. * * To install compiled library: \verbatim $ make install \endverbatim * * By default, QuaZIP compiles as a DLL, but you have other * options: * - Just copy appropriate source files to your project and use them, * but you need to define QUAZIP_STATIC before including any QuaZIP * headers (best done as a compiler option). This will save you from * possile side effects of importing/exporting QuaZIP symbols. * - Compile it as a static library using CONFIG += staticlib qmake * option. QUAZIP_STATIC is defined automatically by qmake in this case. * * Binary compatibility isn't guaranteed even between minor releases, * but usually it's preserved, thanks to the Pimpl idiom. * * \section using Using * * See \ref usage "usage page". * * \section contacts Authors and contacts * * This wrapper has been written by Sergey A. Tachenov, AKA Alqualos. * This is my first open source project, so it may suck, but I did not * find anything like that, so I just had no other choice but to write * it. * * If you have anything to say to me about QuaZIP library, feel free to * do so (read the \ref faq first, though). I can not promise, * though, that I fix all the bugs you report in, add any features you * want, or respond to your critics, or respond to your feedback at all. * I may be busy, I may be tired of working on QuaZIP, I may be even * dead already (you never know...). * * To report bugs or to post ideas about what should be done, use * SourceForge.net's trackers. * If you want to send me a private message, use my e-mail address * stachenov@gmail.com. * * Do not use e-mail to report bugs, please. Reporting bugs and problems * with the SourceForge.net's bug report system has that advantage that * it is visible to public, and I can always search for open tickets * that were created long ago. It is highly unlikely that I will search * my mail for that kind of stuff, so if a bug reported by mail isn't * fixed immediately, it will likely be forgotten forever. * * Copyright (C) 2005-2011 Sergey A. Tachenov **/ mudlet-2.1/src/quazip/quazip-0.4.4/quazip/CMakeLists.txt0000644000175000017500000000100212070466513022276 0ustar csmallcsmallfile(GLOB SRCS "*.c" "*.cpp") file(GLOB PUBLIC_HEADERS "*.h") qt4_wrap_cpp(MOC_SRCS ${PUBLIC_HEADERS}) set(SRCS ${SRCS} ${MOC_SRCS}) add_library(quazip SHARED ${SRCS}) set_target_properties(quazip PROPERTIES VERSION 1 SOVERSION 1.0.0) target_link_libraries(quazip ${QT_QTMAIN_LIBRARY} ${QT_QTCORE_LIBRARY} -lz) install(FILES ${PUBLIC_HEADERS} DESTINATION include/quazip) install(TARGETS quazip LIBRARY DESTINATION ${LIB_DESTINATION} ARCHIVE DESTINATION ${LIB_DESTINATION} RUNTIME DESTINATION ${LIB_DESTINATION}) mudlet-2.1/src/quazip/quazip-0.4.4/quazip/release/0000755000175000017500000000000012070466513021165 5ustar csmallcsmallmudlet-2.1/src/quazip/quazip-0.4.4/quazip/release/quazip.dll0000644000175000017500000036400012070466513023176 0ustar csmallcsmallMZ@ !L!This program cannot be run in DOS mode. $PELcO# 8`0m0 0.text`P`.dataLJ0L"@`.rdata,:<n@`@.bss@.edata@0@.idata@0.reloc0@0BUSmt?m'9rtЋm9st&$1҉m$X[]UVSu tGt$ED$E$:à 1uGu muF1ۉ؍e[^] $Ymt+m벍  1먍v'UmD$mD$E$ɃÍUmD$mD$E$ÐU$mRteD$m$tD$ m$mЋ Hzmt1$)mRt*D$6m$t $Hzmøm말U$mnQt%D$Jm$at $mÍvmUVS1ށ3XispX1ށ3X[^ÐUWVS,É։D$ ED$T$C$SHuE1,[^_ft$C$SfUWVS,ƉӉύMUUԅt,[^_ÐMډlUuUԉ,[^_ÐUWVS,ƉӉύM=UUԅt,[^_ÐMډUU̅uۍMډUUЅuōMډMuU]]ԉ,[^_ÐUEtP$H(E H1øÐUWVSƉUMD$ @,F4D$F D$F$V~EtV tMV ~tMV htMV RtMV tEуMԉсIM ¼U܉ UЉŨEȍMV +tMV tMV tMV tMV tMV itMV StMV =tMċV {tMV et}}}u`Mt3M;MM1Ut EUt}tEtEU؁Ĝ[^_Ð}uEt;} U t M W)׋EUEU9w|t M).MV wm}PKv[؁Ĝ[^_fU U:`fD$ |$F D$F$|V|fD$ |$F D$F$|V|u E1fEvT$ ED$F D$F$|V|9ET$ ED$F D$F$|V|9z)׻L$ ED$F D$F$|V|9v1EOUWVS EU MMM]u}$}} }u]M 1Ƀ [^_SvUS$]t^CDC4C0SHD$D$D$ D$D$$1҅‰S8$[f$[ÐUS$]u$[ÍvS8tyC$=ugC4Ch.ClCpC4C0SHD$D$D$ D$D$$W1҅‰S8$[ÍvS0B9umfUEU uÅtH8tH4 @0B1fÐUS$]E u $[ÅtS4@C0SHD$D$D$ D$D$$1҅‰S8$[fUEu Ívt@ÐUEu Ívt@\ÐUWVSE] u [^_ËtVLFH)Ѕt}9vDžu 1[^_D$ VDT$D$F|$Vpt랉|$ \$D$F|$Vd‰9uvfUWVS,]u u ,[^_ËC(ED$ C<D$C D$C$SuL}E9vDžut C(9Ev,[^_|$ t$C D$C$S9tǍvvfUEt&P8tP$t t;P0t@4f1øÐUS$]t^E C4C$C0SHD$D$D$ D$D$$S1҅‰S8$[Ív$[ÐUWVS]u[^_ÐtG\u tA1t$O@u4G@<$ǃ[^_ÐGP;GTt벐G$豏뿍vUS]t2t$DC D$C$S$|1[ø[ÐUWVSU܅uC D$C$S D$ CpD$C D$C$SS $M…u/S $n…uS $M TD$ |$C D$C$USUtC|S $PK…S $M…S $…S $M ivEC0UU$sDD$<$ySDSl)щSludC@uՉC@@MK<뿍vCt@$@%JC0$yChf‹}}ȃ0fUD$D$E$sÐUWVS,]|{,b1E 51} IMC D$C$S E܅upS$1؉ӉvCNjtDuCtD$ CD$B D$B$URK9ȋUtʼnȾNjuf1C$t]f؋$0u]tEC D$C$St u@t$$,[^_1fS $PKjƅuS $1ɉQƅuS $1ɉ8ƅi@S $ƅH@S $ƅ'S $ƅ M+@S $ƅS $Mƅ}ED$ E D$C D$C$S;E@E Ev$T,[^_ÐUWVS,]E Uu,[^_Ðs,tC0S4T$D$@$1v@C4S0UtK@tMtaC4S@9v…t1׋KEE„E„u E$mE„E$mE„tWE„t:}t u[1<$Gv1$\me[^_ÍvE$mfE$mfE$mov<$.u<$8<$.u$LmtE$mEEE„E„u E$mE„tnE$mE„u E$mEU$EgE<$EuFE$E\mE$4$E4E뺋E$m넋E$mUHU$EmE븉EE„u E$UEU$EͤENZcsUWVSlED$]$=m׍u\$4$`mP$走Et$$!E„$mEЋUT$uԉ4$׍}Љt$<$XmQmEE܉D$]؉$8m|$$$m$D$$d11$lmuQM$mUBUEEtl$ۘE$=S@@uv~J@t8*t뽐ut@t8*ufdžUWVSS K)9~1ɉK,[[^_Ív K Ct9$tg ~2mE8MurJ.tE_t@$t;vs;s} vKFsttQA|fAK f~Nu‹S0)‰S0C;CS @K@C>AmA'1ɉ[[^_fUWVS,ËP XtSItBt$*tK Et>pLuƐM뼍vAK S :EGBS 뜍vAK {,E,[^_fUWVS<ËP 1҉ƺC 8Iut_$brvS ;S;S# RKBSAmA$ƃC01tfBS UEԅS 21fF< F<=uƃD$D$E$U ǃ1U랍v,[^_UWVS,É1IMtxSU1HTG9}vOȊ>=uƃD$D$E$U ǃ1U랍v,[^_UWVS,ÉUʅt*y pu1ɉZ=:PD ƃ BD[ƃ[MQt Z=]PD]ƃ],[^_Éf@8&KMྤmxLFmtT=uƃD$D$E$U؈M ǃ1M܋U떍v1ɉ7tWBD)ƃ)ƃD$D$C$ ǃ1ƃD$D$M $ ǃ1qvƃD$D$C$ ǃ1ivƃD$D$C$ ǃ1v1ɉ UWVSƉӉMuAjfSCC %tP&tbtt+t+u!SuEuSwuՃ[^_Ë [^_Ë [^_ËdžRMMuAmCPwvRvD[^_ú.UWVS,É׉΅IPw$mtPt1ɸ1 1ɸ*< .JBD ƃ = ƃD$D$C$ ǃ1TffEǃ1ɉBD(ƃ(Wt =PD)ƃ)AE䉃,[^_Ê<(t<*=PD(ƃ(Eǃ1ɉ=PD)ƃ)ƃD$D$C$ ǃ1vƃD$D$C$ ǃ1ƃD$D$C$ ǃ1*ƃD$D$C$ ǃ1~1116fUWVSÉUtuU:vǃĜ[^_Ð$`mm}WҋMQ m}Wo롺umEPT놺mMQ9hmźƐmٺߐmhEHP;vJuJ q9tu|}EEEUUEE G E]fBwUZuH} MM]ˍCljֹ}{EEEMBEu]}W|M}t.EUt}Ow||UEE}}EEWlUu% WOmvEf EHx9J$f_Y҉9$ى)ȃՍY܋xǃURUEMMUEM׋B. EEv}p@H Ezvu Ur}+M}D|MfE|E}HMωƹ󥋽|xMP@H ERv}WyE8 Ut&EUtߋ]Kuxc}ǃEPt2u z! <<}W>K>{EMQF@ufJ@8*t8mm mmEP3(mMQI-mW;mNm_m9MQY8*x18*upt ׍W@uUE@E1 F9u U~9~ mUBH- "Ext[EEUUEEREu'    Um$EPmUx MQ:-l EPxUB80yMQ:+.PKEPB0mUBPMA8+/@x"@8>)}G82P:3P EP UB@P mMA@P GmEPOh}W:#Rrr(}W)?5MQ Vm9UBD$D$\mu4$hEPtUB mMQ`9x}E}}EEWE Efx MQz mt }fxmEP m}GP aw -GPH9}W y~EP,[Yy_yU9E]u10A9840XЀ vXwF7ׅP:*X4W1N. MAH P$wmfm6U(}W)q f:*~HRuRv}OWh]ǃ )V{MQ ,z"4B<0?<13mEMQ:5$Lm)mD&m3#m"lauPǃ 0 m[EPA]d-/|RzR:>(}GvrmMQm"]uEMEEE}WRmEE]uu94<_,}UttY -}W-mOfUWVSÉ8_muC<.^<_V<$Nf1I] EE] UEMEEEET$AnD$UĉEЅ9;_H1t E8)!EEEEEMME{EƄED$ED$$UE1}e[^_ÊC =t_PD>ƃ>,[^_ƃD$D$C$ ǃ1iƃD$D$C$ ǃ1i x v d3vUWVS,:+t,[^_fRJMzt|HM1ۉfJDC9]vOʊuƆT$T$U$E dž1ҊEf,[^_US$Ët]tX=HD(ƃ(=t*PD)ƃ)$[Ív؃$[tƃD$D$C$ ǃ1ƃD$D$C$U ǃ1U7U] U0m8t0mBR0muÍ&USxmt)t'xmKu$m#Y[]1=|m @|mu뾍'UPmt]f]Pm냐U,mQm,mr]Ð%m%m%m%m%m%m%m%m%m%m%m%m%m%mQL$=r -=w) ̋@PÐUU1 US]CHCt1]C$ RxD$D$C $ ]ÐUS]$Qx-D$D$C$ ]f1]ÐUS]q1x;Kt [[fC1[[ÍvCK1[[UVS]$Ɖ$rRt;stDD$C $uCse[^Ð$Ve[^Ív$PC1e[^ÍvUS]$Ru 1]fD$C$t݉$Q]ÍvUS]CCD$ D$D$$:C ]ÍvUS]D$ D$D$$C]ÐUE@$QÐUE D$E$t1ÐfUS$ËE$R$ESE]fUE$Qt1ffUVSu] tt] E[^v[^\UVS]u tBt> t 1e[^ÍvC$1Ru&f$$P3tˍve[^1%xm%m%m%m%m%m%m%m%m%m%m%m%m%m%m%m%m%4m%8m%Dm%,m%`m%UWVSEU͐UWVS& 4 C X7       "   w      V   s>^<&( 6 E f    K      6 A    |+9Gh?AS~R                  4               k$0>Ln?1!E "iv "o| "jw#R?_G$7+uW "o| "iv "jwBfI%: *JvcnFbo 6wV@X'6BOn7-dUFbo%go#R?_?V5+!o}=              }UH^-d &A[8 'Wi 'Wi)Uf{)vRc 'Xj 'Xj  Qc  QcPw2*0w6gr'&l)vRc)Uf{6[v6gr%e/|OeXw9"m9"m[l[l,1Vi%h      mrx >[a pm  5MS !Lu!Fo%T7(})!P7}-G6}|m`mmmm(mlibgcc_s_dw2-1.dll__register_frame_infolibgcj_s.dll_Jv_RegisterClasses__deregister_frame_info1.2.5 unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll-1.2.5 zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDllQuaZip::setZipName(): ZIP is already open!QuaZip::goToFirstFile(): ZIP is not open in mdUnzip modeQuaZip::getEntriesCount(): ZIP is not open in mdUnzip modeQuaZip::open(): ZIP already openedQuaZip::open(): set either ZIP file name or IO device firstQuaZip::open(): unknown mode: %dQuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip modeQuaZip::close(): ZIP is not openQuaZip::close(): unknown mode: %dQuaZip::getCurrentFileName(): ZIP is not open in mdUnzip modeQuaZip::setIoDevice(): ZIP is already open!QuaZip::setCurrentFile(): ZIP is not open in mdUnzip modeQuaZip::getFileNameList/getFileInfoList(): ZIP is not open in mdUnzip modeQuaZip::getComment(): ZIP is not open in mdUnzip modeQuaZipFile::atEnd(): call setZipName() or setZip() firstQuaZipFile::atEnd(): file is not openQuaZipFile::pos(): call setZipName() or setZip() firstQuaZipFile::pos(): file is not openQuaZipFile::setFileName(): call setZipName() firstQuaZipFile::setFileName(): should not be used when not using internal QuaZipQuaZipFile::setFileName(): can not set file name for already opened fileQuaZipFile::setZipName(): file is already open - can not set ZIP nameQuaZipFile::setZip(): file is already open - can not set ZIPZIP/UNZIP API error %1QuaZipFile::close(): file isn't openWrong open mode: %dQuaZipFile::open(): already openedQuaZipFile::open(): write mode is incompatible with internal QuaZip approachQuaZipFile::open(): zip is NULLQuaZipFile::open(): file open mode %d incompatible with ZIP open mode %dQuaZipFile::open(): open mode %d not supported by this functionQuaZipFile::open(): Unbuffered mode is not supportedQuaZipFile::open(): zip does not have current fileQuaZipFile$mmm$mTmmmmm\mm$mTmpure virtual method called std::exceptionstd::bad_exception__gnu_cxx::__concurrence_lock_error__gnu_cxx::__concurrence_unlock_errorstd::bad_allocterminate called recursively terminate called after throwing an instance of '' what(): terminate called without an active exception ʭmmmmmʭmʭmʭmʭmܭmܭmmܭmܭmܭmܭmܭmܭmܭmܭmܭmܭmʭmmmmmmmmܭmܭmܭmܭmܭmʭmܭmm mmʭmmmʭmʭmܭmmmmmmmmmܭmmʭmܭmܭmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm_GLOBAL_(anonymous namespace)stcl,m,m,m,m,m,m,m,m,m,mԶmԶmԶmԶmԶmԶmԶmmԶm@mhmԶmmmԶmԶmԶmԶmԶmhm,mmmԶm m4mmܸmԶmԶmԶmԶm,mԶmԶmԶmԶmԶmԶmmmmmmmmmmmԶmmmmmԶmԶmԶmmm@mmmmmm׻mԶmԶmԶmԶmԶmԶmԶmԶmԶmԶmԶmԶmԶmmԶmԶmԶmԶmԶmԶmԶmԶmԶmԶmԶmԶmԶmԶmԶmYm!momԶm7mmԶmԶmԶmԶmԶmԶm˺mԶmԶmmmstring literalstdmmmmmmTm1mmmmmmmmmmmmmmmmmmmmmmmmmrmmmmm9mmmmmmmmmmmmmmmlmmmlmlmlmlmWmWmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmlmWm (::|m|m|mmmm|mmmm|m|mmmmm|mJArray[]vtable for VTT for construction vtable for -in-typeinfo for typeinfo name for typeinfo fn for non-virtual thunk to virtual thunk to covariant return thunk to java Class for guard variable for reference temporary for hidden alias for ::*_Sat _Accum_Fract, operatoroperator : ulllullfalsetruejava resource decltype (...parm#%ld~mmmmmmm4mkmPmZmdmmmmmCm^mm|mmmmmmmlmlmlmlmlmlmlmlmlmDmmdmmmmmmmmm)mQmmmmmfmfmFmmXmHmmmmmmmmmglobal destructors keyed to global constructors keyed to restrict volatile const&&complex imaginary mmmmmmmmmmmmmmmmmmmmmmmmmm m4m@mPmXm`mmmmmhmsigned charboolbooleancharbytedoublelong doublefloat__float128unsigned charintunsigned intunsignedlongunsigned long__int128unsigned __int128shortunsigned shortvoidwchar_tlong longunsigned long longdecimal32decimal64decimal128halfchar16_tchar32_tlm lm xm}mmmmmm m mmm m m m mmœm ғmۓmۓmm m mmmm m mmmmm #mm+m ۓm5m5mRmRmHm Hm Rm Rm \m \m gmgmlmlmumumstd::allocatorallocatorstd::basic_stringbasic_stringstd::stringstd::basic_string, std::allocator >std::istreamstd::basic_istream >basic_istreamstd::ostreamstd::basic_ostream >basic_ostreamstd::iostreamstd::basic_iostream >basic_iostreamtmmammm bmm+m s8m DmF+m im m1ʗm oؗm m1m d(m 8m2kmaN&=aS=aaad&an()cm,co~dV/=dadelete[]de*dldeletedt.dv/eO^=eo^eq==ge>=gt>ixlS<<=le<=ls<<lt<mI-=mL*=mi-mlmm--nanew[]ne!=ngnt!nwnewoR|=oo||or|pL+=pl+pm->*pp++pspt->qu?rM%=rS>>=rm%rs>>sizeof szatalignof azDmGmJmMmOmmRmUmWmUmmZm]m`mbmemgmjmmmpmym|m~mmmmmmmmmmmmmmmmmmmmmmmmęmǙməm̙mϙmҙmՙmؙmڙm|mݙmmmmmmmؙmmmmmmmm m mmmmmmm m$m'm*mm-m0m3m6m8m;m>mAmEmHmJmMmmPmXmPm[m^mgm^mmmmmmmmmmmmȞmmmԞmmmmmmmm@mmm,mmm|mmm|mm@m|mmTm|mmdmmtm10QuaAdler3210QuaZipFile13QuaChecksum327QObject8QuaCrc329QIODeviceN10__cxxabiv115__forced_unwindEN10__cxxabiv117__class_type_infoEN10__cxxabiv119__foreign_exceptionEN10__cxxabiv120__si_class_type_infoEN9__gnu_cxx24__concurrence_lock_errorEN9__gnu_cxx26__concurrence_unlock_errorESt13bad_exceptionSt9bad_allocSt9exceptionSt9type_infomvmvmTvmHvmmmmm,mmLmTm\mdmlmtm|m|mУmmm mmmmЎmmmmmlmmmmmmmm mwmdwm0wm$wm$mmmm,mmmmmmd m( m m, m8m4mmm@m|mTmmmmd mD m m mLmmm0mXmmm<mdmmmHmpm mmTm|mhmPm`mmmmmmlmxmzPL|m $$m]AB FLm)AB $lHmkAB F$8ImAB N$mmAB F$m]AB F$ mfmAB F4m)AB  TmXmAB D$xImmAB F$mAB F$Lmxp mAB F$Nm mAB F$Tmh!mAB F$@Xmq!mAB F$h^mdp"mAB I$damM"mAB F$fm#mAB F$im9 $mAB I$qm$mAB FzP|m  smAB  < tmiAB E`xtmAB |tm@AB Dum*AB &mAB F$tȄmwN&mAB F$]AB F$fl&mAB F m&mAB D$@m&mAB E 8؆m&mAB D$\hm&mAB F$m'mAB F$0mT'mAB F$Pml'mAB E$mT'mAB F$$AB EУmBAB $$mT*mAB F$Lmh*mAB F$tm*mAB F$m*mAB F$,m*mAB FzPL|m $$ԧm*mAB E$Ldm*mAB F$tm5+mAB F mqr+mAB D mq~+mAB DzPL|m $$mVAB FLDm^AB $lmAB F$mrAB F$m+mAB F$m+mAB FzP|m  D m]AB F D mAB F h meAB FTm%AB DzP|m  d meAB D@( m;AB D ` m_AB F m^AB Fm%AB DzPL|m  $mAB D$HHm+mAB EzP|m  mVAB D@Pm_AB D`mKAB DzPL|m  $Tmn+mAB DzP|m  m'AB zPL|m $dm,mAB D|mAB dmAB zPL|m $ m"AB D8m`,mAB  dm$,mAB D mL,mAB D$mCt,mAB F$m>,mAB EzP|m  mAAB DzPL|m $$m,mAB F| lm[AB D8mKAB DXmLAB Dx`m}AB EmMAB D0mMAB Dm?AB DmAB m*AB 0m.AB DP4m"AB lXm0AB BmlAB EbO~oo(XHqLITf^NdaivHvTvvvvܐ8P0Уԕl$(ll,ԧdxxxy؆dyyh x}x<xz8ЃL}||LP@dw$w0wwwwp|Ў Xd@x\xxx0x z0x}Ȅxxxx 81bP,S>w %Eb*>b~#7f@b"Bm0?Xp!2QpAXp"=XvDf  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnquazip.dll_ZN10JlCompress10extractDirE7QStringS0__ZN10JlCompress10removeFileE11QStringList_ZN10JlCompress11compressDirE7QStringS0_b_ZN10JlCompress11extractFileE7QStringS0_S0__ZN10JlCompress11extractFileEP6QuaZip7QStringS2__ZN10JlCompress11getFileListE7QString_ZN10JlCompress12compressFileE7QStringS0__ZN10JlCompress12compressFileEP6QuaZip7QStringS2__ZN10JlCompress12extractFilesE7QString11QStringListS0__ZN10JlCompress13compressFilesE7QString11QStringList_ZN10JlCompress14compressSubDirEP6QuaZip7QStringS2_b_ZN10QuaAdler325resetEv_ZN10QuaAdler325valueEv_ZN10QuaAdler326updateERK10QByteArray_ZN10QuaAdler329calculateERK10QByteArray_ZN10QuaAdler32C1Ev_ZN10QuaAdler32C2Ev_ZN10QuaZipFile10setZipNameERK7QString_ZN10QuaZipFile11getFileInfoEP14QuaZipFileInfo_ZN10QuaZipFile11qt_metacallEN11QMetaObject4CallEiPPv_ZN10QuaZipFile11qt_metacastEPKc_ZN10QuaZipFile11setFileNameERK7QStringN6QuaZip15CaseSensitivityE_ZN10QuaZipFile16staticMetaObjectE_ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEE_ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEEPiS4_bPKc_ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEERK13QuaZipNewInfoPKcjiibiii_ZN10QuaZipFile5closeEv_ZN10QuaZipFile6setZipEP6QuaZip_ZN10QuaZipFile8readDataEPcx_ZN10QuaZipFile9writeDataEPKcx_ZN10QuaZipFileC1EP6QuaZipP7QObject_ZN10QuaZipFileC1EP7QObject_ZN10QuaZipFileC1ERK7QStringP7QObject_ZN10QuaZipFileC1ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject_ZN10QuaZipFileC1Ev_ZN10QuaZipFileC2EP6QuaZipP7QObject_ZN10QuaZipFileC2EP7QObject_ZN10QuaZipFileC2ERK7QStringP7QObject_ZN10QuaZipFileC2ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject_ZN10QuaZipFileC2Ev_ZN10QuaZipFileD0Ev_ZN10QuaZipFileD1Ev_ZN10QuaZipFileD2Ev_ZN13QuaZipNewInfo15setFileDateTimeERK7QString_ZN13QuaZipNewInfoC1ERK7QString_ZN13QuaZipNewInfoC1ERK7QStringS2__ZN13QuaZipNewInfoC2ERK7QString_ZN13QuaZipNewInfoC2ERK7QStringS2__ZN6QuaZip10getUnzFileEv_ZN6QuaZip10getZipFileEv_ZN6QuaZip10setCommentERK7QString_ZN6QuaZip10setZipNameERK7QString_ZN6QuaZip11setIoDeviceEP9QIODevice_ZN6QuaZip12goToNextFileEv_ZN6QuaZip13goToFirstFileEv_ZN6QuaZip14setCurrentFileERK7QStringNS_15CaseSensitivityE_ZN6QuaZip15setCommentCodecEP10QTextCodec_ZN6QuaZip15setCommentCodecEPKc_ZN6QuaZip16setFileNameCodecEP10QTextCodec_ZN6QuaZip16setFileNameCodecEPKc_ZN6QuaZip31setDataDescriptorWritingEnabledEb_ZN6QuaZip4openENS_4ModeEP19zlib_filefunc_def_s_ZN6QuaZip5closeEv_ZN6QuaZipC1EP9QIODevice_ZN6QuaZipC1ERK7QString_ZN6QuaZipC1Ev_ZN6QuaZipC2EP9QIODevice_ZN6QuaZipC2ERK7QString_ZN6QuaZipC2Ev_ZN6QuaZipD1Ev_ZN6QuaZipD2Ev_ZN8QuaCrc325resetEv_ZN8QuaCrc325valueEv_ZN8QuaCrc326updateERK10QByteArray_ZN8QuaCrc329calculateERK10QByteArray_ZN8QuaCrc32C1Ev_ZN8QuaCrc32C2Ev_ZNK10QuaZipFile10getZipNameEv_ZNK10QuaZipFile10metaObjectEv_ZNK10QuaZipFile11getFileNameEv_ZNK10QuaZipFile11getZipErrorEv_ZNK10QuaZipFile12isSequentialEv_ZNK10QuaZipFile14bytesAvailableEv_ZNK10QuaZipFile17getActualFileNameEv_ZNK10QuaZipFile18getCaseSensitivityEv_ZNK10QuaZipFile3posEv_ZNK10QuaZipFile4sizeEv_ZNK10QuaZipFile5atEndEv_ZNK10QuaZipFile5csizeEv_ZNK10QuaZipFile5isRawEv_ZNK10QuaZipFile5usizeEv_ZNK10QuaZipFile6getZipEv_ZNK6QuaZip10getCommentEv_ZNK6QuaZip10getZipNameEv_ZNK6QuaZip11getIoDeviceEv_ZNK6QuaZip11getZipErrorEv_ZNK6QuaZip14hasCurrentFileEv_ZNK6QuaZip15getCommentCodecEv_ZNK6QuaZip15getEntriesCountEv_ZNK6QuaZip15getFileInfoListEv_ZNK6QuaZip15getFileNameListEv_ZNK6QuaZip16getFileNameCodecEv_ZNK6QuaZip18getCurrentFileInfoEP14QuaZipFileInfo_ZNK6QuaZip18getCurrentFileNameEv_ZNK6QuaZip30isDataDescriptorWritingEnabledEv_ZNK6QuaZip6isOpenEv_ZNK6QuaZip7getModeEv_ZTV10QuaAdler32_ZTV10QuaZipFile_ZTV13QuaChecksum32_ZTV8QuaCrc32$0lDx<|":Rfv~ (0:DLV`hr|,H\x(D`x(<`Ht(Dd|,Pp Hl$<Tp0\<h $<\x0Lh(D`lt":Rfv~ (0:DLV`hr|,H\x(D`x(<`Ht(Dd|,Pp Hl$<Tp0\<h $<\x0Lh(D`lt&CloseHandleXCreateSemaphoreAGetCurrentThreadIdEGetLastErrorQGetModuleHandleAlGetProcAddressInterlockedDecrementInterlockedIncrementvReleaseSemaphoreSetLastErrorSleepTlsAllocTlsFreeTlsGetValueTlsSetValue*WaitForSingleObject__mingwthr_key_dtorm_write4__dllonexit_errno _iobGabortbfflushlfputcmfputsqfreeyfwritemallocrandreallocsprintfsrandstrcmpstrcpytime_Unwind_DeleteException_Unwind_GetDataRelBase _Unwind_GetIPInfo _Unwind_GetLanguageSpecificData _Unwind_GetRegionStartf _Unwind_GetTextRelBasef _Unwind_RaiseExceptionf_Unwind_Resumee_Unwind_Resume_or_Rethrow_Unwind_SetGR_Unwind_SetIP!__deregister_frame_infof'__emutls_get_addressP__register_frame_infoL_Z5qFreePvo_Z8qWarningPKczj_ZN10QByteArray11shared_nullE_ZN10QByteArray6resizeEi_ZN10QByteArray7reallocEi_ZN10QByteArrayC1EPKc_ZN10QByteArrayC1Eic_ZN10QByteArrayaSERKS_4_ZN10QTextCodec12codecForNameERK10QByteArray_ZN10QTextCodec14codecForLocaleEv_ZN4QDirC1ERK7QString_ZN4QDirD1Ev_ZN5QDateC1Eiiie_ZN5QFile11setFileNameERK7QString_ZN5QFile4openE6QFlagsIN9QIODevice12OpenModeFlagEEi _ZN5QFile5closeEv$_ZN5QFile6removeERK7QStringO/_ZN5QFileC1ERK7QStringa1_ZN5QFileC1Ev8_ZN5QFileD1EvD_ZN5QTimeC1Eiiii_ZN7QObject10childEventEP11QChildEventn_ZN7QObject10timerEventEP11QTimerEventn_ZN7QObject11customEventEP6QEvent_ZN7QObject11eventFilterEPS_P6QEvent_ZN7QObject13connectNotifyEPKce_ZN7QObject16disconnectNotifyEPKc_ZN7QObject5eventEP6QEventt_ZN7QString11shared_nullE_ZN7QString4freeEPNS_4DataEa6_ZN7QStringaSERKS_a _ZN9QDateTime15currentDateTimeEv _ZN9QDateTimeC1ERK5QDateRK5QTimeN2Qt8TimeSpecEr _ZN9QDateTimeC1ERKS_ _ZN9QDateTimeC1Ev _ZN9QDateTimeD1Ev! _ZN9QDateTimeaSERKS_( _ZN9QFileInfo7setFileERK7QString+ _ZN9QFileInfoC1ERK7QStringt, _ZN9QFileInfoC1ERKS_- _ZN9QFileInfoC1Ev3 _ZN9QFileInfoD1EvD _ZN9QIODevice11qt_metacallEN11QMetaObject4CallEiPPvEE _ZN9QIODevice11qt_metacastEPKceG _ZN9QIODevice11setOpenModeE6QFlagsINS_12OpenModeFlagEEtJ _ZN9QIODevice12readLineDataEPcxgK _ZN9QIODevice14setErrorStringERK7QStringL _ZN9QIODevice16staticMetaObjectEM _ZN9QIODevice16waitForReadyReadEiP _ZN9QIODevice19waitForBytesWrittenEiT _ZN9QIODevice4readEPcxgV _ZN9QIODevice4seekExX _ZN9QIODevice5resetEvZ _ZN9QIODevice5writeEPKcxe _ZN9QIODeviceC2EP7QObjectg _ZN9QIODeviceC2Evj _ZN9QIODeviceD2Evo _ZN9QListData11detach_growEPiikp _ZN9QListData11shared_nullEhu _ZN9QListData6appendEv_v _ZN9QListData6detachEi_/ _ZNK10QTextCodec11fromUnicodeERK7QString8 _ZNK10QTextCodec9toUnicodeEPKct9 _ZNK10QTextCodec9toUnicodeERK10QByteArray_ _ZNK11QMetaObject2trEPKcS1_n _ZNK4QDir13entryInfoListE6QFlagsINS_6FilterEES0_INS_8SortFlagEEQ _ZNK4QDir16absoluteFilePathERK7QString6 _ZNK4QDir16relativeFilePathERK7QString6 _ZNK4QDir6existsEvQ _ZNK4QDir6mkpathERK7QStringRp _ZNK5QDate3dayEvq _ZNK5QDate4yearEvr _ZNK5QDate5monthEvn _ZNK5QFile8fileNameEv _ZNK5QTime4hourEv _ZNK5QTime6minuteEvR _ZNK5QTime6secondEvR" _ZNK7QString3argExiiRK5QCharA _ZNK7QString7toLowerEv_P _ZNK7QStringeqERKS_L _ZNK9QDateTime4dateEv _ZNK9QDateTime4timeEv _ZNK9QFileInfo12absolutePathEvg _ZNK9QFileInfo12lastModifiedEvg _ZNK9QFileInfo16absoluteFilePathEv5 _ZNK9QFileInfo5isDirEvl _ZNK9QFileInfo6existsEvl _ZNK9QFileInfo6isFileEvl _ZNK9QFileInfo8fileNameEv _ZNK9QIODevice11canReadLineEv _ZNK9QIODevice11errorStringEv _ZNK9QIODevice12bytesToWriteEvh _ZNK9QIODevice14bytesAvailableEv _ZNK9QIODevice6isOpenEvd _ZNK9QIODevice8openModeEvadler32icrc32deflate2deflateEndrdeflateInit2_get_crc_tableinflateainflateEndeinflateInit2_KERNEL32.dllmingwm10.dll(msvcrt.dll<<<<<<<<<<<<<<<<<msvcrt.dllPPPPPPPPPPPPPPlibgcc_s_dw2-1.dllddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddQtCore4.dll8 0010L00001 1B1P1y11111111122-292 y5@T446z7 9w99q::::::;;4;D;[;u;;;;?'?]???PY0p0}001`2t22K333445$5U55555556667m77788G8i8888'9L9999>::M;`;`>w>>G?d?????`0+0b0{000001|11111 22222222;3H3u33444455<6l6667:7@7\7l7u7777 848888Y99*:>:D:::::*;;;;;; x>>>>>>?O???p 0121g111111'2@2T2d22333344444444545`5555%666779:9S9X99999o:u:::;;;;;2?n000 1,1H1X1a1t111112k2q223'3-3j3333j4y4 5055555556666707?7E7778Q8888(9C9I9r9999>::;; <<<-<\<}<<< =X=a=}==?-?E?W?]?????00%080>0w00000000K1P111112>2D2^222223233333:4@4[4444445545]5{555556&6h6s6y666677E7U777796999::::::;(;=/=o=u==>>D>S>Y>k>q>>>>>>>??x?000)191G1M1i1112"272=2O2U2g2m2$3Q3W333L4X444 55'5r5555)6F666667:7C77777788%8.8A8X8888888888 99#9/9B9_9e9k99999$:6:D:i:o:::::::::::;;.;A;Z;s;;;;/=F=N=V=^=f=n=v=~=========??< 0!0022_3436679::;;K;P;;;aI>>>2???p0n112222233?4446H778899Q9Y9a99<<<=#=-=>=I=b=w==============> >>>112222&2.262>2F2N2V2^2f2n2v2~222222222222222223'3736!7Z7777778'8<8L8`8888B99 :,:::P:r::F;>?|)0y0V111112O22 3X3:444+5`555.6E6i6q6y6666 7#7+7I7Z77778/88 I>>>f?????40@0L0X0d00001+1C1[1p11111111112 2/2i2222233#3J3V3_3333333C4I4T4g444444445 566667777777 8'8?8G8O8i8q8y888888889'9?9G9O9i9q9y9999r:{::q=?|???  ;<0000p :$:8888888888888 :$:(:,:0:4:8:<:@:D:H:L:P:T:X:\:`:d:h:l:p:t:x:|:::::::::::::::::::::::::::::::::;;; ;;;;; ;$;(;,;0;4;8;<;@;D;H;L;P;T;X;\;`;d;h;l;p;t;x;|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; <$<(<,<0<4<8<<<@>> >$>(>,>0>4>8><>@>D>H>L>P>T>X>\>`>d>h>l>p>t>x>|>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>??? ????? ?$?(?,?0?4?8?>> >>>>> >$>(>,>0>4>8><>@>D>H>L>P>T>X>\>`>d>h>l>p>t>x>|>>>>0000000000000000000000000000111 111$1(1,10141<1@1D1H1L1T1X1\1`1111111111111111111111222$2(2,202<2@2D2H2T2X2\2`2l2p2t2x22222222222222303X33333334!4<4E4d44444445 5,555T5]5|55555556,6P6l666667 7<7i7|77777 8D8l888888 9949=9\9e99999999:$:-:L:U:t:::::::;;4;=;\;e;;;;;;;;<$<-!><>E>d>m>>>>>>>>??%?D?M?l????? 000T0x00000 1141=1\1e111111112%2D2M2l2u2222223D3l3u333333 4D4m44444525H5l5u5555560696]6p6666667,7L7U7l7u7777777 8 8J8`8i888889<9\9|99999:mudlet-2.1/src/quazip/quazip-0.4.4/quazip/release/libquazip.a0000644000175000017500000023131612070466513023335 0ustar csmallcsmall! / 1340540258 0 0 0 9262 ` $r%'0'0)R)R++--//2&2&4j4j669b9b;;>b>b@@C*C*EEGGJPJPLLOOQRQRSSUUXFXFZZ\\_6_6aaccfLfLhhk2k2mmpprfrfttw.w.yfyf{{~~ @@ttFFzzXX||llTT ff00TTzzPP&&hhΪΪӼӼ22،،@@RRxxBBpp~~    VVHH!2!2##&*&*((+L+L--0P0P_quazip_dll_iname__head_quazip_dll__imp___ZTV8QuaCrc32__nm___ZTV8QuaCrc32__imp___ZTV13QuaChecksum32__nm___ZTV13QuaChecksum32__imp___ZTV10QuaZipFile__nm___ZTV10QuaZipFile__imp___ZTV10QuaAdler32__nm___ZTV10QuaAdler32__ZNK6QuaZip7getModeEv__imp___ZNK6QuaZip7getModeEv__ZNK6QuaZip6isOpenEv__imp___ZNK6QuaZip6isOpenEv__ZNK6QuaZip30isDataDescriptorWritingEnabledEv__imp___ZNK6QuaZip30isDataDescriptorWritingEnabledEv__ZNK6QuaZip18getCurrentFileNameEv__imp___ZNK6QuaZip18getCurrentFileNameEv__ZNK6QuaZip18getCurrentFileInfoEP14QuaZipFileInfo__imp___ZNK6QuaZip18getCurrentFileInfoEP14QuaZipFileInfo__ZNK6QuaZip16getFileNameCodecEv__imp___ZNK6QuaZip16getFileNameCodecEv__ZNK6QuaZip15getFileNameListEv__imp___ZNK6QuaZip15getFileNameListEv__ZNK6QuaZip15getFileInfoListEv__imp___ZNK6QuaZip15getFileInfoListEv__ZNK6QuaZip15getEntriesCountEv__imp___ZNK6QuaZip15getEntriesCountEv__ZNK6QuaZip15getCommentCodecEv__imp___ZNK6QuaZip15getCommentCodecEv__ZNK6QuaZip14hasCurrentFileEv__imp___ZNK6QuaZip14hasCurrentFileEv__ZNK6QuaZip11getZipErrorEv__imp___ZNK6QuaZip11getZipErrorEv__ZNK6QuaZip11getIoDeviceEv__imp___ZNK6QuaZip11getIoDeviceEv__ZNK6QuaZip10getZipNameEv__imp___ZNK6QuaZip10getZipNameEv__ZNK6QuaZip10getCommentEv__imp___ZNK6QuaZip10getCommentEv__ZNK10QuaZipFile6getZipEv__imp___ZNK10QuaZipFile6getZipEv__ZNK10QuaZipFile5usizeEv__imp___ZNK10QuaZipFile5usizeEv__ZNK10QuaZipFile5isRawEv__imp___ZNK10QuaZipFile5isRawEv__ZNK10QuaZipFile5csizeEv__imp___ZNK10QuaZipFile5csizeEv__ZNK10QuaZipFile5atEndEv__imp___ZNK10QuaZipFile5atEndEv__ZNK10QuaZipFile4sizeEv__imp___ZNK10QuaZipFile4sizeEv__ZNK10QuaZipFile3posEv__imp___ZNK10QuaZipFile3posEv__ZNK10QuaZipFile18getCaseSensitivityEv__imp___ZNK10QuaZipFile18getCaseSensitivityEv__ZNK10QuaZipFile17getActualFileNameEv__imp___ZNK10QuaZipFile17getActualFileNameEv__ZNK10QuaZipFile14bytesAvailableEv__imp___ZNK10QuaZipFile14bytesAvailableEv__ZNK10QuaZipFile12isSequentialEv__imp___ZNK10QuaZipFile12isSequentialEv__ZNK10QuaZipFile11getZipErrorEv__imp___ZNK10QuaZipFile11getZipErrorEv__ZNK10QuaZipFile11getFileNameEv__imp___ZNK10QuaZipFile11getFileNameEv__ZNK10QuaZipFile10metaObjectEv__imp___ZNK10QuaZipFile10metaObjectEv__ZNK10QuaZipFile10getZipNameEv__imp___ZNK10QuaZipFile10getZipNameEv__ZN8QuaCrc32C2Ev__imp___ZN8QuaCrc32C2Ev__ZN8QuaCrc32C1Ev__imp___ZN8QuaCrc32C1Ev__ZN8QuaCrc329calculateERK10QByteArray__imp___ZN8QuaCrc329calculateERK10QByteArray__ZN8QuaCrc326updateERK10QByteArray__imp___ZN8QuaCrc326updateERK10QByteArray__ZN8QuaCrc325valueEv__imp___ZN8QuaCrc325valueEv__ZN8QuaCrc325resetEv__imp___ZN8QuaCrc325resetEv__ZN6QuaZipD2Ev__imp___ZN6QuaZipD2Ev__ZN6QuaZipD1Ev__imp___ZN6QuaZipD1Ev__ZN6QuaZipC2Ev__imp___ZN6QuaZipC2Ev__ZN6QuaZipC2ERK7QString__imp___ZN6QuaZipC2ERK7QString__ZN6QuaZipC2EP9QIODevice__imp___ZN6QuaZipC2EP9QIODevice__ZN6QuaZipC1Ev__imp___ZN6QuaZipC1Ev__ZN6QuaZipC1ERK7QString__imp___ZN6QuaZipC1ERK7QString__ZN6QuaZipC1EP9QIODevice__imp___ZN6QuaZipC1EP9QIODevice__ZN6QuaZip5closeEv__imp___ZN6QuaZip5closeEv__ZN6QuaZip4openENS_4ModeEP19zlib_filefunc_def_s__imp___ZN6QuaZip4openENS_4ModeEP19zlib_filefunc_def_s__ZN6QuaZip31setDataDescriptorWritingEnabledEb__imp___ZN6QuaZip31setDataDescriptorWritingEnabledEb__ZN6QuaZip16setFileNameCodecEPKc__imp___ZN6QuaZip16setFileNameCodecEPKc__ZN6QuaZip16setFileNameCodecEP10QTextCodec__imp___ZN6QuaZip16setFileNameCodecEP10QTextCodec__ZN6QuaZip15setCommentCodecEPKc__imp___ZN6QuaZip15setCommentCodecEPKc__ZN6QuaZip15setCommentCodecEP10QTextCodec__imp___ZN6QuaZip15setCommentCodecEP10QTextCodec__ZN6QuaZip14setCurrentFileERK7QStringNS_15CaseSensitivityE__imp___ZN6QuaZip14setCurrentFileERK7QStringNS_15CaseSensitivityE__ZN6QuaZip13goToFirstFileEv__imp___ZN6QuaZip13goToFirstFileEv__ZN6QuaZip12goToNextFileEv__imp___ZN6QuaZip12goToNextFileEv__ZN6QuaZip11setIoDeviceEP9QIODevice__imp___ZN6QuaZip11setIoDeviceEP9QIODevice__ZN6QuaZip10setZipNameERK7QString__imp___ZN6QuaZip10setZipNameERK7QString__ZN6QuaZip10setCommentERK7QString__imp___ZN6QuaZip10setCommentERK7QString__ZN6QuaZip10getZipFileEv__imp___ZN6QuaZip10getZipFileEv__ZN6QuaZip10getUnzFileEv__imp___ZN6QuaZip10getUnzFileEv__ZN13QuaZipNewInfoC2ERK7QStringS2___imp___ZN13QuaZipNewInfoC2ERK7QStringS2___ZN13QuaZipNewInfoC2ERK7QString__imp___ZN13QuaZipNewInfoC2ERK7QString__ZN13QuaZipNewInfoC1ERK7QStringS2___imp___ZN13QuaZipNewInfoC1ERK7QStringS2___ZN13QuaZipNewInfoC1ERK7QString__imp___ZN13QuaZipNewInfoC1ERK7QString__ZN13QuaZipNewInfo15setFileDateTimeERK7QString__imp___ZN13QuaZipNewInfo15setFileDateTimeERK7QString__ZN10QuaZipFileD2Ev__imp___ZN10QuaZipFileD2Ev__ZN10QuaZipFileD1Ev__imp___ZN10QuaZipFileD1Ev__ZN10QuaZipFileD0Ev__imp___ZN10QuaZipFileD0Ev__ZN10QuaZipFileC2Ev__imp___ZN10QuaZipFileC2Ev__ZN10QuaZipFileC2ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject__imp___ZN10QuaZipFileC2ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject__ZN10QuaZipFileC2ERK7QStringP7QObject__imp___ZN10QuaZipFileC2ERK7QStringP7QObject__ZN10QuaZipFileC2EP7QObject__imp___ZN10QuaZipFileC2EP7QObject__ZN10QuaZipFileC2EP6QuaZipP7QObject__imp___ZN10QuaZipFileC2EP6QuaZipP7QObject__ZN10QuaZipFileC1Ev__imp___ZN10QuaZipFileC1Ev__ZN10QuaZipFileC1ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject__imp___ZN10QuaZipFileC1ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject__ZN10QuaZipFileC1ERK7QStringP7QObject__imp___ZN10QuaZipFileC1ERK7QStringP7QObject__ZN10QuaZipFileC1EP7QObject__imp___ZN10QuaZipFileC1EP7QObject__ZN10QuaZipFileC1EP6QuaZipP7QObject__imp___ZN10QuaZipFileC1EP6QuaZipP7QObject__ZN10QuaZipFile9writeDataEPKcx__imp___ZN10QuaZipFile9writeDataEPKcx__ZN10QuaZipFile8readDataEPcx__imp___ZN10QuaZipFile8readDataEPcx__ZN10QuaZipFile6setZipEP6QuaZip__imp___ZN10QuaZipFile6setZipEP6QuaZip__ZN10QuaZipFile5closeEv__imp___ZN10QuaZipFile5closeEv__ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEERK13QuaZipNewInfoPKcjiibiii__imp___ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEERK13QuaZipNewInfoPKcjiibiii__ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEEPiS4_bPKc__imp___ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEEPiS4_bPKc__ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEE__imp___ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEE__imp___ZN10QuaZipFile16staticMetaObjectE__nm___ZN10QuaZipFile16staticMetaObjectE__ZN10QuaZipFile11setFileNameERK7QStringN6QuaZip15CaseSensitivityE__imp___ZN10QuaZipFile11setFileNameERK7QStringN6QuaZip15CaseSensitivityE__ZN10QuaZipFile11qt_metacastEPKc__imp___ZN10QuaZipFile11qt_metacastEPKc__ZN10QuaZipFile11qt_metacallEN11QMetaObject4CallEiPPv__imp___ZN10QuaZipFile11qt_metacallEN11QMetaObject4CallEiPPv__ZN10QuaZipFile11getFileInfoEP14QuaZipFileInfo__imp___ZN10QuaZipFile11getFileInfoEP14QuaZipFileInfo__ZN10QuaZipFile10setZipNameERK7QString__imp___ZN10QuaZipFile10setZipNameERK7QString__ZN10QuaAdler32C2Ev__imp___ZN10QuaAdler32C2Ev__ZN10QuaAdler32C1Ev__imp___ZN10QuaAdler32C1Ev__ZN10QuaAdler329calculateERK10QByteArray__imp___ZN10QuaAdler329calculateERK10QByteArray__ZN10QuaAdler326updateERK10QByteArray__imp___ZN10QuaAdler326updateERK10QByteArray__ZN10QuaAdler325valueEv__imp___ZN10QuaAdler325valueEv__ZN10QuaAdler325resetEv__imp___ZN10QuaAdler325resetEv__ZN10JlCompress14compressSubDirEP6QuaZip7QStringS2_b__imp___ZN10JlCompress14compressSubDirEP6QuaZip7QStringS2_b__ZN10JlCompress13compressFilesE7QString11QStringList__imp___ZN10JlCompress13compressFilesE7QString11QStringList__ZN10JlCompress12extractFilesE7QString11QStringListS0___imp___ZN10JlCompress12extractFilesE7QString11QStringListS0___ZN10JlCompress12compressFileEP6QuaZip7QStringS2___imp___ZN10JlCompress12compressFileEP6QuaZip7QStringS2___ZN10JlCompress12compressFileE7QStringS0___imp___ZN10JlCompress12compressFileE7QStringS0___ZN10JlCompress11getFileListE7QString__imp___ZN10JlCompress11getFileListE7QString__ZN10JlCompress11extractFileEP6QuaZip7QStringS2___imp___ZN10JlCompress11extractFileEP6QuaZip7QStringS2___ZN10JlCompress11extractFileE7QStringS0_S0___imp___ZN10JlCompress11extractFileE7QStringS0_S0___ZN10JlCompress11compressDirE7QStringS0_b__imp___ZN10JlCompress11compressDirE7QStringS0_b__ZN10JlCompress10removeFileE11QStringList__imp___ZN10JlCompress10removeFileE11QStringList__ZN10JlCompress10extractDirE7QStringS0___imp___ZN10JlCompress10extractDirE7QStringS0_d000112.o/ 1340540258 0 0 644 254 ` L.idata$40.idata$50.idata$7 0quazip.dll.idata$4.idata$5.idata$7_quazip_dll_inamed000000.o/ 1340540258 0 0 644 328 ` L.idata$20.idata$50.idata$40 .idata$2.idata$5.idata$4(__head_quazip_dll_quazip_dll_inamed000111.o/ 1340540258 0 0 644 485 ` L.text 0.idata$70.idata$50.idata$4 0.idata$60n_ZTV8QuaCrc32.text.idata$7.idata$5.idata$4.idata$6-?__imp___ZTV8QuaCrc32__nm___ZTV8QuaCrc32__head_quazip_dll d000110.o/ 1340540258 0 0 644 505 ` L.text 0.idata$70.idata$5 0.idata$40.idata$60m_ZTV13QuaChecksum32.text.idata$7.idata$5.idata$4.idata$69K__imp___ZTV13QuaChecksum32__nm___ZTV13QuaChecksum32__head_quazip_dll d000109.o/ 1340540258 0 0 644 495 ` L.text 0.idata$70.idata$50.idata$40.idata$60l_ZTV10QuaZipFile.text.idata$7.idata$5.idata$4.idata$63E__imp___ZTV10QuaZipFile__nm___ZTV10QuaZipFile__head_quazip_dll d000108.o/ 1340540258 0 0 644 495 ` L.text 0.idata$70.idata$50.idata$40.idata$60k_ZTV10QuaAdler32.text.idata$7.idata$5.idata$4.idata$63E__imp___ZTV10QuaAdler32__nm___ZTV10QuaAdler32__head_quazip_dll d000107.o/ 1340540258 0 0 644 522 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%j_ZNK6QuaZip7getModeEv.text.idata$7.idata$5.idata$4.idata$68J__ZNK6QuaZip7getModeEv__imp___ZNK6QuaZip7getModeEv__head_quazip_dlld000106.o/ 1340540258 0 0 644 520 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%i_ZNK6QuaZip6isOpenEv.text.idata$7.idata$5.idata$4.idata$66H__ZNK6QuaZip6isOpenEv__imp___ZNK6QuaZip6isOpenEv__head_quazip_dlld000105.o/ 1340540258 0 0 644 594 ` LH.text  0.idata$7*0.idata$540.idata$4>0.idata$600%h_ZNK6QuaZip30isDataDescriptorWritingEnabledEv.text.idata$7.idata$5.idata$4.idata$63hz__ZNK6QuaZip30isDataDescriptorWritingEnabledEv__imp___ZNK6QuaZip30isDataDescriptorWritingEnabledEv__head_quazip_dlld000104.o/ 1340540258 0 0 644 558 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%g_ZNK6QuaZip18getCurrentFileNameEv.text.idata$7.idata$5.idata$4.idata$6'Pb__ZNK6QuaZip18getCurrentFileNameEv__imp___ZNK6QuaZip18getCurrentFileNameEv__head_quazip_dlld000103.o/ 1340540258 0 0 644 606 ` LL.text$ 0.idata$7.0.idata$580.idata$4B0.idata$640%f_ZNK6QuaZip18getCurrentFileInfoEP14QuaZipFileInfo.text.idata$7.idata$5.idata$4.idata$67p__ZNK6QuaZip18getCurrentFileInfoEP14QuaZipFileInfo__imp___ZNK6QuaZip18getCurrentFileInfoEP14QuaZipFileInfo__head_quazip_dlld000102.o/ 1340540258 0 0 644 554 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%e_ZNK6QuaZip16getFileNameCodecEvv.text.idata$7.idata$5.idata$4.idata$6%L^__ZNK6QuaZip16getFileNameCodecEv__imp___ZNK6QuaZip16getFileNameCodecEv__head_quazip_dlld000101.o/ 1340540258 0 0 644 552 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%d_ZNK6QuaZip15getFileNameListEvv.text.idata$7.idata$5.idata$4.idata$6$J\__ZNK6QuaZip15getFileNameListEv__imp___ZNK6QuaZip15getFileNameListEv__head_quazip_dlld000100.o/ 1340540258 0 0 644 552 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%c_ZNK6QuaZip15getFileInfoListEvv.text.idata$7.idata$5.idata$4.idata$6$J\__ZNK6QuaZip15getFileInfoListEv__imp___ZNK6QuaZip15getFileInfoListEv__head_quazip_dlld000099.o/ 1340540258 0 0 644 552 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%b_ZNK6QuaZip15getEntriesCountEvv.text.idata$7.idata$5.idata$4.idata$6$J\__ZNK6QuaZip15getEntriesCountEv__imp___ZNK6QuaZip15getEntriesCountEv__head_quazip_dlld000098.o/ 1340540258 0 0 644 552 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%a_ZNK6QuaZip15getCommentCodecEvv.text.idata$7.idata$5.idata$4.idata$6$J\__ZNK6QuaZip15getCommentCodecEv__imp___ZNK6QuaZip15getCommentCodecEv__head_quazip_dlld000097.o/ 1340540258 0 0 644 546 ` L8.text 0.idata$70.idata$5$0.idata$4.0.idata$6 0%`_ZNK6QuaZip14hasCurrentFileEv.text.idata$7.idata$5.idata$4.idata$6#HZ__ZNK6QuaZip14hasCurrentFileEv__imp___ZNK6QuaZip14hasCurrentFileEv__head_quazip_dlld000096.o/ 1340540258 0 0 644 540 ` L8.text 0.idata$70.idata$5$0.idata$4.0.idata$6 0%__ZNK6QuaZip11getZipErrorEvs.text.idata$7.idata$5.idata$4.idata$6 BT__ZNK6QuaZip11getZipErrorEv__imp___ZNK6QuaZip11getZipErrorEv__head_quazip_dlld000095.o/ 1340540258 0 0 644 540 ` L8.text 0.idata$70.idata$5$0.idata$4.0.idata$6 0%^_ZNK6QuaZip11getIoDeviceEvs.text.idata$7.idata$5.idata$4.idata$6 BT__ZNK6QuaZip11getIoDeviceEv__imp___ZNK6QuaZip11getIoDeviceEv__head_quazip_dlld000094.o/ 1340540258 0 0 644 534 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%]_ZNK6QuaZip10getZipNameEv.text.idata$7.idata$5.idata$4.idata$6@R__ZNK6QuaZip10getZipNameEv__imp___ZNK6QuaZip10getZipNameEv__head_quazip_dlld000093.o/ 1340540258 0 0 644 534 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%\_ZNK6QuaZip10getCommentEv.text.idata$7.idata$5.idata$4.idata$6@R__ZNK6QuaZip10getCommentEv__imp___ZNK6QuaZip10getCommentEv__head_quazip_dlld000092.o/ 1340540258 0 0 644 534 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%[_ZNK10QuaZipFile6getZipEv.text.idata$7.idata$5.idata$4.idata$6@R__ZNK10QuaZipFile6getZipEv__imp___ZNK10QuaZipFile6getZipEv__head_quazip_dlld000091.o/ 1340540258 0 0 644 532 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%Z_ZNK10QuaZipFile5usizeEv.text.idata$7.idata$5.idata$4.idata$6>P__ZNK10QuaZipFile5usizeEv__imp___ZNK10QuaZipFile5usizeEv__head_quazip_dlld000090.o/ 1340540258 0 0 644 532 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%Y_ZNK10QuaZipFile5isRawEv.text.idata$7.idata$5.idata$4.idata$6>P__ZNK10QuaZipFile5isRawEv__imp___ZNK10QuaZipFile5isRawEv__head_quazip_dlld000089.o/ 1340540258 0 0 644 532 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%X_ZNK10QuaZipFile5csizeEv.text.idata$7.idata$5.idata$4.idata$6>P__ZNK10QuaZipFile5csizeEv__imp___ZNK10QuaZipFile5csizeEv__head_quazip_dlld000088.o/ 1340540258 0 0 644 532 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%W_ZNK10QuaZipFile5atEndEv.text.idata$7.idata$5.idata$4.idata$6>P__ZNK10QuaZipFile5atEndEv__imp___ZNK10QuaZipFile5atEndEv__head_quazip_dlld000087.o/ 1340540258 0 0 644 530 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%V_ZNK10QuaZipFile4sizeEve.text.idata$7.idata$5.idata$4.idata$6<N__ZNK10QuaZipFile4sizeEv__imp___ZNK10QuaZipFile4sizeEv__head_quazip_dlld000086.o/ 1340540258 0 0 644 528 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%U_ZNK10QuaZipFile3posEve.text.idata$7.idata$5.idata$4.idata$6:L__ZNK10QuaZipFile3posEv__imp___ZNK10QuaZipFile3posEv__head_quazip_dlld000085.o/ 1340540258 0 0 644 576 ` LD.text 0.idata$7&0.idata$500.idata$4:0.idata$6,0%T_ZNK10QuaZipFile18getCaseSensitivityEv.text.idata$7.idata$5.idata$4.idata$6,Zl__ZNK10QuaZipFile18getCaseSensitivityEv__imp___ZNK10QuaZipFile18getCaseSensitivityEv__head_quazip_dlld000084.o/ 1340540258 0 0 644 570 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%S_ZNK10QuaZipFile17getActualFileNameEv.text.idata$7.idata$5.idata$4.idata$6+Xj__ZNK10QuaZipFile17getActualFileNameEv__imp___ZNK10QuaZipFile17getActualFileNameEv__head_quazip_dlld000083.o/ 1340540258 0 0 644 564 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%R_ZNK10QuaZipFile14bytesAvailableEv.text.idata$7.idata$5.idata$4.idata$6(Rd__ZNK10QuaZipFile14bytesAvailableEv__imp___ZNK10QuaZipFile14bytesAvailableEv__head_quazip_dlld000082.o/ 1340540258 0 0 644 556 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%Q_ZNK10QuaZipFile12isSequentialEv.text.idata$7.idata$5.idata$4.idata$6&N`__ZNK10QuaZipFile12isSequentialEv__imp___ZNK10QuaZipFile12isSequentialEv__head_quazip_dlld000081.o/ 1340540258 0 0 644 554 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%P_ZNK10QuaZipFile11getZipErrorEv.text.idata$7.idata$5.idata$4.idata$6%L^__ZNK10QuaZipFile11getZipErrorEv__imp___ZNK10QuaZipFile11getZipErrorEv__head_quazip_dlld000080.o/ 1340540258 0 0 644 554 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%O_ZNK10QuaZipFile11getFileNameEv.text.idata$7.idata$5.idata$4.idata$6%L^__ZNK10QuaZipFile11getFileNameEv__imp___ZNK10QuaZipFile11getFileNameEv__head_quazip_dlld000079.o/ 1340540258 0 0 644 552 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%N_ZNK10QuaZipFile10metaObjectEv.text.idata$7.idata$5.idata$4.idata$6$J\__ZNK10QuaZipFile10metaObjectEv__imp___ZNK10QuaZipFile10metaObjectEv__head_quazip_dlld000078.o/ 1340540258 0 0 644 552 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%M_ZNK10QuaZipFile10getZipNameEv.text.idata$7.idata$5.idata$4.idata$6$J\__ZNK10QuaZipFile10getZipNameEv__imp___ZNK10QuaZipFile10getZipNameEv__head_quazip_dlld000077.o/ 1340540258 0 0 644 508 ` L,.text 0.idata$70.idata$50.idata$4"0.idata$60%L_ZN8QuaCrc32C2Ev.text.idata$7.idata$5.idata$4.idata$6.@__ZN8QuaCrc32C2Ev__imp___ZN8QuaCrc32C2Ev__head_quazip_dlld000076.o/ 1340540258 0 0 644 508 ` L,.text 0.idata$70.idata$50.idata$4"0.idata$60%K_ZN8QuaCrc32C1Ev.text.idata$7.idata$5.idata$4.idata$6.@__ZN8QuaCrc32C1Ev__imp___ZN8QuaCrc32C1Ev__head_quazip_dlld000075.o/ 1340540258 0 0 644 570 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%J_ZN8QuaCrc329calculateERK10QByteArray.text.idata$7.idata$5.idata$4.idata$6+Xj__ZN8QuaCrc329calculateERK10QByteArray__imp___ZN8QuaCrc329calculateERK10QByteArray__head_quazip_dlld000074.o/ 1340540258 0 0 644 564 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%I_ZN8QuaCrc326updateERK10QByteArraye.text.idata$7.idata$5.idata$4.idata$6(Rd__ZN8QuaCrc326updateERK10QByteArray__imp___ZN8QuaCrc326updateERK10QByteArray__head_quazip_dlld000073.o/ 1340540258 0 0 644 520 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%H_ZN8QuaCrc325valueEv.text.idata$7.idata$5.idata$4.idata$66H__ZN8QuaCrc325valueEv__imp___ZN8QuaCrc325valueEv__head_quazip_dlld000072.o/ 1340540258 0 0 644 520 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%G_ZN8QuaCrc325resetEv.text.idata$7.idata$5.idata$4.idata$66H__ZN8QuaCrc325resetEv__imp___ZN8QuaCrc325resetEv__head_quazip_dlld000071.o/ 1340540258 0 0 644 504 ` L,.text 0.idata$70.idata$50.idata$4"0.idata$60%F_ZN6QuaZipD2EvQ.text.idata$7.idata$5.idata$4.idata$6*<__ZN6QuaZipD2Ev__imp___ZN6QuaZipD2Ev__head_quazip_dlld000070.o/ 1340540258 0 0 644 504 ` L,.text 0.idata$70.idata$50.idata$4"0.idata$60%E_ZN6QuaZipD1EvQ.text.idata$7.idata$5.idata$4.idata$6*<__ZN6QuaZipD1Ev__imp___ZN6QuaZipD1Ev__head_quazip_dlld000069.o/ 1340540258 0 0 644 504 ` L,.text 0.idata$70.idata$50.idata$4"0.idata$60%D_ZN6QuaZipC2EvQ.text.idata$7.idata$5.idata$4.idata$6*<__ZN6QuaZipC2Ev__imp___ZN6QuaZipC2Ev__head_quazip_dlld000068.o/ 1340540258 0 0 644 530 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%C_ZN6QuaZipC2ERK7QString.text.idata$7.idata$5.idata$4.idata$6<N__ZN6QuaZipC2ERK7QString__imp___ZN6QuaZipC2ERK7QString__head_quazip_dlld000067.o/ 1340540258 0 0 644 532 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%B_ZN6QuaZipC2EP9QIODevice.text.idata$7.idata$5.idata$4.idata$6>P__ZN6QuaZipC2EP9QIODevice__imp___ZN6QuaZipC2EP9QIODevice__head_quazip_dlld000066.o/ 1340540258 0 0 644 504 ` L,.text 0.idata$70.idata$50.idata$4"0.idata$60%A_ZN6QuaZipC1EvQ.text.idata$7.idata$5.idata$4.idata$6*<__ZN6QuaZipC1Ev__imp___ZN6QuaZipC1Ev__head_quazip_dlld000065.o/ 1340540258 0 0 644 530 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%@_ZN6QuaZipC1ERK7QString.text.idata$7.idata$5.idata$4.idata$6<N__ZN6QuaZipC1ERK7QString__imp___ZN6QuaZipC1ERK7QString__head_quazip_dlld000064.o/ 1340540258 0 0 644 532 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%?_ZN6QuaZipC1EP9QIODevice.text.idata$7.idata$5.idata$4.idata$6>P__ZN6QuaZipC1EP9QIODevice__imp___ZN6QuaZipC1EP9QIODevice__head_quazip_dlld000063.o/ 1340540258 0 0 644 516 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%>_ZN6QuaZip5closeEvM.text.idata$7.idata$5.idata$4.idata$62D__ZN6QuaZip5closeEv__imp___ZN6QuaZip5closeEv__head_quazip_dlld000062.o/ 1340540258 0 0 644 602 ` LL.text$ 0.idata$7.0.idata$580.idata$4B0.idata$640%=_ZN6QuaZip4openENS_4ModeEP19zlib_filefunc_def_sn.text.idata$7.idata$5.idata$4.idata$65l~__ZN6QuaZip4openENS_4ModeEP19zlib_filefunc_def_s__imp___ZN6QuaZip4openENS_4ModeEP19zlib_filefunc_def_s__head_quazip_dlld000061.o/ 1340540258 0 0 644 594 ` LH.text  0.idata$7*0.idata$540.idata$4>0.idata$600%<_ZN6QuaZip31setDataDescriptorWritingEnabledEb.text.idata$7.idata$5.idata$4.idata$63hz__ZN6QuaZip31setDataDescriptorWritingEnabledEb__imp___ZN6QuaZip31setDataDescriptorWritingEnabledEb__head_quazip_dlld000060.o/ 1340540258 0 0 644 556 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%;_ZN6QuaZip16setFileNameCodecEPKc.text.idata$7.idata$5.idata$4.idata$6&N`__ZN6QuaZip16setFileNameCodecEPKc__imp___ZN6QuaZip16setFileNameCodecEPKc__head_quazip_dlld000059.o/ 1340540258 0 0 644 588 ` LH.text  0.idata$7*0.idata$540.idata$4>0.idata$600%:_ZN6QuaZip16setFileNameCodecEP10QTextCodecs.text.idata$7.idata$5.idata$4.idata$60bt__ZN6QuaZip16setFileNameCodecEP10QTextCodec__imp___ZN6QuaZip16setFileNameCodecEP10QTextCodec__head_quazip_dlld000058.o/ 1340540258 0 0 644 554 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%9_ZN6QuaZip15setCommentCodecEPKcT.text.idata$7.idata$5.idata$4.idata$6%L^__ZN6QuaZip15setCommentCodecEPKc__imp___ZN6QuaZip15setCommentCodecEPKc__head_quazip_dlld000057.o/ 1340540258 0 0 644 582 ` LD.text 0.idata$7&0.idata$500.idata$4:0.idata$6,0%8_ZN6QuaZip15setCommentCodecEP10QTextCodec.text.idata$7.idata$5.idata$4.idata$6/`r__ZN6QuaZip15setCommentCodecEP10QTextCodec__imp___ZN6QuaZip15setCommentCodecEP10QTextCodec__head_quazip_dlld000056.o/ 1340540258 0 0 644 636 ` LX.text0 0.idata$7:0.idata$5D0.idata$4N0.idata$6@0%7_ZN6QuaZip14setCurrentFileERK7QStringNS_15CaseSensitivityEO.text.idata$7.idata$5.idata$4.idata$6@__ZN6QuaZip14setCurrentFileERK7QStringNS_15CaseSensitivityE__imp___ZN6QuaZip14setCurrentFileERK7QStringNS_15CaseSensitivityE__head_quazip_dlld000055.o/ 1340540258 0 0 644 542 ` L8.text 0.idata$70.idata$5$0.idata$4.0.idata$6 0%6_ZN6QuaZip13goToFirstFileEvO.text.idata$7.idata$5.idata$4.idata$6!DV__ZN6QuaZip13goToFirstFileEv__imp___ZN6QuaZip13goToFirstFileEv__head_quazip_dlld000054.o/ 1340540258 0 0 644 540 ` L8.text 0.idata$70.idata$5$0.idata$4.0.idata$6 0%5_ZN6QuaZip12goToNextFileEvO.text.idata$7.idata$5.idata$4.idata$6 BT__ZN6QuaZip12goToNextFileEv__imp___ZN6QuaZip12goToNextFileEv__head_quazip_dlld000053.o/ 1340540258 0 0 644 566 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%4_ZN6QuaZip11setIoDeviceEP9QIODeviceR.text.idata$7.idata$5.idata$4.idata$6)Tf__ZN6QuaZip11setIoDeviceEP9QIODevice__imp___ZN6QuaZip11setIoDeviceEP9QIODevice__head_quazip_dlld000052.o/ 1340540258 0 0 644 558 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%3_ZN6QuaZip10setZipNameERK7QString.text.idata$7.idata$5.idata$4.idata$6'Pb__ZN6QuaZip10setZipNameERK7QString__imp___ZN6QuaZip10setZipNameERK7QString__head_quazip_dlld000051.o/ 1340540258 0 0 644 558 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%2_ZN6QuaZip10setCommentERK7QString.text.idata$7.idata$5.idata$4.idata$6'Pb__ZN6QuaZip10setCommentERK7QString__imp___ZN6QuaZip10setCommentERK7QString__head_quazip_dlld000050.o/ 1340540258 0 0 644 532 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%1_ZN6QuaZip10getZipFileEv.text.idata$7.idata$5.idata$4.idata$6>P__ZN6QuaZip10getZipFileEv__imp___ZN6QuaZip10getZipFileEv__head_quazip_dlld000049.o/ 1340540258 0 0 644 532 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%0_ZN6QuaZip10getUnzFileEv.text.idata$7.idata$5.idata$4.idata$6>P__ZN6QuaZip10getUnzFileEv__imp___ZN6QuaZip10getUnzFileEv__head_quazip_dlld000048.o/ 1340540258 0 0 644 564 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%/_ZN13QuaZipNewInfoC2ERK7QStringS2_R.text.idata$7.idata$5.idata$4.idata$6(Rd__ZN13QuaZipNewInfoC2ERK7QStringS2___imp___ZN13QuaZipNewInfoC2ERK7QStringS2___head_quazip_dlld000047.o/ 1340540258 0 0 644 554 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%._ZN13QuaZipNewInfoC2ERK7QString2.text.idata$7.idata$5.idata$4.idata$6%L^__ZN13QuaZipNewInfoC2ERK7QString__imp___ZN13QuaZipNewInfoC2ERK7QString__head_quazip_dlld000046.o/ 1340540258 0 0 644 564 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%-_ZN13QuaZipNewInfoC1ERK7QStringS2_R.text.idata$7.idata$5.idata$4.idata$6(Rd__ZN13QuaZipNewInfoC1ERK7QStringS2___imp___ZN13QuaZipNewInfoC1ERK7QStringS2___head_quazip_dlld000045.o/ 1340540258 0 0 644 554 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%,_ZN13QuaZipNewInfoC1ERK7QStringi.text.idata$7.idata$5.idata$4.idata$6%L^__ZN13QuaZipNewInfoC1ERK7QString__imp___ZN13QuaZipNewInfoC1ERK7QString__head_quazip_dlld000044.o/ 1340540258 0 0 644 600 ` LL.text$ 0.idata$7.0.idata$580.idata$4B0.idata$640%+_ZN13QuaZipNewInfo15setFileDateTimeERK7QStrings.text.idata$7.idata$5.idata$4.idata$64j|__ZN13QuaZipNewInfo15setFileDateTimeERK7QString__imp___ZN13QuaZipNewInfo15setFileDateTimeERK7QString__head_quazip_dlld000043.o/ 1340540258 0 0 644 518 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%*_ZN10QuaZipFileD2Ev7.text.idata$7.idata$5.idata$4.idata$64F__ZN10QuaZipFileD2Ev__imp___ZN10QuaZipFileD2Ev__head_quazip_dlld000042.o/ 1340540258 0 0 644 518 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%)_ZN10QuaZipFileD1Ev7.text.idata$7.idata$5.idata$4.idata$64F__ZN10QuaZipFileD1Ev__imp___ZN10QuaZipFileD1Ev__head_quazip_dlld000041.o/ 1340540258 0 0 644 518 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%(_ZN10QuaZipFileD0Ev7.text.idata$7.idata$5.idata$4.idata$64F__ZN10QuaZipFileD0Ev__imp___ZN10QuaZipFileD0Ev__head_quazip_dlld000040.o/ 1340540258 0 0 644 518 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%'_ZN10QuaZipFileC2Ev7.text.idata$7.idata$5.idata$4.idata$64F__ZN10QuaZipFileC2Ev__imp___ZN10QuaZipFileC2Ev__head_quazip_dlld000039.o/ 1340540258 0 0 644 660 ` L`.text8 0.idata$7B0.idata$5L0.idata$4V0.idata$6H0%&_ZN10QuaZipFileC2ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject.text.idata$7.idata$5.idata$4.idata$6H__ZN10QuaZipFileC2ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject__imp___ZN10QuaZipFileC2ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject__head_quazip_dlld000038.o/ 1340540258 0 0 644 570 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%%_ZN10QuaZipFileC2ERK7QStringP7QObject.text.idata$7.idata$5.idata$4.idata$6+Xj__ZN10QuaZipFileC2ERK7QStringP7QObject__imp___ZN10QuaZipFileC2ERK7QStringP7QObject__head_quazip_dlld000037.o/ 1340540258 0 0 644 542 ` L8.text 0.idata$70.idata$5$0.idata$4.0.idata$6 0%$_ZN10QuaZipFileC2EP7QObjectQ.text.idata$7.idata$5.idata$4.idata$6!DV__ZN10QuaZipFileC2EP7QObject__imp___ZN10QuaZipFileC2EP7QObject__head_quazip_dlld000036.o/ 1340540258 0 0 644 566 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%#_ZN10QuaZipFileC2EP6QuaZipP7QObjectZ.text.idata$7.idata$5.idata$4.idata$6)Tf__ZN10QuaZipFileC2EP6QuaZipP7QObject__imp___ZN10QuaZipFileC2EP6QuaZipP7QObject__head_quazip_dlld000035.o/ 1340540258 0 0 644 518 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%"_ZN10QuaZipFileC1Ev7.text.idata$7.idata$5.idata$4.idata$64F__ZN10QuaZipFileC1Ev__imp___ZN10QuaZipFileC1Ev__head_quazip_dlld000034.o/ 1340540258 0 0 644 660 ` L`.text8 0.idata$7B0.idata$5L0.idata$4V0.idata$6H0%!_ZN10QuaZipFileC1ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObjecte.text.idata$7.idata$5.idata$4.idata$6H__ZN10QuaZipFileC1ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject__imp___ZN10QuaZipFileC1ERK7QStringS2_N6QuaZip15CaseSensitivityEP7QObject__head_quazip_dlld000033.o/ 1340540258 0 0 644 570 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0% _ZN10QuaZipFileC1ERK7QStringP7QObject.text.idata$7.idata$5.idata$4.idata$6+Xj__ZN10QuaZipFileC1ERK7QStringP7QObject__imp___ZN10QuaZipFileC1ERK7QStringP7QObject__head_quazip_dlld000032.o/ 1340540258 0 0 644 542 ` L8.text 0.idata$70.idata$5$0.idata$4.0.idata$6 0%_ZN10QuaZipFileC1EP7QObjectQ.text.idata$7.idata$5.idata$4.idata$6!DV__ZN10QuaZipFileC1EP7QObject__imp___ZN10QuaZipFileC1EP7QObject__head_quazip_dlld000031.o/ 1340540258 0 0 644 566 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%_ZN10QuaZipFileC1EP6QuaZipP7QObjectv.text.idata$7.idata$5.idata$4.idata$6)Tf__ZN10QuaZipFileC1EP6QuaZipP7QObject__imp___ZN10QuaZipFileC1EP6QuaZipP7QObject__head_quazip_dlld000030.o/ 1340540258 0 0 644 552 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%_ZN10QuaZipFile9writeDataEPKcxI.text.idata$7.idata$5.idata$4.idata$6$J\__ZN10QuaZipFile9writeDataEPKcx__imp___ZN10QuaZipFile9writeDataEPKcx__head_quazip_dlld000029.o/ 1340540258 0 0 644 544 ` L8.text 0.idata$70.idata$5$0.idata$4.0.idata$6 0%_ZN10QuaZipFile8readDataEPcx.text.idata$7.idata$5.idata$4.idata$6"FX__ZN10QuaZipFile8readDataEPcx__imp___ZN10QuaZipFile8readDataEPcx__head_quazip_dlld000028.o/ 1340540258 0 0 644 554 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%_ZN10QuaZipFile6setZipEP6QuaZipI.text.idata$7.idata$5.idata$4.idata$6%L^__ZN10QuaZipFile6setZipEP6QuaZip__imp___ZN10QuaZipFile6setZipEP6QuaZip__head_quazip_dlld000027.o/ 1340540258 0 0 644 530 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60%_ZN10QuaZipFile5closeEvl.text.idata$7.idata$5.idata$4.idata$6<N__ZN10QuaZipFile5closeEv__imp___ZN10QuaZipFile5closeEv__head_quazip_dlld000026.o/ 1340540258 0 0 644 710 ` Lp.textH 0.idata$7R0.idata$5\0.idata$4f0.idata$6X0%_ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEERK13QuaZipNewInfoPKcjiibiii$.text.idata$7.idata$5.idata$4.idata$6Y__ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEERK13QuaZipNewInfoPKcjiibiii__imp___ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEERK13QuaZipNewInfoPKcjiibiii__head_quazip_dlld000025.o/ 1340540258 0 0 644 654 ` L\.text4 0.idata$7>0.idata$5H0.idata$4R0.idata$6D0%_ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEEPiS4_bPKc.text.idata$7.idata$5.idata$4.idata$6G__ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEEPiS4_bPKc__imp___ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEEPiS4_bPKc__head_quazip_dlld000024.o/ 1340540258 0 0 644 628 ` LT.text, 0.idata$760.idata$5@0.idata$4J0.idata$6<0%_ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEE.text.idata$7.idata$5.idata$4.idata$6>~__ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEE__imp___ZN10QuaZipFile4openE6QFlagsIN9QIODevice12OpenModeFlagEE__head_quazip_dlld000023.o/ 1340540258 0 0 644 551 ` L..text 0.idata$70.idata$50.idata$4$0.idata$6(0_ZN10QuaZipFile16staticMetaObjectEE.text.idata$7.idata$5.idata$4.idata$6.Wi__imp___ZN10QuaZipFile16staticMetaObjectE__nm___ZN10QuaZipFile16staticMetaObjectE__head_quazip_dll d000022.o/ 1340540258 0 0 644 654 ` L\.text4 0.idata$7>0.idata$5H0.idata$4R0.idata$6D0%_ZN10QuaZipFile11setFileNameERK7QStringN6QuaZip15CaseSensitivityE.text.idata$7.idata$5.idata$4.idata$6G__ZN10QuaZipFile11setFileNameERK7QStringN6QuaZip15CaseSensitivityE__imp___ZN10QuaZipFile11setFileNameERK7QStringN6QuaZip15CaseSensitivityE__head_quazip_dlld000021.o/ 1340540258 0 0 644 556 ` L<.text 0.idata$70.idata$5(0.idata$420.idata$6$0%_ZN10QuaZipFile11qt_metacastEPKc.text.idata$7.idata$5.idata$4.idata$6&N`__ZN10QuaZipFile11qt_metacastEPKc__imp___ZN10QuaZipFile11qt_metacastEPKc__head_quazip_dlld000020.o/ 1340540258 0 0 644 618 ` LP.text( 0.idata$720.idata$5<0.idata$4F0.idata$680%_ZN10QuaZipFile11qt_metacallEN11QMetaObject4CallEiPPv.text.idata$7.idata$5.idata$4.idata$6;x__ZN10QuaZipFile11qt_metacallEN11QMetaObject4CallEiPPv__imp___ZN10QuaZipFile11qt_metacallEN11QMetaObject4CallEiPPv__head_quazip_dlld000019.o/ 1340540258 0 0 644 600 ` LL.text$ 0.idata$7.0.idata$580.idata$4B0.idata$640%_ZN10QuaZipFile11getFileInfoEP14QuaZipFileInfoS.text.idata$7.idata$5.idata$4.idata$64j|__ZN10QuaZipFile11getFileInfoEP14QuaZipFileInfo__imp___ZN10QuaZipFile11getFileInfoEP14QuaZipFileInfo__head_quazip_dlld000018.o/ 1340540258 0 0 644 576 ` LD.text 0.idata$7&0.idata$500.idata$4:0.idata$6,0%_ZN10QuaZipFile10setZipNameERK7QString.text.idata$7.idata$5.idata$4.idata$6,Zl__ZN10QuaZipFile10setZipNameERK7QString__imp___ZN10QuaZipFile10setZipNameERK7QString__head_quazip_dlld000017.o/ 1340540258 0 0 644 518 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%_ZN10QuaAdler32C2Evu.text.idata$7.idata$5.idata$4.idata$64F__ZN10QuaAdler32C2Ev__imp___ZN10QuaAdler32C2Ev__head_quazip_dlld000016.o/ 1340540258 0 0 644 518 ` L0.text 0.idata$70.idata$50.idata$4&0.idata$60%_ZN10QuaAdler32C1Evu.text.idata$7.idata$5.idata$4.idata$64F__ZN10QuaAdler32C1Ev__imp___ZN10QuaAdler32C1Ev__head_quazip_dlld000015.o/ 1340540258 0 0 644 580 ` LD.text 0.idata$7&0.idata$500.idata$4:0.idata$6,0%_ZN10QuaAdler329calculateERK10QByteArray.text.idata$7.idata$5.idata$4.idata$6.^p__ZN10QuaAdler329calculateERK10QByteArray__imp___ZN10QuaAdler329calculateERK10QByteArray__head_quazip_dlld000014.o/ 1340540258 0 0 644 570 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0% _ZN10QuaAdler326updateERK10QByteArray.text.idata$7.idata$5.idata$4.idata$6+Xj__ZN10QuaAdler326updateERK10QByteArray__imp___ZN10QuaAdler326updateERK10QByteArray__head_quazip_dlld000013.o/ 1340540258 0 0 644 530 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60% _ZN10QuaAdler325valueEvs.text.idata$7.idata$5.idata$4.idata$6<N__ZN10QuaAdler325valueEv__imp___ZN10QuaAdler325valueEv__head_quazip_dlld000012.o/ 1340540258 0 0 644 530 ` L4.text  0.idata$70.idata$5 0.idata$4*0.idata$60% _ZN10QuaAdler325resetEvs.text.idata$7.idata$5.idata$4.idata$6<N__ZN10QuaAdler325resetEv__imp___ZN10QuaAdler325resetEv__head_quazip_dlld000011.o/ 1340540258 0 0 644 616 ` LP.text( 0.idata$720.idata$5<0.idata$4F0.idata$680% _ZN10JlCompress14compressSubDirEP6QuaZip7QStringS2_b.text.idata$7.idata$5.idata$4.idata$6:v__ZN10JlCompress14compressSubDirEP6QuaZip7QStringS2_b__imp___ZN10JlCompress14compressSubDirEP6QuaZip7QStringS2_b__head_quazip_dlld000010.o/ 1340540258 0 0 644 616 ` LP.text( 0.idata$720.idata$5<0.idata$4F0.idata$680% _ZN10JlCompress13compressFilesE7QString11QStringList.text.idata$7.idata$5.idata$4.idata$6:v__ZN10JlCompress13compressFilesE7QString11QStringList__imp___ZN10JlCompress13compressFilesE7QString11QStringList__head_quazip_dlld000009.o/ 1340540258 0 0 644 624 ` LT.text, 0.idata$760.idata$5@0.idata$4J0.idata$6<0%_ZN10JlCompress12extractFilesE7QString11QStringListS0_.text.idata$7.idata$5.idata$4.idata$6<z__ZN10JlCompress12extractFilesE7QString11QStringListS0___imp___ZN10JlCompress12extractFilesE7QString11QStringListS0___head_quazip_dlld000008.o/ 1340540258 0 0 644 606 ` LL.text$ 0.idata$7.0.idata$580.idata$4B0.idata$640%_ZN10JlCompress12compressFileEP6QuaZip7QStringS2_.text.idata$7.idata$5.idata$4.idata$67p__ZN10JlCompress12compressFileEP6QuaZip7QStringS2___imp___ZN10JlCompress12compressFileEP6QuaZip7QStringS2___head_quazip_dlld000007.o/ 1340540258 0 0 644 582 ` LD.text 0.idata$7&0.idata$500.idata$4:0.idata$6,0%_ZN10JlCompress12compressFileE7QStringS0_.text.idata$7.idata$5.idata$4.idata$6/`r__ZN10JlCompress12compressFileE7QStringS0___imp___ZN10JlCompress12compressFileE7QStringS0___head_quazip_dlld000006.o/ 1340540258 0 0 644 570 ` L@.text 0.idata$7"0.idata$5,0.idata$460.idata$6(0%_ZN10JlCompress11getFileListE7QString.text.idata$7.idata$5.idata$4.idata$6+Xj__ZN10JlCompress11getFileListE7QString__imp___ZN10JlCompress11getFileListE7QString__head_quazip_dlld000005.o/ 1340540258 0 0 644 604 ` LL.text$ 0.idata$7.0.idata$580.idata$4B0.idata$640%_ZN10JlCompress11extractFileEP6QuaZip7QStringS2_.text.idata$7.idata$5.idata$4.idata$66n__ZN10JlCompress11extractFileEP6QuaZip7QStringS2___imp___ZN10JlCompress11extractFileEP6QuaZip7QStringS2___head_quazip_dlld000004.o/ 1340540258 0 0 644 590 ` LH.text  0.idata$7*0.idata$540.idata$4>0.idata$600%_ZN10JlCompress11extractFileE7QStringS0_S0_.text.idata$7.idata$5.idata$4.idata$61dv__ZN10JlCompress11extractFileE7QStringS0_S0___imp___ZN10JlCompress11extractFileE7QStringS0_S0___head_quazip_dlld000003.o/ 1340540258 0 0 644 582 ` LD.text 0.idata$7&0.idata$500.idata$4:0.idata$6,0%_ZN10JlCompress11compressDirE7QStringS0_b.text.idata$7.idata$5.idata$4.idata$6/`r__ZN10JlCompress11compressDirE7QStringS0_b__imp___ZN10JlCompress11compressDirE7QStringS0_b__head_quazip_dlld000002.o/ 1340540258 0 0 644 582 ` LD.text 0.idata$7&0.idata$500.idata$4:0.idata$6,0%_ZN10JlCompress10removeFileE11QStringList.text.idata$7.idata$5.idata$4.idata$6/`r__ZN10JlCompress10removeFileE11QStringList__imp___ZN10JlCompress10removeFileE11QStringList__head_quazip_dlld000001.o/ 1340540258 0 0 644 578 ` LD.text 0.idata$7&0.idata$500.idata$4:0.idata$6,0%_ZN10JlCompress10extractDirE7QStringS0_.text.idata$7.idata$5.idata$4.idata$6-\n__ZN10JlCompress10extractDirE7QStringS0___imp___ZN10JlCompress10extractDirE7QStringS0___head_quazip_dllmudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazipfile.cpp0000644000175000017500000003257012070466513022431 0ustar csmallcsmall/* Copyright (C) 2005-2011 Sergey A. Tachenov This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant, see quazip/(un)zip.h files for details, basically it's zlib license. **/ #include "quazipfile.h" using namespace std; /// The implementation class for QuaZip. /** \internal This class contains all the private stuff for the QuaZipFile class, thus allowing to preserve binary compatibility between releases, the technique known as the Pimpl (private implementation) idiom. */ class QuaZipFilePrivate { friend class QuaZipFile; private: /// The pointer to the associated QuaZipFile instance. QuaZipFile *q; /// The QuaZip object to work with. QuaZip *zip; /// The file name. QString fileName; /// Case sensitivity mode. QuaZip::CaseSensitivity caseSensitivity; /// Whether this file is opened in the raw mode. bool raw; /// Write position to keep track of. /** QIODevice::pos() is broken for non-seekable devices, so we need our own position. */ qint64 writePos; /// Uncompressed size to write along with a raw file. ulong uncompressedSize; /// CRC to write along with a raw file. quint32 crc; /// Whether \ref zip points to an internal QuaZip instance. /** This is true if the archive was opened by name, rather than by supplying an existing QuaZip instance. */ bool internal; /// The last error. int zipError; /// Resets \ref zipError. inline void resetZipError() const {setZipError(UNZ_OK);} /// Sets the zip error. /** This function is marked as const although it changes one field. This allows to call it from const functions that don't change anything by themselves. */ void setZipError(int zipError) const; /// The constructor for the corresponding QuaZipFile constructor. inline QuaZipFilePrivate(QuaZipFile *q): q(q), zip(NULL), internal(true), zipError(UNZ_OK) {} /// The constructor for the corresponding QuaZipFile constructor. inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName): q(q), internal(true), zipError(UNZ_OK) { zip=new QuaZip(zipName); } /// The constructor for the corresponding QuaZipFile constructor. inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName, QuaZip::CaseSensitivity cs): q(q), internal(true), zipError(UNZ_OK) { zip=new QuaZip(zipName); this->fileName=fileName; this->caseSensitivity=cs; } /// The constructor for the QuaZipFile constructor accepting a file name. inline QuaZipFilePrivate(QuaZipFile *q, QuaZip *zip): q(q), zip(zip), internal(false), zipError(UNZ_OK) {} /// The destructor. inline ~QuaZipFilePrivate() { if (internal) delete zip; } }; QuaZipFile::QuaZipFile(): p(new QuaZipFilePrivate(this)) { } QuaZipFile::QuaZipFile(QObject *parent): QIODevice(parent), p(new QuaZipFilePrivate(this)) { } QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent): QIODevice(parent), p(new QuaZipFilePrivate(this, zipName)) { } QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName, QuaZip::CaseSensitivity cs, QObject *parent): QIODevice(parent), p(new QuaZipFilePrivate(this, zipName, fileName, cs)) { } QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent): QIODevice(parent), p(new QuaZipFilePrivate(this, zip)) { } QuaZipFile::~QuaZipFile() { if (isOpen()) close(); delete p; } QString QuaZipFile::getZipName() const { return p->zip==NULL ? QString() : p->zip->getZipName(); } QuaZip *QuaZipFile::getZip() const { return p->internal ? NULL : p->zip; } QString QuaZipFile::getActualFileName()const { p->setZipError(UNZ_OK); if (p->zip == NULL || (openMode() & WriteOnly)) return QString(); QString name=p->zip->getCurrentFileName(); if(name.isNull()) p->setZipError(p->zip->getZipError()); return name; } void QuaZipFile::setZipName(const QString& zipName) { if(isOpen()) { qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name"); return; } if(p->zip!=NULL && p->internal) delete p->zip; p->zip=new QuaZip(zipName); p->internal=true; } void QuaZipFile::setZip(QuaZip *zip) { if(isOpen()) { qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP"); return; } if(p->zip!=NULL && p->internal) delete p->zip; p->zip=zip; p->fileName=QString(); p->internal=false; } void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs) { if(p->zip==NULL) { qWarning("QuaZipFile::setFileName(): call setZipName() first"); return; } if(!p->internal) { qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip"); return; } if(isOpen()) { qWarning("QuaZipFile::setFileName(): can not set file name for already opened file"); return; } p->fileName=fileName; p->caseSensitivity=cs; } void QuaZipFilePrivate::setZipError(int zipError) const { QuaZipFilePrivate *fakeThis = const_cast(this); // non-const fakeThis->zipError=zipError; if(zipError==UNZ_OK) q->setErrorString(QString()); else q->setErrorString(q->tr("ZIP/UNZIP API error %1").arg(zipError)); } bool QuaZipFile::open(OpenMode mode) { return open(mode, NULL); } bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password) { p->resetZipError(); if(isOpen()) { qWarning("QuaZipFile::open(): already opened"); return false; } if(mode&Unbuffered) { qWarning("QuaZipFile::open(): Unbuffered mode is not supported"); return false; } if((mode&ReadOnly)&&!(mode&WriteOnly)) { if(p->internal) { if(!p->zip->open(QuaZip::mdUnzip)) { p->setZipError(p->zip->getZipError()); return false; } if(!p->zip->setCurrentFile(p->fileName, p->caseSensitivity)) { p->setZipError(p->zip->getZipError()); p->zip->close(); return false; } } else { if(p->zip==NULL) { qWarning("QuaZipFile::open(): zip is NULL"); return false; } if(p->zip->getMode()!=QuaZip::mdUnzip) { qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", (int)mode, (int)p->zip->getMode()); return false; } if(!p->zip->hasCurrentFile()) { qWarning("QuaZipFile::open(): zip does not have current file"); return false; } } p->setZipError(unzOpenCurrentFile3(p->zip->getUnzFile(), method, level, (int)raw, password)); if(p->zipError==UNZ_OK) { setOpenMode(mode); p->raw=raw; return true; } else return false; } qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode); return false; } bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info, const char *password, quint32 crc, int method, int level, bool raw, int windowBits, int memLevel, int strategy) { zip_fileinfo info_z; p->resetZipError(); if(isOpen()) { qWarning("QuaZipFile::open(): already opened"); return false; } if((mode&WriteOnly)&&!(mode&ReadOnly)) { if(p->internal) { qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach"); return false; } if(p->zip==NULL) { qWarning("QuaZipFile::open(): zip is NULL"); return false; } if(p->zip->getMode()!=QuaZip::mdCreate&&p->zip->getMode()!=QuaZip::mdAppend&&p->zip->getMode()!=QuaZip::mdAdd) { qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", (int)mode, (int)p->zip->getMode()); return false; } info_z.tmz_date.tm_year=info.dateTime.date().year(); info_z.tmz_date.tm_mon=info.dateTime.date().month() - 1; info_z.tmz_date.tm_mday=info.dateTime.date().day(); info_z.tmz_date.tm_hour=info.dateTime.time().hour(); info_z.tmz_date.tm_min=info.dateTime.time().minute(); info_z.tmz_date.tm_sec=info.dateTime.time().second(); info_z.dosDate = 0; info_z.internal_fa=(uLong)info.internalAttr; info_z.external_fa=(uLong)info.externalAttr; if (!p->zip->isDataDescriptorWritingEnabled()) zipClearFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR); p->setZipError(zipOpenNewFileInZip3(p->zip->getZipFile(), p->zip->getFileNameCodec()->fromUnicode(info.name).constData(), &info_z, info.extraLocal.constData(), info.extraLocal.length(), info.extraGlobal.constData(), info.extraGlobal.length(), p->zip->getCommentCodec()->fromUnicode(info.comment).constData(), method, level, (int)raw, windowBits, memLevel, strategy, password, (uLong)crc)); if(p->zipError==UNZ_OK) { p->writePos=0; setOpenMode(mode); p->raw=raw; if(raw) { p->crc=crc; p->uncompressedSize=info.uncompressedSize; } return true; } else return false; } qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode); return false; } bool QuaZipFile::isSequential()const { return true; } qint64 QuaZipFile::pos()const { if(p->zip==NULL) { qWarning("QuaZipFile::pos(): call setZipName() or setZip() first"); return -1; } if(!isOpen()) { qWarning("QuaZipFile::pos(): file is not open"); return -1; } if(openMode()&ReadOnly) // QIODevice::pos() is broken for sequential devices, // but thankfully bytesAvailable() returns the number of // bytes buffered, so we know how far ahead we are. return unztell(p->zip->getUnzFile()) - QIODevice::bytesAvailable(); else return p->writePos; } bool QuaZipFile::atEnd()const { if(p->zip==NULL) { qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first"); return false; } if(!isOpen()) { qWarning("QuaZipFile::atEnd(): file is not open"); return false; } if(openMode()&ReadOnly) // the same problem as with pos() return QIODevice::bytesAvailable() == 0 && unzeof(p->zip->getUnzFile())==1; else return true; } qint64 QuaZipFile::size()const { if(!isOpen()) { qWarning("QuaZipFile::atEnd(): file is not open"); return -1; } if(openMode()&ReadOnly) return p->raw?csize():usize(); else return p->writePos; } qint64 QuaZipFile::csize()const { unz_file_info info_z; p->setZipError(UNZ_OK); if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1; p->setZipError(unzGetCurrentFileInfo(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0)); if(p->zipError!=UNZ_OK) return -1; return info_z.compressed_size; } qint64 QuaZipFile::usize()const { unz_file_info info_z; p->setZipError(UNZ_OK); if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1; p->setZipError(unzGetCurrentFileInfo(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0)); if(p->zipError!=UNZ_OK) return -1; return info_z.uncompressed_size; } bool QuaZipFile::getFileInfo(QuaZipFileInfo *info) { if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return false; p->zip->getCurrentFileInfo(info); p->setZipError(p->zip->getZipError()); return p->zipError==UNZ_OK; } void QuaZipFile::close() { p->resetZipError(); if(p->zip==NULL||!p->zip->isOpen()) return; if(!isOpen()) { qWarning("QuaZipFile::close(): file isn't open"); return; } if(openMode()&ReadOnly) p->setZipError(unzCloseCurrentFile(p->zip->getUnzFile())); else if(openMode()&WriteOnly) if(isRaw()) p->setZipError(zipCloseFileInZipRaw(p->zip->getZipFile(), p->uncompressedSize, p->crc)); else p->setZipError(zipCloseFileInZip(p->zip->getZipFile())); else { qWarning("Wrong open mode: %d", (int)openMode()); return; } if(p->zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen); else return; if(p->internal) { p->zip->close(); p->setZipError(p->zip->getZipError()); } } qint64 QuaZipFile::readData(char *data, qint64 maxSize) { p->setZipError(UNZ_OK); qint64 bytesRead=unzReadCurrentFile(p->zip->getUnzFile(), data, (unsigned)maxSize); if(bytesRead<0) p->setZipError((int)bytesRead); return bytesRead; } qint64 QuaZipFile::writeData(const char* data, qint64 maxSize) { p->setZipError(ZIP_OK); p->setZipError(zipWriteInFileInZip(p->zip->getZipFile(), data, (uint)maxSize)); if(p->zipError!=ZIP_OK) return -1; else { p->writePos+=maxSize; return maxSize; } } QString QuaZipFile::getFileName() const { return p->fileName; } QuaZip::CaseSensitivity QuaZipFile::getCaseSensitivity() const { return p->caseSensitivity; } bool QuaZipFile::isRaw() const { return p->raw; } int QuaZipFile::getZipError() const { return p->zipError; } qint64 QuaZipFile::bytesAvailable() const { return size() - pos(); } mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazip.pri0000644000175000017500000000125612070466513021576 0ustar csmallcsmallINCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += $$PWD/crypt.h \ $$PWD/ioapi.h \ $$PWD/JlCompress.h \ $$PWD/quaadler32.h \ $$PWD/quachecksum32.h \ $$PWD/quacrc32.h \ $$PWD/quazip.h \ $$PWD/quazipfile.h \ $$PWD/quazipfileinfo.h \ $$PWD/quazipnewinfo.h \ $$PWD/unzip.h \ $$PWD/zip.h SOURCES += $$PWD/qioapi.cpp \ $$PWD/JlCompress.cpp \ $$PWD/quaadler32.cpp \ $$PWD/quacrc32.cpp \ $$PWD/quazip.cpp \ $$PWD/quazipfile.cpp \ $$PWD/quazipnewinfo.cpp \ $$PWD/unzip.c \ $$PWD/zip.c mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazipfileinfo.h0000644000175000017500000000355312070466513022751 0ustar csmallcsmall#ifndef QUA_ZIPFILEINFO_H #define QUA_ZIPFILEINFO_H /* Copyright (C) 2005-2011 Sergey A. Tachenov This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant, see quazip/(un)zip.h files for details, basically it's zlib license. **/ #include #include #include "quazip_global.h" /// Information about a file inside archive. /** Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to * fill this structure. */ struct QUAZIP_EXPORT QuaZipFileInfo { /// File name. QString name; /// Version created by. quint16 versionCreated; /// Version needed to extract. quint16 versionNeeded; /// General purpose flags. quint16 flags; /// Compression method. quint16 method; /// Last modification date and time. QDateTime dateTime; /// CRC. quint32 crc; /// Compressed file size. quint32 compressedSize; /// Uncompressed file size. quint32 uncompressedSize; /// Disk number start. quint16 diskNumberStart; /// Internal file attributes. quint16 internalAttr; /// External file attributes. quint32 externalAttr; /// Comment. QString comment; /// Extra field. QByteArray extra; }; #endif mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quacrc32.h0000644000175000017500000000075612070466513021351 0ustar csmallcsmall#ifndef QUACRC32_H #define QUACRC32_H #include "quachecksum32.h" ///CRC32 checksum /** \class QuaCrc32 quacrc32.h * This class wrappers the crc32 function with the QuaChecksum32 interface. * See QuaChecksum32 for more info. */ class QUAZIP_EXPORT QuaCrc32 : public QuaChecksum32 { public: QuaCrc32(); quint32 calculate(const QByteArray &data); void reset(); void update(const QByteArray &buf); quint32 value(); private: quint32 checksum; }; #endif //QUACRC32_H mudlet-2.1/src/quazip/quazip-0.4.4/quazip/Makefile.Release0000644000175000017500000002466712070466513022603 0ustar csmallcsmall############################################################################# # Makefile for building: quazip # Generated by qmake (2.01a) (Qt 4.7.4) on: So 24. Jun 14:17:20 2012 # Project: quazip.pro # Template: lib ############################################################################# ####### Compiler, tools and options CC = gcc CXX = g++ DEFINES = -DUNICODE -DQT_LARGEFILE_SUPPORT -DQUAZIP_BUILD -DQT_DLL -DQT_NO_DEBUG -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT CFLAGS = -O2 -Wall $(DEFINES) CXXFLAGS = -O2 -Wall -frtti -fexceptions -mthreads $(DEFINES) INCPATH = -I"c:\QtSDK\Desktop\Qt\4.7.4\mingw\include\QtCore" -I"c:\QtSDK\Desktop\Qt\4.7.4\mingw\include" -I"." -I"c:\mudlet_package_MINGW\zlib-1.2.5" -I"c:\QtSDK\Desktop\Qt\4.7.4\mingw\include\ActiveQt" -I"release" -I"c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\default" LINK = g++ LFLAGS = -Wl,-s -mthreads -shared -Wl,--out-implib,release\libquazip.a LIBS = -L"c:\QtSDK\Desktop\Qt\4.7.4\mingw\lib" -lQtCore4 QMAKE = c:\QtSDK\Desktop\Qt\4.7.4\mingw\bin\qmake.exe IDC = c:\QtSDK\Desktop\Qt\4.7.4\mingw\bin\idc.exe IDL = midl ZIP = zip -r -9 DEF_FILE = RES_FILE = COPY = copy /y COPY_FILE = $(COPY) COPY_DIR = xcopy /s /q /y /i DEL_FILE = del DEL_DIR = rmdir MOVE = move CHK_DIR_EXISTS= if not exist MKDIR = mkdir INSTALL_FILE = $(COPY_FILE) INSTALL_PROGRAM = $(COPY_FILE) INSTALL_DIR = $(COPY_DIR) ####### Output directory OBJECTS_DIR = release ####### Files SOURCES = unzip.c \ zip.c \ JlCompress.cpp \ qioapi.cpp \ quaadler32.cpp \ quacrc32.cpp \ quazip.cpp \ quazipfile.cpp \ quazipnewinfo.cpp release\moc_quazipfile.cpp OBJECTS = release/unzip.o \ release/zip.o \ release/JlCompress.o \ release/qioapi.o \ release/quaadler32.o \ release/quacrc32.o \ release/quazip.o \ release/quazipfile.o \ release/quazipnewinfo.o \ release/moc_quazipfile.o DIST = QMAKE_TARGET = quazip DESTDIR = release\ #avoid trailing-slash linebreak TARGET = quazip.dll DESTDIR_TARGET = release\quazip.dll ####### Implicit rules .SUFFIXES: .cpp .cc .cxx .c .cpp.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< .cc.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< .cxx.o: $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< .c.o: $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< ####### Build rules first: all all: Makefile.Release $(DESTDIR_TARGET) $(DESTDIR_TARGET): $(OBJECTS) $(LINK) $(LFLAGS) -o $(DESTDIR_TARGET) object_script.quazip.Release $(LIBS) qmake: FORCE @$(QMAKE) -o Makefile.Release quazip.pro dist: $(ZIP) quazip.zip $(SOURCES) $(DIST) quazip.pro c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\qconfig.pri c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\modules\qt_webkit_version.pri c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\qt_functions.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\qt_config.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\exclusive_builds.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\default_pre.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\default_pre.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\release.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\debug_and_release.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\default_post.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\default_post.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\build_pass.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\warn_on.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\qt.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\thread.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\moc.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\rtti.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\exceptions.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\stl.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\shared.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\dll.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\win32\windows.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\resources.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\uic.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\yacc.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\lex.prf c:\QtSDK\Desktop\Qt\4.7.4\mingw\mkspecs\features\include_source_dir.prf HEADERS RESOURCES IMAGES SOURCES OBJECTIVE_SOURCES FORMS YACCSOURCES YACCSOURCES LEXSOURCES clean: compiler_clean -$(DEL_FILE) release\unzip.o release\zip.o release\JlCompress.o release\qioapi.o release\quaadler32.o release\quacrc32.o release\quazip.o release\quazipfile.o release\quazipnewinfo.o release\moc_quazipfile.o -$(DEL_FILE) release\libquazip.a distclean: clean -$(DEL_FILE) $(DESTDIR_TARGET) -$(DEL_FILE) Makefile.Release check: first mocclean: compiler_moc_header_clean compiler_moc_source_clean mocables: compiler_moc_header_make_all compiler_moc_source_make_all compiler_moc_header_make_all: release/moc_quazipfile.cpp compiler_moc_header_clean: -$(DEL_FILE) release\moc_quazipfile.cpp release/moc_quazipfile.cpp: quazip_global.h \ quazip.h \ zip.h \ ioapi.h \ unzip.h \ quazipfileinfo.h \ quazipnewinfo.h \ quazipfile.h C:\QtSDK\Desktop\Qt\4.7.4\mingw\bin\moc.exe $(DEFINES) $(INCPATH) -D__GNUC__ -DWIN32 quazipfile.h -o release\moc_quazipfile.cpp compiler_rcc_make_all: compiler_rcc_clean: compiler_image_collection_make_all: qmake_image_collection.cpp compiler_image_collection_clean: -$(DEL_FILE) qmake_image_collection.cpp compiler_moc_source_make_all: compiler_moc_source_clean: compiler_uic_make_all: compiler_uic_clean: compiler_yacc_decl_make_all: compiler_yacc_decl_clean: compiler_yacc_impl_make_all: compiler_yacc_impl_clean: compiler_lex_make_all: compiler_lex_clean: compiler_clean: compiler_moc_header_clean ####### Compile release/unzip.o: unzip.c unzip.h \ ioapi.h \ crypt.h \ quazip_global.h $(CC) -c $(CFLAGS) $(INCPATH) -o release\unzip.o unzip.c release/zip.o: zip.c zip.h \ ioapi.h \ quazip_global.h \ crypt.h $(CC) -c $(CFLAGS) $(INCPATH) -o release\zip.o zip.c release/JlCompress.o: JlCompress.cpp JlCompress.h \ quazip.h \ zip.h \ ioapi.h \ unzip.h \ quazip_global.h \ quazipfileinfo.h \ quazipfile.h \ quazipnewinfo.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release\JlCompress.o JlCompress.cpp release/qioapi.o: qioapi.cpp ioapi.h \ quazip_global.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release\qioapi.o qioapi.cpp release/quaadler32.o: quaadler32.cpp quaadler32.h \ quachecksum32.h \ quazip_global.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release\quaadler32.o quaadler32.cpp release/quacrc32.o: quacrc32.cpp quacrc32.h \ quachecksum32.h \ quazip_global.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release\quacrc32.o quacrc32.cpp release/quazip.o: quazip.cpp quazip.h \ zip.h \ ioapi.h \ unzip.h \ quazip_global.h \ quazipfileinfo.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release\quazip.o quazip.cpp release/quazipfile.o: quazipfile.cpp quazipfile.h \ quazip_global.h \ quazip.h \ zip.h \ ioapi.h \ unzip.h \ quazipfileinfo.h \ quazipnewinfo.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release\quazipfile.o quazipfile.cpp release/quazipnewinfo.o: quazipnewinfo.cpp quazipnewinfo.h \ quazip_global.h $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release\quazipnewinfo.o quazipnewinfo.cpp release/moc_quazipfile.o: release/moc_quazipfile.cpp $(CXX) -c $(CXXFLAGS) $(INCPATH) -o release\moc_quazipfile.o release\moc_quazipfile.cpp ####### Install install_headers: first FORCE @$(CHK_DIR_EXISTS) $(INSTALL_ROOT)\include\quazip $(MKDIR) $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\crypt.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\ioapi.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\JlCompress.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quaadler32.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quachecksum32.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quacrc32.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quazip.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quazipfile.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quazipfileinfo.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quazipnewinfo.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\quazip_global.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\unzip.h $(INSTALL_ROOT)\include\quazip -$(INSTALL_FILE) c:\Users\heiko\mudlet\src\quazip\quazip-0.4.4\quazip\zip.h $(INSTALL_ROOT)\include\quazip uninstall_headers: FORCE -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\crypt.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\ioapi.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\JlCompress.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quaadler32.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quachecksum32.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quacrc32.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quazip.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quazipfile.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quazipfileinfo.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quazipnewinfo.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\quazip_global.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\unzip.h -$(DEL_FILE) $(INSTALL_ROOT)\include\quazip\zip.h -$(DEL_DIR) $(INSTALL_ROOT)\include\quazip install_target: first FORCE @$(CHK_DIR_EXISTS) $(INSTALL_ROOT)\lib $(MKDIR) $(INSTALL_ROOT)\lib -$(INSTALL_FILE) "release\libquazip.a" "$(INSTALL_ROOT)\lib\libquazip.a" -$(INSTALL_FILE) "$(DESTDIR_TARGET)" "$(INSTALL_ROOT)\lib\$(TARGET)" uninstall_target: FORCE -$(DEL_FILE) "$(INSTALL_ROOT)\lib\libquazip.a" -$(DEL_FILE) "$(INSTALL_ROOT)\lib\$(TARGET)" -$(DEL_DIR) $(INSTALL_ROOT)\lib install: install_headers install_target FORCE uninstall: uninstall_headers uninstall_target FORCE FORCE: mudlet-2.1/src/quazip/quazip-0.4.4/quazip/unzip.c0000644000175000017500000014032412070466513021062 0ustar csmallcsmall/* unzip.c -- IO for uncompress .zip files using zlib Version 1.01e, February 12th, 2005 Copyright (C) 1998-2005 Gilles Vollant Read unzip.h for more info Modified by Sergey A. Tachenov to integrate with Qt. */ /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of compatibility with older software. The following is from the original crypt.c. Code woven in by Terry Thorsen 1/2003. */ /* Copyright (c) 1990-2000 Info-ZIP. All rights reserved. See the accompanying file LICENSE, version 2000-Apr-09 or later (the contents of which are also included in zip.h) for terms of use. If, for some reason, all these files are missing, the Info-ZIP license also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html */ /* crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] The encryption/decryption parts of this source code (as opposed to the non-echoing password parts) were originally written in Europe. The whole source package can be freely distributed, including from the USA. (Prior to January 2000, re-export from the US was a violation of US law.) */ /* This encryption code is a direct transcription of the algorithm from Roger Schlafly, described by Phil Katz in the file appnote.txt. This file (appnote.txt) is distributed with the PKZIP program (even in the version without encryption capabilities). */ #include #include #include #include "zlib.h" #include "unzip.h" #ifdef STDC # include # include # include #endif #ifdef NO_ERRNO_H extern int errno; #else # include #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ #ifndef CASESENSITIVITYDEFAULT_NO # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) # define CASESENSITIVITYDEFAULT_NO # endif #endif #ifndef UNZ_BUFSIZE #define UNZ_BUFSIZE (16384) #endif #ifndef UNZ_MAXFILENAMEINZIP #define UNZ_MAXFILENAMEINZIP (256) #endif #ifndef ALLOC # define ALLOC(size) (malloc(size)) #endif #ifndef TRYFREE # define TRYFREE(p) {if (p) free(p);} #endif #define SIZECENTRALDIRITEM (0x2e) #define SIZEZIPLOCALHEADER (0x1e) const char unz_copyright[] = " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; /* unz_file_info_interntal contain internal info about a file in zipfile*/ typedef struct unz_file_info_internal_s { uLong offset_curfile;/* relative offset of local header 4 bytes */ } unz_file_info_internal; /* file_in_zip_read_info_s contain internal information about a file in zipfile, when reading and decompress it */ typedef struct { char *read_buffer; /* internal buffer for compressed data */ z_stream stream; /* zLib stream structure for inflate */ uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ uLong stream_initialised; /* flag set if stream structure is initialised*/ uLong offset_local_extrafield;/* offset of the local extra field */ uInt size_local_extrafield;/* size of the local extra field */ uLong pos_local_extrafield; /* position in the local extra field in read*/ uLong crc32; /* crc32 of all data uncompressed */ uLong crc32_wait; /* crc32 we must obtain after decompress all */ uLong rest_read_compressed; /* number of byte to be decompressed */ uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ zlib_filefunc_def z_filefunc; voidpf filestream; /* io structore of the zipfile */ uLong compression_method; /* compression method (0==store) */ uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ int raw; } file_in_zip_read_info_s; /* unz_s contain internal information about the zipfile */ typedef struct { zlib_filefunc_def z_filefunc; voidpf filestream; /* io structore of the zipfile */ unz_global_info gi; /* public global information */ uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ uLong num_file; /* number of the current file in the zipfile*/ uLong pos_in_central_dir; /* pos of the current file in the central dir*/ uLong current_file_ok; /* flag about the usability of the current file*/ uLong central_pos; /* position of the beginning of the central dir*/ uLong size_central_dir; /* size of the central directory */ uLong offset_central_dir; /* offset of start of central directory with respect to the starting disk number */ unz_file_info cur_file_info; /* public info about the current file in zip*/ unz_file_info_internal cur_file_info_internal; /* private info about it*/ file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current file if we are decompressing it */ int encrypted; # ifndef NOUNCRYPT unsigned long keys[3]; /* keys defining the pseudo-random sequence */ const unsigned long* pcrc_32_tab; # endif } unz_s; #ifndef NOUNCRYPT #include "crypt.h" #endif /* =========================================================================== Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. IN assertion: the stream s has been sucessfully opened for reading. */ local int unzlocal_getByte OF(( const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream, int *pi)); local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) const zlib_filefunc_def* pzlib_filefunc_def; voidpf filestream; int *pi; { unsigned char c; int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); if (err==1) { *pi = (int)c; return UNZ_OK; } else { if (ZERROR(*pzlib_filefunc_def,filestream)) return UNZ_ERRNO; else return UNZ_EOF; } } /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ local int unzlocal_getShort OF(( const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) const zlib_filefunc_def* pzlib_filefunc_def; voidpf filestream; uLong *pX; { uLong x ; int i; int err; err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); x = (uLong)i; if (err==UNZ_OK) err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<8; if (err==UNZ_OK) *pX = x; else *pX = 0; return err; } local int unzlocal_getLong OF(( const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) const zlib_filefunc_def* pzlib_filefunc_def; voidpf filestream; uLong *pX; { uLong x ; int i; int err; err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); x = (uLong)i; if (err==UNZ_OK) err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<8; if (err==UNZ_OK) err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<16; if (err==UNZ_OK) err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<24; if (err==UNZ_OK) *pX = x; else *pX = 0; return err; } /* My own strcmpi / strcasecmp */ local int strcmpcasenosensitive_internal (fileName1,fileName2) const char* fileName1; const char* fileName2; { for (;;) { char c1=*(fileName1++); char c2=*(fileName2++); if ((c1>='a') && (c1<='z')) c1 -= 0x20; if ((c2>='a') && (c2<='z')) c2 -= 0x20; if (c1=='\0') return ((c2=='\0') ? 0 : -1); if (c2=='\0') return 1; if (c1c2) return 1; } } #ifdef CASESENSITIVITYDEFAULT_NO #define CASESENSITIVITYDEFAULTVALUE 2 #else #define CASESENSITIVITYDEFAULTVALUE 1 #endif #ifndef STRCMPCASENOSENTIVEFUNCTION #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal #endif /* Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi or strcasecmp) If iCaseSenisivity = 0, case sensitivity is defaut of your operating system (like 1 on Unix, 2 on Windows) */ extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) const char* fileName1; const char* fileName2; int iCaseSensitivity; { if (iCaseSensitivity==0) iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; if (iCaseSensitivity==1) return strcmp(fileName1,fileName2); return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); } #ifndef BUFREADCOMMENT #define BUFREADCOMMENT (0x400) #endif /* Locate the Central directory of a zipfile (at the end, just before the global comment) */ local uLong unzlocal_SearchCentralDir OF(( const zlib_filefunc_def* pzlib_filefunc_def, voidpf filestream)); local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) const zlib_filefunc_def* pzlib_filefunc_def; voidpf filestream; { unsigned char* buf; uLong uSizeFile; uLong uBackRead; uLong uMaxBack=0xffff; /* maximum size of global comment */ uLong uPosFound=0; if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0; uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) return 0; uBackRead = 4; while (uBackReaduMaxBack) uBackRead = uMaxBack; else uBackRead+=BUFREADCOMMENT; uReadPos = uSizeFile-uBackRead ; uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) break; if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) break; for (i=(int)uReadSize-3; (i--)>0;) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { uPosFound = uReadPos+i; break; } if (uPosFound!=0) break; } TRYFREE(buf); return uPosFound; } /* Open a Zip file. path contain the full pathname (by example, on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer "zlib/zlib114.zip". If the zipfile cannot be opened (file doesn't exist or in not valid), the return value is NULL. Else, the return value is a unzFile Handle, usable with other function of this unzip package. */ extern unzFile ZEXPORT unzOpen2 (file, pzlib_filefunc_def) voidpf file; zlib_filefunc_def* pzlib_filefunc_def; { unz_s us; unz_s *s; uLong central_pos,uL; uLong number_disk; /* number of the current dist, used for spaning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used for spaning ZIP, unsupported, always 0*/ uLong number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ int err=UNZ_OK; if (unz_copyright[0]!=' ') return NULL; if (pzlib_filefunc_def==NULL) fill_qiodevice_filefunc(&us.z_filefunc); else us.z_filefunc = *pzlib_filefunc_def; us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, file, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING); if (us.filestream==NULL) return NULL; central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); if (central_pos==0) err=UNZ_ERRNO; if (ZSEEK(us.z_filefunc, us.filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) err=UNZ_ERRNO; /* the signature, already checked */ if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; /* number of this disk */ if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) err=UNZ_ERRNO; /* number of the disk with the start of the central directory */ if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) err=UNZ_ERRNO; /* total number of entries in the central dir on this disk */ if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) err=UNZ_ERRNO; /* total number of entries in the central dir */ if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) err=UNZ_ERRNO; if ((number_entry_CD!=us.gi.number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=UNZ_BADZIPFILE; /* size of the central directory */ if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) err=UNZ_ERRNO; /* offset of start of central directory with respect to the starting disk number */ if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) err=UNZ_ERRNO; /* zipfile comment length */ if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) err=UNZ_ERRNO; if ((central_pospfile_in_zip_read!=NULL) unzCloseCurrentFile(file); ZCLOSE(s->z_filefunc, s->filestream); TRYFREE(s); return UNZ_OK; } /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) unzFile file; unz_global_info *pglobal_info; { unz_s* s; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; *pglobal_info=s->gi; return UNZ_OK; } /* Translate date/time from Dos format to tm_unz (readable more easilty) */ local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) uLong ulDosDate; tm_unz* ptm; { uLong uDate; uDate = (uLong)(ulDosDate>>16); ptm->tm_mday = (uInt)(uDate&0x1f) ; ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; } /* Get Info about the current file in the zipfile, with internal only info */ local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, unz_file_info *pfile_info, unz_file_info_internal *pfile_info_internal, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)); local int unzlocal_GetCurrentFileInfoInternal (file, pfile_info, pfile_info_internal, szFileName, fileNameBufferSize, extraField, extraFieldBufferSize, szComment, commentBufferSize) unzFile file; unz_file_info *pfile_info; unz_file_info_internal *pfile_info_internal; char *szFileName; uLong fileNameBufferSize; void *extraField; uLong extraFieldBufferSize; char *szComment; uLong commentBufferSize; { unz_s* s; unz_file_info file_info; unz_file_info_internal file_info_internal; int err=UNZ_OK; uLong uMagic; uLong uSeek=0; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; if (ZSEEK(s->z_filefunc, s->filestream, s->pos_in_central_dir+s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET)!=0) err=UNZ_ERRNO; /* we check the magic */ if (err==UNZ_OK) { if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) err=UNZ_ERRNO; else if (uMagic!=0x02014b50) err=UNZ_BADZIPFILE; } if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) err=UNZ_ERRNO; unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) err=UNZ_ERRNO; uSeek+=file_info.size_filename; if ((err==UNZ_OK) && (szFileName!=NULL)) { uLong uSizeRead ; if (file_info.size_filename0) && (fileNameBufferSize>0)) if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) err=UNZ_ERRNO; uSeek -= uSizeRead; } if ((err==UNZ_OK) && (extraField!=NULL)) { uLong uSizeRead ; if (file_info.size_file_extraz_filefunc, s->filestream,uSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) uSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) err=UNZ_ERRNO; uSeek += file_info.size_file_extra - uSizeRead; } else uSeek+=file_info.size_file_extra; if ((err==UNZ_OK) && (szComment!=NULL)) { uLong uSizeRead ; if (file_info.size_file_commentz_filefunc, s->filestream,uSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) uSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_comment>0) && (commentBufferSize>0)) if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) err=UNZ_ERRNO; uSeek+=file_info.size_file_comment - uSizeRead; } else uSeek+=file_info.size_file_comment; if ((err==UNZ_OK) && (pfile_info!=NULL)) *pfile_info=file_info; if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) *pfile_info_internal=file_info_internal; return err; } /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ extern int ZEXPORT unzGetCurrentFileInfo (file, pfile_info, szFileName, fileNameBufferSize, extraField, extraFieldBufferSize, szComment, commentBufferSize) unzFile file; unz_file_info *pfile_info; char *szFileName; uLong fileNameBufferSize; void *extraField; uLong extraFieldBufferSize; char *szComment; uLong commentBufferSize; { return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, szFileName,fileNameBufferSize, extraField,extraFieldBufferSize, szComment,commentBufferSize); } /* Set the current file of the zipfile to the first file. return UNZ_OK if there is no problem */ extern int ZEXPORT unzGoToFirstFile (file) unzFile file; { int err=UNZ_OK; unz_s* s; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; s->pos_in_central_dir=s->offset_central_dir; s->num_file=0; err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return err; } /* Set the current file of the zipfile to the next file. return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ extern int ZEXPORT unzGoToNextFile (file) unzFile file; { unz_s* s; int err; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ if (s->num_file+1==s->gi.number_entry) return UNZ_END_OF_LIST_OF_FILE; s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; s->num_file++; err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return err; } /* Try locate the file szFileName in the zipfile. For the iCaseSensitivity signification, see unzipStringFileNameCompare return value : UNZ_OK if the file is found. It becomes the current file. UNZ_END_OF_LIST_OF_FILE if the file is not found */ extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) unzFile file; const char *szFileName; int iCaseSensitivity; { unz_s* s; int err; /* We remember the 'current' position in the file so that we can jump * back there if we fail. */ unz_file_info cur_file_infoSaved; unz_file_info_internal cur_file_info_internalSaved; uLong num_fileSaved; uLong pos_in_central_dirSaved; if (file==NULL) return UNZ_PARAMERROR; if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) return UNZ_PARAMERROR; s=(unz_s*)file; if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; /* Save the current state */ num_fileSaved = s->num_file; pos_in_central_dirSaved = s->pos_in_central_dir; cur_file_infoSaved = s->cur_file_info; cur_file_info_internalSaved = s->cur_file_info_internal; err = unzGoToFirstFile(file); while (err == UNZ_OK) { char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; err = unzGetCurrentFileInfo(file,NULL, szCurrentFileName,sizeof(szCurrentFileName)-1, NULL,0,NULL,0); if (err == UNZ_OK) { if (unzStringFileNameCompare(szCurrentFileName, szFileName,iCaseSensitivity)==0) return UNZ_OK; err = unzGoToNextFile(file); } } /* We failed, so restore the state of the 'current file' to where we * were. */ s->num_file = num_fileSaved ; s->pos_in_central_dir = pos_in_central_dirSaved ; s->cur_file_info = cur_file_infoSaved; s->cur_file_info_internal = cur_file_info_internalSaved; return err; } /* /////////////////////////////////////////// // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) // I need random access // // Further optimization could be realized by adding an ability // to cache the directory in memory. The goal being a single // comprehensive file read to put the file I need in a memory. */ /* typedef struct unz_file_pos_s { uLong pos_in_zip_directory; // offset in file uLong num_of_file; // # of file } unz_file_pos; */ extern int ZEXPORT unzGetFilePos(file, file_pos) unzFile file; unz_file_pos* file_pos; { unz_s* s; if (file==NULL || file_pos==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; file_pos->pos_in_zip_directory = s->pos_in_central_dir; file_pos->num_of_file = s->num_file; return UNZ_OK; } extern int ZEXPORT unzGoToFilePos(file, file_pos) unzFile file; unz_file_pos* file_pos; { unz_s* s; int err; if (file==NULL || file_pos==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; /* jump to the right spot */ s->pos_in_central_dir = file_pos->pos_in_zip_directory; s->num_file = file_pos->num_of_file; /* set the current file */ err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); /* return results */ s->current_file_ok = (err == UNZ_OK); return err; } /* // Unzip Helper Functions - should be here? /////////////////////////////////////////// */ /* Read the local header of the current zipfile Check the coherency of the local header and info in the end of central directory about this file store in *piSizeVar the size of extra info in local header (filename and size of extra field data) */ local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, poffset_local_extrafield, psize_local_extrafield) unz_s* s; uInt* piSizeVar; uLong *poffset_local_extrafield; uInt *psize_local_extrafield; { uLong uMagic,uData,uFlags; uLong size_filename; uLong size_extra_field; int err=UNZ_OK; *piSizeVar = 0; *poffset_local_extrafield = 0; *psize_local_extrafield = 0; if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (err==UNZ_OK) { if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) err=UNZ_ERRNO; else if (uMagic!=0x04034b50) err=UNZ_BADZIPFILE; } if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) err=UNZ_ERRNO; /* else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) err=UNZ_BADZIPFILE; */ if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) err=UNZ_ERRNO; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) err=UNZ_ERRNO; else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) err=UNZ_BADZIPFILE; if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && (s->cur_file_info.compression_method!=Z_DEFLATED)) err=UNZ_BADZIPFILE; if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ err=UNZ_ERRNO; if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ err=UNZ_ERRNO; else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) err=UNZ_BADZIPFILE; if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ err=UNZ_ERRNO; else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) err=UNZ_BADZIPFILE; if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ err=UNZ_ERRNO; else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) err=UNZ_BADZIPFILE; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) err=UNZ_ERRNO; else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) err=UNZ_BADZIPFILE; *piSizeVar += (uInt)size_filename; if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) err=UNZ_ERRNO; *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename; *psize_local_extrafield = (uInt)size_extra_field; *piSizeVar += (uInt)size_extra_field; return err; } /* Open for reading data the current file in the zipfile. If there is no error and the file is opened, the return value is UNZ_OK. */ extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) unzFile file; int* method; int* level; int raw; const char* password; { int err=UNZ_OK; uInt iSizeVar; unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; uLong offset_local_extrafield; /* offset of the local extra field */ uInt size_local_extrafield; /* size of the local extra field */ # ifndef NOUNCRYPT char source[12]; # else if (password != NULL) return UNZ_PARAMERROR; # endif if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; if (!s->current_file_ok) return UNZ_PARAMERROR; if (s->pfile_in_zip_read != NULL) unzCloseCurrentFile(file); if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) return UNZ_BADZIPFILE; pfile_in_zip_read_info = (file_in_zip_read_info_s*) ALLOC(sizeof(file_in_zip_read_info_s)); if (pfile_in_zip_read_info==NULL) return UNZ_INTERNALERROR; pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; pfile_in_zip_read_info->pos_local_extrafield=0; pfile_in_zip_read_info->raw=raw; if (pfile_in_zip_read_info->read_buffer==NULL) { TRYFREE(pfile_in_zip_read_info); return UNZ_INTERNALERROR; } pfile_in_zip_read_info->stream_initialised=0; if (method!=NULL) *method = (int)s->cur_file_info.compression_method; if (level!=NULL) { *level = 6; switch (s->cur_file_info.flag & 0x06) { case 6 : *level = 1; break; case 4 : *level = 2; break; case 2 : *level = 9; break; } } if ((s->cur_file_info.compression_method!=0) && (s->cur_file_info.compression_method!=Z_DEFLATED)) err=UNZ_BADZIPFILE; pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; pfile_in_zip_read_info->crc32=0; pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; pfile_in_zip_read_info->filestream=s->filestream; pfile_in_zip_read_info->z_filefunc=s->z_filefunc; pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; pfile_in_zip_read_info->stream.total_out = 0; if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) { pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; pfile_in_zip_read_info->stream.zfree = (free_func)0; pfile_in_zip_read_info->stream.opaque = (voidpf)0; pfile_in_zip_read_info->stream.next_in = (voidpf)0; pfile_in_zip_read_info->stream.avail_in = 0; err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); if (err == Z_OK) pfile_in_zip_read_info->stream_initialised=1; else { TRYFREE(pfile_in_zip_read_info); return err; } /* windowBits is passed < 0 to tell that there is no zlib header. * Note that in this case inflate *requires* an extra "dummy" byte * after the compressed stream in order to complete decompression and * return Z_STREAM_END. * In unzip, i don't wait absolutely Z_STREAM_END because I known the * size of both compressed and uncompressed data */ } pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size ; pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size ; pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar; pfile_in_zip_read_info->stream.avail_in = (uInt)0; s->pfile_in_zip_read = pfile_in_zip_read_info; # ifndef NOUNCRYPT if (password != NULL) { int i; s->pcrc_32_tab = get_crc_table(); init_keys(password,s->keys,s->pcrc_32_tab); if (ZSEEK(s->z_filefunc, s->filestream, s->pfile_in_zip_read->pos_in_zipfile + s->pfile_in_zip_read->byte_before_the_zipfile, SEEK_SET)!=0) return UNZ_INTERNALERROR; if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) return UNZ_INTERNALERROR; for (i = 0; i<12; i++) zdecode(s->keys,s->pcrc_32_tab,source[i]); s->pfile_in_zip_read->pos_in_zipfile+=12; s->encrypted=1; } # endif return UNZ_OK; } extern int ZEXPORT unzOpenCurrentFile (file) unzFile file; { return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); } extern int ZEXPORT unzOpenCurrentFilePassword (file, password) unzFile file; const char* password; { return unzOpenCurrentFile3(file, NULL, NULL, 0, password); } extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) unzFile file; int* method; int* level; int raw; { return unzOpenCurrentFile3(file, method, level, raw, NULL); } /* Read bytes from the current file. buf contain buffer where data must be copied len the size of buf. return the number of byte copied if somes bytes are copied return 0 if the end of file was reached return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ extern int ZEXPORT unzReadCurrentFile (file, buf, len) unzFile file; voidp buf; unsigned len; { int err=UNZ_OK; uInt iRead = 0; unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; if ((pfile_in_zip_read_info->read_buffer == NULL)) return UNZ_END_OF_LIST_OF_FILE; if (len==0) return 0; pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; pfile_in_zip_read_info->stream.avail_out = (uInt)len; if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && (!(pfile_in_zip_read_info->raw))) pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_uncompressed; if ((len>pfile_in_zip_read_info->rest_read_compressed+ pfile_in_zip_read_info->stream.avail_in) && (pfile_in_zip_read_info->raw)) pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_compressed+ pfile_in_zip_read_info->stream.avail_in; while (pfile_in_zip_read_info->stream.avail_out>0) { if ((pfile_in_zip_read_info->stream.avail_in==0) && (pfile_in_zip_read_info->rest_read_compressed>0)) { uInt uReadThis = UNZ_BUFSIZE; if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; if (uReadThis == 0) return UNZ_EOF; if (ZSEEK(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (ZREAD(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->read_buffer, uReadThis)!=uReadThis) return UNZ_ERRNO; # ifndef NOUNCRYPT if(s->encrypted) { uInt i; for(i=0;iread_buffer[i] = zdecode(s->keys,s->pcrc_32_tab, pfile_in_zip_read_info->read_buffer[i]); } # endif pfile_in_zip_read_info->pos_in_zipfile += uReadThis; pfile_in_zip_read_info->rest_read_compressed-=uReadThis; pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->read_buffer; pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; } if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) { uInt uDoCopy,i ; if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed == 0)) return (iRead==0) ? UNZ_EOF : iRead; if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in) uDoCopy = pfile_in_zip_read_info->stream.avail_out ; else uDoCopy = pfile_in_zip_read_info->stream.avail_in ; for (i=0;istream.next_out+i) = *(pfile_in_zip_read_info->stream.next_in+i); pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, pfile_in_zip_read_info->stream.next_out, uDoCopy); pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; pfile_in_zip_read_info->stream.avail_in -= uDoCopy; pfile_in_zip_read_info->stream.avail_out -= uDoCopy; pfile_in_zip_read_info->stream.next_out += uDoCopy; pfile_in_zip_read_info->stream.next_in += uDoCopy; pfile_in_zip_read_info->stream.total_out += uDoCopy; iRead += uDoCopy; } else { uLong uTotalOutBefore,uTotalOutAfter; const Bytef *bufBefore; uLong uOutThis; int flush=Z_SYNC_FLUSH; uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; bufBefore = pfile_in_zip_read_info->stream.next_out; /* if ((pfile_in_zip_read_info->rest_read_uncompressed == pfile_in_zip_read_info->stream.avail_out) && (pfile_in_zip_read_info->rest_read_compressed == 0)) flush = Z_FINISH; */ err=inflate(&pfile_in_zip_read_info->stream,flush); if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) err = Z_DATA_ERROR; uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; uOutThis = uTotalOutAfter-uTotalOutBefore; pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); if (err==Z_STREAM_END) return (iRead==0) ? UNZ_EOF : iRead; if (err!=Z_OK) break; } } if (err==Z_OK) return iRead; return err; } /* Give the current position in uncompressed data */ extern z_off_t ZEXPORT unztell (file) unzFile file; { unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; return (z_off_t)pfile_in_zip_read_info->stream.total_out; } /* return 1 if the end of file was reached, 0 elsewhere */ extern int ZEXPORT unzeof (file) unzFile file; { unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; if (pfile_in_zip_read_info->rest_read_uncompressed == 0) return 1; else return 0; } /* Read extra field from the current file (opened by unzOpenCurrentFile) This is the local-header version of the extra field (sometimes, there is more info in the local-header version than in the central-header) if buf==NULL, it return the size of the local extra field that can be read if buf!=NULL, len is the size of the buffer, the extra header is copied in buf. the return value is the number of bytes copied in buf, or (if <0) the error code */ extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) unzFile file; voidp buf; unsigned len; { unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; uInt read_now; uLong size_to_read; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; size_to_read = (pfile_in_zip_read_info->size_local_extrafield - pfile_in_zip_read_info->pos_local_extrafield); if (buf==NULL) return (int)size_to_read; if (len>size_to_read) read_now = (uInt)size_to_read; else read_now = (uInt)len ; if (read_now==0) return 0; if (ZSEEK(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->offset_local_extrafield + pfile_in_zip_read_info->pos_local_extrafield, ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (ZREAD(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, buf,read_now)!=read_now) return UNZ_ERRNO; return (int)read_now; } /* Close the file in zip opened with unzipOpenCurrentFile Return UNZ_CRCERROR if all the file was read but the CRC is not good */ extern int ZEXPORT unzCloseCurrentFile (file) unzFile file; { int err=UNZ_OK; unz_s* s; file_in_zip_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && (!pfile_in_zip_read_info->raw)) { if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) err=UNZ_CRCERROR; } TRYFREE(pfile_in_zip_read_info->read_buffer); pfile_in_zip_read_info->read_buffer = NULL; if (pfile_in_zip_read_info->stream_initialised) inflateEnd(&pfile_in_zip_read_info->stream); pfile_in_zip_read_info->stream_initialised = 0; TRYFREE(pfile_in_zip_read_info); s->pfile_in_zip_read=NULL; return err; } /* Get the global comment string of the ZipFile, in the szComment buffer. uSizeBuf is the size of the szComment buffer. return the number of byte copied or an error code <0 */ extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) unzFile file; char *szComment; uLong uSizeBuf; { unz_s* s; uLong uReadThis ; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; uReadThis = uSizeBuf; if (uReadThis>s->gi.size_comment) uReadThis = s->gi.size_comment; if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (uReadThis>0) { *szComment='\0'; if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) return UNZ_ERRNO; } if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) *(szComment+s->gi.size_comment)='\0'; return (int)uReadThis; } /* Additions by RX '2004 */ extern uLong ZEXPORT unzGetOffset (file) unzFile file; { unz_s* s; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; if (!s->current_file_ok) return 0; if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) if (s->num_file==s->gi.number_entry) return 0; return s->pos_in_central_dir; } extern int ZEXPORT unzSetOffset (file, pos) unzFile file; uLong pos; { unz_s* s; int err; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; s->pos_in_central_dir = pos; s->num_file = s->gi.number_entry; /* hack */ err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return err; } mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazip_global.h0000644000175000017500000000322012070466513022544 0ustar csmallcsmall/** Copyright (C) 2005-2011 Sergey A. Tachenov This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant, see quazip/(un)zip.h files for details, basically it's zlib license. */ #ifndef QUAZIP_GLOBAL_H #define QUAZIP_GLOBAL_H #include /** This is automatically defined when building a static library, but when including QuaZip sources directly into a project, QUAZIP_STATIC should be defined explicitly to avoid possible troubles with unnecessary importing/exporting. */ #ifdef QUAZIP_STATIC #define QUAZIP_EXPORT #else /** * When building a DLL with MSVC, QUAZIP_BUILD must be defined. * qglobal.h takes care of defining Q_DECL_* correctly for msvc/gcc. */ #if defined(QUAZIP_BUILD) #define QUAZIP_EXPORT Q_DECL_EXPORT #else #define QUAZIP_EXPORT Q_DECL_IMPORT #endif #endif // QUAZIP_STATIC #ifdef __GNUC__ #define UNUSED __attribute__((__unused__)) #else #define UNUSED #endif #endif // QUAZIP_GLOBAL_H mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quacrc32.cpp0000644000175000017500000000067312070466513021702 0ustar csmallcsmall#include "quacrc32.h" #include "zlib.h" QuaCrc32::QuaCrc32() { reset(); } quint32 QuaCrc32::calculate(const QByteArray &data) { return crc32( crc32(0L, Z_NULL, 0), (const Bytef*)data.data(), data.size() ); } void QuaCrc32::reset() { checksum = crc32(0L, Z_NULL, 0); } void QuaCrc32::update(const QByteArray &buf) { checksum = crc32( checksum, (const Bytef*)buf.data(), buf.size() ); } quint32 QuaCrc32::value() { return checksum; } mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quachecksum32.h0000644000175000017500000000257012070466513022400 0ustar csmallcsmall#ifndef QUACHECKSUM32_H #define QUACHECKSUM32_H #include #include "quazip_global.h" /// Checksum interface. /** \class QuaChecksum32 quachecksum32.h * This is an interface for 32 bit checksums. * Classes implementing this interface can calcunate a certin * checksum in a single step: * \code * QChecksum32 *crc32 = new QuaCrc32(); * rasoult = crc32->calculate(data); * \endcode * or by streaming the data: * \code * QChecksum32 *crc32 = new QuaCrc32(); * while(!fileA.atEnd()) * crc32->update(fileA.read(bufSize)); * resoultA = crc32->value(); * crc32->reset(); * while(!fileB.atEnd()) * crc32->update(fileB.read(bufSize)); * resoultB = crc32->value(); * \endcode */ class QUAZIP_EXPORT QuaChecksum32 { public: ///Calculates the checksum for data. /** \a data source data * \return data checksum * * This function has no efect on the value returned by value(). */ virtual quint32 calculate(const QByteArray &data) = 0; ///Resets the calculation on a checksun for a stream. virtual void reset() = 0; ///Updates the calculated checksum for the stream /** \a buf next portion of data from the stream */ virtual void update(const QByteArray &buf) = 0; ///Value of the checksum calculated for the stream passed throw update(). /** \return checksum */ virtual quint32 value() = 0; }; #endif //QUACHECKSUM32_H mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazipfile.h0000644000175000017500000004621412070466513022076 0ustar csmallcsmall#ifndef QUA_ZIPFILE_H #define QUA_ZIPFILE_H /* Copyright (C) 2005-2011 Sergey A. Tachenov This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant, see quazip/(un)zip.h files for details, basically it's zlib license. **/ #include #include "quazip_global.h" #include "quazip.h" #include "quazipnewinfo.h" class QuaZipFilePrivate; /// A file inside ZIP archive. /** \class QuaZipFile quazipfile.h * This is the most interesting class. Not only it provides C++ * interface to the ZIP/UNZIP package, but also integrates it with Qt by * subclassing QIODevice. This makes possible to access files inside ZIP * archive using QTextStream or QDataStream, for example. Actually, this * is the main purpose of the whole QuaZIP library. * * You can either use existing QuaZip instance to create instance of * this class or pass ZIP archive file name to this class, in which case * it will create internal QuaZip object. See constructors' descriptions * for details. Writing is only possible with the existing instance. * * Note that due to the underlying library's limitation it is not * possible to use multiple QuaZipFile instances to open several files * in the same archive at the same time. If you need to write to * multiple files in parallel, then you should write to temporary files * first, then pack them all at once when you have finished writing. If * you need to read multiple files inside the same archive in parallel, * you should extract them all into a temporary directory first. * * \section quazipfile-sequential Sequential or random-access? * * At the first thought, QuaZipFile has fixed size, the start and the * end and should be therefore considered random-access device. But * there is one major obstacle to making it random-access: ZIP/UNZIP API * does not support seek() operation and the only way to implement it is * through reopening the file and re-reading to the required position, * but this is prohibitively slow. * * Therefore, QuaZipFile is considered to be a sequential device. This * has advantage of availability of the ungetChar() operation (QIODevice * does not implement it properly for non-sequential devices unless they * support seek()). Disadvantage is a somewhat strange behaviour of the * size() and pos() functions. This should be kept in mind while using * this class. * **/ class QUAZIP_EXPORT QuaZipFile: public QIODevice { friend class QuaZipFilePrivate; Q_OBJECT private: QuaZipFilePrivate *p; // these are not supported nor implemented QuaZipFile(const QuaZipFile& that); QuaZipFile& operator=(const QuaZipFile& that); protected: /// Implementation of the QIODevice::readData(). qint64 readData(char *data, qint64 maxSize); /// Implementation of the QIODevice::writeData(). qint64 writeData(const char *data, qint64 maxSize); public: /// Constructs a QuaZipFile instance. /** You should use setZipName() and setFileName() or setZip() before * trying to call open() on the constructed object. **/ QuaZipFile(); /// Constructs a QuaZipFile instance. /** \a parent argument specifies this object's parent object. * * You should use setZipName() and setFileName() or setZip() before * trying to call open() on the constructed object. **/ QuaZipFile(QObject *parent); /// Constructs a QuaZipFile instance. /** \a parent argument specifies this object's parent object and \a * zipName specifies ZIP archive file name. * * You should use setFileName() before trying to call open() on the * constructed object. * * QuaZipFile constructed by this constructor can be used for read * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. **/ QuaZipFile(const QString& zipName, QObject *parent =NULL); /// Constructs a QuaZipFile instance. /** \a parent argument specifies this object's parent object, \a * zipName specifies ZIP archive file name and \a fileName and \a cs * specify a name of the file to open inside archive. * * QuaZipFile constructed by this constructor can be used for read * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. * * \sa QuaZip::setCurrentFile() **/ QuaZipFile(const QString& zipName, const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =NULL); /// Constructs a QuaZipFile instance. /** \a parent argument specifies this object's parent object. * * \a zip is the pointer to the existing QuaZip object. This * QuaZipFile object then can be used to read current file in the * \a zip or to write to the file inside it. * * \warning Using this constructor for reading current file can be * tricky. Let's take the following example: * \code * QuaZip zip("archive.zip"); * zip.open(QuaZip::mdUnzip); * zip.setCurrentFile("file-in-archive"); * QuaZipFile file(&zip); * file.open(QIODevice::ReadOnly); * // ok, now we can read from the file * file.read(somewhere, some); * zip.setCurrentFile("another-file-in-archive"); // oops... * QuaZipFile anotherFile(&zip); * anotherFile.open(QIODevice::ReadOnly); * anotherFile.read(somewhere, some); // this is still ok... * file.read(somewhere, some); // and this is NOT * \endcode * So, what exactly happens here? When we change current file in the * \c zip archive, \c file that references it becomes invalid * (actually, as far as I understand ZIP/UNZIP sources, it becomes * closed, but QuaZipFile has no means to detect it). * * Summary: do not close \c zip object or change its current file as * long as QuaZipFile is open. Even better - use another constructors * which create internal QuaZip instances, one per object, and * therefore do not cause unnecessary trouble. This constructor may * be useful, though, if you already have a QuaZip instance and do * not want to access several files at once. Good example: * \code * QuaZip zip("archive.zip"); * zip.open(QuaZip::mdUnzip); * // first, we need some information about archive itself * QByteArray comment=zip.getComment(); * // and now we are going to access files inside it * QuaZipFile file(&zip); * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { * file.open(QIODevice::ReadOnly); * // do something cool with file here * file.close(); // do not forget to close! * } * zip.close(); * \endcode **/ QuaZipFile(QuaZip *zip, QObject *parent =NULL); /// Destroys a QuaZipFile instance. /** Closes file if open, destructs internal QuaZip object (if it * exists and \em is internal, of course). **/ virtual ~QuaZipFile(); /// Returns the ZIP archive file name. /** If this object was created by passing QuaZip pointer to the * constructor, this function will return that QuaZip's file name * (or null string if that object does not have file name yet). * * Otherwise, returns associated ZIP archive file name or null * string if there are no name set yet. * * \sa setZipName() getFileName() **/ QString getZipName()const; /// Returns a pointer to the associated QuaZip object. /** Returns \c NULL if there is no associated QuaZip or it is * internal (so you will not mess with it). **/ QuaZip* getZip()const; /// Returns file name. /** This function returns file name you passed to this object either * by using * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) * or by calling setFileName(). Real name of the file may differ in * case if you used case-insensitivity. * * Returns null string if there is no file name set yet. This is the * case when this QuaZipFile operates on the existing QuaZip object * (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used). * * \sa getActualFileName **/ QString getFileName() const; /// Returns case sensitivity of the file name. /** This function returns case sensitivity argument you passed to * this object either by using * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) * or by calling setFileName(). * * Returns unpredictable value if getFileName() returns null string * (this is the case when you did not used setFileName() or * constructor above). * * \sa getFileName **/ QuaZip::CaseSensitivity getCaseSensitivity() const; /// Returns the actual file name in the archive. /** This is \em not a ZIP archive file name, but a name of file inside * archive. It is not necessary the same name that you have passed * to the * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*), * setFileName() or QuaZip::setCurrentFile() - this is the real file * name inside archive, so it may differ in case if the file name * search was case-insensitive. * * Equivalent to calling getCurrentFileName() on the associated * QuaZip object. Returns null string if there is no associated * QuaZip object or if it does not have a current file yet. And this * is the case if you called setFileName() but did not open the * file yet. So this is perfectly fine: * \code * QuaZipFile file("somezip.zip"); * file.setFileName("somefile"); * QString name=file.getName(); // name=="somefile" * QString actual=file.getActualFileName(); // actual is null string * file.open(QIODevice::ReadOnly); * QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows * \endcode * * \sa getZipName(), getFileName(), QuaZip::CaseSensitivity **/ QString getActualFileName()const; /// Sets the ZIP archive file name. /** Automatically creates internal QuaZip object and destroys * previously created internal QuaZip object, if any. * * Will do nothing if this file is already open. You must close() it * first. **/ void setZipName(const QString& zipName); /// Returns \c true if the file was opened in raw mode. /** If the file is not open, the returned value is undefined. * * \sa open(OpenMode,int*,int*,bool,const char*) **/ bool isRaw() const; /// Binds to the existing QuaZip instance. /** This function destroys internal QuaZip object, if any, and makes * this QuaZipFile to use current file in the \a zip object for any * further operations. See QuaZipFile(QuaZip*,QObject*) for the * possible pitfalls. * * Will do nothing if the file is currently open. You must close() * it first. **/ void setZip(QuaZip *zip); /// Sets the file name. /** Will do nothing if at least one of the following conditions is * met: * - ZIP name has not been set yet (getZipName() returns null * string). * - This QuaZipFile is associated with external QuaZip. In this * case you should call that QuaZip's setCurrentFile() function * instead! * - File is already open so setting the name is meaningless. * * \sa QuaZip::setCurrentFile **/ void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault); /// Opens a file for reading. /** Returns \c true on success, \c false otherwise. * Call getZipError() to get error code. * * \note Since ZIP/UNZIP API provides buffered reading only, * QuaZipFile does not support unbuffered reading. So do not pass * QIODevice::Unbuffered flag in \a mode, or open will fail. **/ virtual bool open(OpenMode mode); /// Opens a file for reading. /** \overload * Argument \a password specifies a password to decrypt the file. If * it is NULL then this function behaves just like open(OpenMode). **/ inline bool open(OpenMode mode, const char *password) {return open(mode, NULL, NULL, false, password);} /// Opens a file for reading. /** \overload * Argument \a password specifies a password to decrypt the file. * * An integers pointed by \a method and \a level will receive codes * of the compression method and level used. See unzip.h. * * If raw is \c true then no decompression is performed. * * \a method should not be \c NULL. \a level can be \c NULL if you * don't want to know the compression level. **/ bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =NULL); /// Opens a file for writing. /** \a info argument specifies information about file. It should at * least specify a correct file name. Also, it is a good idea to * specify correct timestamp (by default, current time will be * used). See QuaZipNewInfo. * * The \a password argument specifies the password for crypting. Pass NULL * if you don't need any crypting. The \a crc argument was supposed * to be used for crypting too, but then it turned out that it's * false information, so you need to set it to 0 unless you want to * use the raw mode (see below). * * Arguments \a method and \a level specify compression method and * level. The only method supported is Z_DEFLATED, but you may also * specify 0 for no compression. If all of the files in the archive * use both method 0 and either level 0 is explicitly specified or * data descriptor writing is disabled with * QuaZip::setDataDescriptorWritingEnabled(), then the * resulting archive is supposed to be compatible with the 1.0 ZIP * format version, should you need that. Except for this, \a level * has no other effects with method 0. * * If \a raw is \c true, no compression is performed. In this case, * \a crc and uncompressedSize field of the \a info are required. * * Arguments \a windowBits, \a memLevel, \a strategy provide zlib * algorithms tuning. See deflateInit2() in zlib. **/ bool open(OpenMode mode, const QuaZipNewInfo& info, const char *password =NULL, quint32 crc =0, int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false, int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY); /// Returns \c true, but \ref quazipfile-sequential "beware"! virtual bool isSequential()const; /// Returns current position in the file. /** Implementation of the QIODevice::pos(). When reading, this * function is a wrapper to the ZIP/UNZIP unztell(), therefore it is * unable to keep track of the ungetChar() calls (which is * non-virtual and therefore is dangerous to reimplement). So if you * are using ungetChar() feature of the QIODevice, this function * reports incorrect value until you get back characters which you * ungot. * * When writing, pos() returns number of bytes already written * (uncompressed unless you use raw mode). * * \note Although * \ref quazipfile-sequential "QuaZipFile is a sequential device" * and therefore pos() should always return zero, it does not, * because it would be misguiding. Keep this in mind. * * This function returns -1 if the file or archive is not open. * * Error code returned by getZipError() is not affected by this * function call. **/ virtual qint64 pos()const; /// Returns \c true if the end of file was reached. /** This function returns \c false in the case of error. This means * that you called this function on either not open file, or a file * in the not open archive or even on a QuaZipFile instance that * does not even have QuaZip instance associated. Do not do that * because there is no means to determine whether \c false is * returned because of error or because end of file was reached. * Well, on the other side you may interpret \c false return value * as "there is no file open to check for end of file and there is * no end of file therefore". * * When writing, this function always returns \c true (because you * are always writing to the end of file). * * Error code returned by getZipError() is not affected by this * function call. **/ virtual bool atEnd()const; /// Returns file size. /** This function returns csize() if the file is open for reading in * raw mode, usize() if it is open for reading in normal mode and * pos() if it is open for writing. * * Returns -1 on error, call getZipError() to get error code. * * \note This function returns file size despite that * \ref quazipfile-sequential "QuaZipFile is considered to be sequential device", * for which size() should return bytesAvailable() instead. But its * name would be very misguiding otherwise, so just keep in mind * this inconsistence. **/ virtual qint64 size()const; /// Returns compressed file size. /** Equivalent to calling getFileInfo() and then getting * compressedSize field, but more convenient and faster. * * File must be open for reading before calling this function. * * Returns -1 on error, call getZipError() to get error code. **/ qint64 csize()const; /// Returns uncompressed file size. /** Equivalent to calling getFileInfo() and then getting * uncompressedSize field, but more convenient and faster. See * getFileInfo() for a warning. * * File must be open for reading before calling this function. * * Returns -1 on error, call getZipError() to get error code. **/ qint64 usize()const; /// Gets information about current file. /** This function does the same thing as calling * QuaZip::getCurrentFileInfo() on the associated QuaZip object, * but you can not call getCurrentFileInfo() if the associated * QuaZip is internal (because you do not have access to it), while * you still can call this function in that case. * * File must be open for reading before calling this function. * * Returns \c false in the case of an error. **/ bool getFileInfo(QuaZipFileInfo *info); /// Closes the file. /** Call getZipError() to determine if the close was successful. **/ virtual void close(); /// Returns the error code returned by the last ZIP/UNZIP API call. int getZipError() const; /// Returns the number of bytes available for reading. virtual qint64 bytesAvailable() const; }; #endif mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazip.pro0000644000175000017500000000321212070466513021576 0ustar csmallcsmallTEMPLATE = lib CONFIG += qt warn_on QT -= gui DEPENDPATH += . INCLUDEPATH += . DEFINES += QUAZIP_BUILD CONFIG(staticlib): DEFINES += QUAZIP_STATIC # Input HEADERS += \ crypt.h\ ioapi.h\ JlCompress.h\ quaadler32.h\ quachecksum32.h\ quacrc32.h\ quazip.h\ quazipfile.h\ quazipfileinfo.h\ quazipnewinfo.h\ quazip_global.h\ unzip.h\ zip.h\ SOURCES += *.c *.cpp unix:!symbian { headers.path=$$PREFIX/include/quazip headers.files=$$HEADERS target.path=$$PREFIX/lib INSTALLS += headers target OBJECTS_DIR=.obj MOC_DIR=.moc } win32 { headers.path=$$PREFIX/include/quazip headers.files=$$HEADERS target.path=$$PREFIX/lib INSTALLS += headers target } symbian { # Note, on Symbian you may run into troubles with LGPL. # The point is, if your application uses some version of QuaZip, # and a newer binary compatible version of QuaZip is released, then # the users of your application must be able to relink it with the # new QuaZip version. For example, to take advantage of some QuaZip # bug fixes. # This is probably best achieved by building QuaZip as a static # library and providing linkable object files of your application, # so users can relink it. CONFIG += staticlib CONFIG += debug_and_release LIBS += -lezip #Export headers to SDK Epoc32/include directory exportheaders.sources = $$HEADERS exportheaders.path = quazip for(header, exportheaders.sources) { BLD_INF_RULES.prj_exports += "$$header $$exportheaders.path/$$basename(header)" } } win32:INCLUDEPATH += "c:\mudlet_package_MINGW\zlib-1.2.5"mudlet-2.1/src/quazip/quazip-0.4.4/quazip/object_script.quazip.Release0000644000175000017500000000034112070466513025207 0ustar csmallcsmallINPUT( ./release\unzip.o ./release\zip.o ./release\JlCompress.o ./release\qioapi.o ./release\quaadler32.o ./release\quacrc32.o ./release\quazip.o ./release\quazipfile.o ./release\quazipnewinfo.o ./release\moc_quazipfile.o ); mudlet-2.1/src/quazip/quazip-0.4.4/quazip/zip.h0000644000175000017500000002166212070466513020527 0ustar csmallcsmall/* zip.h -- IO for compress .zip files using zlib Version 1.01e, February 12th, 2005 Copyright (C) 1998-2005 Gilles Vollant This unzip package allow creates .ZIP file, compatible with PKZip 2.04g WinZip, InfoZip tools and compatible. Multi volume ZipFile (span) are not supported. Encryption compatible with pkzip 2.04g only supported Old compressions used by old PKZip 1.x are not supported For uncompress .zip file, look at unzip.h I WAIT FEEDBACK at mail info@winimage.com Visit also http://www.winimage.com/zLibDll/unzip.html for evolution Condition of use and distribution are the same than zlib : This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Modified by Sergey A. Tachenov to integrate with Qt. */ /* for more info about .ZIP format, see http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip http://www.info-zip.org/pub/infozip/doc/ PkWare has also a specification at : ftp://ftp.pkware.com/probdesc.zip */ #ifndef _zip_H #define _zip_H #ifdef __cplusplus extern "C" { #endif #ifndef _ZLIB_H #include "zlib.h" #endif #ifndef _ZLIBIOAPI_H #include "ioapi.h" #endif #if defined(STRICTZIP) || defined(STRICTZIPUNZIP) /* like the STRICT of WIN32, we define a pointer that cannot be converted from (void*) without cast */ typedef struct TagzipFile__ { int unused; } zipFile__; typedef zipFile__ *zipFile; #else typedef voidp zipFile; #endif #define ZIP_OK (0) #define ZIP_EOF (0) #define ZIP_ERRNO (Z_ERRNO) #define ZIP_PARAMERROR (-102) #define ZIP_BADZIPFILE (-103) #define ZIP_INTERNALERROR (-104) #define ZIP_WRITE_DATA_DESCRIPTOR 0x8u #ifndef DEF_MEM_LEVEL # if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 # else # define DEF_MEM_LEVEL MAX_MEM_LEVEL # endif #endif /* default memLevel */ /* tm_zip contain date/time info */ typedef struct tm_zip_s { uInt tm_sec; /* seconds after the minute - [0,59] */ uInt tm_min; /* minutes after the hour - [0,59] */ uInt tm_hour; /* hours since midnight - [0,23] */ uInt tm_mday; /* day of the month - [1,31] */ uInt tm_mon; /* months since January - [0,11] */ uInt tm_year; /* years - [1980..2044] */ } tm_zip; typedef struct { tm_zip tmz_date; /* date in understandable format */ uLong dosDate; /* if dos_date == 0, tmu_date is used */ /* uLong flag; */ /* general purpose bit flag 2 bytes */ uLong internal_fa; /* internal file attributes 2 bytes */ uLong external_fa; /* external file attributes 4 bytes */ } zip_fileinfo; typedef const char* zipcharpc; #define APPEND_STATUS_CREATE (0) #define APPEND_STATUS_CREATEAFTER (1) #define APPEND_STATUS_ADDINZIP (2) extern zipFile ZEXPORT zipOpen OF((voidpf file, int append)); /* Create a zipfile. file is whatever the IO API accepts. For Qt IO API it's a pointer to QIODevice. For fopen() IO API it's a file name (const char*). if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip will be created at the end of the file. (useful if the file contain a self extractor code) if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will add files in existing zip (be sure you don't add file that doesn't exist) If the zipfile cannot be opened, the return value is NULL. Else, the return value is a zipFile Handle, usable with other function of this zip package. */ /* Note : there is no delete function into a zipfile. If you want delete file into a zipfile, you must open a zipfile, and create another Of couse, you can use RAW reading and writing to copy the file you did not want delte */ extern zipFile ZEXPORT zipOpen2 OF((voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc_def)); extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level)); /* Open a file in the ZIP for writing. filename : the filename in zip (if NULL, '-' without quote will be used *zipfi contain supplemental information if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local contains the extrafield data the the local header if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global contains the extrafield data the the local header if comment != NULL, comment contain the comment string method contain the compression method (0 for store, Z_DEFLATED for deflate) level contain the level of compression (can be Z_DEFAULT_COMPRESSION) */ extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw)); /* Same than zipOpenNewFileInZip, except if raw=1, we write raw file */ extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char* password, uLong crcForCtypting)); /* Same than zipOpenNewFileInZip2, except windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 password : crypting password (NULL for no crypting) crcForCtypting : crc of file to compress (needed for crypting) */ extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, const void* buf, unsigned len)); /* Write data in the zipfile */ extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); /* Close the current file in the zipfile */ extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, uLong uncompressed_size, uLong crc32)); /* Close the current file in the zipfile, for fiel opened with parameter raw=1 in zipOpenNewFileInZip2 uncompressed_size and crc32 are value for the uncompressed size */ extern int ZEXPORT zipClose OF((zipFile file, const char* global_comment)); /* Close the zipfile */ /* Added by Sergey A. Tachenov to tweak zipping behaviour. */ extern int ZEXPORT zipSetFlags(zipFile file, unsigned flags); extern int ZEXPORT zipClearFlags(zipFile file, unsigned flags); #ifdef __cplusplus } #endif #endif /* _zip_H */ mudlet-2.1/src/quazip/quazip-0.4.4/quazip/unzip.h0000644000175000017500000003134412070466513021070 0ustar csmallcsmall/* unzip.h -- IO for uncompress .zip files using zlib Version 1.01e, February 12th, 2005 Copyright (C) 1998-2005 Gilles Vollant This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g WinZip, InfoZip tools and compatible. Multi volume ZipFile (span) are not supported. Encryption compatible with pkzip 2.04g only supported Old compressions used by old PKZip 1.x are not supported I WAIT FEEDBACK at mail info@winimage.com Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution Condition of use and distribution are the same than zlib : This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Modified by Sergey A. Tachenov to integrate with Qt. */ /* for more info about .ZIP format, see http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip http://www.info-zip.org/pub/infozip/doc/ PkWare has also a specification at : ftp://ftp.pkware.com/probdesc.zip */ #ifndef _unz_H #define _unz_H #ifdef __cplusplus extern "C" { #endif #ifndef _ZLIB_H #include "zlib.h" #endif #ifndef _ZLIBIOAPI_H #include "ioapi.h" #endif #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) /* like the STRICT of WIN32, we define a pointer that cannot be converted from (void*) without cast */ typedef struct TagunzFile__ { int unused; } unzFile__; typedef unzFile__ *unzFile; #else typedef voidp unzFile; #endif #define UNZ_OK (0) #define UNZ_END_OF_LIST_OF_FILE (-100) #define UNZ_ERRNO (Z_ERRNO) #define UNZ_EOF (0) #define UNZ_PARAMERROR (-102) #define UNZ_BADZIPFILE (-103) #define UNZ_INTERNALERROR (-104) #define UNZ_CRCERROR (-105) /* tm_unz contain date/time info */ typedef struct tm_unz_s { uInt tm_sec; /* seconds after the minute - [0,59] */ uInt tm_min; /* minutes after the hour - [0,59] */ uInt tm_hour; /* hours since midnight - [0,23] */ uInt tm_mday; /* day of the month - [1,31] */ uInt tm_mon; /* months since January - [0,11] */ uInt tm_year; /* years - [1980..2044] */ } tm_unz; /* unz_global_info structure contain global data about the ZIPfile These data comes from the end of central dir */ typedef struct unz_global_info_s { uLong number_entry; /* total number of entries in the central dir on this disk */ uLong size_comment; /* size of the global comment of the zipfile */ } unz_global_info; /* unz_file_info contain information about a file in the zipfile */ typedef struct unz_file_info_s { uLong version; /* version made by 2 bytes */ uLong version_needed; /* version needed to extract 2 bytes */ uLong flag; /* general purpose bit flag 2 bytes */ uLong compression_method; /* compression method 2 bytes */ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ uLong crc; /* crc-32 4 bytes */ uLong compressed_size; /* compressed size 4 bytes */ uLong uncompressed_size; /* uncompressed size 4 bytes */ uLong size_filename; /* filename length 2 bytes */ uLong size_file_extra; /* extra field length 2 bytes */ uLong size_file_comment; /* file comment length 2 bytes */ uLong disk_num_start; /* disk number start 2 bytes */ uLong internal_fa; /* internal file attributes 2 bytes */ uLong external_fa; /* external file attributes 4 bytes */ tm_unz tmu_date; } unz_file_info; extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, const char* fileName2, int iCaseSensitivity)); /* Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi or strcasecmp) If iCaseSenisivity = 0, case sensitivity is defaut of your operating system (like 1 on Unix, 2 on Windows) */ extern unzFile ZEXPORT unzOpen OF((voidpf file)); /* Open a Zip file. path contain whatever zopen_file from the IO API accepts. For Qt implementation it is a pointer to QIODevice, for fopen() implementation it's a file name. If the zipfile cannot be opened (file don't exist or in not valid), the return value is NULL. Else, the return value is a unzFile Handle, usable with other function of this unzip package. */ extern unzFile ZEXPORT unzOpen2 OF((voidpf file, zlib_filefunc_def* pzlib_filefunc_def)); /* Open a Zip file, like unzOpen, but provide a set of file low level API for read/write the zip file (see ioapi.h) */ extern int ZEXPORT unzClose OF((unzFile file)); /* Close a ZipFile opened with unzipOpen. If there is files inside the .Zip opened with unzOpenCurrentFile (see later), these files MUST be closed with unzipCloseCurrentFile before call unzipClose. return UNZ_OK if there is no problem. */ extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, unz_global_info *pglobal_info)); /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ extern int ZEXPORT unzGetGlobalComment OF((unzFile file, char *szComment, uLong uSizeBuf)); /* Get the global comment string of the ZipFile, in the szComment buffer. uSizeBuf is the size of the szComment buffer. return the number of byte copied or an error code <0 */ /***************************************************************************/ /* Unzip package allow you browse the directory of the zipfile */ extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); /* Set the current file of the zipfile to the first file. return UNZ_OK if there is no problem */ extern int ZEXPORT unzGoToNextFile OF((unzFile file)); /* Set the current file of the zipfile to the next file. return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ extern int ZEXPORT unzLocateFile OF((unzFile file, const char *szFileName, int iCaseSensitivity)); /* Try locate the file szFileName in the zipfile. For the iCaseSensitivity signification, see unzStringFileNameCompare return value : UNZ_OK if the file is found. It becomes the current file. UNZ_END_OF_LIST_OF_FILE if the file is not found */ /* ****************************************** */ /* Ryan supplied functions */ /* unz_file_info contain information about a file in the zipfile */ typedef struct unz_file_pos_s { uLong pos_in_zip_directory; /* offset in zip file directory */ uLong num_of_file; /* # of file */ } unz_file_pos; extern int ZEXPORT unzGetFilePos( unzFile file, unz_file_pos* file_pos); extern int ZEXPORT unzGoToFilePos( unzFile file, unz_file_pos* file_pos); /* ****************************************** */ extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, unz_file_info *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)); /* Get Info about the current file if pfile_info!=NULL, the *pfile_info structure will contain somes info about the current file if szFileName!=NULL, the filemane string will be copied in szFileName (fileNameBufferSize is the size of the buffer) if extraField!=NULL, the extra field information will be copied in extraField (extraFieldBufferSize is the size of the buffer). This is the Central-header version of the extra field if szComment!=NULL, the comment string of the file will be copied in szComment (commentBufferSize is the size of the buffer) */ /***************************************************************************/ /* for reading the content of the current zipfile, you can open it, read data from it, and close it (you can close it before reading all the file) */ extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); /* Open for reading data the current file in the zipfile. If there is no error, the return value is UNZ_OK. */ extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, const char* password)); /* Open for reading data the current file in the zipfile. password is a crypting password If there is no error, the return value is UNZ_OK. */ extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, int* method, int* level, int raw)); /* Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) if raw==1 *method will receive method of compression, *level will receive level of compression note : you can set level parameter as NULL (if you did not want known level, but you CANNOT set method parameter as NULL */ extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, int* method, int* level, int raw, const char* password)); /* Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) if raw==1 *method will receive method of compression, *level will receive level of compression note : you can set level parameter as NULL (if you did not want known level, but you CANNOT set method parameter as NULL */ extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); /* Close the file in zip opened with unzOpenCurrentFile Return UNZ_CRCERROR if all the file was read but the CRC is not good */ extern int ZEXPORT unzReadCurrentFile OF((unzFile file, voidp buf, unsigned len)); /* Read bytes from the current file (opened by unzOpenCurrentFile) buf contain buffer where data must be copied len the size of buf. return the number of byte copied if somes bytes are copied return 0 if the end of file was reached return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ extern z_off_t ZEXPORT unztell OF((unzFile file)); /* Give the current position in uncompressed data */ extern int ZEXPORT unzeof OF((unzFile file)); /* return 1 if the end of file was reached, 0 elsewhere */ extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, voidp buf, unsigned len)); /* Read extra field from the current file (opened by unzOpenCurrentFile) This is the local-header version of the extra field (sometimes, there is more info in the local-header version than in the central-header) if buf==NULL, it return the size of the local extra field if buf!=NULL, len is the size of the buffer, the extra header is copied in buf. the return value is the number of bytes copied in buf, or (if <0) the error code */ /***************************************************************************/ /* Get the current file offset */ extern uLong ZEXPORT unzGetOffset (unzFile file); /* Set the current file offset */ extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); #ifdef __cplusplus } #endif #endif /* _unz_H */ mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazip.vcproj0000644000175000017500000001152312070466513022305 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/quazip/JlCompress.cpp0000644000175000017500000003554012070466513022341 0ustar csmallcsmall#include "JlCompress.h" #include static bool copyData(QIODevice &inFile, QIODevice &outFile) { while (!inFile.atEnd()) { char buf[4096]; qint64 readLen = inFile.read(buf, 4096); if (readLen <= 0) return false; if (outFile.write(buf, readLen) != readLen) return false; } return true; } /**OK * Comprime il file fileName, nell'oggetto zip, con il nome fileDest. * * La funzione fallisce se: * * zip==NULL; * * l'oggetto zip e stato aperto in una modalita non compatibile con l'aggiunta di file; * * non e possibile aprire il file d'origine; * * non e possibile creare il file all'interno dell'oggetto zip; * * si e rilevato un errore nella copia dei dati; * * non e stato possibile chiudere il file all'interno dell'oggetto zip; */ bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) { // zip: oggetto dove aggiungere il file // fileName: nome del file reale // fileDest: nome del file all'interno del file compresso // Controllo l'apertura dello zip if (!zip) return false; if (zip->getMode()!=QuaZip::mdCreate && zip->getMode()!=QuaZip::mdAppend && zip->getMode()!=QuaZip::mdAdd) return false; // Apro il file originale QFile inFile; inFile.setFileName(fileName); if(!inFile.open(QIODevice::ReadOnly)) return false; // Apro il file risulato QuaZipFile outFile(zip); if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName()))) return false; // Copio i dati if (!copyData(inFile, outFile) || outFile.getZipError()!=UNZ_OK) { return false; } // Chiudo i file outFile.close(); if (outFile.getZipError()!=UNZ_OK) return false; inFile.close(); return true; } /**OK * Comprime la cartella dir nel file fileCompressed, se recursive e true allora * comprime anche le sotto cartelle. I nomi dei file preceduti dal path creato * togliendo il pat della cartella origDir al path della cartella dir. * Se la funzione fallisce restituisce false e cancella il file che si e tentato * di creare. * * La funzione fallisce se: * * zip==NULL; * * l'oggetto zip e stato aperto in una modalita non compatibile con l'aggiunta di file; * * la cartella dir non esiste; * * la compressione di una sotto cartella fallisce (1); * * la compressione di un file fallisce; * (1) La funzione si richiama in maniera ricorsiva per comprimere le sotto cartelle * dunque gli errori di compressione di una sotto cartella sono gli stessi di questa * funzione. */ bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive) { // zip: oggetto dove aggiungere il file // dir: cartella reale corrente // origDir: cartella reale originale // (path(dir)-path(origDir)) = path interno all'oggetto zip // Controllo l'apertura dello zip if (!zip) return false; if (zip->getMode()!=QuaZip::mdCreate && zip->getMode()!=QuaZip::mdAppend && zip->getMode()!=QuaZip::mdAdd) return false; // Controllo la cartella QDir directory(dir); if (!directory.exists()) return false; // Se comprimo anche le sotto cartelle if (recursive) { // Per ogni sotto cartella QFileInfoList files = directory.entryInfoList(QDir::AllDirs|QDir::NoDotAndDotDot); Q_FOREACH (QFileInfo file, files) { // Comprimo la sotto cartella if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive)) return false; } } // Per ogni file nella cartella QFileInfoList files = directory.entryInfoList(QDir::Files); QDir origDirectory(origDir); Q_FOREACH (QFileInfo file, files) { // Se non e un file o e il file compresso che sto creando if(!file.isFile()||file.absoluteFilePath()==zip->getZipName()) continue; // Creo il nome relativo da usare all'interno del file compresso QString filename = origDirectory.relativeFilePath(file.absoluteFilePath()); // Comprimo il file if (!compressFile(zip,file.absoluteFilePath(),filename)) return false; } return true; } /**OK * Estrae il file fileName, contenuto nell'oggetto zip, con il nome fileDest. * Se la funzione fallisce restituisce false e cancella il file che si e tentato di estrarre. * * La funzione fallisce se: * * zip==NULL; * * l'oggetto zip e stato aperto in una modalita non compatibile con l'estrazione di file; * * non e possibile aprire il file all'interno dell'oggetto zip; * * non e possibile creare il file estratto; * * si e rilevato un errore nella copia dei dati (1); * * non e stato possibile chiudere il file all'interno dell'oggetto zip (1); * * (1): prima di uscire dalla funzione cancella il file estratto. */ bool JlCompress::extractFile(QuaZip* zip, QString fileName, QString fileDest) { // zip: oggetto dove aggiungere il file // filename: nome del file reale // fileincompress: nome del file all'interno del file compresso // Controllo l'apertura dello zip if (!zip) return false; if (zip->getMode()!=QuaZip::mdUnzip) return false; // Apro il file compresso zip->setCurrentFile(fileName); QuaZipFile inFile(zip); if(!inFile.open(QIODevice::ReadOnly) || inFile.getZipError()!=UNZ_OK) return false; // Controllo esistenza cartella file risultato QDir curDir; if (!curDir.mkpath(QFileInfo(fileDest).absolutePath())) { return false; } if (QFileInfo(fileDest).isDir()) return true; // Apro il file risultato QFile outFile; outFile.setFileName(fileDest); if(!outFile.open(QIODevice::WriteOnly)) return false; // Copio i dati if (!copyData(inFile, outFile) || inFile.getZipError()!=UNZ_OK) { outFile.close(); removeFile(QStringList(fileDest)); return false; } outFile.close(); // Chiudo i file inFile.close(); if (inFile.getZipError()!=UNZ_OK) { removeFile(QStringList(fileDest)); return false; } return true; } /** * Rimuove i file il cui nome e specificato all'interno di listFile. * Restituisce true se tutti i file sono stati cancellati correttamente, attenzione * perche puo restituire false anche se alcuni file non esistevano e si e tentato * di cancellarli. */ bool JlCompress::removeFile(QStringList listFile) { bool ret = true; // Per ogni file for (int i=0; iopen(QuaZip::mdCreate)) { delete zip; QFile::remove(fileCompressed); return false; } // Aggiungo il file if (!compressFile(zip,file,QFileInfo(file).fileName())) { delete zip; QFile::remove(fileCompressed); return false; } // Chiudo il file zip zip->close(); if(zip->getZipError()!=0) { delete zip; QFile::remove(fileCompressed); return false; } delete zip; return true; } /**OK * Comprime i file specificati in files nel file fileCompressed. * Se la funzione fallisce restituisce false e cancella il file che si e tentato * di creare. * * La funzione fallisce se: * * non si riesce ad aprire l'oggetto zip; * * la compressione di un file fallisce; * * non si riesce a chiudere l'oggetto zip; */ bool JlCompress::compressFiles(QString fileCompressed, QStringList files) { // Creo lo zip QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath()); QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); if(!zip->open(QuaZip::mdCreate)) { delete zip; QFile::remove(fileCompressed); return false; } // Comprimo i file QFileInfo info; Q_FOREACH (QString file, files) { info.setFile(file); if (!info.exists() || !compressFile(zip,file,info.fileName())) { delete zip; QFile::remove(fileCompressed); return false; } } // Chiudo il file zip zip->close(); if(zip->getZipError()!=0) { delete zip; QFile::remove(fileCompressed); return false; } delete zip; return true; } /**OK * Comprime la cartella dir nel file fileCompressed, se recursive e true allora * comprime anche le sotto cartelle. * Se la funzione fallisce restituisce false e cancella il file che si e tentato * di creare. * * La funzione fallisce se: * * non si riesce ad aprire l'oggetto zip; * * la compressione di un file fallisce; * * non si riesce a chiudere l'oggetto zip; */ bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive) { // Creo lo zip QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath()); QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); if(!zip->open(QuaZip::mdCreate)) { delete zip; QFile::remove(fileCompressed); return false; } // Aggiungo i file e le sotto cartelle if (!compressSubDir(zip,dir,dir,recursive)) { delete zip; QFile::remove(fileCompressed); return false; } // Chiudo il file zip zip->close(); if(zip->getZipError()!=0) { delete zip; QFile::remove(fileCompressed); return false; } delete zip; return true; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /**OK * Estrae il file fileName, contenuto nel file fileCompressed, con il nome fileDest. * Se fileDest = "" allora il file viene estratto con lo stesso nome con cui e * stato compresso. * Se la funzione fallisce cancella il file che si e tentato di estrarre. * Restituisce il nome assoluto del file estratto. * * La funzione fallisce se: * * non si riesce ad aprire l'oggetto zip; * * l'estrazione del file fallisce; * * non si riesce a chiudere l'oggetto zip; */ QString JlCompress::extractFile(QString fileCompressed, QString fileName, QString fileDest) { // Apro lo zip QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath()); if(!zip->open(QuaZip::mdUnzip)) { delete zip; return QString(); } // Estraggo il file if (fileDest.isEmpty()) fileDest = fileName; if (!extractFile(zip,fileName,fileDest)) { delete zip; return QString(); } // Chiudo il file zip zip->close(); if(zip->getZipError()!=0) { removeFile(QStringList(fileDest)); return QString(); } delete zip; return QFileInfo(fileDest).absoluteFilePath(); } /**OK * Estrae i file specificati in files, contenuti nel file fileCompressed, nella * cartella dir. La struttura a cartelle del file compresso viene rispettata. * Se dir = "" allora il file viene estratto nella cartella corrente. * Se la funzione fallisce cancella i file che si e tentato di estrarre. * Restituisce i nomi assoluti dei file estratti. * * La funzione fallisce se: * * non si riesce ad aprire l'oggetto zip; * * l'estrazione di un file fallisce; * * non si riesce a chiudere l'oggetto zip; */ QStringList JlCompress::extractFiles(QString fileCompressed, QStringList files, QString dir) { // Creo lo zip QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath()); if(!zip->open(QuaZip::mdUnzip)) { delete zip; return QStringList(); } // Estraggo i file QStringList extracted; for (int i=0; iclose(); if(zip->getZipError()!=0) { delete zip; removeFile(extracted); return QStringList(); } delete zip; return extracted; } /**OK * Estrae il file fileCompressed nella cartella dir. * Se dir = "" allora il file viene estratto nella cartella corrente. * Se la funzione fallisce cancella i file che si e tentato di estrarre. * Restituisce i nomi assoluti dei file estratti. * * La funzione fallisce se: * * non si riesce ad aprire l'oggetto zip; * * la compressione di un file fallisce; * * non si riesce a chiudere l'oggetto zip; */ QStringList JlCompress::extractDir(QString fileCompressed, QString dir) { // Apro lo zip QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath()); if(!zip->open(QuaZip::mdUnzip)) { delete zip; return QStringList(); } // Estraggo i file QStringList lst = getFileList(fileCompressed); QDir directory(dir); QStringList extracted; for (int i=0; iclose(); if(zip->getZipError()!=0) { delete zip; removeFile(extracted); return QStringList(); } delete zip; return extracted; } /**OK * Restituisce la lista dei file resenti nel file compresso fileCompressed. * Se la funzione fallisce, restituisce un elenco vuoto. * * La funzione fallisce se: * * non si riesce ad aprire l'oggetto zip; * * la richiesta di informazioni di un file fallisce; * * non si riesce a chiudere l'oggetto zip; */ QStringList JlCompress::getFileList(QString fileCompressed) { // Apro lo zip QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath()); if(!zip->open(QuaZip::mdUnzip)) { delete zip; return QStringList(); } // Estraggo i nomi dei file QStringList lst; QuaZipFileInfo info; for(bool more=zip->goToFirstFile(); more; more=zip->goToNextFile()) { if(!zip->getCurrentFileInfo(&info)) { delete zip; return QStringList(); } lst << info.name; //info.name.toLocal8Bit().constData() } // Chiudo il file zip zip->close(); if(zip->getZipError()!=0) { delete zip; return QStringList(); } delete zip; return lst; } mudlet-2.1/src/quazip/quazip-0.4.4/quazip/quazipnewinfo.h0000644000175000017500000000716212070466513022623 0ustar csmallcsmall#ifndef QUA_ZIPNEWINFO_H #define QUA_ZIPNEWINFO_H /* Copyright (C) 2005-2011 Sergey A. Tachenov This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant, see quazip/(un)zip.h files for details, basically it's zlib license. **/ #include #include #include "quazip_global.h" /// Information about a file to be created. /** This structure holds information about a file to be created inside * ZIP archive. At least name should be set to something correct before * passing this structure to * QuaZipFile::open(OpenMode,const QuaZipNewInfo&,int,int,bool). **/ struct QUAZIP_EXPORT QuaZipNewInfo { /// File name. /** This field holds file name inside archive, including path relative * to archive root. **/ QString name; /// File timestamp. /** This is the last file modification date and time. Will be stored * in the archive central directory. It is a good practice to set it * to the source file timestamp instead of archive creating time. Use * setFileDateTime() or QuaZipNewInfo(const QString&, const QString&). **/ QDateTime dateTime; /// File internal attributes. quint16 internalAttr; /// File external attributes. quint32 externalAttr; /// File comment. /** Will be encoded using QuaZip::getCommentCodec(). **/ QString comment; /// File local extra field. QByteArray extraLocal; /// File global extra field. QByteArray extraGlobal; /// Uncompressed file size. /** This is only needed if you are using raw file zipping mode, i. e. * adding precompressed file in the zip archive. **/ ulong uncompressedSize; /// Constructs QuaZipNewInfo instance. /** Initializes name with \a name, dateTime with current date and * time. Attributes are initialized with zeros, comment and extra * field with null values. **/ QuaZipNewInfo(const QString& name); /// Constructs QuaZipNewInfo instance. /** Initializes name with \a name and dateTime with timestamp of the * file named \a file. If the \a file does not exists or its timestamp * is inaccessible (e. g. you do not have read permission for the * directory file in), uses current date and time. Attributes are * initialized with zeros, comment and extra field with null values. * * \sa setFileDateTime() **/ QuaZipNewInfo(const QString& name, const QString& file); /// Sets the file timestamp from the existing file. /** Use this function to set the file timestamp from the existing * file. Use it like this: * \code * QuaZipFile zipFile(&zip); * QFile file("file-to-add"); * file.open(QIODevice::ReadOnly); * QuaZipNewInfo info("file-name-in-archive"); * info.setFileDateTime("file-to-add"); // take the timestamp from file * zipFile.open(QIODevice::WriteOnly, info); * \endcode * * This function does not change dateTime if some error occured (e. g. * file is inaccessible). **/ void setFileDateTime(const QString& file); }; #endif mudlet-2.1/src/quazip/quazip-0.4.4/quazip/JlCompress.h0000644000175000017500000001033512070466513022001 0ustar csmallcsmall#ifndef JLCOMPRESSFOLDER_H_ #define JLCOMPRESSFOLDER_H_ #include "quazip.h" #include "quazipfile.h" #include "quazipfileinfo.h" #include #include #include #include /// Utility class for typical operations. /** This class contains a number of useful static functions to perform simple operations, such as mass ZIP packing or extraction. */ class QUAZIP_EXPORT JlCompress { private: /// Compress a single file. /** \param zip Opened zip to compress the file to. \param fileName The full path to the source file. \param fileDest The full name of the file inside the archive. \return true if success, false otherwise. */ static bool compressFile(QuaZip* zip, QString fileName, QString fileDest); /// Compress a subdirectory. /** \param parentZip Opened zip containing the parent directory. \param dir The full path to the directory to pack. \param parentDir The full path to the directory corresponding to the root of the ZIP. \param recursive Whether to pack sub-directories as well or only files. \return true if success, false otherwise. */ static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive = true); /// Extract a single file. /** \param zip The opened zip archive to extract from. \param fileName The full name of the file to extract. \param fileDest The full path to the destination file. \return true if success, false otherwise. */ static bool extractFile(QuaZip* zip, QString fileName, QString fileDest); /// Remove some files. /** \param listFile The list of files to remove. \return true if success, false otherwise. */ static bool removeFile(QStringList listFile); public: /// Compress a single file. /** \param fileCompressed The name of the archive. \param file The file to compress. \return true if success, false otherwise. */ static bool compressFile(QString fileCompressed, QString file); /// Compress a list of files. /** \param fileCompressed The name of the archive. \param files The file list to compress. \return true if success, false otherwise. */ static bool compressFiles(QString fileCompressed, QStringList files); /// Compress a whole directory. /** \param fileCompressed The name of the archive. \param dir The directory to compress. \param recursive Whether to pack the subdirectories as well, or just regular files. \return true if success, false otherwise. */ static bool compressDir(QString fileCompressed, QString dir = QString(), bool recursive = true); public: /// Extract a single file. /** \param fileCompressed The name of the archive. \param fileName The file to extract. \param fileDest The destination file, assumed to be identical to \a file if left empty. \return The list of the full paths of the files extracted, empty on failure. */ static QString extractFile(QString fileCompressed, QString fileName, QString fileDest = QString()); /// Extract a list of files. /** \param fileCompressed The name of the archive. \param files The file list to extract. \param dir The directory to put the files to, the current directory if left empty. \return The list of the full paths of the files extracted, empty on failure. */ static QStringList extractFiles(QString fileCompressed, QStringList files, QString dir = QString()); /// Extract a whole archive. /** \param fileCompressed The name of the archive. \param dir The directory to extract to, the current directory if left empty. \return The list of the full paths of the files extracted, empty on failure. */ static QStringList extractDir(QString fileCompressed, QString dir = QString()); /// Get the file list. /** \return The list of the files in the archive, or, more precisely, the list of the entries, including both files and directories if they are present separately. */ static QStringList getFileList(QString fileCompressed); }; #endif /* JLCOMPRESSFOLDER_H_ */ mudlet-2.1/src/quazip/quazip-0.4.4/README.txt0000644000175000017500000000437012070466513017736 0ustar csmallcsmallQuaZIP is the C++ wrapper for the Gilles Vollant's ZIP/UNZIP package using Trolltech's Qt library. It contains original ZIP/UNZIP package C code and therefore depends on zlib library. Also, it depends on Qt 4. To comile it on UNIX dialect: $ cd quazip $ qmake $ make You must make sure that: * You have Qt 4 properly and fully installed (including tools and headers, not just library) * "qmake" command runs Qt 4's qmake, not some other version (you'll have to type full path to qmake otherwise). To install compiled shared library, just type: $ make install By default, it installs in /usr/local, but you may change it using $ qmake PREFIX=/wherever/you/whant/to/install You do not have to compile and install QuaZIP to use it. You can just (and sometimes it may be the best way) add QuaZIP's source files to your project and use them. See doc/html or, if you do not have a browser, quazip/*.h and quazip/doc/* files for the more detailed documentation. For Windows, it's essentially the same, but you may have to adjust settings for different environments. If you want to include QuaZIP sources directly into your project or if you want to use QuaZIP compiled as a static library using "qmake CONFIG+=statliclib", you have to define the QUAZIP_STATIC macro, otherwise you're likely to run into problems as QuaZIP symbols will be marked as dllimported. Copyright notice: Copyright (C) 2005-2011 Sergey A. Tachenov This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 See COPYING file for the full LGPL text. Original ZIP package is copyrighted by Gilles Vollant, see quazip/(un)zip.h files for details, basically it's zlib license. mudlet-2.1/src/quazip/quazip-0.4.4/doc/0000755000175000017500000000000012070466513017001 5ustar csmallcsmallmudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/0000755000175000017500000000000012070466513020116 5ustar csmallcsmallmudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaCrc32__inherit__graph.md50000644000175000017500000000004012070466513026271 0ustar csmallcsmall494c6ee53c032c90c71e084fc73592f9mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/index.tex0000644000175000017500000001351012070466513021747 0ustar csmallcsmall \section{Overview}\label{index_overview} QuaZIP is a simple C++ wrapper over {\tt Gilles Vollant's ZIP/UNZIP package} that can be used to access ZIP archives. It uses {\tt Trolltech's Qt toolkit}. If you do not know what Qt is, you have two options: \begin{DoxyItemize} \item Just forget about QuaZIP. \item Learn more about Qt by downloading it and/or reading excellent {\tt official Qt documentation} \end{DoxyItemize} The choice is yours, but if you are really interested in cross-\/platform (Windows/Linux/BSD/UNIX/Mac/Others) software development, I would definitely recommend you the second choice $^\wedge$\_\-$^\wedge$ QuaZIP allows you to access files inside ZIP archives using QIODevice API, and -\/ yes! -\/ that means that you can also use QTextStream, QDataStream or whatever you would like to use on your zipped files. QuaZIP provides complete abstraction of the ZIP/UNZIP API, for both reading from and writing to ZIP archives.\section{Download QuaZIP}\label{index_download} Downloads are available from {\tt QuaZIP project's page at SourceForge.net}.\section{Platforms supported}\label{index_platforms} QuaZIP has been currently tested with Qt 4.0.0 on the following platforms: \begin{DoxyItemize} \item linux-\/g++ \item freebsd-\/g++ \item hpux-\/acc \item win32-\/g++ (MinGW) \end{DoxyItemize} No testing has been done on other systems. Of course, patches to make it work on any platform that it currently does not work on are always welcome!\section{What is new in this version of QuaZIP?}\label{index_whats-new} See the NEWS file supplied with the distribution.\section{Requirements}\label{index_Requirements} Just {\tt zlib} and Qt 4. Well, Qt 4 depends on zlib anyway.\section{Building, testing and installing}\label{index_building} \begin{DoxyNote}{Note} Instructions given in this section assume that you are using some UNIX dialect, but the build process should be very similar on win32-\/g++ platform too. On other platforms it's essentially the same process, maybe with some qmake adjustments not specific to QuaZIP itself. \end{DoxyNote} To build the library, run: \begin{DoxyVerb} $ cd /wherever/quazip/source/is/quazip-x.y.z/quazip $ qmake [PREFIX=where-to-install] $ make \end{DoxyVerb} Make sure that you have Qt 4 installed with all required headers and utilities (not just library) and that you run qmake utility of the Qt 4, not some other version you may have already installed (you may need to type full path to qmake like /usr/local/qt4/bin/qmake). To reconfigure (with another PREFIX, for example), just run qmake with appropriate arguments again. If you need to specify additional include path or libraries, use qmake features (see qmake reference in the Qt documentation). For example: \begin{DoxyVerb} $ qmake LIBS+=-L/usr/local/zlib/lib INCLUDEPATH+=/usr/local/zlib/include \end{DoxyVerb} (note abscence of \char`\"{}-\/I\char`\"{} before include path) To check if QuaZIP's basic features work ok on your platform, you may wish to compile simple test programs provided in test directory. Look in the sources of the tests to find out about their requirements. Typically, the test looks something like this: \begin{DoxyVerb} $ cd /wherever/quazip/source/is/quazip-x.y.z/test/zip $ qmake $ make $ ./zip $ cd ../unzip $ cp ../zip/test.zip ./test.zip $ mkdir out $ qmake $ make $ ./unzip \end{DoxyVerb} You should see the zip contents with details as the output of the \char`\"{}./unzip\char`\"{}. Ignore message saying you should check the file name for testCase() if you do not want to test \doxyref{locale-\/aware case-\/insensitivity}{p.}{classQuaZip_a6053a1d249ed210a85c9d5eb7cf9cdbe}. Otherwise, see the sources. In any case, this message appearing means that everything else was fine. Otherwise, you will get some other error message instead. Investigate it or send bug report including message, platform and QuaZIP version used. To install compiled library: \begin{DoxyVerb} $ make install \end{DoxyVerb} By default, QuaZIP compiles as a DLL, but you have other options: \begin{DoxyItemize} \item Just copy appropriate source files to your project and use them, but you need to define QUAZIP\_\-STATIC before including any QuaZIP headers (best done as a compiler option). This will save you from possile side effects of importing/exporting QuaZIP symbols. \item Compile it as a static library using CONFIG += staticlib qmake option. QUAZIP\_\-STATIC is defined automatically by qmake in this case. \end{DoxyItemize} Binary compatibility isn't guaranteed even between minor releases, but usually it's preserved, thanks to the Pimpl idiom.\section{Using}\label{index_using} See \doxyref{usage page}{p.}{usage}.\section{Authors and contacts}\label{index_contacts} This wrapper has been written by Sergey A. Tachenov, AKA Alqualos. This is my first open source project, so it may suck, but I did not find anything like that, so I just had no other choice but to write it. If you have anything to say to me about QuaZIP library, feel free to do so (read the \doxyref{QuaZip FAQ}{p.}{faq} first, though). I can not promise, though, that I fix all the bugs you report in, add any features you want, or respond to your critics, or respond to your feedback at all. I may be busy, I may be tired of working on QuaZIP, I may be even dead already (you never know...). To report bugs or to post ideas about what should be done, use SourceForge.net's {\tt trackers}. If you want to send me a private message, use my e-\/mail address {\tt stachenov@gmail.com}. Do not use e-\/mail to report bugs, please. Reporting bugs and problems with the SourceForge.net's bug report system has that advantage that it is visible to public, and I can always search for open tickets that were created long ago. It is highly unlikely that I will search my mail for that kind of stuff, so if a bug reported by mail isn't fixed immediately, it will likely be forgotten forever. Copyright (C) 2005-\/2011 Sergey A. Tachenov mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/structQuaZipNewInfo.tex0000644000175000017500000001631012070466513024605 0ustar csmallcsmall\section{QuaZipNewInfo Struct Reference} \label{structQuaZipNewInfo}\index{QuaZipNewInfo@{QuaZipNewInfo}} Information about a file to be created. {\ttfamily \#include $<$quazipnewinfo.h$>$} \subsection*{Public Member Functions} \begin{DoxyCompactItemize} \item {\bf QuaZipNewInfo} (const QString \&{\bf name}) \begin{DoxyCompactList}\small\item\em Constructs \doxyref{QuaZipNewInfo}{p.}{structQuaZipNewInfo} instance. \end{DoxyCompactList}\item {\bf QuaZipNewInfo} (const QString \&{\bf name}, const QString \&file) \begin{DoxyCompactList}\small\item\em Constructs \doxyref{QuaZipNewInfo}{p.}{structQuaZipNewInfo} instance. \end{DoxyCompactList}\item void {\bf setFileDateTime} (const QString \&file) \begin{DoxyCompactList}\small\item\em Sets the file timestamp from the existing file. \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection*{Public Attributes} \begin{DoxyCompactItemize} \item QString {\bf name} \begin{DoxyCompactList}\small\item\em File name. \end{DoxyCompactList}\item QDateTime {\bf dateTime} \begin{DoxyCompactList}\small\item\em File timestamp. \end{DoxyCompactList}\item quint16 {\bf internalAttr}\label{structQuaZipNewInfo_a59ce9776c2ac7547ade8cb4c404c77ab} \begin{DoxyCompactList}\small\item\em File internal attributes. \end{DoxyCompactList}\item quint32 {\bf externalAttr}\label{structQuaZipNewInfo_affd1a9700d302e1395bd04f0864da7d0} \begin{DoxyCompactList}\small\item\em File external attributes. \end{DoxyCompactList}\item QString {\bf comment} \begin{DoxyCompactList}\small\item\em File comment. \end{DoxyCompactList}\item QByteArray {\bf extraLocal}\label{structQuaZipNewInfo_ab377a81c51cf495c7aeee4f19340a43f} \begin{DoxyCompactList}\small\item\em File local extra field. \end{DoxyCompactList}\item QByteArray {\bf extraGlobal}\label{structQuaZipNewInfo_abda207eb3949db3a88761c1b06e6bd58} \begin{DoxyCompactList}\small\item\em File global extra field. \end{DoxyCompactList}\item ulong {\bf uncompressedSize} \begin{DoxyCompactList}\small\item\em Uncompressed file size. \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection{Detailed Description} Information about a file to be created. This structure holds information about a file to be created inside ZIP archive. At least name should be set to something correct before passing this structure to QuaZipFile::open(OpenMode,const QuaZipNewInfo\&,int,int,bool). \subsection{Constructor \& Destructor Documentation} \index{QuaZipNewInfo@{QuaZipNewInfo}!QuaZipNewInfo@{QuaZipNewInfo}} \index{QuaZipNewInfo@{QuaZipNewInfo}!QuaZipNewInfo@{QuaZipNewInfo}} \subsubsection[{QuaZipNewInfo}]{\setlength{\rightskip}{0pt plus 5cm}QuaZipNewInfo::QuaZipNewInfo ( \begin{DoxyParamCaption} \item[{const QString \&}]{name} \end{DoxyParamCaption} )}\label{structQuaZipNewInfo_a46c0f551cf9e6b2131929beb39187aac} Constructs \doxyref{QuaZipNewInfo}{p.}{structQuaZipNewInfo} instance. Initializes name with {\itshape name\/}, dateTime with current date and time. Attributes are initialized with zeros, comment and extra field with null values. \index{QuaZipNewInfo@{QuaZipNewInfo}!QuaZipNewInfo@{QuaZipNewInfo}} \index{QuaZipNewInfo@{QuaZipNewInfo}!QuaZipNewInfo@{QuaZipNewInfo}} \subsubsection[{QuaZipNewInfo}]{\setlength{\rightskip}{0pt plus 5cm}QuaZipNewInfo::QuaZipNewInfo ( \begin{DoxyParamCaption} \item[{const QString \&}]{name, } \item[{const QString \&}]{file} \end{DoxyParamCaption} )}\label{structQuaZipNewInfo_ad47cf11f4277edcb09a8ba2b2963f2a9} Constructs \doxyref{QuaZipNewInfo}{p.}{structQuaZipNewInfo} instance. Initializes name with {\itshape name\/} and dateTime with timestamp of the file named {\itshape file\/}. If the {\itshape file\/} does not exists or its timestamp is inaccessible (e. g. you do not have read permission for the directory file in), uses current date and time. Attributes are initialized with zeros, comment and extra field with null values. \begin{DoxySeeAlso}{See also} \doxyref{setFileDateTime()}{p.}{structQuaZipNewInfo_a2b18b554d056877a2f33ffb9d241ed85} \end{DoxySeeAlso} References dateTime. \subsection{Member Function Documentation} \index{QuaZipNewInfo@{QuaZipNewInfo}!setFileDateTime@{setFileDateTime}} \index{setFileDateTime@{setFileDateTime}!QuaZipNewInfo@{QuaZipNewInfo}} \subsubsection[{setFileDateTime}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZipNewInfo::setFileDateTime ( \begin{DoxyParamCaption} \item[{const QString \&}]{file} \end{DoxyParamCaption} )}\label{structQuaZipNewInfo_a2b18b554d056877a2f33ffb9d241ed85} Sets the file timestamp from the existing file. Use this function to set the file timestamp from the existing file. Use it like this: \begin{DoxyCode} QuaZipFile zipFile(&zip); QFile file("file-to-add"); file.open(QIODevice::ReadOnly); QuaZipNewInfo info("file-name-in-archive"); info.setFileDateTime("file-to-add"); // take the timestamp from file zipFile.open(QIODevice::WriteOnly, info); \end{DoxyCode} This function does not change dateTime if some error occured (e. g. file is inaccessible). References dateTime. \subsection{Member Data Documentation} \index{QuaZipNewInfo@{QuaZipNewInfo}!name@{name}} \index{name@{name}!QuaZipNewInfo@{QuaZipNewInfo}} \subsubsection[{name}]{\setlength{\rightskip}{0pt plus 5cm}QString {\bf QuaZipNewInfo::name}}\label{structQuaZipNewInfo_a2bdef01b6ac3326e48598e32bfa5fbe8} File name. This field holds file name inside archive, including path relative to archive root. Referenced by QuaZipFile::open(). \index{QuaZipNewInfo@{QuaZipNewInfo}!dateTime@{dateTime}} \index{dateTime@{dateTime}!QuaZipNewInfo@{QuaZipNewInfo}} \subsubsection[{dateTime}]{\setlength{\rightskip}{0pt plus 5cm}QDateTime {\bf QuaZipNewInfo::dateTime}}\label{structQuaZipNewInfo_aec7f3ac72c72a2e10b82ad64c2fa3453} File timestamp. This is the last file modification date and time. Will be stored in the archive central directory. It is a good practice to set it to the source file timestamp instead of archive creating time. Use \doxyref{setFileDateTime()}{p.}{structQuaZipNewInfo_a2b18b554d056877a2f33ffb9d241ed85} or \doxyref{QuaZipNewInfo(const QString\&, const QString\&)}{p.}{structQuaZipNewInfo_ad47cf11f4277edcb09a8ba2b2963f2a9}. Referenced by QuaZipFile::open(), QuaZipNewInfo(), and setFileDateTime(). \index{QuaZipNewInfo@{QuaZipNewInfo}!comment@{comment}} \index{comment@{comment}!QuaZipNewInfo@{QuaZipNewInfo}} \subsubsection[{comment}]{\setlength{\rightskip}{0pt plus 5cm}QString {\bf QuaZipNewInfo::comment}}\label{structQuaZipNewInfo_ae24b1d38c3550b4724862ffcf8f20924} File comment. Will be encoded using \doxyref{QuaZip::getCommentCodec()}{p.}{classQuaZip_a008260161781d8b5d2a0a28493fddaf4}. Referenced by QuaZipFile::open(). \index{QuaZipNewInfo@{QuaZipNewInfo}!uncompressedSize@{uncompressedSize}} \index{uncompressedSize@{uncompressedSize}!QuaZipNewInfo@{QuaZipNewInfo}} \subsubsection[{uncompressedSize}]{\setlength{\rightskip}{0pt plus 5cm}ulong {\bf QuaZipNewInfo::uncompressedSize}}\label{structQuaZipNewInfo_a18c079b3f2f5ab6eecdd61d6dbe93be6} Uncompressed file size. This is only needed if you are using raw file zipping mode, i. e. adding precompressed file in the zip archive. Referenced by QuaZipFile::open(). The documentation for this struct was generated from the following files:\begin{DoxyCompactItemize} \item quazip/quazipnewinfo.h\item quazip/quazipnewinfo.cpp\end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZipFile__coll__graph.md50000644000175000017500000000004012070466513026246 0ustar csmallcsmalld4c12e105f1f89650e643227b7eb6b67mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZipPrivate.tex0000644000175000017500000000142612070466513024435 0ustar csmallcsmall\section{QuaZipPrivate Class Reference} \label{classQuaZipPrivate}\index{QuaZipPrivate@{QuaZipPrivate}} All the internal stuff for the \doxyref{QuaZip}{p.}{classQuaZip} class. Collaboration diagram for QuaZipPrivate: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=120pt]{classQuaZipPrivate__coll__graph} \end{center} \end{figure} \subsection*{Friends} \begin{DoxyCompactItemize} \item class {\bf QuaZip}\label{classQuaZipPrivate_a913fb7bbd3527119ebb8052d57132af2} \end{DoxyCompactItemize} \subsection{Detailed Description} All the internal stuff for the \doxyref{QuaZip}{p.}{classQuaZip} class. The documentation for this class was generated from the following file:\begin{DoxyCompactItemize} \item quazip/quazip.cpp\end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaChecksum32__inherit__graph.md50000644000175000017500000000004012070466513027324 0ustar csmallcsmallfe6eaf22d351a7125f230bf0b6ba2704mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/dir_13eff9bb9851318b001ebebd72594ac4_dep.eps0000644000175000017500000001065212070466513026755 0ustar csmallcsmall%!PS-Adobe-3.0 %%Creator: graphviz version 2.28.0 (20110507.0327) %%Title: G %%Pages: (atend) %%BoundingBox: (atend) %%EndComments save %%BeginProlog /DotDict 200 dict def DotDict begin /setupLatin1 { mark /EncodingVector 256 array def EncodingVector 0 ISOLatin1Encoding 0 255 getinterval putinterval EncodingVector 45 /hyphen put % Set up ISO Latin 1 character encoding /starnetISO { dup dup findfont dup length dict begin { 1 index /FID ne { def }{ pop pop } ifelse } forall /Encoding EncodingVector def currentdict end definefont } def /Times-Roman starnetISO def /Times-Italic starnetISO def /Times-Bold starnetISO def /Times-BoldItalic starnetISO def /Helvetica starnetISO def /Helvetica-Oblique starnetISO def /Helvetica-Bold starnetISO def /Helvetica-BoldOblique starnetISO def /Courier starnetISO def /Courier-Oblique starnetISO def /Courier-Bold starnetISO def /Courier-BoldOblique starnetISO def cleartomark } bind def %%BeginResource: procset graphviz 0 0 /coord-font-family /Times-Roman def /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def /InvScaleFactor 1.0 def /set_scale { dup 1 exch div /InvScaleFactor exch def scale } bind def % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def /bold { 2 setlinewidth } bind def /filled { } bind def /unfilled { } bind def /rounded { } bind def /diagonals { } bind def % hooks for setting color /nodecolor { sethsbcolor } bind def /edgecolor { sethsbcolor } bind def /graphcolor { sethsbcolor } bind def /nopcolor {pop pop pop} bind def /beginpage { % i j npages /npages exch def /j exch def /i exch def /str 10 string def npages 1 gt { gsave coordfont setfont 0 0 moveto (\() show i str cvs show (,) show j str cvs show (\)) show grestore } if } bind def /set_font { findfont exch scalefont setfont } def % draw text fitted to its expected width /alignedtext { % width text /text exch def /width exch def gsave width 0 gt { [] 0 setdash text stringwidth pop width exch sub text length div 0 text ashow } if grestore } def /boxprim { % xcorner ycorner xsize ysize 4 2 roll moveto 2 copy exch 0 rlineto 0 exch rlineto pop neg 0 rlineto closepath } bind def /ellipse_path { /ry exch def /rx exch def /y exch def /x exch def matrix currentmatrix newpath x y translate rx ry scale 0 0 1 0 360 arc setmatrix } bind def /endpage { showpage } bind def /showpage { } def /layercolorseq [ % layer color sequence - darkest to lightest [0 0 0] [.2 .8 .8] [.4 .8 .8] [.6 .8 .8] [.8 .8 .8] ] def /layerlen layercolorseq length def /setlayer {/maxlayer exch def /curlayer exch def layercolorseq curlayer 1 sub layerlen mod get aload pop sethsbcolor /nodecolor {nopcolor} def /edgecolor {nopcolor} def /graphcolor {nopcolor} def } bind def /onlayer { curlayer ne {invis} if } def /onlayers { /myupper exch def /mylower exch def curlayer mylower lt curlayer myupper gt or {invis} if } def /curlayer 0 def %%EndResource %%EndProlog %%BeginSetup 14 default-font-family set_font 1 setmiterlimit % /arrowlength 10 def % /arrowwidth 5 def % make sure pdfmark is harmless for PS-interpreters other than Distiller /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % make '<<' and '>>' safe on PS Level 1 devices /languagelevel where {pop languagelevel}{1} ifelse 2 lt { userdict (<<) cvn ([) cvn load put userdict (>>) cvn ([) cvn load put } if %%EndSetup setupLatin1 %%Page: 1 1 %%PageBoundingBox: 36 36 98 80 %%PageOrientation: Portrait 0 0 1 beginpage gsave 36 36 62 44 boxprim clip newpath 1 1 set_scale 0 rotate 40 41 translate % dir_13eff9bb9851318b001ebebd72594ac4 gsave [ /Rect [ 0 0 54 36 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI (dir_13eff9bb9851318b001ebebd72594ac4.html) >> /Subtype /Link /ANN pdfmark 0.66667 0.066667 1 nodecolor newpath 54 36 moveto 0 36 lineto 0 0 lineto 54 0 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 54 36 moveto 0 36 lineto 0 0 lineto 54 0 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 12.5 15.5 moveto 29 (quazip) alignedtext grestore endpage showpage grestore %%PageTrailer %%EndPage: 1 %%Trailer %%Pages: 1 %%BoundingBox: 36 36 98 80 end restore %%EOF mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/dirs.tex0000644000175000017500000000035212070466513021601 0ustar csmallcsmall\section{Directories} This directory hierarchy is sorted roughly, but not completely, alphabetically:\begin{DoxyCompactList} \item \contentsline{section}{quazip}{\pageref{dir_13eff9bb9851318b001ebebd72594ac4}}{} \end{DoxyCompactList} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZipFile__coll__graph.eps0000644000175000017500000002021512070466513026356 0ustar csmallcsmall%!PS-Adobe-3.0 %%Creator: graphviz version 2.28.0 (20110507.0327) %%Title: G %%Pages: (atend) %%BoundingBox: (atend) %%EndComments save %%BeginProlog /DotDict 200 dict def DotDict begin /setupLatin1 { mark /EncodingVector 256 array def EncodingVector 0 ISOLatin1Encoding 0 255 getinterval putinterval EncodingVector 45 /hyphen put % Set up ISO Latin 1 character encoding /starnetISO { dup dup findfont dup length dict begin { 1 index /FID ne { def }{ pop pop } ifelse } forall /Encoding EncodingVector def currentdict end definefont } def /Times-Roman starnetISO def /Times-Italic starnetISO def /Times-Bold starnetISO def /Times-BoldItalic starnetISO def /Helvetica starnetISO def /Helvetica-Oblique starnetISO def /Helvetica-Bold starnetISO def /Helvetica-BoldOblique starnetISO def /Courier starnetISO def /Courier-Oblique starnetISO def /Courier-Bold starnetISO def /Courier-BoldOblique starnetISO def cleartomark } bind def %%BeginResource: procset graphviz 0 0 /coord-font-family /Times-Roman def /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def /InvScaleFactor 1.0 def /set_scale { dup 1 exch div /InvScaleFactor exch def scale } bind def % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def /bold { 2 setlinewidth } bind def /filled { } bind def /unfilled { } bind def /rounded { } bind def /diagonals { } bind def % hooks for setting color /nodecolor { sethsbcolor } bind def /edgecolor { sethsbcolor } bind def /graphcolor { sethsbcolor } bind def /nopcolor {pop pop pop} bind def /beginpage { % i j npages /npages exch def /j exch def /i exch def /str 10 string def npages 1 gt { gsave coordfont setfont 0 0 moveto (\() show i str cvs show (,) show j str cvs show (\)) show grestore } if } bind def /set_font { findfont exch scalefont setfont } def % draw text fitted to its expected width /alignedtext { % width text /text exch def /width exch def gsave width 0 gt { [] 0 setdash text stringwidth pop width exch sub text length div 0 text ashow } if grestore } def /boxprim { % xcorner ycorner xsize ysize 4 2 roll moveto 2 copy exch 0 rlineto 0 exch rlineto pop neg 0 rlineto closepath } bind def /ellipse_path { /ry exch def /rx exch def /y exch def /x exch def matrix currentmatrix newpath x y translate rx ry scale 0 0 1 0 360 arc setmatrix } bind def /endpage { showpage } bind def /showpage { } def /layercolorseq [ % layer color sequence - darkest to lightest [0 0 0] [.2 .8 .8] [.4 .8 .8] [.6 .8 .8] [.8 .8 .8] ] def /layerlen layercolorseq length def /setlayer {/maxlayer exch def /curlayer exch def layercolorseq curlayer 1 sub layerlen mod get aload pop sethsbcolor /nodecolor {nopcolor} def /edgecolor {nopcolor} def /graphcolor {nopcolor} def } bind def /onlayer { curlayer ne {invis} if } def /onlayers { /myupper exch def /mylower exch def curlayer mylower lt curlayer myupper gt or {invis} if } def /curlayer 0 def %%EndResource %%EndProlog %%BeginSetup 14 default-font-family set_font 1 setmiterlimit % /arrowlength 10 def % /arrowwidth 5 def % make sure pdfmark is harmless for PS-interpreters other than Distiller /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % make '<<' and '>>' safe on PS Level 1 devices /languagelevel where {pop languagelevel}{1} ifelse 2 lt { userdict (<<) cvn ([) cvn load put userdict (>>) cvn ([) cvn load put } if %%EndSetup setupLatin1 %%Page: 1 1 %%PageBoundingBox: 36 36 231 132 %%PageOrientation: Portrait 0 0 1 beginpage gsave 36 36 195 96 boxprim clip newpath 1 1 set_scale 0 rotate 40 41 translate % Node1 gsave 0 0 0.74902 nodecolor newpath 2.5 68.5 moveto 2.5 87.5 lineto 65.5 87.5 lineto 65.5 68.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 2.5 68.5 moveto 2.5 87.5 lineto 65.5 87.5 lineto 65.5 68.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 10.5 75.5 moveto 47 (QuaZipFile) alignedtext grestore % Node2 gsave [ /Rect [ 0 0 92 20 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaZipFilePrivate.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 0 .5 moveto 0 19.5 lineto 92 19.5 lineto 92 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 0 .5 moveto 0 19.5 lineto 92 19.5 lineto 92 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 8 7.5 moveto 76 (QuaZipFilePrivate) alignedtext grestore % Node1->Node2 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 28.58 58.5 moveto 27.46 51.93 27.11 44.55 29 38 curveto 30.9 31.4 34.95 24.86 38.62 19.87 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 25.24 59.56 moveto 30.96 68.48 lineto 32.05 57.94 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 25.24 59.56 moveto 30.96 68.48 lineto 32.05 57.94 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 29 41.5 moveto 6 (q) alignedtext grestore % Node2->Node1 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 42.57 29.85 moveto 40.27 42.53 37.34 58.64 35.57 68.37 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 46.05 30.31 moveto 44.39 19.84 lineto 39.16 29.05 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 46.05 30.31 moveto 44.39 19.84 lineto 39.16 29.05 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 42 41.5 moveto 6 (p) alignedtext grestore % Node3 gsave [ /Rect [ 96.5 68 143 88 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaZip.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 96.5 68.5 moveto 96.5 87.5 lineto 143.5 87.5 lineto 143.5 68.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 96.5 68.5 moveto 96.5 87.5 lineto 143.5 87.5 lineto 143.5 68.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 104.5 75.5 moveto 31 (QuaZip) alignedtext grestore % Node3->Node2 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 102.52 61.41 moveto 87.99 48.45 67.81 30.46 55.91 19.84 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 100.53 64.33 moveto 110.33 68.37 lineto 105.19 59.1 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 100.53 64.33 moveto 110.33 68.37 lineto 105.19 59.1 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 90 41.5 moveto 13 (zip) alignedtext grestore % Node4 gsave [ /Rect [ 110.5 0 187 20 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaZipPrivate.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 110.5 .5 moveto 110.5 19.5 lineto 187.5 19.5 lineto 187.5 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 110.5 .5 moveto 110.5 19.5 lineto 187.5 19.5 lineto 187.5 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 118.5 7.5 moveto 61 (QuaZipPrivate) alignedtext grestore % Node3->Node4 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 119.52 58.1 moveto 119.97 51.5 121.2 44.2 124 38 curveto 127.21 30.9 133.04 24.43 138.26 19.61 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 116.02 58.17 moveto 119.35 68.23 lineto 123.02 58.29 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 116.02 58.17 moveto 119.35 68.23 lineto 123.02 58.29 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 124 41.5 moveto 6 (q) alignedtext grestore % Node4->Node3 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 141.05 29.09 moveto 135.43 41.87 128.15 58.45 123.79 68.37 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 144.3 30.4 moveto 145.12 19.84 lineto 137.89 27.59 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 144.3 30.4 moveto 145.12 19.84 lineto 137.89 27.59 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 138 41.5 moveto 6 (p) alignedtext grestore endpage showpage grestore %%PageTrailer %%EndPage: 1 %%Trailer %%Pages: 1 %%BoundingBox: 36 36 231 132 end restore %%EOF mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZipFilePrivate.tex0000644000175000017500000000145212070466513025234 0ustar csmallcsmall\section{QuaZipFilePrivate Class Reference} \label{classQuaZipFilePrivate}\index{QuaZipFilePrivate@{QuaZipFilePrivate}} The implementation class for \doxyref{QuaZip}{p.}{classQuaZip}. Collaboration diagram for QuaZipFilePrivate: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=231pt]{classQuaZipFilePrivate__coll__graph} \end{center} \end{figure} \subsection*{Friends} \begin{DoxyCompactItemize} \item class {\bf QuaZipFile}\label{classQuaZipFilePrivate_a40bd4ccb6d2d00726e1de81329ebaa7a} \end{DoxyCompactItemize} \subsection{Detailed Description} The implementation class for \doxyref{QuaZip}{p.}{classQuaZip}. The documentation for this class was generated from the following file:\begin{DoxyCompactItemize} \item quazip/quazipfile.cpp\end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/dir_13eff9bb9851318b001ebebd72594ac4_dep.md50000644000175000017500000000004012070466513026641 0ustar csmallcsmallab13d57f3a00938eccee7c13470124f3mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZip.tex0000644000175000017500000011527012070466513023105 0ustar csmallcsmall\section{QuaZip Class Reference} \label{classQuaZip}\index{QuaZip@{QuaZip}} ZIP archive. {\ttfamily \#include $<$quazip/quazip.h$>$} Collaboration diagram for QuaZip: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=120pt]{classQuaZip__coll__graph} \end{center} \end{figure} \subsection*{Public Types} \begin{DoxyCompactItemize} \item enum {\bf Constants} \{ {\bf MAX\_\-FILE\_\-NAME\_\-LENGTH} = 256 \} \begin{DoxyCompactList}\small\item\em Useful constants. \end{DoxyCompactList}\item enum {\bf Mode} \{ \par {\bf mdNotOpen}, {\bf mdUnzip}, {\bf mdCreate}, {\bf mdAppend}, \par {\bf mdAdd} \} \begin{DoxyCompactList}\small\item\em Open mode of the ZIP file. \end{DoxyCompactList}\item enum {\bf CaseSensitivity} \{ {\bf csDefault} = 0, {\bf csSensitive} = 1, {\bf csInsensitive} = 2 \} \begin{DoxyCompactList}\small\item\em Case sensitivity for the file names. \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection*{Public Member Functions} \begin{DoxyCompactItemize} \item {\bf QuaZip} () \begin{DoxyCompactList}\small\item\em Constructs \doxyref{QuaZip}{p.}{classQuaZip} object. \end{DoxyCompactList}\item {\bf QuaZip} (const QString \&zipName)\label{classQuaZip_aaea7294b02abd22379cc3a9fccb754b7} \begin{DoxyCompactList}\small\item\em Constructs \doxyref{QuaZip}{p.}{classQuaZip} object associated with ZIP file {\itshape zipName\/}. \end{DoxyCompactList}\item {\bf QuaZip} (QIODevice $\ast$ioDevice) \begin{DoxyCompactList}\small\item\em Constructs \doxyref{QuaZip}{p.}{classQuaZip} object associated with ZIP file represented by {\itshape ioDevice\/}. \end{DoxyCompactList}\item {\bf $\sim$QuaZip} () \begin{DoxyCompactList}\small\item\em Destroys \doxyref{QuaZip}{p.}{classQuaZip} object. \end{DoxyCompactList}\item bool {\bf open} ({\bf Mode} mode, zlib\_\-filefunc\_\-def $\ast$ioApi=NULL) \begin{DoxyCompactList}\small\item\em Opens ZIP file. \end{DoxyCompactList}\item void {\bf close} () \begin{DoxyCompactList}\small\item\em Closes ZIP file. \end{DoxyCompactList}\item void {\bf setFileNameCodec} (QTextCodec $\ast$fileNameCodec) \begin{DoxyCompactList}\small\item\em Sets the codec used to encode/decode file names inside archive. \end{DoxyCompactList}\item void {\bf setFileNameCodec} (const char $\ast$fileNameCodecName) \begin{DoxyCompactList}\small\item\em Sets the codec used to encode/decode file names inside archive. \end{DoxyCompactList}\item QTextCodec $\ast$ {\bf getFileNameCodec} () const \label{classQuaZip_a27b866aa2c75ea6f9c438cbb6e32b43c} \begin{DoxyCompactList}\small\item\em Returns the codec used to encode/decode comments inside archive. \end{DoxyCompactList}\item void {\bf setCommentCodec} (QTextCodec $\ast$commentCodec) \begin{DoxyCompactList}\small\item\em Sets the codec used to encode/decode comments inside archive. \end{DoxyCompactList}\item void {\bf setCommentCodec} (const char $\ast$commentCodecName) \begin{DoxyCompactList}\small\item\em Sets the codec used to encode/decode comments inside archive. \end{DoxyCompactList}\item QTextCodec $\ast$ {\bf getCommentCodec} () const \label{classQuaZip_a008260161781d8b5d2a0a28493fddaf4} \begin{DoxyCompactList}\small\item\em Returns the codec used to encode/decode comments inside archive. \end{DoxyCompactList}\item QString {\bf getZipName} () const \begin{DoxyCompactList}\small\item\em Returns the name of the ZIP file. \end{DoxyCompactList}\item void {\bf setZipName} (const QString \&zipName) \begin{DoxyCompactList}\small\item\em Sets the name of the ZIP file. \end{DoxyCompactList}\item QIODevice $\ast$ {\bf getIoDevice} () const \begin{DoxyCompactList}\small\item\em Returns the device representing this ZIP file. \end{DoxyCompactList}\item void {\bf setIoDevice} (QIODevice $\ast$ioDevice) \begin{DoxyCompactList}\small\item\em Sets the device representing the ZIP file. \end{DoxyCompactList}\item {\bf Mode} {\bf getMode} () const \label{classQuaZip_a129ceff04d28fb00531f7bf7f9329664} \begin{DoxyCompactList}\small\item\em Returns the mode in which ZIP file was opened. \end{DoxyCompactList}\item bool {\bf isOpen} () const \label{classQuaZip_a5b869a9c0d4f49955b759592fec08888} \begin{DoxyCompactList}\small\item\em Returns {\ttfamily true} if ZIP file is open, {\ttfamily false} otherwise. \end{DoxyCompactList}\item int {\bf getZipError} () const \begin{DoxyCompactList}\small\item\em Returns the error code of the last operation. \end{DoxyCompactList}\item int {\bf getEntriesCount} () const \begin{DoxyCompactList}\small\item\em Returns number of the entries in the ZIP central directory. \end{DoxyCompactList}\item QString {\bf getComment} () const \label{classQuaZip_ae55cfbf2296132df808c557b62433051} \begin{DoxyCompactList}\small\item\em Returns global comment in the ZIP file. \end{DoxyCompactList}\item void {\bf setComment} (const QString \&comment) \begin{DoxyCompactList}\small\item\em Sets global comment in the ZIP file. \end{DoxyCompactList}\item bool {\bf goToFirstFile} () \begin{DoxyCompactList}\small\item\em Sets the current file to the first file in the archive. \end{DoxyCompactList}\item bool {\bf goToNextFile} () \begin{DoxyCompactList}\small\item\em Sets the current file to the next file in the archive. \end{DoxyCompactList}\item bool {\bf setCurrentFile} (const QString \&fileName, {\bf CaseSensitivity} cs=csDefault) \begin{DoxyCompactList}\small\item\em Sets current file by its name. \end{DoxyCompactList}\item bool {\bf hasCurrentFile} () const \label{classQuaZip_a00b237d926648f45da86db25e7cfb697} \begin{DoxyCompactList}\small\item\em Returns {\ttfamily true} if the current file has been set. \end{DoxyCompactList}\item bool {\bf getCurrentFileInfo} ({\bf QuaZipFileInfo} $\ast$info) const \begin{DoxyCompactList}\small\item\em Retrieves information about the current file. \end{DoxyCompactList}\item QString {\bf getCurrentFileName} () const \begin{DoxyCompactList}\small\item\em Returns the current file name. \end{DoxyCompactList}\item unzFile {\bf getUnzFile} () \begin{DoxyCompactList}\small\item\em Returns {\ttfamily unzFile} handle. \end{DoxyCompactList}\item zipFile {\bf getZipFile} () \begin{DoxyCompactList}\small\item\em Returns {\ttfamily zipFile} handle. \end{DoxyCompactList}\item void {\bf setDataDescriptorWritingEnabled} (bool enabled) \begin{DoxyCompactList}\small\item\em Changes the data descriptor writing mode. \end{DoxyCompactList}\item bool {\bf isDataDescriptorWritingEnabled} () const \begin{DoxyCompactList}\small\item\em Returns the data descriptor default writing mode. \end{DoxyCompactList}\item QStringList {\bf getFileNameList} () const \begin{DoxyCompactList}\small\item\em Returns a list of files inside the archive. \end{DoxyCompactList}\item QList$<$ {\bf QuaZipFileInfo} $>$ {\bf getFileInfoList} () const \begin{DoxyCompactList}\small\item\em Returns information list about all files inside the archive. \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection*{Friends} \begin{DoxyCompactItemize} \item class {\bf QuaZipPrivate}\label{classQuaZip_a5d400b33a69412e9d419a484aaf476cd} \end{DoxyCompactItemize} \subsection{Detailed Description} ZIP archive. This class implements basic interface to the ZIP archive. It can be used to read table contents of the ZIP archive and retreiving information about the files inside it. You can also use this class to open files inside archive by passing pointer to the instance of this class to the constructor of the \doxyref{QuaZipFile}{p.}{classQuaZipFile} class. But see \doxyref{QuaZipFile::QuaZipFile(QuaZip$\ast$, QObject$\ast$)}{p.}{classQuaZipFile_a54e944a6b3d27030f64c8f30d2cc33bb} for the possible pitfalls. This class is indended to provide interface to the ZIP subpackage of the ZIP/UNZIP package as well as to the UNZIP subpackage. But currently it supports only UNZIP. The use of this class is simple -\/ just create instance using constructor, then set ZIP archive file name using setFile() function (if you did not passed the name to the constructor), then \doxyref{open()}{p.}{classQuaZip_abfa4e6018b2964a3d10a4c54e5ab3962} and then use different functions to work with it! Well, if you are paranoid, you may also wish to call close before destructing the instance, to check for errors on close. You may also use \doxyref{getUnzFile()}{p.}{classQuaZip_a3b78a652f296ff4a678a791e8294e642} and \doxyref{getZipFile()}{p.}{classQuaZip_a425043a4d7cc31e2fe2bba73d954f15c} functions to get the ZIP archive handle and use it with ZIP/UNZIP package API directly. This class supports localized file names inside ZIP archive, but you have to set up proper codec with setCodec() function. By default, locale codec will be used, which is probably ok for UNIX systems, but will almost certainly fail with ZIP archives created in Windows. This is because Windows ZIP programs have strange habit of using DOS encoding for file names in ZIP archives. For example, ZIP archive with cyrillic names created in Windows will have file names in {\ttfamily IBM866} encoding instead of {\ttfamily WINDOWS-\/1251}. I think that calling one function is not much trouble, but for true platform independency it would be nice to have some mechanism for file name encoding auto detection using locale information. Does anyone know a good way to do it? \subsection{Member Enumeration Documentation} \index{QuaZip@{QuaZip}!Constants@{Constants}} \index{Constants@{Constants}!QuaZip@{QuaZip}} \subsubsection[{Constants}]{\setlength{\rightskip}{0pt plus 5cm}enum {\bf QuaZip::Constants}}\label{classQuaZip_adce46b942c341dbb5c851eadead65459} Useful constants. \begin{Desc} \item[Enumerator: ]\par \begin{description} \index{MAX\_\-FILE\_\-NAME\_\-LENGTH@{MAX\_\-FILE\_\-NAME\_\-LENGTH}!QuaZip@{QuaZip}}\index{QuaZip@{QuaZip}!MAX\_\-FILE\_\-NAME\_\-LENGTH@{MAX\_\-FILE\_\-NAME\_\-LENGTH}}\item[{\em MAX\_\-FILE\_\-NAME\_\-LENGTH\label{classQuaZip_adce46b942c341dbb5c851eadead65459ab26ce1a9c9e94f901dc2cf90fa5baa4b} }]Maximum file name length. Taken from {\ttfamily UNZ\_\-MAXFILENAMEINZIP} constant in unzip.c. \end{description} \end{Desc} \index{QuaZip@{QuaZip}!Mode@{Mode}} \index{Mode@{Mode}!QuaZip@{QuaZip}} \subsubsection[{Mode}]{\setlength{\rightskip}{0pt plus 5cm}enum {\bf QuaZip::Mode}}\label{classQuaZip_a47e28d4116ee716fdd6b431b821d0be4} Open mode of the ZIP file. \begin{Desc} \item[Enumerator: ]\par \begin{description} \index{mdNotOpen@{mdNotOpen}!QuaZip@{QuaZip}}\index{QuaZip@{QuaZip}!mdNotOpen@{mdNotOpen}}\item[{\em mdNotOpen\label{classQuaZip_a47e28d4116ee716fdd6b431b821d0be4ac87ddb1e901e1ec700c16ee0d4d398ce} }]ZIP file is not open. This is the initial mode. \index{mdUnzip@{mdUnzip}!QuaZip@{QuaZip}}\index{QuaZip@{QuaZip}!mdUnzip@{mdUnzip}}\item[{\em mdUnzip\label{classQuaZip_a47e28d4116ee716fdd6b431b821d0be4a803a371910c2dc830d111e9ce5b58897} }]ZIP file is open for reading files inside it. \index{mdCreate@{mdCreate}!QuaZip@{QuaZip}}\index{QuaZip@{QuaZip}!mdCreate@{mdCreate}}\item[{\em mdCreate\label{classQuaZip_a47e28d4116ee716fdd6b431b821d0be4a25ae05b12590540af8c66ae8298b928e} }]ZIP file was created with \doxyref{open()}{p.}{classQuaZip_abfa4e6018b2964a3d10a4c54e5ab3962} call. \index{mdAppend@{mdAppend}!QuaZip@{QuaZip}}\index{QuaZip@{QuaZip}!mdAppend@{mdAppend}}\item[{\em mdAppend\label{classQuaZip_a47e28d4116ee716fdd6b431b821d0be4ab807f0c65653a16d77b365801fd25582} }]ZIP file was opened in append mode. This refers to {\ttfamily APPEND\_\-STATUS\_\-CREATEAFTER} mode in ZIP/UNZIP package and means that zip is appended to some existing file what is useful when that file contains self-\/extractor code. This is obviously {\itshape not\/} what you whant to use to add files to the existing ZIP archive. \index{mdAdd@{mdAdd}!QuaZip@{QuaZip}}\index{QuaZip@{QuaZip}!mdAdd@{mdAdd}}\item[{\em mdAdd\label{classQuaZip_a47e28d4116ee716fdd6b431b821d0be4a22c745f349f06add449af523254fdaec} }]ZIP file was opened for adding files in the archive. \end{description} \end{Desc} \index{QuaZip@{QuaZip}!CaseSensitivity@{CaseSensitivity}} \index{CaseSensitivity@{CaseSensitivity}!QuaZip@{QuaZip}} \subsubsection[{CaseSensitivity}]{\setlength{\rightskip}{0pt plus 5cm}enum {\bf QuaZip::CaseSensitivity}}\label{classQuaZip_a6053a1d249ed210a85c9d5eb7cf9cdbe} Case sensitivity for the file names. This is what you specify when accessing files in the archive. Works perfectly fine with any characters thanks to Qt's great unicode support. This is different from ZIP/UNZIP API, where only US-\/ASCII characters was supported. \begin{Desc} \item[Enumerator: ]\par \begin{description} \index{csDefault@{csDefault}!QuaZip@{QuaZip}}\index{QuaZip@{QuaZip}!csDefault@{csDefault}}\item[{\em csDefault\label{classQuaZip_a6053a1d249ed210a85c9d5eb7cf9cdbeac3cca8c0b976cf6397a28a5c84e75253} }]Default for platform. Case sensitive for UNIX, not for Windows. \index{csSensitive@{csSensitive}!QuaZip@{QuaZip}}\index{QuaZip@{QuaZip}!csSensitive@{csSensitive}}\item[{\em csSensitive\label{classQuaZip_a6053a1d249ed210a85c9d5eb7cf9cdbead8d86b0c34203336cad09348cfa5356e} }]Case sensitive. \index{csInsensitive@{csInsensitive}!QuaZip@{QuaZip}}\index{QuaZip@{QuaZip}!csInsensitive@{csInsensitive}}\item[{\em csInsensitive\label{classQuaZip_a6053a1d249ed210a85c9d5eb7cf9cdbea3e492bcc3f64f41a74906cecc45fb366} }]Case insensitive. \end{description} \end{Desc} \subsection{Constructor \& Destructor Documentation} \index{QuaZip@{QuaZip}!QuaZip@{QuaZip}} \index{QuaZip@{QuaZip}!QuaZip@{QuaZip}} \subsubsection[{QuaZip}]{\setlength{\rightskip}{0pt plus 5cm}QuaZip::QuaZip ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )}\label{classQuaZip_a970e0f401c7cfd7a78e78572f758eec4} Constructs \doxyref{QuaZip}{p.}{classQuaZip} object. Call setName() before opening constructed object. \index{QuaZip@{QuaZip}!QuaZip@{QuaZip}} \index{QuaZip@{QuaZip}!QuaZip@{QuaZip}} \subsubsection[{QuaZip}]{\setlength{\rightskip}{0pt plus 5cm}QuaZip::QuaZip ( \begin{DoxyParamCaption} \item[{QIODevice $\ast$}]{ioDevice} \end{DoxyParamCaption} )}\label{classQuaZip_ae52ebadd5ce64cdb49d7e198904b0b8c} Constructs \doxyref{QuaZip}{p.}{classQuaZip} object associated with ZIP file represented by {\itshape ioDevice\/}. The IO device must be seekable, otherwise an error will occur when opening. \index{QuaZip@{QuaZip}!$\sim$QuaZip@{$\sim$QuaZip}} \index{$\sim$QuaZip@{$\sim$QuaZip}!QuaZip@{QuaZip}} \subsubsection[{$\sim$QuaZip}]{\setlength{\rightskip}{0pt plus 5cm}QuaZip::$\sim$QuaZip ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )}\label{classQuaZip_af60a2d3930b90f3b25a3148baecad81e} Destroys \doxyref{QuaZip}{p.}{classQuaZip} object. Calls \doxyref{close()}{p.}{classQuaZip_a7a4323b73e12f3b4470109f200728f9f} if necessary. References close(), and isOpen(). \subsection{Member Function Documentation} \index{QuaZip@{QuaZip}!open@{open}} \index{open@{open}!QuaZip@{QuaZip}} \subsubsection[{open}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZip::open ( \begin{DoxyParamCaption} \item[{{\bf Mode}}]{mode, } \item[{zlib\_\-filefunc\_\-def $\ast$}]{ioApi = {\ttfamily NULL}} \end{DoxyParamCaption} )}\label{classQuaZip_abfa4e6018b2964a3d10a4c54e5ab3962} Opens ZIP file. Argument {\itshape mode\/} specifies open mode of the ZIP archive. See Mode for details. Note that there is zipOpen2() function in the ZIP/UNZIP API which accepts {\itshape globalcomment\/} argument, but it does not use it anywhere, so this \doxyref{open()}{p.}{classQuaZip_abfa4e6018b2964a3d10a4c54e5ab3962} function does not have this argument. See \doxyref{setComment()}{p.}{classQuaZip_a1b5d936a203859340574d5908ffa2222} if you need to set global comment. If the ZIP file is accessed via explicitly set QIODevice, then this device is opened in the necessary mode. If the device was already opened by some other means, then the behaviour is defined by the device implementation, but generally it is not a very good idea. For example, QFile will at least issue a warning. \begin{DoxyReturn}{Returns} {\ttfamily true} if successful, {\ttfamily false} otherwise. \end{DoxyReturn} \begin{DoxyNote}{Note} ZIP/UNZIP API open calls do not return error code -\/ they just return {\ttfamily NULL} indicating an error. But to make things easier, \doxyref{quazip.h}{p.}{quazip_8h_source} header defines additional error code {\ttfamily UNZ\_\-ERROROPEN} and \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} will return it if the open call of the ZIP/UNZIP API returns {\ttfamily NULL}. \end{DoxyNote} Argument {\itshape ioApi\/} specifies IO function set for ZIP/UNZIP package to use. See unzip.h, zip.h and ioapi.h for details. Note that IO API for \doxyref{QuaZip}{p.}{classQuaZip} is different from the original package. The file path argument was changed to be of type {\ttfamily voidpf}, and \doxyref{QuaZip}{p.}{classQuaZip} passes a QIODevice pointer there. This QIODevice is either set explicitly via \doxyref{setIoDevice()}{p.}{classQuaZip_a64642948b6531ee54f5522f29e388cc6} or the \doxyref{QuaZip(QIODevice$\ast$)}{p.}{classQuaZip_ae52ebadd5ce64cdb49d7e198904b0b8c} constructor, or it is created internally when opening the archive by its file name. The default API (qioapi.cpp) just delegates everything to the QIODevice API. Not only this allows to use a QIODevice instead of file name, but also has a nice side effect of raising the file size limit from 2G to 4G. In short: just forget about the {\itshape ioApi\/} argument and you'll be fine. References isOpen(), mdAdd, mdAppend, mdCreate, mdUnzip, QuaZipPrivate::unzFile\_\-f, and QuaZipPrivate::zipFile\_\-f. Referenced by JlCompress::compressDir(), JlCompress::compressFile(), JlCompress::compressFiles(), JlCompress::extractDir(), JlCompress::extractFile(), JlCompress::extractFiles(), JlCompress::getFileList(), and QuaZipFile::open(). \index{QuaZip@{QuaZip}!close@{close}} \index{close@{close}!QuaZip@{QuaZip}} \subsubsection[{close}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZip::close ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )}\label{classQuaZip_a7a4323b73e12f3b4470109f200728f9f} Closes ZIP file. Call \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} to determine if the close was successful. The underlying QIODevice is also closed, regardless of whether it was set explicitly or not. References mdAdd, mdAppend, mdCreate, mdNotOpen, mdUnzip, QuaZipPrivate::unzFile\_\-f, and QuaZipPrivate::zipFile\_\-f. Referenced by QuaZipFile::close(), JlCompress::compressDir(), JlCompress::compressFile(), JlCompress::compressFiles(), JlCompress::extractDir(), JlCompress::extractFile(), JlCompress::extractFiles(), JlCompress::getFileList(), QuaZipFile::open(), and $\sim$QuaZip(). \index{QuaZip@{QuaZip}!setFileNameCodec@{setFileNameCodec}} \index{setFileNameCodec@{setFileNameCodec}!QuaZip@{QuaZip}} \subsubsection[{setFileNameCodec}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZip::setFileNameCodec ( \begin{DoxyParamCaption} \item[{QTextCodec $\ast$}]{fileNameCodec} \end{DoxyParamCaption} )}\label{classQuaZip_a339010b5566704ba3c9cafbfe848d8fb} Sets the codec used to encode/decode file names inside archive. This is necessary to access files in the ZIP archive created under Windows with non-\/latin characters in file names. For example, file names with cyrillic letters will be in {\ttfamily IBM866} encoding. \index{QuaZip@{QuaZip}!setFileNameCodec@{setFileNameCodec}} \index{setFileNameCodec@{setFileNameCodec}!QuaZip@{QuaZip}} \subsubsection[{setFileNameCodec}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZip::setFileNameCodec ( \begin{DoxyParamCaption} \item[{const char $\ast$}]{fileNameCodecName} \end{DoxyParamCaption} )}\label{classQuaZip_a8f283519a195aa1d9076bbbb01ea0497} Sets the codec used to encode/decode file names inside archive. This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName)); \index{QuaZip@{QuaZip}!setCommentCodec@{setCommentCodec}} \index{setCommentCodec@{setCommentCodec}!QuaZip@{QuaZip}} \subsubsection[{setCommentCodec}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZip::setCommentCodec ( \begin{DoxyParamCaption} \item[{QTextCodec $\ast$}]{commentCodec} \end{DoxyParamCaption} )}\label{classQuaZip_a1c81fca7215a4374f6f03872ade4885b} Sets the codec used to encode/decode comments inside archive. This codec defaults to locale codec, which is probably ok. \index{QuaZip@{QuaZip}!setCommentCodec@{setCommentCodec}} \index{setCommentCodec@{setCommentCodec}!QuaZip@{QuaZip}} \subsubsection[{setCommentCodec}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZip::setCommentCodec ( \begin{DoxyParamCaption} \item[{const char $\ast$}]{commentCodecName} \end{DoxyParamCaption} )}\label{classQuaZip_a413f3c56b54a9a47258d53802cb606e7} Sets the codec used to encode/decode comments inside archive. This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Equivalent to calling setCommentCodec(QTextCodec::codecForName(codecName)); \index{QuaZip@{QuaZip}!getZipName@{getZipName}} \index{getZipName@{getZipName}!QuaZip@{QuaZip}} \subsubsection[{getZipName}]{\setlength{\rightskip}{0pt plus 5cm}QString QuaZip::getZipName ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZip_a4f7deef08ff40aeb1a7a04bcd7f228c2} Returns the name of the ZIP file. Returns null string if no ZIP file name has been set, for example when the \doxyref{QuaZip}{p.}{classQuaZip} instance is set up to use a QIODevice instead. \begin{DoxySeeAlso}{See also} \doxyref{setZipName()}{p.}{classQuaZip_aa80b661de1262af905d1677dbcb008cc}, \doxyref{setIoDevice()}{p.}{classQuaZip_a64642948b6531ee54f5522f29e388cc6}, \doxyref{getIoDevice()}{p.}{classQuaZip_afd3ba12fe68748acbf8b7cc14a5a1c29} \end{DoxySeeAlso} Referenced by QuaZipFile::getZipName(). \index{QuaZip@{QuaZip}!setZipName@{setZipName}} \index{setZipName@{setZipName}!QuaZip@{QuaZip}} \subsubsection[{setZipName}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZip::setZipName ( \begin{DoxyParamCaption} \item[{const QString \&}]{zipName} \end{DoxyParamCaption} )}\label{classQuaZip_aa80b661de1262af905d1677dbcb008cc} Sets the name of the ZIP file. Does nothing if the ZIP file is open. Does not reset error code returned by \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4}. \begin{DoxySeeAlso}{See also} \doxyref{setIoDevice()}{p.}{classQuaZip_a64642948b6531ee54f5522f29e388cc6}, \doxyref{getIoDevice()}{p.}{classQuaZip_afd3ba12fe68748acbf8b7cc14a5a1c29}, \doxyref{getZipName()}{p.}{classQuaZip_a4f7deef08ff40aeb1a7a04bcd7f228c2} \end{DoxySeeAlso} References isOpen(). \index{QuaZip@{QuaZip}!getIoDevice@{getIoDevice}} \index{getIoDevice@{getIoDevice}!QuaZip@{QuaZip}} \subsubsection[{getIoDevice}]{\setlength{\rightskip}{0pt plus 5cm}QIODevice $\ast$ QuaZip::getIoDevice ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZip_afd3ba12fe68748acbf8b7cc14a5a1c29} Returns the device representing this ZIP file. Returns null string if no device has been set explicitly, for example when opening a ZIP file by name. \begin{DoxySeeAlso}{See also} \doxyref{setIoDevice()}{p.}{classQuaZip_a64642948b6531ee54f5522f29e388cc6}, \doxyref{getZipName()}{p.}{classQuaZip_a4f7deef08ff40aeb1a7a04bcd7f228c2}, \doxyref{setZipName()}{p.}{classQuaZip_aa80b661de1262af905d1677dbcb008cc} \end{DoxySeeAlso} \index{QuaZip@{QuaZip}!setIoDevice@{setIoDevice}} \index{setIoDevice@{setIoDevice}!QuaZip@{QuaZip}} \subsubsection[{setIoDevice}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZip::setIoDevice ( \begin{DoxyParamCaption} \item[{QIODevice $\ast$}]{ioDevice} \end{DoxyParamCaption} )}\label{classQuaZip_a64642948b6531ee54f5522f29e388cc6} Sets the device representing the ZIP file. Does nothing if the ZIP file is open. Does not reset error code returned by \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4}. \begin{DoxySeeAlso}{See also} \doxyref{getIoDevice()}{p.}{classQuaZip_afd3ba12fe68748acbf8b7cc14a5a1c29}, \doxyref{getZipName()}{p.}{classQuaZip_a4f7deef08ff40aeb1a7a04bcd7f228c2}, \doxyref{setZipName()}{p.}{classQuaZip_aa80b661de1262af905d1677dbcb008cc} \end{DoxySeeAlso} References isOpen(). \index{QuaZip@{QuaZip}!getZipError@{getZipError}} \index{getZipError@{getZipError}!QuaZip@{QuaZip}} \subsubsection[{getZipError}]{\setlength{\rightskip}{0pt plus 5cm}int QuaZip::getZipError ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} Returns the error code of the last operation. Returns {\ttfamily UNZ\_\-OK} if the last operation was successful. Error code resets to {\ttfamily UNZ\_\-OK} every time you call any function that accesses something inside ZIP archive, even if it is {\ttfamily const} (like \doxyref{getEntriesCount()}{p.}{classQuaZip_a2ea4bd1fca948637c35c2d2752bb5a80}). \doxyref{open()}{p.}{classQuaZip_abfa4e6018b2964a3d10a4c54e5ab3962} and \doxyref{close()}{p.}{classQuaZip_a7a4323b73e12f3b4470109f200728f9f} calls reset error code too. See documentation for the specific functions for details on error detection. Referenced by QuaZipFile::close(), JlCompress::compressDir(), JlCompress::compressFile(), JlCompress::compressFiles(), JlCompress::extractDir(), JlCompress::extractFile(), JlCompress::extractFiles(), QuaZipFile::getActualFileName(), QuaZipFile::getFileInfo(), JlCompress::getFileList(), and QuaZipFile::open(). \index{QuaZip@{QuaZip}!getEntriesCount@{getEntriesCount}} \index{getEntriesCount@{getEntriesCount}!QuaZip@{QuaZip}} \subsubsection[{getEntriesCount}]{\setlength{\rightskip}{0pt plus 5cm}int QuaZip::getEntriesCount ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZip_a2ea4bd1fca948637c35c2d2752bb5a80} Returns number of the entries in the ZIP central directory. Returns negative error code in the case of error. The same error code will be returned by subsequent \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} call. References mdUnzip, and QuaZipPrivate::unzFile\_\-f. \index{QuaZip@{QuaZip}!setComment@{setComment}} \index{setComment@{setComment}!QuaZip@{QuaZip}} \subsubsection[{setComment}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZip::setComment ( \begin{DoxyParamCaption} \item[{const QString \&}]{comment} \end{DoxyParamCaption} )}\label{classQuaZip_a1b5d936a203859340574d5908ffa2222} Sets global comment in the ZIP file. Comment will be written to the archive on close operation. \begin{DoxySeeAlso}{See also} \doxyref{open()}{p.}{classQuaZip_abfa4e6018b2964a3d10a4c54e5ab3962} \end{DoxySeeAlso} \index{QuaZip@{QuaZip}!goToFirstFile@{goToFirstFile}} \index{goToFirstFile@{goToFirstFile}!QuaZip@{QuaZip}} \subsubsection[{goToFirstFile}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZip::goToFirstFile ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )}\label{classQuaZip_a745488f9177bcec3cdb858587584e033} Sets the current file to the first file in the archive. Returns {\ttfamily true} on success, {\ttfamily false} otherwise. Call \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} to get the error code. References mdUnzip, and QuaZipPrivate::unzFile\_\-f. Referenced by JlCompress::getFileList(), and setCurrentFile(). \index{QuaZip@{QuaZip}!goToNextFile@{goToNextFile}} \index{goToNextFile@{goToNextFile}!QuaZip@{QuaZip}} \subsubsection[{goToNextFile}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZip::goToNextFile ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )}\label{classQuaZip_aee6779b6cd338420c2e8c5655fa8ba97} Sets the current file to the next file in the archive. Returns {\ttfamily true} on success, {\ttfamily false} otherwise. Call \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} to determine if there was an error. Should be used only in \doxyref{QuaZip::mdUnzip}{p.}{classQuaZip_a47e28d4116ee716fdd6b431b821d0be4a803a371910c2dc830d111e9ce5b58897} mode. \begin{DoxyNote}{Note} If the end of file was reached, \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} will return {\ttfamily UNZ\_\-OK} instead of {\ttfamily UNZ\_\-END\_\-OF\_\-LIST\_\-OF\_\-FILE}. This is to make things like this easier: \begin{DoxyCode} for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { // do something } if(zip.getZipError()==UNZ_OK) { // ok, there was no error } \end{DoxyCode} \end{DoxyNote} References mdUnzip, and QuaZipPrivate::unzFile\_\-f. Referenced by JlCompress::getFileList(), and setCurrentFile(). \index{QuaZip@{QuaZip}!setCurrentFile@{setCurrentFile}} \index{setCurrentFile@{setCurrentFile}!QuaZip@{QuaZip}} \subsubsection[{setCurrentFile}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZip::setCurrentFile ( \begin{DoxyParamCaption} \item[{const QString \&}]{fileName, } \item[{{\bf CaseSensitivity}}]{cs = {\ttfamily csDefault}} \end{DoxyParamCaption} )}\label{classQuaZip_a6c657bfcfccb59d728e0da24c677d899} Sets current file by its name. Returns {\ttfamily true} if successful, {\ttfamily false} otherwise. Argument {\itshape cs\/} specifies case sensitivity of the file name. Call \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} in the case of a failure to get error code. This is not a wrapper to unzLocateFile() function. That is because I had to implement locale-\/specific case-\/insensitive comparison. Here are the differences from the original implementation: \begin{DoxyItemize} \item If the file was not found, error code is {\ttfamily UNZ\_\-OK}, not {\ttfamily UNZ\_\-END\_\-OF\_\-LIST\_\-OF\_\-FILE} (see also \doxyref{goToNextFile()}{p.}{classQuaZip_aee6779b6cd338420c2e8c5655fa8ba97}). \item If this function fails, it unsets the current file rather than resetting it back to what it was before the call. \end{DoxyItemize} If {\itshape fileName\/} is null string then this function unsets the current file and return {\ttfamily true}. Note that you should close the file first if it is open! See \doxyref{QuaZipFile::QuaZipFile(QuaZip$\ast$,QObject$\ast$)}{p.}{classQuaZipFile_a54e944a6b3d27030f64c8f30d2cc33bb} for the details. Should be used only in \doxyref{QuaZip::mdUnzip}{p.}{classQuaZip_a47e28d4116ee716fdd6b431b821d0be4a803a371910c2dc830d111e9ce5b58897} mode. \begin{DoxySeeAlso}{See also} \doxyref{setFileNameCodec()}{p.}{classQuaZip_a339010b5566704ba3c9cafbfe848d8fb}, \doxyref{CaseSensitivity}{p.}{classQuaZip_a6053a1d249ed210a85c9d5eb7cf9cdbe} \end{DoxySeeAlso} References csDefault, csSensitive, getCurrentFileName(), goToFirstFile(), goToNextFile(), MAX\_\-FILE\_\-NAME\_\-LENGTH, mdUnzip, and QuaZipPrivate::unzFile\_\-f. Referenced by QuaZipFile::open(). \index{QuaZip@{QuaZip}!getCurrentFileInfo@{getCurrentFileInfo}} \index{getCurrentFileInfo@{getCurrentFileInfo}!QuaZip@{QuaZip}} \subsubsection[{getCurrentFileInfo}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZip::getCurrentFileInfo ( \begin{DoxyParamCaption} \item[{{\bf QuaZipFileInfo} $\ast$}]{info} \end{DoxyParamCaption} ) const}\label{classQuaZip_a9c91a53ed4c2038e153c64bdc097ebe8} Retrieves information about the current file. Fills the structure pointed by {\itshape info\/}. Returns {\ttfamily true} on success, {\ttfamily false} otherwise. In the latter case structure pointed by {\itshape info\/} remains untouched. If there was an error, \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} returns error code. Should be used only in \doxyref{QuaZip::mdUnzip}{p.}{classQuaZip_a47e28d4116ee716fdd6b431b821d0be4a803a371910c2dc830d111e9ce5b58897} mode. Does nothing and returns {\ttfamily false} in any of the following cases. \begin{DoxyItemize} \item ZIP is not open; \item ZIP does not have current file; \item {\itshape info\/} is {\ttfamily NULL}; \end{DoxyItemize} In all these cases \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} returns {\ttfamily UNZ\_\-OK} since there is no ZIP/UNZIP API call. References QuaZipFileInfo::comment, QuaZipFileInfo::compressedSize, QuaZipFileInfo::crc, QuaZipFileInfo::dateTime, QuaZipFileInfo::diskNumberStart, QuaZipFileInfo::externalAttr, QuaZipFileInfo::extra, QuaZipFileInfo::flags, hasCurrentFile(), QuaZipFileInfo::internalAttr, isOpen(), mdUnzip, QuaZipFileInfo::method, QuaZipFileInfo::name, QuaZipFileInfo::uncompressedSize, QuaZipPrivate::unzFile\_\-f, QuaZipFileInfo::versionCreated, and QuaZipFileInfo::versionNeeded. Referenced by QuaZipFile::getFileInfo(), and JlCompress::getFileList(). \index{QuaZip@{QuaZip}!getCurrentFileName@{getCurrentFileName}} \index{getCurrentFileName@{getCurrentFileName}!QuaZip@{QuaZip}} \subsubsection[{getCurrentFileName}]{\setlength{\rightskip}{0pt plus 5cm}QString QuaZip::getCurrentFileName ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZip_a9783f8b4f39cd55e71e975aea78fd54a} Returns the current file name. Equivalent to calling \doxyref{getCurrentFileInfo()}{p.}{classQuaZip_a9c91a53ed4c2038e153c64bdc097ebe8} and then getting {\ttfamily name} field of the \doxyref{QuaZipFileInfo}{p.}{structQuaZipFileInfo} structure, but faster and more convenient. Should be used only in \doxyref{QuaZip::mdUnzip}{p.}{classQuaZip_a47e28d4116ee716fdd6b431b821d0be4a803a371910c2dc830d111e9ce5b58897} mode. References hasCurrentFile(), isOpen(), MAX\_\-FILE\_\-NAME\_\-LENGTH, mdUnzip, and QuaZipPrivate::unzFile\_\-f. Referenced by QuaZipFile::getActualFileName(), and setCurrentFile(). \index{QuaZip@{QuaZip}!getUnzFile@{getUnzFile}} \index{getUnzFile@{getUnzFile}!QuaZip@{QuaZip}} \subsubsection[{getUnzFile}]{\setlength{\rightskip}{0pt plus 5cm}unzFile QuaZip::getUnzFile ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )}\label{classQuaZip_a3b78a652f296ff4a678a791e8294e642} Returns {\ttfamily unzFile} handle. You can use this handle to directly call UNZIP part of the ZIP/UNZIP package functions (see unzip.h). \begin{DoxyWarning}{Warning} When using the handle returned by this function, please keep in mind that \doxyref{QuaZip}{p.}{classQuaZip} class is unable to detect any changes you make in the ZIP file state (e. g. changing current file, or closing the handle). So please do not do anything with this handle that is possible to do with the functions of this class. Or at least return the handle in the original state before calling some another function of this class (including implicit destructor calls and calls from the \doxyref{QuaZipFile}{p.}{classQuaZipFile} objects that refer to this \doxyref{QuaZip}{p.}{classQuaZip} instance!). So if you have changed the current file in the ZIP archive -\/ then change it back or you may experience some strange behavior or even crashes. \end{DoxyWarning} References QuaZipPrivate::unzFile\_\-f. Referenced by QuaZipFile::atEnd(), QuaZipFile::close(), QuaZipFile::csize(), QuaZipFile::open(), QuaZipFile::pos(), QuaZipFile::readData(), and QuaZipFile::usize(). \index{QuaZip@{QuaZip}!getZipFile@{getZipFile}} \index{getZipFile@{getZipFile}!QuaZip@{QuaZip}} \subsubsection[{getZipFile}]{\setlength{\rightskip}{0pt plus 5cm}zipFile QuaZip::getZipFile ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )}\label{classQuaZip_a425043a4d7cc31e2fe2bba73d954f15c} Returns {\ttfamily zipFile} handle. You can use this handle to directly call ZIP part of the ZIP/UNZIP package functions (see zip.h). Warnings about the \doxyref{getUnzFile()}{p.}{classQuaZip_a3b78a652f296ff4a678a791e8294e642} function also apply to this function. References QuaZipPrivate::zipFile\_\-f. Referenced by QuaZipFile::close(), QuaZipFile::open(), and QuaZipFile::writeData(). \index{QuaZip@{QuaZip}!setDataDescriptorWritingEnabled@{setDataDescriptorWritingEnabled}} \index{setDataDescriptorWritingEnabled@{setDataDescriptorWritingEnabled}!QuaZip@{QuaZip}} \subsubsection[{setDataDescriptorWritingEnabled}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZip::setDataDescriptorWritingEnabled ( \begin{DoxyParamCaption} \item[{bool}]{enabled} \end{DoxyParamCaption} )}\label{classQuaZip_a6c23a12af88f7ea5edd4f9c0a24b9453} Changes the data descriptor writing mode. According to the ZIP format specification, a file inside archive may have a data descriptor immediately following the file data. This is reflected by a special flag in the local file header and in the central directory. By default, QuaZIP sets this flag and writes the data descriptor unless both method and level were set to 0, in which case it operates in 1.0-\/compatible mode and never writes data descriptors. By setting this flag to false, it is possible to disable data descriptor writing, thus increasing compatibility with archive readers that don't understand this feature of the ZIP file format. Setting this flag affects all the \doxyref{QuaZipFile}{p.}{classQuaZipFile} instances that are opened after this flag is set. The data descriptor writing mode is enabled by default. \begin{DoxyParams}{Parameters} {\em enabled} & If {\ttfamily true}, enable local descriptor writing, disable it otherwise.\\ \hline \end{DoxyParams} \begin{DoxySeeAlso}{See also} QuaZipFile::setDataDescriptorWritingEnabled() \end{DoxySeeAlso} \index{QuaZip@{QuaZip}!isDataDescriptorWritingEnabled@{isDataDescriptorWritingEnabled}} \index{isDataDescriptorWritingEnabled@{isDataDescriptorWritingEnabled}!QuaZip@{QuaZip}} \subsubsection[{isDataDescriptorWritingEnabled}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZip::isDataDescriptorWritingEnabled ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZip_ae5c665a59447c2d30e63e9c6df48ebb7} Returns the data descriptor default writing mode. \begin{DoxySeeAlso}{See also} \doxyref{setDataDescriptorWritingEnabled()}{p.}{classQuaZip_a6c23a12af88f7ea5edd4f9c0a24b9453} \end{DoxySeeAlso} Referenced by QuaZipFile::open(). \index{QuaZip@{QuaZip}!getFileNameList@{getFileNameList}} \index{getFileNameList@{getFileNameList}!QuaZip@{QuaZip}} \subsubsection[{getFileNameList}]{\setlength{\rightskip}{0pt plus 5cm}QStringList QuaZip::getFileNameList ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZip_abb38d8b4c9c4ae0728b48caae9dd82de} Returns a list of files inside the archive. \begin{DoxyReturn}{Returns} A list of file names or an empty list if there was an error or if the archive is empty (call \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} to figure out which). \end{DoxyReturn} \begin{DoxySeeAlso}{See also} \doxyref{getFileInfoList()}{p.}{classQuaZip_a7486af66bede8e131db0cd2e81881387} \end{DoxySeeAlso} \index{QuaZip@{QuaZip}!getFileInfoList@{getFileInfoList}} \index{getFileInfoList@{getFileInfoList}!QuaZip@{QuaZip}} \subsubsection[{getFileInfoList}]{\setlength{\rightskip}{0pt plus 5cm}QList$<$ {\bf QuaZipFileInfo} $>$ QuaZip::getFileInfoList ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZip_a7486af66bede8e131db0cd2e81881387} Returns information list about all files inside the archive. \begin{DoxyReturn}{Returns} A list of \doxyref{QuaZipFileInfo}{p.}{structQuaZipFileInfo} objects or an empty list if there was an error or if the archive is empty (call \doxyref{getZipError()}{p.}{classQuaZip_a28b91a6282ddd9382c96a069572c6fb4} to figure out which). \end{DoxyReturn} \begin{DoxySeeAlso}{See also} \doxyref{getFileNameList()}{p.}{classQuaZip_abb38d8b4c9c4ae0728b48caae9dd82de} \end{DoxySeeAlso} The documentation for this class was generated from the following files:\begin{DoxyCompactItemize} \item quazip/quazip.h\item quazip/quazip.cpp\end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classJlCompress.tex0000644000175000017500000002504712070466513023757 0ustar csmallcsmall\section{JlCompress Class Reference} \label{classJlCompress}\index{JlCompress@{JlCompress}} Utility class for typical operations. {\ttfamily \#include $<$JlCompress.h$>$} \subsection*{Static Public Member Functions} \begin{DoxyCompactItemize} \item static bool {\bf compressFile} (QString fileCompressed, QString file) \begin{DoxyCompactList}\small\item\em Compress a single file. \end{DoxyCompactList}\item static bool {\bf compressFiles} (QString fileCompressed, QStringList files) \begin{DoxyCompactList}\small\item\em Compress a list of files. \end{DoxyCompactList}\item static bool {\bf compressDir} (QString fileCompressed, QString dir=QString(), bool recursive=true) \begin{DoxyCompactList}\small\item\em Compress a whole directory. \end{DoxyCompactList}\item static QString {\bf extractFile} (QString fileCompressed, QString fileName, QString fileDest=QString()) \begin{DoxyCompactList}\small\item\em Extract a single file. \end{DoxyCompactList}\item static QStringList {\bf extractFiles} (QString fileCompressed, QStringList files, QString dir=QString()) \begin{DoxyCompactList}\small\item\em Extract a list of files. \end{DoxyCompactList}\item static QStringList {\bf extractDir} (QString fileCompressed, QString dir=QString()) \begin{DoxyCompactList}\small\item\em Extract a whole archive. \end{DoxyCompactList}\item static QStringList {\bf getFileList} (QString fileCompressed) \begin{DoxyCompactList}\small\item\em Get the file list. \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection{Detailed Description} Utility class for typical operations. This class contains a number of useful static functions to perform simple operations, such as mass ZIP packing or extraction. \subsection{Member Function Documentation} \index{JlCompress@{JlCompress}!compressFile@{compressFile}} \index{compressFile@{compressFile}!JlCompress@{JlCompress}} \subsubsection[{compressFile}]{\setlength{\rightskip}{0pt plus 5cm}bool JlCompress::compressFile ( \begin{DoxyParamCaption} \item[{QString}]{fileCompressed, } \item[{QString}]{file} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [static]}}\label{classJlCompress_a4a4de9c62ecf161bb658d4d80495ea97} Compress a single file. \begin{DoxyParams}{Parameters} {\em fileCompressed} & The name of the archive. \\ \hline {\em file} & The file to compress. \\ \hline \end{DoxyParams} \begin{DoxyReturn}{Returns} true if success, false otherwise. \end{DoxyReturn} OK Comprime il file fileName nel file fileCompressed. Se la funzione fallisce restituisce false e cancella il file che si e tentato di creare. La funzione fallisce se: $\ast$ non si riesce ad aprire l'oggetto zip; $\ast$ la compressione del file fallisce; $\ast$ non si riesce a chiudere l'oggetto zip; References QuaZip::close(), QuaZip::getZipError(), QuaZip::mdCreate, and QuaZip::open(). \index{JlCompress@{JlCompress}!compressFiles@{compressFiles}} \index{compressFiles@{compressFiles}!JlCompress@{JlCompress}} \subsubsection[{compressFiles}]{\setlength{\rightskip}{0pt plus 5cm}bool JlCompress::compressFiles ( \begin{DoxyParamCaption} \item[{QString}]{fileCompressed, } \item[{QStringList}]{files} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [static]}}\label{classJlCompress_a9cdb92d29a94c6b13a718a3249685846} Compress a list of files. \begin{DoxyParams}{Parameters} {\em fileCompressed} & The name of the archive. \\ \hline {\em files} & The file list to compress. \\ \hline \end{DoxyParams} \begin{DoxyReturn}{Returns} true if success, false otherwise. \end{DoxyReturn} OK Comprime i file specificati in files nel file fileCompressed. Se la funzione fallisce restituisce false e cancella il file che si e tentato di creare. La funzione fallisce se: $\ast$ non si riesce ad aprire l'oggetto zip; $\ast$ la compressione di un file fallisce; $\ast$ non si riesce a chiudere l'oggetto zip; References QuaZip::close(), QuaZip::getZipError(), QuaZip::mdCreate, and QuaZip::open(). \index{JlCompress@{JlCompress}!compressDir@{compressDir}} \index{compressDir@{compressDir}!JlCompress@{JlCompress}} \subsubsection[{compressDir}]{\setlength{\rightskip}{0pt plus 5cm}bool JlCompress::compressDir ( \begin{DoxyParamCaption} \item[{QString}]{fileCompressed, } \item[{QString}]{dir = {\ttfamily QString()}, } \item[{bool}]{recursive = {\ttfamily true}} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [static]}}\label{classJlCompress_a8708eafcadc5c192a1d492e784cfc98f} Compress a whole directory. \begin{DoxyParams}{Parameters} {\em fileCompressed} & The name of the archive. \\ \hline {\em dir} & The directory to compress. \\ \hline {\em recursive} & Whether to pack the subdirectories as well, or just regular files. \\ \hline \end{DoxyParams} \begin{DoxyReturn}{Returns} true if success, false otherwise. \end{DoxyReturn} OK Comprime la cartella dir nel file fileCompressed, se recursive e true allora comprime anche le sotto cartelle. Se la funzione fallisce restituisce false e cancella il file che si e tentato di creare. La funzione fallisce se: $\ast$ non si riesce ad aprire l'oggetto zip; $\ast$ la compressione di un file fallisce; $\ast$ non si riesce a chiudere l'oggetto zip; References QuaZip::close(), QuaZip::getZipError(), QuaZip::mdCreate, and QuaZip::open(). \index{JlCompress@{JlCompress}!extractFile@{extractFile}} \index{extractFile@{extractFile}!JlCompress@{JlCompress}} \subsubsection[{extractFile}]{\setlength{\rightskip}{0pt plus 5cm}QString JlCompress::extractFile ( \begin{DoxyParamCaption} \item[{QString}]{fileCompressed, } \item[{QString}]{fileName, } \item[{QString}]{fileDest = {\ttfamily QString()}} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [static]}}\label{classJlCompress_a38c0d58bfe3bbbcb3cf4e98d126633a3} Extract a single file. \begin{DoxyParams}{Parameters} {\em fileCompressed} & The name of the archive. \\ \hline {\em fileName} & The file to extract. \\ \hline {\em fileDest} & The destination file, assumed to be identical to {\itshape file\/} if left empty. \\ \hline \end{DoxyParams} \begin{DoxyReturn}{Returns} The list of the full paths of the files extracted, empty on failure. \end{DoxyReturn} OK Estrae il file fileName, contenuto nel file fileCompressed, con il nome fileDest. Se fileDest = \char`\"{}\char`\"{} allora il file viene estratto con lo stesso nome con cui e stato compresso. Se la funzione fallisce cancella il file che si e tentato di estrarre. Restituisce il nome assoluto del file estratto. La funzione fallisce se: $\ast$ non si riesce ad aprire l'oggetto zip; $\ast$ l'estrazione del file fallisce; $\ast$ non si riesce a chiudere l'oggetto zip; References QuaZip::close(), QuaZip::getZipError(), QuaZip::mdUnzip, and QuaZip::open(). \index{JlCompress@{JlCompress}!extractFiles@{extractFiles}} \index{extractFiles@{extractFiles}!JlCompress@{JlCompress}} \subsubsection[{extractFiles}]{\setlength{\rightskip}{0pt plus 5cm}QStringList JlCompress::extractFiles ( \begin{DoxyParamCaption} \item[{QString}]{fileCompressed, } \item[{QStringList}]{files, } \item[{QString}]{dir = {\ttfamily QString()}} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [static]}}\label{classJlCompress_a309e9ee366719a4d8aa28f837fab73ae} Extract a list of files. \begin{DoxyParams}{Parameters} {\em fileCompressed} & The name of the archive. \\ \hline {\em files} & The file list to extract. \\ \hline {\em dir} & The directory to put the files to, the current directory if left empty. \\ \hline \end{DoxyParams} \begin{DoxyReturn}{Returns} The list of the full paths of the files extracted, empty on failure. \end{DoxyReturn} OK Estrae i file specificati in files, contenuti nel file fileCompressed, nella cartella dir. La struttura a cartelle del file compresso viene rispettata. Se dir = \char`\"{}\char`\"{} allora il file viene estratto nella cartella corrente. Se la funzione fallisce cancella i file che si e tentato di estrarre. Restituisce i nomi assoluti dei file estratti. La funzione fallisce se: $\ast$ non si riesce ad aprire l'oggetto zip; $\ast$ l'estrazione di un file fallisce; $\ast$ non si riesce a chiudere l'oggetto zip; References QuaZip::close(), QuaZip::getZipError(), QuaZip::mdUnzip, and QuaZip::open(). \index{JlCompress@{JlCompress}!extractDir@{extractDir}} \index{extractDir@{extractDir}!JlCompress@{JlCompress}} \subsubsection[{extractDir}]{\setlength{\rightskip}{0pt plus 5cm}QStringList JlCompress::extractDir ( \begin{DoxyParamCaption} \item[{QString}]{fileCompressed, } \item[{QString}]{dir = {\ttfamily QString()}} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [static]}}\label{classJlCompress_a365a153baa4c11812d93cbca60b6a293} Extract a whole archive. \begin{DoxyParams}{Parameters} {\em fileCompressed} & The name of the archive. \\ \hline {\em dir} & The directory to extract to, the current directory if left empty. \\ \hline \end{DoxyParams} \begin{DoxyReturn}{Returns} The list of the full paths of the files extracted, empty on failure. \end{DoxyReturn} OK Estrae il file fileCompressed nella cartella dir. Se dir = \char`\"{}\char`\"{} allora il file viene estratto nella cartella corrente. Se la funzione fallisce cancella i file che si e tentato di estrarre. Restituisce i nomi assoluti dei file estratti. La funzione fallisce se: $\ast$ non si riesce ad aprire l'oggetto zip; $\ast$ la compressione di un file fallisce; $\ast$ non si riesce a chiudere l'oggetto zip; References QuaZip::close(), getFileList(), QuaZip::getZipError(), QuaZip::mdUnzip, and QuaZip::open(). \index{JlCompress@{JlCompress}!getFileList@{getFileList}} \index{getFileList@{getFileList}!JlCompress@{JlCompress}} \subsubsection[{getFileList}]{\setlength{\rightskip}{0pt plus 5cm}QStringList JlCompress::getFileList ( \begin{DoxyParamCaption} \item[{QString}]{fileCompressed} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [static]}}\label{classJlCompress_ab42422be913f817d7e04c1b1cd5d0156} Get the file list. \begin{DoxyReturn}{Returns} The list of the files in the archive, or, more precisely, the list of the entries, including both files and directories if they are present separately. \end{DoxyReturn} OK Restituisce la lista dei file resenti nel file compresso fileCompressed. Se la funzione fallisce, restituisce un elenco vuoto. La funzione fallisce se: $\ast$ non si riesce ad aprire l'oggetto zip; $\ast$ la richiesta di informazioni di un file fallisce; $\ast$ non si riesce a chiudere l'oggetto zip; References QuaZip::close(), QuaZip::getCurrentFileInfo(), QuaZip::getZipError(), QuaZip::goToFirstFile(), QuaZip::goToNextFile(), QuaZip::mdUnzip, QuaZipFileInfo::name, and QuaZip::open(). Referenced by extractDir(). The documentation for this class was generated from the following files:\begin{DoxyCompactItemize} \item quazip/JlCompress.h\item quazip/JlCompress.cpp\end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaCrc32.tex0000644000175000017500000000713312070466513023215 0ustar csmallcsmall\section{QuaCrc32 Class Reference} \label{classQuaCrc32}\index{QuaCrc32@{QuaCrc32}} CRC32 checksum. {\ttfamily \#include $<$quazip/quacrc32.h$>$} Inheritance diagram for QuaCrc32: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=136pt]{classQuaCrc32__inherit__graph} \end{center} \end{figure} Collaboration diagram for QuaCrc32: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=136pt]{classQuaCrc32__coll__graph} \end{center} \end{figure} \subsection*{Public Member Functions} \begin{DoxyCompactItemize} \item quint32 {\bf calculate} (const QByteArray \&data) \begin{DoxyCompactList}\small\item\em Calculates the checksum for data. \end{DoxyCompactList}\item void {\bf reset} ()\label{classQuaCrc32_a3fe7ce6cb73512c963ffaabfbbc66363} \begin{DoxyCompactList}\small\item\em Resets the calculation on a checksun for a stream. \end{DoxyCompactList}\item void {\bf update} (const QByteArray \&buf) \begin{DoxyCompactList}\small\item\em Updates the calculated checksum for the stream. \end{DoxyCompactList}\item quint32 {\bf value} () \begin{DoxyCompactList}\small\item\em Value of the checksum calculated for the stream passed throw \doxyref{update()}{p.}{classQuaCrc32_a5015d80e04afe6e6d094155b7e99888e}. \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection{Detailed Description} CRC32 checksum. This class wrappers the crc32 function with the \doxyref{QuaChecksum32}{p.}{classQuaChecksum32} interface. See \doxyref{QuaChecksum32}{p.}{classQuaChecksum32} for more info. \subsection{Member Function Documentation} \index{QuaCrc32@{QuaCrc32}!calculate@{calculate}} \index{calculate@{calculate}!QuaCrc32@{QuaCrc32}} \subsubsection[{calculate}]{\setlength{\rightskip}{0pt plus 5cm}quint32 QuaCrc32::calculate ( \begin{DoxyParamCaption} \item[{const QByteArray \&}]{data} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaCrc32_aaf6fdf6e36e55c97bf9eab6ec65ecb9e} Calculates the checksum for data. {\itshape data\/} source data \begin{DoxyReturn}{Returns} data checksum \end{DoxyReturn} This function has no efect on the value returned by \doxyref{value()}{p.}{classQuaCrc32_a957ce46a53862f75c89d6a3ac4f73389}. Implements {\bf QuaChecksum32} \doxyref{}{p.}{classQuaChecksum32_a14d800fcfd55b2ae11ef07d3924fe0b1}. \index{QuaCrc32@{QuaCrc32}!update@{update}} \index{update@{update}!QuaCrc32@{QuaCrc32}} \subsubsection[{update}]{\setlength{\rightskip}{0pt plus 5cm}void QuaCrc32::update ( \begin{DoxyParamCaption} \item[{const QByteArray \&}]{buf} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaCrc32_a5015d80e04afe6e6d094155b7e99888e} Updates the calculated checksum for the stream. {\itshape buf\/} next portion of data from the stream Implements {\bf QuaChecksum32} \doxyref{}{p.}{classQuaChecksum32_a63a6ed3171f9243214d307da67557f7e}. \index{QuaCrc32@{QuaCrc32}!value@{value}} \index{value@{value}!QuaCrc32@{QuaCrc32}} \subsubsection[{value}]{\setlength{\rightskip}{0pt plus 5cm}quint32 QuaCrc32::value ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaCrc32_a957ce46a53862f75c89d6a3ac4f73389} Value of the checksum calculated for the stream passed throw \doxyref{update()}{p.}{classQuaCrc32_a5015d80e04afe6e6d094155b7e99888e}. \begin{DoxyReturn}{Returns} checksum \end{DoxyReturn} Implements {\bf QuaChecksum32} \doxyref{}{p.}{classQuaChecksum32_afd836e7534194fce08356be6a8336da7}. The documentation for this class was generated from the following files:\begin{DoxyCompactItemize} \item quazip/quacrc32.h\item quazip/quacrc32.cpp\end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/faq.tex0000644000175000017500000000151212070466513021406 0ustar csmallcsmall\label{faq_faq-non-QIODevice} Q. Is there any way to use \doxyref{QuaZipFile}{p.}{classQuaZipFile} in Qt where you are supposed to use normal (non-\/zipped) file, but not through QIODevice API? A. Usually not. For example, if you are passing file name to some database driver (like SQLite), Qt usually just passes this name down to the 3rd-\/party library, which is usually does not know anything about QIODevice and therefore there is no way to pass \doxyref{QuaZipFile}{p.}{classQuaZipFile} as normal file. However, if we are talking about some place where you pass file name, and then indirectly use QFile to open it, then it is a good idea to make overloaded method, which accepts QIODevice pointer. Then you would be able to pass \doxyref{QuaZipFile}{p.}{classQuaZipFile} as well as many other nice things such as QBuffer or QProcess. mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZipPrivate__coll__graph.md50000644000175000017500000000004012070466513027001 0ustar csmallcsmall03e89dfdd147054460a64a46c1bdc9c2mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaCrc32__coll__graph.md50000644000175000017500000000004012070466513025560 0ustar csmallcsmall494c6ee53c032c90c71e084fc73592f9mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZipFile.tex0000644000175000017500000011250012070466513023676 0ustar csmallcsmall\section{QuaZipFile Class Reference} \label{classQuaZipFile}\index{QuaZipFile@{QuaZipFile}} A file inside ZIP archive. {\ttfamily \#include $<$quazip/quazipfile.h$>$} Collaboration diagram for QuaZipFile: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=231pt]{classQuaZipFile__coll__graph} \end{center} \end{figure} \subsection*{Public Member Functions} \begin{DoxyCompactItemize} \item {\bf QuaZipFile} () \begin{DoxyCompactList}\small\item\em Constructs a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. \end{DoxyCompactList}\item {\bf QuaZipFile} (QObject $\ast$parent) \begin{DoxyCompactList}\small\item\em Constructs a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. \end{DoxyCompactList}\item {\bf QuaZipFile} (const QString \&zipName, QObject $\ast$parent=NULL) \begin{DoxyCompactList}\small\item\em Constructs a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. \end{DoxyCompactList}\item {\bf QuaZipFile} (const QString \&zipName, const QString \&fileName, {\bf QuaZip::CaseSensitivity} cs=QuaZip::csDefault, QObject $\ast$parent=NULL) \begin{DoxyCompactList}\small\item\em Constructs a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. \end{DoxyCompactList}\item {\bf QuaZipFile} ({\bf QuaZip} $\ast$zip, QObject $\ast$parent=NULL) \begin{DoxyCompactList}\small\item\em Constructs a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. \end{DoxyCompactList}\item virtual {\bf $\sim$QuaZipFile} () \begin{DoxyCompactList}\small\item\em Destroys a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. \end{DoxyCompactList}\item QString {\bf getZipName} () const \begin{DoxyCompactList}\small\item\em Returns the ZIP archive file name. \end{DoxyCompactList}\item {\bf QuaZip} $\ast$ {\bf getZip} () const \begin{DoxyCompactList}\small\item\em Returns a pointer to the associated \doxyref{QuaZip}{p.}{classQuaZip} object. \end{DoxyCompactList}\item QString {\bf getFileName} () const \begin{DoxyCompactList}\small\item\em Returns file name. \end{DoxyCompactList}\item {\bf QuaZip::CaseSensitivity} {\bf getCaseSensitivity} () const \begin{DoxyCompactList}\small\item\em Returns case sensitivity of the file name. \end{DoxyCompactList}\item QString {\bf getActualFileName} () const \begin{DoxyCompactList}\small\item\em Returns the actual file name in the archive. \end{DoxyCompactList}\item void {\bf setZipName} (const QString \&zipName) \begin{DoxyCompactList}\small\item\em Sets the ZIP archive file name. \end{DoxyCompactList}\item bool {\bf isRaw} () const \begin{DoxyCompactList}\small\item\em Returns {\ttfamily true} if the file was opened in raw mode. \end{DoxyCompactList}\item void {\bf setZip} ({\bf QuaZip} $\ast$zip) \begin{DoxyCompactList}\small\item\em Binds to the existing \doxyref{QuaZip}{p.}{classQuaZip} instance. \end{DoxyCompactList}\item void {\bf setFileName} (const QString \&fileName, {\bf QuaZip::CaseSensitivity} cs=QuaZip::csDefault) \begin{DoxyCompactList}\small\item\em Sets the file name. \end{DoxyCompactList}\item virtual bool {\bf open} (OpenMode mode) \begin{DoxyCompactList}\small\item\em Opens a file for reading. \end{DoxyCompactList}\item bool {\bf open} (OpenMode mode, const char $\ast$password) \begin{DoxyCompactList}\small\item\em Opens a file for reading. \end{DoxyCompactList}\item bool {\bf open} (OpenMode mode, int $\ast$method, int $\ast$level, bool raw, const char $\ast$password=NULL) \begin{DoxyCompactList}\small\item\em Opens a file for reading. \end{DoxyCompactList}\item bool {\bf open} (OpenMode mode, const {\bf QuaZipNewInfo} \&info, const char $\ast$password=NULL, quint32 crc=0, int method=Z\_\-DEFLATED, int level=Z\_\-DEFAULT\_\-COMPRESSION, bool raw=false, int windowBits=-\/MAX\_\-WBITS, int memLevel=DEF\_\-MEM\_\-LEVEL, int strategy=Z\_\-DEFAULT\_\-STRATEGY) \begin{DoxyCompactList}\small\item\em Opens a file for writing. \end{DoxyCompactList}\item virtual bool {\bf isSequential} () const \label{classQuaZipFile_a64430ec50820c8096f963a7e5f53001f} \begin{DoxyCompactList}\small\item\em Returns {\ttfamily true}, but \doxyref{beware}{p.}{classQuaZipFile_quazipfile-sequential}! \end{DoxyCompactList}\item virtual qint64 {\bf pos} () const \begin{DoxyCompactList}\small\item\em Returns current position in the file. \end{DoxyCompactList}\item virtual bool {\bf atEnd} () const \begin{DoxyCompactList}\small\item\em Returns {\ttfamily true} if the end of file was reached. \end{DoxyCompactList}\item virtual qint64 {\bf size} () const \begin{DoxyCompactList}\small\item\em Returns file size. \end{DoxyCompactList}\item qint64 {\bf csize} () const \begin{DoxyCompactList}\small\item\em Returns compressed file size. \end{DoxyCompactList}\item qint64 {\bf usize} () const \begin{DoxyCompactList}\small\item\em Returns uncompressed file size. \end{DoxyCompactList}\item bool {\bf getFileInfo} ({\bf QuaZipFileInfo} $\ast$info) \begin{DoxyCompactList}\small\item\em Gets information about current file. \end{DoxyCompactList}\item virtual void {\bf close} () \begin{DoxyCompactList}\small\item\em Closes the file. \end{DoxyCompactList}\item int {\bf getZipError} () const \label{classQuaZipFile_a26d2ee56aad947193b73052f80597ef0} \begin{DoxyCompactList}\small\item\em Returns the error code returned by the last ZIP/UNZIP API call. \end{DoxyCompactList}\item virtual qint64 {\bf bytesAvailable} () const \label{classQuaZipFile_a29fbfb34677f69394ae7c986ffd3a0c1} \begin{DoxyCompactList}\small\item\em Returns the number of bytes available for reading. \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection*{Protected Member Functions} \begin{DoxyCompactItemize} \item qint64 {\bf readData} (char $\ast$data, qint64 maxSize)\label{classQuaZipFile_aa1f2274e1579327855a17d67a9046ec2} \begin{DoxyCompactList}\small\item\em Implementation of the QIODevice::readData(). \end{DoxyCompactList}\item qint64 {\bf writeData} (const char $\ast$data, qint64 maxSize)\label{classQuaZipFile_abd07949a6fcc2ef094d2be5398bc8e7c} \begin{DoxyCompactList}\small\item\em Implementation of the QIODevice::writeData(). \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection*{Friends} \begin{DoxyCompactItemize} \item class {\bf QuaZipFilePrivate}\label{classQuaZipFile_abeded291f2788ca39fe2256d78f95266} \end{DoxyCompactItemize} \subsection{Detailed Description} A file inside ZIP archive. This is the most interesting class. Not only it provides C++ interface to the ZIP/UNZIP package, but also integrates it with Qt by subclassing QIODevice. This makes possible to access files inside ZIP archive using QTextStream or QDataStream, for example. Actually, this is the main purpose of the whole QuaZIP library. You can either use existing \doxyref{QuaZip}{p.}{classQuaZip} instance to create instance of this class or pass ZIP archive file name to this class, in which case it will create internal \doxyref{QuaZip}{p.}{classQuaZip} object. See constructors' descriptions for details. Writing is only possible with the existing instance. Note that due to the underlying library's limitation it is not possible to use multiple \doxyref{QuaZipFile}{p.}{classQuaZipFile} instances to open several files in the same archive at the same time. If you need to write to multiple files in parallel, then you should write to temporary files first, then pack them all at once when you have finished writing. If you need to read multiple files inside the same archive in parallel, you should extract them all into a temporary directory first.\subsection{Sequential or random-\/access?}\label{classQuaZipFile_quazipfile-sequential} At the first thought, \doxyref{QuaZipFile}{p.}{classQuaZipFile} has fixed size, the start and the end and should be therefore considered random-\/access device. But there is one major obstacle to making it random-\/access: ZIP/UNZIP API does not support seek() operation and the only way to implement it is through reopening the file and re-\/reading to the required position, but this is prohibitively slow. Therefore, \doxyref{QuaZipFile}{p.}{classQuaZipFile} is considered to be a sequential device. This has advantage of availability of the ungetChar() operation (QIODevice does not implement it properly for non-\/sequential devices unless they support seek()). Disadvantage is a somewhat strange behaviour of the \doxyref{size()}{p.}{classQuaZipFile_ad1a17cc690a01c3edfb82984c3a4c8f0} and \doxyref{pos()}{p.}{classQuaZipFile_a90fd55dab83eca7f95df50b2c41b7f22} functions. This should be kept in mind while using this class. \subsection{Constructor \& Destructor Documentation} \index{QuaZipFile@{QuaZipFile}!QuaZipFile@{QuaZipFile}} \index{QuaZipFile@{QuaZipFile}!QuaZipFile@{QuaZipFile}} \subsubsection[{QuaZipFile}]{\setlength{\rightskip}{0pt plus 5cm}QuaZipFile::QuaZipFile ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )}\label{classQuaZipFile_ad31592e0e8a9eaa009c6c0e2040a2158} Constructs a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. You should use \doxyref{setZipName()}{p.}{classQuaZipFile_ac8109e9a5c19bea75982ff6986b5cb1e} and \doxyref{setFileName()}{p.}{classQuaZipFile_a3732ca7704379d457b6a27db8837de95} or \doxyref{setZip()}{p.}{classQuaZipFile_ab7939a26d1e8de2f6aca54f49a12b980} before trying to call \doxyref{open()}{p.}{classQuaZipFile_a4c20c0ef00ae79c9a59eafe2906c9384} on the constructed object. \index{QuaZipFile@{QuaZipFile}!QuaZipFile@{QuaZipFile}} \index{QuaZipFile@{QuaZipFile}!QuaZipFile@{QuaZipFile}} \subsubsection[{QuaZipFile}]{\setlength{\rightskip}{0pt plus 5cm}QuaZipFile::QuaZipFile ( \begin{DoxyParamCaption} \item[{QObject $\ast$}]{parent} \end{DoxyParamCaption} )}\label{classQuaZipFile_a1349ad27f1947bc3e346d83dbf9586c4} Constructs a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. {\itshape parent\/} argument specifies this object's parent object. You should use \doxyref{setZipName()}{p.}{classQuaZipFile_ac8109e9a5c19bea75982ff6986b5cb1e} and \doxyref{setFileName()}{p.}{classQuaZipFile_a3732ca7704379d457b6a27db8837de95} or \doxyref{setZip()}{p.}{classQuaZipFile_ab7939a26d1e8de2f6aca54f49a12b980} before trying to call \doxyref{open()}{p.}{classQuaZipFile_a4c20c0ef00ae79c9a59eafe2906c9384} on the constructed object. \index{QuaZipFile@{QuaZipFile}!QuaZipFile@{QuaZipFile}} \index{QuaZipFile@{QuaZipFile}!QuaZipFile@{QuaZipFile}} \subsubsection[{QuaZipFile}]{\setlength{\rightskip}{0pt plus 5cm}QuaZipFile::QuaZipFile ( \begin{DoxyParamCaption} \item[{const QString \&}]{zipName, } \item[{QObject $\ast$}]{parent = {\ttfamily NULL}} \end{DoxyParamCaption} )}\label{classQuaZipFile_ae614495d6b2404a6c59d7cfca5c3f6fd} Constructs a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. {\itshape parent\/} argument specifies this object's parent object and {\itshape zipName\/} specifies ZIP archive file name. You should use \doxyref{setFileName()}{p.}{classQuaZipFile_a3732ca7704379d457b6a27db8837de95} before trying to call \doxyref{open()}{p.}{classQuaZipFile_a4c20c0ef00ae79c9a59eafe2906c9384} on the constructed object. \doxyref{QuaZipFile}{p.}{classQuaZipFile} constructed by this constructor can be used for read only access. Use \doxyref{QuaZipFile(QuaZip$\ast$,QObject$\ast$)}{p.}{classQuaZipFile_a54e944a6b3d27030f64c8f30d2cc33bb} for writing. \index{QuaZipFile@{QuaZipFile}!QuaZipFile@{QuaZipFile}} \index{QuaZipFile@{QuaZipFile}!QuaZipFile@{QuaZipFile}} \subsubsection[{QuaZipFile}]{\setlength{\rightskip}{0pt plus 5cm}QuaZipFile::QuaZipFile ( \begin{DoxyParamCaption} \item[{const QString \&}]{zipName, } \item[{const QString \&}]{fileName, } \item[{{\bf QuaZip::CaseSensitivity}}]{cs = {\ttfamily QuaZip::csDefault}, } \item[{QObject $\ast$}]{parent = {\ttfamily NULL}} \end{DoxyParamCaption} )}\label{classQuaZipFile_ac6e883b5a5d3a58c9c56eb497dd91220} Constructs a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. {\itshape parent\/} argument specifies this object's parent object, {\itshape zipName\/} specifies ZIP archive file name and {\itshape fileName\/} and {\itshape cs\/} specify a name of the file to open inside archive. \doxyref{QuaZipFile}{p.}{classQuaZipFile} constructed by this constructor can be used for read only access. Use \doxyref{QuaZipFile(QuaZip$\ast$,QObject$\ast$)}{p.}{classQuaZipFile_a54e944a6b3d27030f64c8f30d2cc33bb} for writing. \begin{DoxySeeAlso}{See also} \doxyref{QuaZip::setCurrentFile()}{p.}{classQuaZip_a6c657bfcfccb59d728e0da24c677d899} \end{DoxySeeAlso} \index{QuaZipFile@{QuaZipFile}!QuaZipFile@{QuaZipFile}} \index{QuaZipFile@{QuaZipFile}!QuaZipFile@{QuaZipFile}} \subsubsection[{QuaZipFile}]{\setlength{\rightskip}{0pt plus 5cm}QuaZipFile::QuaZipFile ( \begin{DoxyParamCaption} \item[{{\bf QuaZip} $\ast$}]{zip, } \item[{QObject $\ast$}]{parent = {\ttfamily NULL}} \end{DoxyParamCaption} )}\label{classQuaZipFile_a54e944a6b3d27030f64c8f30d2cc33bb} Constructs a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. {\itshape parent\/} argument specifies this object's parent object. {\itshape zip\/} is the pointer to the existing \doxyref{QuaZip}{p.}{classQuaZip} object. This \doxyref{QuaZipFile}{p.}{classQuaZipFile} object then can be used to read current file in the {\itshape zip\/} or to write to the file inside it. \begin{DoxyWarning}{Warning} Using this constructor for reading current file can be tricky. Let's take the following example: \begin{DoxyCode} QuaZip zip("archive.zip"); zip.open(QuaZip::mdUnzip); zip.setCurrentFile("file-in-archive"); QuaZipFile file(&zip); file.open(QIODevice::ReadOnly); // ok, now we can read from the file file.read(somewhere, some); zip.setCurrentFile("another-file-in-archive"); // oops... QuaZipFile anotherFile(&zip); anotherFile.open(QIODevice::ReadOnly); anotherFile.read(somewhere, some); // this is still ok... file.read(somewhere, some); // and this is NOT \end{DoxyCode} So, what exactly happens here? When we change current file in the {\ttfamily zip} archive, {\ttfamily file} that references it becomes invalid (actually, as far as I understand ZIP/UNZIP sources, it becomes closed, but \doxyref{QuaZipFile}{p.}{classQuaZipFile} has no means to detect it). \end{DoxyWarning} Summary: do not close {\ttfamily zip} object or change its current file as long as \doxyref{QuaZipFile}{p.}{classQuaZipFile} is open. Even better -\/ use another constructors which create internal \doxyref{QuaZip}{p.}{classQuaZip} instances, one per object, and therefore do not cause unnecessary trouble. This constructor may be useful, though, if you already have a \doxyref{QuaZip}{p.}{classQuaZip} instance and do not want to access several files at once. Good example: \begin{DoxyCode} QuaZip zip("archive.zip"); zip.open(QuaZip::mdUnzip); // first, we need some information about archive itself QByteArray comment=zip.getComment(); // and now we are going to access files inside it QuaZipFile file(&zip); for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { file.open(QIODevice::ReadOnly); // do something cool with file here file.close(); // do not forget to close! } zip.close(); \end{DoxyCode} \index{QuaZipFile@{QuaZipFile}!$\sim$QuaZipFile@{$\sim$QuaZipFile}} \index{$\sim$QuaZipFile@{$\sim$QuaZipFile}!QuaZipFile@{QuaZipFile}} \subsubsection[{$\sim$QuaZipFile}]{\setlength{\rightskip}{0pt plus 5cm}QuaZipFile::$\sim$QuaZipFile ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaZipFile_aa1e5a0cf491bafae6cc73e649caa97fc} Destroys a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance. Closes file if open, destructs internal \doxyref{QuaZip}{p.}{classQuaZip} object (if it exists and {\itshape is\/} internal, of course). References close(). \subsection{Member Function Documentation} \index{QuaZipFile@{QuaZipFile}!getZipName@{getZipName}} \index{getZipName@{getZipName}!QuaZipFile@{QuaZipFile}} \subsubsection[{getZipName}]{\setlength{\rightskip}{0pt plus 5cm}QString QuaZipFile::getZipName ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZipFile_a6f034a714aa94631367590de3f8f4e22} Returns the ZIP archive file name. If this object was created by passing \doxyref{QuaZip}{p.}{classQuaZip} pointer to the constructor, this function will return that QuaZip's file name (or null string if that object does not have file name yet). Otherwise, returns associated ZIP archive file name or null string if there are no name set yet. \begin{DoxySeeAlso}{See also} \doxyref{setZipName()}{p.}{classQuaZipFile_ac8109e9a5c19bea75982ff6986b5cb1e} \doxyref{getFileName()}{p.}{classQuaZipFile_a6999362e70a5b2396fba5cfb30095ff9} \end{DoxySeeAlso} References QuaZip::getZipName(). \index{QuaZipFile@{QuaZipFile}!getZip@{getZip}} \index{getZip@{getZip}!QuaZipFile@{QuaZipFile}} \subsubsection[{getZip}]{\setlength{\rightskip}{0pt plus 5cm}{\bf QuaZip} $\ast$ QuaZipFile::getZip ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZipFile_a72daf8a9da14907a801a783603003205} Returns a pointer to the associated \doxyref{QuaZip}{p.}{classQuaZip} object. Returns {\ttfamily NULL} if there is no associated \doxyref{QuaZip}{p.}{classQuaZip} or it is internal (so you will not mess with it). \index{QuaZipFile@{QuaZipFile}!getFileName@{getFileName}} \index{getFileName@{getFileName}!QuaZipFile@{QuaZipFile}} \subsubsection[{getFileName}]{\setlength{\rightskip}{0pt plus 5cm}QString QuaZipFile::getFileName ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZipFile_a6999362e70a5b2396fba5cfb30095ff9} Returns file name. This function returns file name you passed to this object either by using \doxyref{QuaZipFile(const QString\&,const QString\&,QuaZip::CaseSensitivity,QObject$\ast$)}{p.}{classQuaZipFile_ac6e883b5a5d3a58c9c56eb497dd91220} or by calling \doxyref{setFileName()}{p.}{classQuaZipFile_a3732ca7704379d457b6a27db8837de95}. Real name of the file may differ in case if you used case-\/insensitivity. Returns null string if there is no file name set yet. This is the case when this \doxyref{QuaZipFile}{p.}{classQuaZipFile} operates on the existing \doxyref{QuaZip}{p.}{classQuaZip} object (constructor \doxyref{QuaZipFile(QuaZip$\ast$,QObject$\ast$)}{p.}{classQuaZipFile_a54e944a6b3d27030f64c8f30d2cc33bb} or \doxyref{setZip()}{p.}{classQuaZipFile_ab7939a26d1e8de2f6aca54f49a12b980} was used). \begin{DoxySeeAlso}{See also} \doxyref{getActualFileName}{p.}{classQuaZipFile_a7b8e3c39026855cd98661a1b2815c220} \end{DoxySeeAlso} \index{QuaZipFile@{QuaZipFile}!getCaseSensitivity@{getCaseSensitivity}} \index{getCaseSensitivity@{getCaseSensitivity}!QuaZipFile@{QuaZipFile}} \subsubsection[{getCaseSensitivity}]{\setlength{\rightskip}{0pt plus 5cm}{\bf QuaZip::CaseSensitivity} QuaZipFile::getCaseSensitivity ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZipFile_a25dbfddc589bf6b69b39905f3c3bcc73} Returns case sensitivity of the file name. This function returns case sensitivity argument you passed to this object either by using \doxyref{QuaZipFile(const QString\&,const QString\&,QuaZip::CaseSensitivity,QObject$\ast$)}{p.}{classQuaZipFile_ac6e883b5a5d3a58c9c56eb497dd91220} or by calling \doxyref{setFileName()}{p.}{classQuaZipFile_a3732ca7704379d457b6a27db8837de95}. Returns unpredictable value if \doxyref{getFileName()}{p.}{classQuaZipFile_a6999362e70a5b2396fba5cfb30095ff9} returns null string (this is the case when you did not used \doxyref{setFileName()}{p.}{classQuaZipFile_a3732ca7704379d457b6a27db8837de95} or constructor above). \begin{DoxySeeAlso}{See also} \doxyref{getFileName}{p.}{classQuaZipFile_a6999362e70a5b2396fba5cfb30095ff9} \end{DoxySeeAlso} \index{QuaZipFile@{QuaZipFile}!getActualFileName@{getActualFileName}} \index{getActualFileName@{getActualFileName}!QuaZipFile@{QuaZipFile}} \subsubsection[{getActualFileName}]{\setlength{\rightskip}{0pt plus 5cm}QString QuaZipFile::getActualFileName ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZipFile_a7b8e3c39026855cd98661a1b2815c220} Returns the actual file name in the archive. This is {\itshape not\/} a ZIP archive file name, but a name of file inside archive. It is not necessary the same name that you have passed to the \doxyref{QuaZipFile(const QString\&,const QString\&,QuaZip::CaseSensitivity,QObject$\ast$)}{p.}{classQuaZipFile_ac6e883b5a5d3a58c9c56eb497dd91220}, \doxyref{setFileName()}{p.}{classQuaZipFile_a3732ca7704379d457b6a27db8837de95} or \doxyref{QuaZip::setCurrentFile()}{p.}{classQuaZip_a6c657bfcfccb59d728e0da24c677d899} -\/ this is the real file name inside archive, so it may differ in case if the file name search was case-\/insensitive. Equivalent to calling getCurrentFileName() on the associated \doxyref{QuaZip}{p.}{classQuaZip} object. Returns null string if there is no associated \doxyref{QuaZip}{p.}{classQuaZip} object or if it does not have a current file yet. And this is the case if you called \doxyref{setFileName()}{p.}{classQuaZipFile_a3732ca7704379d457b6a27db8837de95} but did not open the file yet. So this is perfectly fine: \begin{DoxyCode} QuaZipFile file("somezip.zip"); file.setFileName("somefile"); QString name=file.getName(); // name=="somefile" QString actual=file.getActualFileName(); // actual is null string file.open(QIODevice::ReadOnly); QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows \end{DoxyCode} \begin{DoxySeeAlso}{See also} \doxyref{getZipName()}{p.}{classQuaZipFile_a6f034a714aa94631367590de3f8f4e22}, \doxyref{getFileName()}{p.}{classQuaZipFile_a6999362e70a5b2396fba5cfb30095ff9}, \doxyref{QuaZip::CaseSensitivity}{p.}{classQuaZip_a6053a1d249ed210a85c9d5eb7cf9cdbe} \end{DoxySeeAlso} References QuaZip::getCurrentFileName(), and QuaZip::getZipError(). \index{QuaZipFile@{QuaZipFile}!setZipName@{setZipName}} \index{setZipName@{setZipName}!QuaZipFile@{QuaZipFile}} \subsubsection[{setZipName}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZipFile::setZipName ( \begin{DoxyParamCaption} \item[{const QString \&}]{zipName} \end{DoxyParamCaption} )}\label{classQuaZipFile_ac8109e9a5c19bea75982ff6986b5cb1e} Sets the ZIP archive file name. Automatically creates internal \doxyref{QuaZip}{p.}{classQuaZip} object and destroys previously created internal \doxyref{QuaZip}{p.}{classQuaZip} object, if any. Will do nothing if this file is already open. You must \doxyref{close()}{p.}{classQuaZipFile_a42a39b12619bccd3d419ee60bbb3fcf6} it first. \index{QuaZipFile@{QuaZipFile}!isRaw@{isRaw}} \index{isRaw@{isRaw}!QuaZipFile@{QuaZipFile}} \subsubsection[{isRaw}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZipFile::isRaw ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZipFile_a0df3db94c2a34c8d17ddaa0f54fc32c1} Returns {\ttfamily true} if the file was opened in raw mode. If the file is not open, the returned value is undefined. \begin{DoxySeeAlso}{See also} \doxyref{open(OpenMode,int$\ast$,int$\ast$,bool,const char$\ast$)}{p.}{classQuaZipFile_aed75bace51f2bb4c3e4f656ab4493aac} \end{DoxySeeAlso} Referenced by close(). \index{QuaZipFile@{QuaZipFile}!setZip@{setZip}} \index{setZip@{setZip}!QuaZipFile@{QuaZipFile}} \subsubsection[{setZip}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZipFile::setZip ( \begin{DoxyParamCaption} \item[{{\bf QuaZip} $\ast$}]{zip} \end{DoxyParamCaption} )}\label{classQuaZipFile_ab7939a26d1e8de2f6aca54f49a12b980} Binds to the existing \doxyref{QuaZip}{p.}{classQuaZip} instance. This function destroys internal \doxyref{QuaZip}{p.}{classQuaZip} object, if any, and makes this \doxyref{QuaZipFile}{p.}{classQuaZipFile} to use current file in the {\itshape zip\/} object for any further operations. See \doxyref{QuaZipFile(QuaZip$\ast$,QObject$\ast$)}{p.}{classQuaZipFile_a54e944a6b3d27030f64c8f30d2cc33bb} for the possible pitfalls. Will do nothing if the file is currently open. You must \doxyref{close()}{p.}{classQuaZipFile_a42a39b12619bccd3d419ee60bbb3fcf6} it first. \index{QuaZipFile@{QuaZipFile}!setFileName@{setFileName}} \index{setFileName@{setFileName}!QuaZipFile@{QuaZipFile}} \subsubsection[{setFileName}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZipFile::setFileName ( \begin{DoxyParamCaption} \item[{const QString \&}]{fileName, } \item[{{\bf QuaZip::CaseSensitivity}}]{cs = {\ttfamily QuaZip::csDefault}} \end{DoxyParamCaption} )}\label{classQuaZipFile_a3732ca7704379d457b6a27db8837de95} Sets the file name. Will do nothing if at least one of the following conditions is met: \begin{DoxyItemize} \item ZIP name has not been set yet (\doxyref{getZipName()}{p.}{classQuaZipFile_a6f034a714aa94631367590de3f8f4e22} returns null string). \item This \doxyref{QuaZipFile}{p.}{classQuaZipFile} is associated with external \doxyref{QuaZip}{p.}{classQuaZip}. In this case you should call that QuaZip's setCurrentFile() function instead! \item File is already open so setting the name is meaningless. \end{DoxyItemize} \begin{DoxySeeAlso}{See also} \doxyref{QuaZip::setCurrentFile}{p.}{classQuaZip_a6c657bfcfccb59d728e0da24c677d899} \end{DoxySeeAlso} \index{QuaZipFile@{QuaZipFile}!open@{open}} \index{open@{open}!QuaZipFile@{QuaZipFile}} \subsubsection[{open}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZipFile::open ( \begin{DoxyParamCaption} \item[{OpenMode}]{mode} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaZipFile_a4c20c0ef00ae79c9a59eafe2906c9384} Opens a file for reading. Returns {\ttfamily true} on success, {\ttfamily false} otherwise. Call \doxyref{getZipError()}{p.}{classQuaZipFile_a26d2ee56aad947193b73052f80597ef0} to get error code. \begin{DoxyNote}{Note} Since ZIP/UNZIP API provides buffered reading only, \doxyref{QuaZipFile}{p.}{classQuaZipFile} does not support unbuffered reading. So do not pass QIODevice::Unbuffered flag in {\itshape mode\/}, or open will fail. \end{DoxyNote} \index{QuaZipFile@{QuaZipFile}!open@{open}} \index{open@{open}!QuaZipFile@{QuaZipFile}} \subsubsection[{open}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZipFile::open ( \begin{DoxyParamCaption} \item[{OpenMode}]{mode, } \item[{const char $\ast$}]{password} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [inline]}}\label{classQuaZipFile_a0bff0d15bbcd70306dc4a553a55776b9} Opens a file for reading. This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Argument {\itshape password\/} specifies a password to decrypt the file. If it is NULL then this function behaves just like \doxyref{open(OpenMode)}{p.}{classQuaZipFile_a4c20c0ef00ae79c9a59eafe2906c9384}. References open(). Referenced by open(). \index{QuaZipFile@{QuaZipFile}!open@{open}} \index{open@{open}!QuaZipFile@{QuaZipFile}} \subsubsection[{open}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZipFile::open ( \begin{DoxyParamCaption} \item[{OpenMode}]{mode, } \item[{int $\ast$}]{method, } \item[{int $\ast$}]{level, } \item[{bool}]{raw, } \item[{const char $\ast$}]{password = {\ttfamily NULL}} \end{DoxyParamCaption} )}\label{classQuaZipFile_aed75bace51f2bb4c3e4f656ab4493aac} Opens a file for reading. This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Argument {\itshape password\/} specifies a password to decrypt the file. An integers pointed by {\itshape method\/} and {\itshape level\/} will receive codes of the compression method and level used. See unzip.h. If raw is {\ttfamily true} then no decompression is performed. {\itshape method\/} should not be {\ttfamily NULL}. {\itshape level\/} can be {\ttfamily NULL} if you don't want to know the compression level. References QuaZip::close(), QuaZip::getMode(), QuaZip::getUnzFile(), QuaZip::getZipError(), QuaZip::hasCurrentFile(), QuaZip::mdUnzip, QuaZip::open(), and QuaZip::setCurrentFile(). \index{QuaZipFile@{QuaZipFile}!open@{open}} \index{open@{open}!QuaZipFile@{QuaZipFile}} \subsubsection[{open}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZipFile::open ( \begin{DoxyParamCaption} \item[{OpenMode}]{mode, } \item[{const {\bf QuaZipNewInfo} \&}]{info, } \item[{const char $\ast$}]{password = {\ttfamily NULL}, } \item[{quint32}]{crc = {\ttfamily 0}, } \item[{int}]{method = {\ttfamily Z\_\-DEFLATED}, } \item[{int}]{level = {\ttfamily Z\_\-DEFAULT\_\-COMPRESSION}, } \item[{bool}]{raw = {\ttfamily false}, } \item[{int}]{windowBits = {\ttfamily -\/MAX\_\-WBITS}, } \item[{int}]{memLevel = {\ttfamily DEF\_\-MEM\_\-LEVEL}, } \item[{int}]{strategy = {\ttfamily Z\_\-DEFAULT\_\-STRATEGY}} \end{DoxyParamCaption} )}\label{classQuaZipFile_a2429ea59c77371d7af56d739db130b18} Opens a file for writing. {\itshape info\/} argument specifies information about file. It should at least specify a correct file name. Also, it is a good idea to specify correct timestamp (by default, current time will be used). See \doxyref{QuaZipNewInfo}{p.}{structQuaZipNewInfo}. The {\itshape password\/} argument specifies the password for crypting. Pass NULL if you don't need any crypting. The {\itshape crc\/} argument was supposed to be used for crypting too, but then it turned out that it's false information, so you need to set it to 0 unless you want to use the raw mode (see below). Arguments {\itshape method\/} and {\itshape level\/} specify compression method and level. The only method supported is Z\_\-DEFLATED, but you may also specify 0 for no compression. If all of the files in the archive use both method 0 and either level 0 is explicitly specified or data descriptor writing is disabled with \doxyref{QuaZip::setDataDescriptorWritingEnabled()}{p.}{classQuaZip_a6c23a12af88f7ea5edd4f9c0a24b9453}, then the resulting archive is supposed to be compatible with the 1.0 ZIP format version, should you need that. Except for this, {\itshape level\/} has no other effects with method 0. If {\itshape raw\/} is {\ttfamily true}, no compression is performed. In this case, {\itshape crc\/} and uncompressedSize field of the {\itshape info\/} are required. Arguments {\itshape windowBits\/}, {\itshape memLevel\/}, {\itshape strategy\/} provide zlib algorithms tuning. See deflateInit2() in zlib. References QuaZipNewInfo::comment, QuaZipNewInfo::dateTime, QuaZipNewInfo::externalAttr, QuaZipNewInfo::extraGlobal, QuaZipNewInfo::extraLocal, QuaZip::getCommentCodec(), QuaZip::getFileNameCodec(), QuaZip::getMode(), QuaZip::getZipFile(), QuaZipNewInfo::internalAttr, QuaZip::isDataDescriptorWritingEnabled(), QuaZip::mdAdd, QuaZip::mdAppend, QuaZip::mdCreate, QuaZipNewInfo::name, and QuaZipNewInfo::uncompressedSize. \index{QuaZipFile@{QuaZipFile}!pos@{pos}} \index{pos@{pos}!QuaZipFile@{QuaZipFile}} \subsubsection[{pos}]{\setlength{\rightskip}{0pt plus 5cm}qint64 QuaZipFile::pos ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaZipFile_a90fd55dab83eca7f95df50b2c41b7f22} Returns current position in the file. Implementation of the QIODevice::pos(). When reading, this function is a wrapper to the ZIP/UNZIP unztell(), therefore it is unable to keep track of the ungetChar() calls (which is non-\/virtual and therefore is dangerous to reimplement). So if you are using ungetChar() feature of the QIODevice, this function reports incorrect value until you get back characters which you ungot. When writing, \doxyref{pos()}{p.}{classQuaZipFile_a90fd55dab83eca7f95df50b2c41b7f22} returns number of bytes already written (uncompressed unless you use raw mode). \begin{DoxyNote}{Note} Although \doxyref{QuaZipFile is a sequential device}{p.}{classQuaZipFile_quazipfile-sequential} and therefore \doxyref{pos()}{p.}{classQuaZipFile_a90fd55dab83eca7f95df50b2c41b7f22} should always return zero, it does not, because it would be misguiding. Keep this in mind. \end{DoxyNote} This function returns -\/1 if the file or archive is not open. Error code returned by \doxyref{getZipError()}{p.}{classQuaZipFile_a26d2ee56aad947193b73052f80597ef0} is not affected by this function call. References QuaZip::getUnzFile(). Referenced by bytesAvailable(). \index{QuaZipFile@{QuaZipFile}!atEnd@{atEnd}} \index{atEnd@{atEnd}!QuaZipFile@{QuaZipFile}} \subsubsection[{atEnd}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZipFile::atEnd ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaZipFile_a1e3f4c3c075da98af426fc167440cfc3} Returns {\ttfamily true} if the end of file was reached. This function returns {\ttfamily false} in the case of error. This means that you called this function on either not open file, or a file in the not open archive or even on a \doxyref{QuaZipFile}{p.}{classQuaZipFile} instance that does not even have \doxyref{QuaZip}{p.}{classQuaZip} instance associated. Do not do that because there is no means to determine whether {\ttfamily false} is returned because of error or because end of file was reached. Well, on the other side you may interpret {\ttfamily false} return value as \char`\"{}there is no file open to check for end of file and there is no end of file therefore\char`\"{}. When writing, this function always returns {\ttfamily true} (because you are always writing to the end of file). Error code returned by \doxyref{getZipError()}{p.}{classQuaZipFile_a26d2ee56aad947193b73052f80597ef0} is not affected by this function call. References bytesAvailable(), and QuaZip::getUnzFile(). \index{QuaZipFile@{QuaZipFile}!size@{size}} \index{size@{size}!QuaZipFile@{QuaZipFile}} \subsubsection[{size}]{\setlength{\rightskip}{0pt plus 5cm}qint64 QuaZipFile::size ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaZipFile_ad1a17cc690a01c3edfb82984c3a4c8f0} Returns file size. This function returns \doxyref{csize()}{p.}{classQuaZipFile_ac4da08e5cdec368a2a686775f7dc5639} if the file is open for reading in raw mode, \doxyref{usize()}{p.}{classQuaZipFile_a4814b5e6e39fb254737b81ea10964f50} if it is open for reading in normal mode and \doxyref{pos()}{p.}{classQuaZipFile_a90fd55dab83eca7f95df50b2c41b7f22} if it is open for writing. Returns -\/1 on error, call \doxyref{getZipError()}{p.}{classQuaZipFile_a26d2ee56aad947193b73052f80597ef0} to get error code. \begin{DoxyNote}{Note} This function returns file size despite that \doxyref{QuaZipFile is considered to be sequential device}{p.}{classQuaZipFile_quazipfile-sequential}, for which \doxyref{size()}{p.}{classQuaZipFile_ad1a17cc690a01c3edfb82984c3a4c8f0} should return \doxyref{bytesAvailable()}{p.}{classQuaZipFile_a29fbfb34677f69394ae7c986ffd3a0c1} instead. But its name would be very misguiding otherwise, so just keep in mind this inconsistence. \end{DoxyNote} References csize(), and usize(). Referenced by bytesAvailable(). \index{QuaZipFile@{QuaZipFile}!csize@{csize}} \index{csize@{csize}!QuaZipFile@{QuaZipFile}} \subsubsection[{csize}]{\setlength{\rightskip}{0pt plus 5cm}qint64 QuaZipFile::csize ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZipFile_ac4da08e5cdec368a2a686775f7dc5639} Returns compressed file size. Equivalent to calling \doxyref{getFileInfo()}{p.}{classQuaZipFile_ad3f5807329321be21b12c1ba5798b359} and then getting compressedSize field, but more convenient and faster. File must be open for reading before calling this function. Returns -\/1 on error, call \doxyref{getZipError()}{p.}{classQuaZipFile_a26d2ee56aad947193b73052f80597ef0} to get error code. References QuaZip::getMode(), QuaZip::getUnzFile(), and QuaZip::mdUnzip. Referenced by size(). \index{QuaZipFile@{QuaZipFile}!usize@{usize}} \index{usize@{usize}!QuaZipFile@{QuaZipFile}} \subsubsection[{usize}]{\setlength{\rightskip}{0pt plus 5cm}qint64 QuaZipFile::usize ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} ) const}\label{classQuaZipFile_a4814b5e6e39fb254737b81ea10964f50} Returns uncompressed file size. Equivalent to calling \doxyref{getFileInfo()}{p.}{classQuaZipFile_ad3f5807329321be21b12c1ba5798b359} and then getting uncompressedSize field, but more convenient and faster. See \doxyref{getFileInfo()}{p.}{classQuaZipFile_ad3f5807329321be21b12c1ba5798b359} for a warning. File must be open for reading before calling this function. Returns -\/1 on error, call \doxyref{getZipError()}{p.}{classQuaZipFile_a26d2ee56aad947193b73052f80597ef0} to get error code. References QuaZip::getMode(), QuaZip::getUnzFile(), and QuaZip::mdUnzip. Referenced by size(). \index{QuaZipFile@{QuaZipFile}!getFileInfo@{getFileInfo}} \index{getFileInfo@{getFileInfo}!QuaZipFile@{QuaZipFile}} \subsubsection[{getFileInfo}]{\setlength{\rightskip}{0pt plus 5cm}bool QuaZipFile::getFileInfo ( \begin{DoxyParamCaption} \item[{{\bf QuaZipFileInfo} $\ast$}]{info} \end{DoxyParamCaption} )}\label{classQuaZipFile_ad3f5807329321be21b12c1ba5798b359} Gets information about current file. This function does the same thing as calling \doxyref{QuaZip::getCurrentFileInfo()}{p.}{classQuaZip_a9c91a53ed4c2038e153c64bdc097ebe8} on the associated \doxyref{QuaZip}{p.}{classQuaZip} object, but you can not call getCurrentFileInfo() if the associated \doxyref{QuaZip}{p.}{classQuaZip} is internal (because you do not have access to it), while you still can call this function in that case. File must be open for reading before calling this function. Returns {\ttfamily false} in the case of an error. References QuaZip::getCurrentFileInfo(), QuaZip::getMode(), QuaZip::getZipError(), and QuaZip::mdUnzip. \index{QuaZipFile@{QuaZipFile}!close@{close}} \index{close@{close}!QuaZipFile@{QuaZipFile}} \subsubsection[{close}]{\setlength{\rightskip}{0pt plus 5cm}void QuaZipFile::close ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaZipFile_a42a39b12619bccd3d419ee60bbb3fcf6} Closes the file. Call \doxyref{getZipError()}{p.}{classQuaZipFile_a26d2ee56aad947193b73052f80597ef0} to determine if the close was successful. References QuaZip::close(), QuaZip::getUnzFile(), QuaZip::getZipError(), QuaZip::getZipFile(), QuaZip::isOpen(), and isRaw(). Referenced by $\sim$QuaZipFile(). The documentation for this class was generated from the following files:\begin{DoxyCompactItemize} \item quazip/quazipfile.h\item quazip/quazipfile.cpp\end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZipPrivate__coll__graph.eps0000644000175000017500000001330212070466513027110 0ustar csmallcsmall%!PS-Adobe-3.0 %%Creator: graphviz version 2.28.0 (20110507.0327) %%Title: G %%Pages: (atend) %%BoundingBox: (atend) %%EndComments save %%BeginProlog /DotDict 200 dict def DotDict begin /setupLatin1 { mark /EncodingVector 256 array def EncodingVector 0 ISOLatin1Encoding 0 255 getinterval putinterval EncodingVector 45 /hyphen put % Set up ISO Latin 1 character encoding /starnetISO { dup dup findfont dup length dict begin { 1 index /FID ne { def }{ pop pop } ifelse } forall /Encoding EncodingVector def currentdict end definefont } def /Times-Roman starnetISO def /Times-Italic starnetISO def /Times-Bold starnetISO def /Times-BoldItalic starnetISO def /Helvetica starnetISO def /Helvetica-Oblique starnetISO def /Helvetica-Bold starnetISO def /Helvetica-BoldOblique starnetISO def /Courier starnetISO def /Courier-Oblique starnetISO def /Courier-Bold starnetISO def /Courier-BoldOblique starnetISO def cleartomark } bind def %%BeginResource: procset graphviz 0 0 /coord-font-family /Times-Roman def /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def /InvScaleFactor 1.0 def /set_scale { dup 1 exch div /InvScaleFactor exch def scale } bind def % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def /bold { 2 setlinewidth } bind def /filled { } bind def /unfilled { } bind def /rounded { } bind def /diagonals { } bind def % hooks for setting color /nodecolor { sethsbcolor } bind def /edgecolor { sethsbcolor } bind def /graphcolor { sethsbcolor } bind def /nopcolor {pop pop pop} bind def /beginpage { % i j npages /npages exch def /j exch def /i exch def /str 10 string def npages 1 gt { gsave coordfont setfont 0 0 moveto (\() show i str cvs show (,) show j str cvs show (\)) show grestore } if } bind def /set_font { findfont exch scalefont setfont } def % draw text fitted to its expected width /alignedtext { % width text /text exch def /width exch def gsave width 0 gt { [] 0 setdash text stringwidth pop width exch sub text length div 0 text ashow } if grestore } def /boxprim { % xcorner ycorner xsize ysize 4 2 roll moveto 2 copy exch 0 rlineto 0 exch rlineto pop neg 0 rlineto closepath } bind def /ellipse_path { /ry exch def /rx exch def /y exch def /x exch def matrix currentmatrix newpath x y translate rx ry scale 0 0 1 0 360 arc setmatrix } bind def /endpage { showpage } bind def /showpage { } def /layercolorseq [ % layer color sequence - darkest to lightest [0 0 0] [.2 .8 .8] [.4 .8 .8] [.6 .8 .8] [.8 .8 .8] ] def /layerlen layercolorseq length def /setlayer {/maxlayer exch def /curlayer exch def layercolorseq curlayer 1 sub layerlen mod get aload pop sethsbcolor /nodecolor {nopcolor} def /edgecolor {nopcolor} def /graphcolor {nopcolor} def } bind def /onlayer { curlayer ne {invis} if } def /onlayers { /myupper exch def /mylower exch def curlayer mylower lt curlayer myupper gt or {invis} if } def /curlayer 0 def %%EndResource %%EndProlog %%BeginSetup 14 default-font-family set_font 1 setmiterlimit % /arrowlength 10 def % /arrowwidth 5 def % make sure pdfmark is harmless for PS-interpreters other than Distiller /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % make '<<' and '>>' safe on PS Level 1 devices /languagelevel where {pop languagelevel}{1} ifelse 2 lt { userdict (<<) cvn ([) cvn load put userdict (>>) cvn ([) cvn load put } if %%EndSetup setupLatin1 %%Page: 1 1 %%PageBoundingBox: 36 36 120 132 %%PageOrientation: Portrait 0 0 1 beginpage gsave 36 36 84 96 boxprim clip newpath 1 1 set_scale 0 rotate 40 41 translate % Node1 gsave 0 0 0.74902 nodecolor newpath -.5 68.5 moveto -.5 87.5 lineto 76.5 87.5 lineto 76.5 68.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath -.5 68.5 moveto -.5 87.5 lineto 76.5 87.5 lineto 76.5 68.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 7.5 75.5 moveto 61 (QuaZipPrivate) alignedtext grestore % Node2 gsave [ /Rect [ 14.5 0 61 20 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaZip.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 14.5 .5 moveto 14.5 19.5 lineto 61.5 19.5 lineto 61.5 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 14.5 .5 moveto 14.5 19.5 lineto 61.5 19.5 lineto 61.5 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 22.5 7.5 moveto 31 (QuaZip) alignedtext grestore % Node1->Node2 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 30.23 58.65 moveto 29.3 55.8 28.51 52.85 28 50 curveto 26.1 39.4 30.11 27.44 33.6 19.59 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 27.03 60.11 moveto 33.85 68.22 lineto 33.58 57.63 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 27.03 60.11 moveto 33.85 68.22 lineto 33.58 57.63 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 28 41.5 moveto 6 (p) alignedtext grestore % Node2->Node1 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 38 29.85 moveto 38 42.53 38 58.64 38 68.37 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 41.5 29.84 moveto 38 19.84 lineto 34.5 29.84 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 41.5 29.84 moveto 38 19.84 lineto 34.5 29.84 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 38 41.5 moveto 6 (q) alignedtext grestore endpage showpage grestore %%PageTrailer %%EndPage: 1 %%Trailer %%Pages: 1 %%BoundingBox: 36 36 120 132 end restore %%EOF mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaAdler32__inherit__graph.eps0000644000175000017500000001212612070466513026723 0ustar csmallcsmall%!PS-Adobe-3.0 %%Creator: graphviz version 2.28.0 (20110507.0327) %%Title: G %%Pages: (atend) %%BoundingBox: (atend) %%EndComments save %%BeginProlog /DotDict 200 dict def DotDict begin /setupLatin1 { mark /EncodingVector 256 array def EncodingVector 0 ISOLatin1Encoding 0 255 getinterval putinterval EncodingVector 45 /hyphen put % Set up ISO Latin 1 character encoding /starnetISO { dup dup findfont dup length dict begin { 1 index /FID ne { def }{ pop pop } ifelse } forall /Encoding EncodingVector def currentdict end definefont } def /Times-Roman starnetISO def /Times-Italic starnetISO def /Times-Bold starnetISO def /Times-BoldItalic starnetISO def /Helvetica starnetISO def /Helvetica-Oblique starnetISO def /Helvetica-Bold starnetISO def /Helvetica-BoldOblique starnetISO def /Courier starnetISO def /Courier-Oblique starnetISO def /Courier-Bold starnetISO def /Courier-BoldOblique starnetISO def cleartomark } bind def %%BeginResource: procset graphviz 0 0 /coord-font-family /Times-Roman def /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def /InvScaleFactor 1.0 def /set_scale { dup 1 exch div /InvScaleFactor exch def scale } bind def % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def /bold { 2 setlinewidth } bind def /filled { } bind def /unfilled { } bind def /rounded { } bind def /diagonals { } bind def % hooks for setting color /nodecolor { sethsbcolor } bind def /edgecolor { sethsbcolor } bind def /graphcolor { sethsbcolor } bind def /nopcolor {pop pop pop} bind def /beginpage { % i j npages /npages exch def /j exch def /i exch def /str 10 string def npages 1 gt { gsave coordfont setfont 0 0 moveto (\() show i str cvs show (,) show j str cvs show (\)) show grestore } if } bind def /set_font { findfont exch scalefont setfont } def % draw text fitted to its expected width /alignedtext { % width text /text exch def /width exch def gsave width 0 gt { [] 0 setdash text stringwidth pop width exch sub text length div 0 text ashow } if grestore } def /boxprim { % xcorner ycorner xsize ysize 4 2 roll moveto 2 copy exch 0 rlineto 0 exch rlineto pop neg 0 rlineto closepath } bind def /ellipse_path { /ry exch def /rx exch def /y exch def /x exch def matrix currentmatrix newpath x y translate rx ry scale 0 0 1 0 360 arc setmatrix } bind def /endpage { showpage } bind def /showpage { } def /layercolorseq [ % layer color sequence - darkest to lightest [0 0 0] [.2 .8 .8] [.4 .8 .8] [.6 .8 .8] [.8 .8 .8] ] def /layerlen layercolorseq length def /setlayer {/maxlayer exch def /curlayer exch def layercolorseq curlayer 1 sub layerlen mod get aload pop sethsbcolor /nodecolor {nopcolor} def /edgecolor {nopcolor} def /graphcolor {nopcolor} def } bind def /onlayer { curlayer ne {invis} if } def /onlayers { /myupper exch def /mylower exch def curlayer mylower lt curlayer myupper gt or {invis} if } def /curlayer 0 def %%EndResource %%EndProlog %%BeginSetup 14 default-font-family set_font 1 setmiterlimit % /arrowlength 10 def % /arrowwidth 5 def % make sure pdfmark is harmless for PS-interpreters other than Distiller /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % make '<<' and '>>' safe on PS Level 1 devices /languagelevel where {pop languagelevel}{1} ifelse 2 lt { userdict (<<) cvn ([) cvn load put userdict (>>) cvn ([) cvn load put } if %%EndSetup setupLatin1 %%Page: 1 1 %%PageBoundingBox: 36 36 136 120 %%PageOrientation: Portrait 0 0 1 beginpage gsave 36 36 100 84 boxprim clip newpath 1 1 set_scale 0 rotate 40 41 translate % Node1 gsave 0 0 0.74902 nodecolor newpath 12 .5 moveto 12 19.5 lineto 80 19.5 lineto 80 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 12 .5 moveto 12 19.5 lineto 80 19.5 lineto 80 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 20 7.5 moveto 52 (QuaAdler32) alignedtext grestore % Node2 gsave [ /Rect [ 0 56 92 76 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaChecksum32.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 0 56.5 moveto 0 75.5 lineto 92 75.5 lineto 92 56.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 0 56.5 moveto 0 75.5 lineto 92 75.5 lineto 92 56.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 8 63.5 moveto 76 (QuaChecksum32) alignedtext grestore % Node2->Node1 gsave 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 46 45.8 moveto 46 36.91 46 26.78 46 19.75 curveto stroke 0.66667 0.77647 0.43922 edgecolor newpath 42.5 46.08 moveto 46 56.08 lineto 49.5 46.08 lineto closepath fill 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 42.5 46.08 moveto 46 56.08 lineto 49.5 46.08 lineto closepath stroke grestore endpage showpage grestore %%PageTrailer %%EndPage: 1 %%Trailer %%Pages: 1 %%BoundingBox: 36 36 136 120 end restore %%EOF mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZip__coll__graph.eps0000644000175000017500000001331012070466513025554 0ustar csmallcsmall%!PS-Adobe-3.0 %%Creator: graphviz version 2.28.0 (20110507.0327) %%Title: G %%Pages: (atend) %%BoundingBox: (atend) %%EndComments save %%BeginProlog /DotDict 200 dict def DotDict begin /setupLatin1 { mark /EncodingVector 256 array def EncodingVector 0 ISOLatin1Encoding 0 255 getinterval putinterval EncodingVector 45 /hyphen put % Set up ISO Latin 1 character encoding /starnetISO { dup dup findfont dup length dict begin { 1 index /FID ne { def }{ pop pop } ifelse } forall /Encoding EncodingVector def currentdict end definefont } def /Times-Roman starnetISO def /Times-Italic starnetISO def /Times-Bold starnetISO def /Times-BoldItalic starnetISO def /Helvetica starnetISO def /Helvetica-Oblique starnetISO def /Helvetica-Bold starnetISO def /Helvetica-BoldOblique starnetISO def /Courier starnetISO def /Courier-Oblique starnetISO def /Courier-Bold starnetISO def /Courier-BoldOblique starnetISO def cleartomark } bind def %%BeginResource: procset graphviz 0 0 /coord-font-family /Times-Roman def /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def /InvScaleFactor 1.0 def /set_scale { dup 1 exch div /InvScaleFactor exch def scale } bind def % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def /bold { 2 setlinewidth } bind def /filled { } bind def /unfilled { } bind def /rounded { } bind def /diagonals { } bind def % hooks for setting color /nodecolor { sethsbcolor } bind def /edgecolor { sethsbcolor } bind def /graphcolor { sethsbcolor } bind def /nopcolor {pop pop pop} bind def /beginpage { % i j npages /npages exch def /j exch def /i exch def /str 10 string def npages 1 gt { gsave coordfont setfont 0 0 moveto (\() show i str cvs show (,) show j str cvs show (\)) show grestore } if } bind def /set_font { findfont exch scalefont setfont } def % draw text fitted to its expected width /alignedtext { % width text /text exch def /width exch def gsave width 0 gt { [] 0 setdash text stringwidth pop width exch sub text length div 0 text ashow } if grestore } def /boxprim { % xcorner ycorner xsize ysize 4 2 roll moveto 2 copy exch 0 rlineto 0 exch rlineto pop neg 0 rlineto closepath } bind def /ellipse_path { /ry exch def /rx exch def /y exch def /x exch def matrix currentmatrix newpath x y translate rx ry scale 0 0 1 0 360 arc setmatrix } bind def /endpage { showpage } bind def /showpage { } def /layercolorseq [ % layer color sequence - darkest to lightest [0 0 0] [.2 .8 .8] [.4 .8 .8] [.6 .8 .8] [.8 .8 .8] ] def /layerlen layercolorseq length def /setlayer {/maxlayer exch def /curlayer exch def layercolorseq curlayer 1 sub layerlen mod get aload pop sethsbcolor /nodecolor {nopcolor} def /edgecolor {nopcolor} def /graphcolor {nopcolor} def } bind def /onlayer { curlayer ne {invis} if } def /onlayers { /myupper exch def /mylower exch def curlayer mylower lt curlayer myupper gt or {invis} if } def /curlayer 0 def %%EndResource %%EndProlog %%BeginSetup 14 default-font-family set_font 1 setmiterlimit % /arrowlength 10 def % /arrowwidth 5 def % make sure pdfmark is harmless for PS-interpreters other than Distiller /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % make '<<' and '>>' safe on PS Level 1 devices /languagelevel where {pop languagelevel}{1} ifelse 2 lt { userdict (<<) cvn ([) cvn load put userdict (>>) cvn ([) cvn load put } if %%EndSetup setupLatin1 %%Page: 1 1 %%PageBoundingBox: 36 36 120 132 %%PageOrientation: Portrait 0 0 1 beginpage gsave 36 36 84 96 boxprim clip newpath 1 1 set_scale 0 rotate 40 41 translate % Node1 gsave 0 0 0.74902 nodecolor newpath 14.5 68.5 moveto 14.5 87.5 lineto 61.5 87.5 lineto 61.5 68.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 14.5 68.5 moveto 14.5 87.5 lineto 61.5 87.5 lineto 61.5 68.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 22.5 75.5 moveto 31 (QuaZip) alignedtext grestore % Node2 gsave [ /Rect [ -.5 0 76 20 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaZipPrivate.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath -.5 .5 moveto -.5 19.5 lineto 76.5 19.5 lineto 76.5 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath -.5 .5 moveto -.5 19.5 lineto 76.5 19.5 lineto 76.5 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 7.5 7.5 moveto 61 (QuaZipPrivate) alignedtext grestore % Node1->Node2 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 30.23 58.65 moveto 29.3 55.8 28.51 52.85 28 50 curveto 26.1 39.4 30.11 27.44 33.6 19.59 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 27.03 60.11 moveto 33.85 68.22 lineto 33.58 57.63 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 27.03 60.11 moveto 33.85 68.22 lineto 33.58 57.63 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 28 41.5 moveto 6 (q) alignedtext grestore % Node2->Node1 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 38 29.85 moveto 38 42.53 38 58.64 38 68.37 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 41.5 29.84 moveto 38 19.84 lineto 34.5 29.84 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 41.5 29.84 moveto 38 19.84 lineto 34.5 29.84 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 38 41.5 moveto 6 (p) alignedtext grestore endpage showpage grestore %%PageTrailer %%EndPage: 1 %%Trailer %%Pages: 1 %%BoundingBox: 36 36 120 132 end restore %%EOF mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaChecksum32.tex0000644000175000017500000001033212070466513024243 0ustar csmallcsmall\section{QuaChecksum32 Class Reference} \label{classQuaChecksum32}\index{QuaChecksum32@{QuaChecksum32}} Checksum interface. {\ttfamily \#include $<$quazip/quachecksum32.h$>$} Inheritance diagram for QuaChecksum32: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=190pt]{classQuaChecksum32__inherit__graph} \end{center} \end{figure} \subsection*{Public Member Functions} \begin{DoxyCompactItemize} \item virtual quint32 {\bf calculate} (const QByteArray \&data)=0 \begin{DoxyCompactList}\small\item\em Calculates the checksum for data. \end{DoxyCompactList}\item virtual void {\bf reset} ()=0\label{classQuaChecksum32_ad3f5db3c76b00069db9bda333cb49d57} \begin{DoxyCompactList}\small\item\em Resets the calculation on a checksun for a stream. \end{DoxyCompactList}\item virtual void {\bf update} (const QByteArray \&buf)=0 \begin{DoxyCompactList}\small\item\em Updates the calculated checksum for the stream. \end{DoxyCompactList}\item virtual quint32 {\bf value} ()=0 \begin{DoxyCompactList}\small\item\em Value of the checksum calculated for the stream passed throw \doxyref{update()}{p.}{classQuaChecksum32_a63a6ed3171f9243214d307da67557f7e}. \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection{Detailed Description} Checksum interface. This is an interface for 32 bit checksums. Classes implementing this interface can calcunate a certin checksum in a single step: \begin{DoxyCode} QChecksum32 *crc32 = new QuaCrc32(); rasoult = crc32->calculate(data); \end{DoxyCode} or by streaming the data: \begin{DoxyCode} QChecksum32 *crc32 = new QuaCrc32(); while(!fileA.atEnd()) crc32->update(fileA.read(bufSize)); resoultA = crc32->value(); crc32->reset(); while(!fileB.atEnd()) crc32->update(fileB.read(bufSize)); resoultB = crc32->value(); \end{DoxyCode} \subsection{Member Function Documentation} \index{QuaChecksum32@{QuaChecksum32}!calculate@{calculate}} \index{calculate@{calculate}!QuaChecksum32@{QuaChecksum32}} \subsubsection[{calculate}]{\setlength{\rightskip}{0pt plus 5cm}virtual quint32 QuaChecksum32::calculate ( \begin{DoxyParamCaption} \item[{const QByteArray \&}]{data} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [pure virtual]}}\label{classQuaChecksum32_a14d800fcfd55b2ae11ef07d3924fe0b1} Calculates the checksum for data. {\itshape data\/} source data \begin{DoxyReturn}{Returns} data checksum \end{DoxyReturn} This function has no efect on the value returned by \doxyref{value()}{p.}{classQuaChecksum32_afd836e7534194fce08356be6a8336da7}. Implemented in {\bf QuaAdler32} \doxyref{}{p.}{classQuaAdler32_a350e84fd000ebfa3c33503336a7b21bb}, and {\bf QuaCrc32} \doxyref{}{p.}{classQuaCrc32_aaf6fdf6e36e55c97bf9eab6ec65ecb9e}. \index{QuaChecksum32@{QuaChecksum32}!update@{update}} \index{update@{update}!QuaChecksum32@{QuaChecksum32}} \subsubsection[{update}]{\setlength{\rightskip}{0pt plus 5cm}virtual void QuaChecksum32::update ( \begin{DoxyParamCaption} \item[{const QByteArray \&}]{buf} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [pure virtual]}}\label{classQuaChecksum32_a63a6ed3171f9243214d307da67557f7e} Updates the calculated checksum for the stream. {\itshape buf\/} next portion of data from the stream Implemented in {\bf QuaAdler32} \doxyref{}{p.}{classQuaAdler32_aba24f7b16aa0cdc26f81a9ad687fc653}, and {\bf QuaCrc32} \doxyref{}{p.}{classQuaCrc32_a5015d80e04afe6e6d094155b7e99888e}. \index{QuaChecksum32@{QuaChecksum32}!value@{value}} \index{value@{value}!QuaChecksum32@{QuaChecksum32}} \subsubsection[{value}]{\setlength{\rightskip}{0pt plus 5cm}virtual quint32 QuaChecksum32::value ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [pure virtual]}}\label{classQuaChecksum32_afd836e7534194fce08356be6a8336da7} Value of the checksum calculated for the stream passed throw \doxyref{update()}{p.}{classQuaChecksum32_a63a6ed3171f9243214d307da67557f7e}. \begin{DoxyReturn}{Returns} checksum \end{DoxyReturn} Implemented in {\bf QuaAdler32} \doxyref{}{p.}{classQuaAdler32_a2022e1db95c23cef220b335e44d74fb1}, and {\bf QuaCrc32} \doxyref{}{p.}{classQuaCrc32_a957ce46a53862f75c89d6a3ac4f73389}. The documentation for this class was generated from the following file:\begin{DoxyCompactItemize} \item quazip/quachecksum32.h\end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaChecksum32__inherit__graph.eps0000644000175000017500000001370012070466513027435 0ustar csmallcsmall%!PS-Adobe-3.0 %%Creator: graphviz version 2.28.0 (20110507.0327) %%Title: G %%Pages: (atend) %%BoundingBox: (atend) %%EndComments save %%BeginProlog /DotDict 200 dict def DotDict begin /setupLatin1 { mark /EncodingVector 256 array def EncodingVector 0 ISOLatin1Encoding 0 255 getinterval putinterval EncodingVector 45 /hyphen put % Set up ISO Latin 1 character encoding /starnetISO { dup dup findfont dup length dict begin { 1 index /FID ne { def }{ pop pop } ifelse } forall /Encoding EncodingVector def currentdict end definefont } def /Times-Roman starnetISO def /Times-Italic starnetISO def /Times-Bold starnetISO def /Times-BoldItalic starnetISO def /Helvetica starnetISO def /Helvetica-Oblique starnetISO def /Helvetica-Bold starnetISO def /Helvetica-BoldOblique starnetISO def /Courier starnetISO def /Courier-Oblique starnetISO def /Courier-Bold starnetISO def /Courier-BoldOblique starnetISO def cleartomark } bind def %%BeginResource: procset graphviz 0 0 /coord-font-family /Times-Roman def /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def /InvScaleFactor 1.0 def /set_scale { dup 1 exch div /InvScaleFactor exch def scale } bind def % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def /bold { 2 setlinewidth } bind def /filled { } bind def /unfilled { } bind def /rounded { } bind def /diagonals { } bind def % hooks for setting color /nodecolor { sethsbcolor } bind def /edgecolor { sethsbcolor } bind def /graphcolor { sethsbcolor } bind def /nopcolor {pop pop pop} bind def /beginpage { % i j npages /npages exch def /j exch def /i exch def /str 10 string def npages 1 gt { gsave coordfont setfont 0 0 moveto (\() show i str cvs show (,) show j str cvs show (\)) show grestore } if } bind def /set_font { findfont exch scalefont setfont } def % draw text fitted to its expected width /alignedtext { % width text /text exch def /width exch def gsave width 0 gt { [] 0 setdash text stringwidth pop width exch sub text length div 0 text ashow } if grestore } def /boxprim { % xcorner ycorner xsize ysize 4 2 roll moveto 2 copy exch 0 rlineto 0 exch rlineto pop neg 0 rlineto closepath } bind def /ellipse_path { /ry exch def /rx exch def /y exch def /x exch def matrix currentmatrix newpath x y translate rx ry scale 0 0 1 0 360 arc setmatrix } bind def /endpage { showpage } bind def /showpage { } def /layercolorseq [ % layer color sequence - darkest to lightest [0 0 0] [.2 .8 .8] [.4 .8 .8] [.6 .8 .8] [.8 .8 .8] ] def /layerlen layercolorseq length def /setlayer {/maxlayer exch def /curlayer exch def layercolorseq curlayer 1 sub layerlen mod get aload pop sethsbcolor /nodecolor {nopcolor} def /edgecolor {nopcolor} def /graphcolor {nopcolor} def } bind def /onlayer { curlayer ne {invis} if } def /onlayers { /myupper exch def /mylower exch def curlayer mylower lt curlayer myupper gt or {invis} if } def /curlayer 0 def %%EndResource %%EndProlog %%BeginSetup 14 default-font-family set_font 1 setmiterlimit % /arrowlength 10 def % /arrowwidth 5 def % make sure pdfmark is harmless for PS-interpreters other than Distiller /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % make '<<' and '>>' safe on PS Level 1 devices /languagelevel where {pop languagelevel}{1} ifelse 2 lt { userdict (<<) cvn ([) cvn load put userdict (>>) cvn ([) cvn load put } if %%EndSetup setupLatin1 %%Page: 1 1 %%PageBoundingBox: 36 36 190 120 %%PageOrientation: Portrait 0 0 1 beginpage gsave 36 36 154 84 boxprim clip newpath 1 1 set_scale 0 rotate 40 41 translate % Node1 gsave 0 0 0.74902 nodecolor newpath 29 56.5 moveto 29 75.5 lineto 121 75.5 lineto 121 56.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 29 56.5 moveto 29 75.5 lineto 121 75.5 lineto 121 56.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 37 63.5 moveto 76 (QuaChecksum32) alignedtext grestore % Node2 gsave [ /Rect [ 0 0 68 20 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaAdler32.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 0 .5 moveto 0 19.5 lineto 68 19.5 lineto 68 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 0 .5 moveto 0 19.5 lineto 68 19.5 lineto 68 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 8 7.5 moveto 52 (QuaAdler32) alignedtext grestore % Node1->Node2 gsave 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 61.98 47.86 moveto 54.88 38.5 46.4 27.33 40.64 19.75 curveto stroke 0.66667 0.77647 0.43922 edgecolor newpath 59.39 50.24 moveto 68.23 56.08 lineto 64.97 46 lineto closepath fill 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 59.39 50.24 moveto 68.23 56.08 lineto 64.97 46 lineto closepath stroke grestore % Node3 gsave [ /Rect [ 86 0 146 20 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaCrc32.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 86 .5 moveto 86 19.5 lineto 146 19.5 lineto 146 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 86 .5 moveto 86 19.5 lineto 146 19.5 lineto 146 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 94 7.5 moveto 44 (QuaCrc32) alignedtext grestore % Node1->Node3 gsave 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 88.02 47.86 moveto 95.12 38.5 103.6 27.33 109.36 19.75 curveto stroke 0.66667 0.77647 0.43922 edgecolor newpath 85.03 46 moveto 81.77 56.08 lineto 90.61 50.24 lineto closepath fill 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 85.03 46 moveto 81.77 56.08 lineto 90.61 50.24 lineto closepath stroke grestore endpage showpage grestore %%PageTrailer %%EndPage: 1 %%Trailer %%Pages: 1 %%BoundingBox: 36 36 190 120 end restore %%EOF mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/annotated.tex0000644000175000017500000000241512070466513022617 0ustar csmallcsmall\section{Class List} Here are the classes, structs, unions and interfaces with brief descriptions:\begin{DoxyCompactList} \item\contentsline{section}{{\bf JlCompress} (Utility class for typical operations )}{\pageref{classJlCompress}}{} \item\contentsline{section}{{\bf QuaAdler32} (Adler32 checksum )}{\pageref{classQuaAdler32}}{} \item\contentsline{section}{{\bf QuaChecksum32} (Checksum interface )}{\pageref{classQuaChecksum32}}{} \item\contentsline{section}{{\bf QuaCrc32} (CRC32 checksum )}{\pageref{classQuaCrc32}}{} \item\contentsline{section}{{\bf QuaZip} (ZIP archive )}{\pageref{classQuaZip}}{} \item\contentsline{section}{{\bf QuaZipFile} (A file inside ZIP archive )}{\pageref{classQuaZipFile}}{} \item\contentsline{section}{{\bf QuaZipFileInfo} (Information about a file inside archive )}{\pageref{structQuaZipFileInfo}}{} \item\contentsline{section}{{\bf QuaZipFilePrivate} (The implementation class for \doxyref{QuaZip}{p.}{classQuaZip} )}{\pageref{classQuaZipFilePrivate}}{} \item\contentsline{section}{{\bf QuaZipNewInfo} (Information about a file to be created )}{\pageref{structQuaZipNewInfo}}{} \item\contentsline{section}{{\bf QuaZipPrivate} (All the internal stuff for the \doxyref{QuaZip}{p.}{classQuaZip} class )}{\pageref{classQuaZipPrivate}}{} \end{DoxyCompactList} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaAdler32__inherit__graph.md50000644000175000017500000000004012070466513026611 0ustar csmallcsmalldbe414b63f5eac72ebd22d72dbae868fmudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/usage.tex0000644000175000017500000000756312070466513021757 0ustar csmallcsmallThis page provides general information on QuaZIP usage. See classes \doxyref{QuaZip}{p.}{classQuaZip} and \doxyref{QuaZipFile}{p.}{classQuaZipFile} for the detailed documentation on what can QuaZIP do and what can not. Also, reading comments in the zip.h and unzip.h files (taken from the original ZIP/UNZIP package) is always a good idea too. After all, QuaZIP is just a wrapper with a few convenience extensions and reimplementations. \doxyref{QuaZip}{p.}{classQuaZip} is a class representing ZIP archive, \doxyref{QuaZipFile}{p.}{classQuaZipFile} represents a file inside archive and subclasses QIODevice as well.\section{Terminology}\label{usage_terminology} \char`\"{}QuaZIP\char`\"{} means whole this library, while \char`\"{}QuaZip\char`\"{} (not case difference) is just one class in it. \char`\"{}ZIP/UNZIP API\char`\"{} means the original API of the Gilles Vollant's ZIP/UNZIP package. It was slightly modified to better integrate with Qt. \char`\"{}ZIP\char`\"{}, \char`\"{}ZIP archive\char`\"{} or \char`\"{}ZIP file\char`\"{} means any ZIP archive. Typically this is a plain file with \char`\"{}.zip\char`\"{} (or \char`\"{}.ZIP\char`\"{}) file name suffix. \char`\"{}A file inside archive\char`\"{}, \char`\"{}a file inside ZIP\char`\"{} or something like that means file either being read or written from/to some ZIP archive.\section{Error handling}\label{usage_error-handling} Almost any call to ZIP/UNZIP API return some error code. Most of the original API's error checking could be done in this wrapper as well, but it would cause unnecessary code bloating without any benefit. So, QuaZIP only checks for situations that ZIP/UNZIP API can not check for. For example, ZIP/UNZIP API has no \char`\"{}ZIP open mode\char`\"{} concept because read and write modes are completely separated. On the other hand, to avoid creating classes like \char`\"{}QuaZipReader\char`\"{}, \char`\"{}QuaZipWriter\char`\"{} or something like that, QuaZIP introduces \char`\"{}ZIP open mode\char`\"{} concept instead, thus making it possible to use one class (\doxyref{QuaZip}{p.}{classQuaZip}) for both reading and writing. But this leads to additional open mode checks which are not done in ZIP/UNZIP package. Therefore, error checking is two-\/level (QuaZIP's level and ZIP/UNZIP API level), which sometimes can be confusing, so here are some advices on how the error checking should be properly done: \begin{DoxyItemize} \item Both \doxyref{QuaZip}{p.}{classQuaZip} and \doxyref{QuaZipFile}{p.}{classQuaZipFile} have getZipError() function, which return error code of the last ZIP/UNZIP API call. Most function calls reset error code to UNZ\_\-OK on success and set error code on failure. Some functions do not reset error code. Most of them are {\ttfamily const} and do not access ZIP archive in any way. Some, on the other hand, {\itshape do\/} access ZIP archive, but do not reset or set error code. For example, \doxyref{QuaZipFile::pos()}{p.}{classQuaZipFile_a90fd55dab83eca7f95df50b2c41b7f22} function. Such functions are explicitly marked in the documentation. \item Most functions have its own way to report errors, by returning a null string, negative value or {\ttfamily false}. If such a function returns error value, call getZipError() to get more information about error. See \char`\"{}zip.h\char`\"{} and \char`\"{}unzip.h\char`\"{} of the ZIP/UNZIP package for error codes. \item If the function returns error-\/stating value (like {\ttfamily false}), but getZipError() returns UNZ\_\-OK, it means that you did something obviously wrong. For example, tried to write in the archive open for reading or not open at all. You better just do not do that! Most functions also issue a warning using qWarning() function in such cases. See documentation for a specific function for details on when it should not be called. \end{DoxyItemize} I know that this is somewhat messy, but I could not find a better way to do all the error handling. mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZip__coll__graph.md50000644000175000017500000000004012070466513025446 0ustar csmallcsmall285ae05030356ab7fd5c5be4e423dbb5mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZipFilePrivate__coll__graph.eps0000644000175000017500000002024412070466513027713 0ustar csmallcsmall%!PS-Adobe-3.0 %%Creator: graphviz version 2.28.0 (20110507.0327) %%Title: G %%Pages: (atend) %%BoundingBox: (atend) %%EndComments save %%BeginProlog /DotDict 200 dict def DotDict begin /setupLatin1 { mark /EncodingVector 256 array def EncodingVector 0 ISOLatin1Encoding 0 255 getinterval putinterval EncodingVector 45 /hyphen put % Set up ISO Latin 1 character encoding /starnetISO { dup dup findfont dup length dict begin { 1 index /FID ne { def }{ pop pop } ifelse } forall /Encoding EncodingVector def currentdict end definefont } def /Times-Roman starnetISO def /Times-Italic starnetISO def /Times-Bold starnetISO def /Times-BoldItalic starnetISO def /Helvetica starnetISO def /Helvetica-Oblique starnetISO def /Helvetica-Bold starnetISO def /Helvetica-BoldOblique starnetISO def /Courier starnetISO def /Courier-Oblique starnetISO def /Courier-Bold starnetISO def /Courier-BoldOblique starnetISO def cleartomark } bind def %%BeginResource: procset graphviz 0 0 /coord-font-family /Times-Roman def /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def /InvScaleFactor 1.0 def /set_scale { dup 1 exch div /InvScaleFactor exch def scale } bind def % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def /bold { 2 setlinewidth } bind def /filled { } bind def /unfilled { } bind def /rounded { } bind def /diagonals { } bind def % hooks for setting color /nodecolor { sethsbcolor } bind def /edgecolor { sethsbcolor } bind def /graphcolor { sethsbcolor } bind def /nopcolor {pop pop pop} bind def /beginpage { % i j npages /npages exch def /j exch def /i exch def /str 10 string def npages 1 gt { gsave coordfont setfont 0 0 moveto (\() show i str cvs show (,) show j str cvs show (\)) show grestore } if } bind def /set_font { findfont exch scalefont setfont } def % draw text fitted to its expected width /alignedtext { % width text /text exch def /width exch def gsave width 0 gt { [] 0 setdash text stringwidth pop width exch sub text length div 0 text ashow } if grestore } def /boxprim { % xcorner ycorner xsize ysize 4 2 roll moveto 2 copy exch 0 rlineto 0 exch rlineto pop neg 0 rlineto closepath } bind def /ellipse_path { /ry exch def /rx exch def /y exch def /x exch def matrix currentmatrix newpath x y translate rx ry scale 0 0 1 0 360 arc setmatrix } bind def /endpage { showpage } bind def /showpage { } def /layercolorseq [ % layer color sequence - darkest to lightest [0 0 0] [.2 .8 .8] [.4 .8 .8] [.6 .8 .8] [.8 .8 .8] ] def /layerlen layercolorseq length def /setlayer {/maxlayer exch def /curlayer exch def layercolorseq curlayer 1 sub layerlen mod get aload pop sethsbcolor /nodecolor {nopcolor} def /edgecolor {nopcolor} def /graphcolor {nopcolor} def } bind def /onlayer { curlayer ne {invis} if } def /onlayers { /myupper exch def /mylower exch def curlayer mylower lt curlayer myupper gt or {invis} if } def /curlayer 0 def %%EndResource %%EndProlog %%BeginSetup 14 default-font-family set_font 1 setmiterlimit % /arrowlength 10 def % /arrowwidth 5 def % make sure pdfmark is harmless for PS-interpreters other than Distiller /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % make '<<' and '>>' safe on PS Level 1 devices /languagelevel where {pop languagelevel}{1} ifelse 2 lt { userdict (<<) cvn ([) cvn load put userdict (>>) cvn ([) cvn load put } if %%EndSetup setupLatin1 %%Page: 1 1 %%PageBoundingBox: 36 36 231 200 %%PageOrientation: Portrait 0 0 1 beginpage gsave 36 36 195 164 boxprim clip newpath 1 1 set_scale 0 rotate 40 41 translate % Node1 gsave 0 0 0.74902 nodecolor newpath 0 68.5 moveto 0 87.5 lineto 92 87.5 lineto 92 68.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 0 68.5 moveto 0 87.5 lineto 92 87.5 lineto 92 68.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 8 75.5 moveto 76 (QuaZipFilePrivate) alignedtext grestore % Node4 gsave [ /Rect [ 14.5 0 77 20 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaZipFile.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 14.5 .5 moveto 14.5 19.5 lineto 77.5 19.5 lineto 77.5 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 14.5 .5 moveto 14.5 19.5 lineto 77.5 19.5 lineto 77.5 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 22.5 7.5 moveto 47 (QuaZipFile) alignedtext grestore % Node1->Node4 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 37.93 58.6 moveto 35.99 52.14 34.78 44.79 36 38 curveto 37.13 31.7 39.63 24.95 41.85 19.78 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 34.82 60.27 moveto 41.6 68.41 lineto 41.37 57.81 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 34.82 60.27 moveto 41.6 68.41 lineto 41.37 57.81 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 36 41.5 moveto 6 (p) alignedtext grestore % Node2 gsave [ /Rect [ 96.5 136 143 156 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaZip.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 96.5 136.5 moveto 96.5 155.5 lineto 143.5 155.5 lineto 143.5 136.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 96.5 136.5 moveto 96.5 155.5 lineto 143.5 155.5 lineto 143.5 136.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 104.5 143.5 moveto 31 (QuaZip) alignedtext grestore % Node2->Node1 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 102.52 129.41 moveto 87.99 116.45 67.81 98.46 55.91 87.84 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 100.53 132.33 moveto 110.33 136.37 lineto 105.19 127.1 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 100.53 132.33 moveto 110.33 136.37 lineto 105.19 127.1 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 90 109.5 moveto 13 (zip) alignedtext grestore % Node3 gsave [ /Rect [ 110.5 68 187 88 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaZipPrivate.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 110.5 68.5 moveto 110.5 87.5 lineto 187.5 87.5 lineto 187.5 68.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 110.5 68.5 moveto 110.5 87.5 lineto 187.5 87.5 lineto 187.5 68.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 118.5 75.5 moveto 61 (QuaZipPrivate) alignedtext grestore % Node2->Node3 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 119.52 126.1 moveto 119.97 119.5 121.2 112.2 124 106 curveto 127.21 98.9 133.04 92.43 138.26 87.61 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 116.02 126.17 moveto 119.35 136.23 lineto 123.02 126.29 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 116.02 126.17 moveto 119.35 136.23 lineto 123.02 126.29 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 124 109.5 moveto 6 (q) alignedtext grestore % Node3->Node2 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 141.05 97.09 moveto 135.43 109.87 128.15 126.45 123.79 136.37 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 144.3 98.4 moveto 145.12 87.84 lineto 137.89 95.59 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 144.3 98.4 moveto 145.12 87.84 lineto 137.89 95.59 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 138 109.5 moveto 6 (p) alignedtext grestore % Node4->Node1 gsave 1 setlinewidth dashed 0.77647 0.75294 0.80392 edgecolor newpath 46 29.85 moveto 46 42.53 46 58.64 46 68.37 curveto stroke 0.77647 0.75294 0.80392 edgecolor newpath 49.5 29.84 moveto 46 19.84 lineto 42.5 29.84 lineto closepath fill 1 setlinewidth solid 0.77647 0.75294 0.80392 edgecolor newpath 49.5 29.84 moveto 46 19.84 lineto 42.5 29.84 lineto closepath stroke 0 0 0 edgecolor 10 /Helvetica set_font 46 41.5 moveto 6 (q) alignedtext grestore endpage showpage grestore %%PageTrailer %%EndPage: 1 %%Trailer %%Pages: 1 %%BoundingBox: 36 36 231 200 end restore %%EOF mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaAdler32__coll__graph.md50000644000175000017500000000004012070466513026100 0ustar csmallcsmalldbe414b63f5eac72ebd22d72dbae868fmudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/refman.tex0000644000175000017500000000325112070466513022111 0ustar csmallcsmall\documentclass[a4paper]{book} \usepackage{makeidx} \usepackage{graphicx} \usepackage{multicol} \usepackage{float} \usepackage{listings} \usepackage{color} \usepackage{ifthen} \usepackage[table]{xcolor} \usepackage{textcomp} \usepackage{alltt} \usepackage[utf8]{inputenc} \usepackage{mathptmx} \usepackage[scaled=.90]{helvet} \usepackage{courier} \usepackage{sectsty} \usepackage[titles]{tocloft} \usepackage{doxygen} \lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=8,numbers=left } \makeindex \setcounter{tocdepth}{3} \renewcommand{\footrulewidth}{0.4pt} \renewcommand{\familydefault}{\sfdefault} \begin{document} \begin{titlepage} \vspace*{7cm} \begin{center} {\Large QuaZIP \\[1ex]\large quazip-\/0-\/4-\/4 }\\ \vspace*{1cm} {\large Generated by Doxygen 1.7.4}\\ \vspace*{0.5cm} {\small Sat Jan 14 2012 14:54:05}\\ \end{center} \end{titlepage} \clearemptydoublepage \pagenumbering{roman} \tableofcontents \clearemptydoublepage \pagenumbering{arabic} \chapter{QuaZIP -\/ Qt/C++ wrapper for ZIP/UNZIP package} \label{index}\input{index} \chapter{QuaZip FAQ} \label{faq} \input{faq} \chapter{Usage} \label{usage} \input{usage} \chapter{Directory Hierarchy} \input{dirs} \chapter{Class Index} \input{hierarchy} \chapter{Class Index} \input{annotated} \chapter{Directory Documentation} \input{dir_13eff9bb9851318b001ebebd72594ac4} \chapter{Class Documentation} \input{classJlCompress} \input{classQuaAdler32} \input{classQuaChecksum32} \input{classQuaCrc32} \input{classQuaZip} \input{classQuaZipFile} \input{structQuaZipFileInfo} \input{classQuaZipFilePrivate} \input{structQuaZipNewInfo} \input{classQuaZipPrivate} \printindex \end{document} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/structQuaZipFileInfo.tex0000644000175000017500000000614212070466513024735 0ustar csmallcsmall\section{QuaZipFileInfo Struct Reference} \label{structQuaZipFileInfo}\index{QuaZipFileInfo@{QuaZipFileInfo}} Information about a file inside archive. {\ttfamily \#include $<$quazipfileinfo.h$>$} \subsection*{Public Attributes} \begin{DoxyCompactItemize} \item QString {\bf name}\label{structQuaZipFileInfo_a16ac323965deccf0232bfae69d933a84} \begin{DoxyCompactList}\small\item\em File name. \end{DoxyCompactList}\item quint16 {\bf versionCreated}\label{structQuaZipFileInfo_a52f3f1d960ebaa2acbc2a86458fa3e6e} \begin{DoxyCompactList}\small\item\em Version created by. \end{DoxyCompactList}\item quint16 {\bf versionNeeded}\label{structQuaZipFileInfo_a8b73982808bded49e88e624a65e1a94f} \begin{DoxyCompactList}\small\item\em Version needed to extract. \end{DoxyCompactList}\item quint16 {\bf flags}\label{structQuaZipFileInfo_a56d36f777e4fc892c71e22d080622e2c} \begin{DoxyCompactList}\small\item\em General purpose flags. \end{DoxyCompactList}\item quint16 {\bf method}\label{structQuaZipFileInfo_af5c1bbda7f5dec2c358e7a543564de4c} \begin{DoxyCompactList}\small\item\em Compression method. \end{DoxyCompactList}\item QDateTime {\bf dateTime}\label{structQuaZipFileInfo_ad6993d099436813a27fd31aebe42911a} \begin{DoxyCompactList}\small\item\em Last modification date and time. \end{DoxyCompactList}\item quint32 {\bf crc}\label{structQuaZipFileInfo_aceee045c9ebce0b9724f40d342bc99ea} \begin{DoxyCompactList}\small\item\em CRC. \end{DoxyCompactList}\item quint32 {\bf compressedSize}\label{structQuaZipFileInfo_af6116eaac1f36b2a4b3a6a39851a85cc} \begin{DoxyCompactList}\small\item\em Compressed file size. \end{DoxyCompactList}\item quint32 {\bf uncompressedSize}\label{structQuaZipFileInfo_a0eb908e1b1ea637d1f1f4d6aa31db07f} \begin{DoxyCompactList}\small\item\em Uncompressed file size. \end{DoxyCompactList}\item quint16 {\bf diskNumberStart}\label{structQuaZipFileInfo_aa70157fdc2bd8de10405055b4233050b} \begin{DoxyCompactList}\small\item\em Disk number start. \end{DoxyCompactList}\item quint16 {\bf internalAttr}\label{structQuaZipFileInfo_a36e681a93b041617addee78cb939c93d} \begin{DoxyCompactList}\small\item\em Internal file attributes. \end{DoxyCompactList}\item quint32 {\bf externalAttr}\label{structQuaZipFileInfo_afeb65ffdacc4fc0ba7848d4b37f62ecf} \begin{DoxyCompactList}\small\item\em External file attributes. \end{DoxyCompactList}\item QString {\bf comment}\label{structQuaZipFileInfo_adc2aad7bbd87ce3415e2a19851266bfc} \begin{DoxyCompactList}\small\item\em Comment. \end{DoxyCompactList}\item QByteArray {\bf extra}\label{structQuaZipFileInfo_affc7b097de2c3c2ef5801c60f96adc72} \begin{DoxyCompactList}\small\item\em Extra field. \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection{Detailed Description} Information about a file inside archive. Call \doxyref{QuaZip::getCurrentFileInfo()}{p.}{classQuaZip_a9c91a53ed4c2038e153c64bdc097ebe8} or \doxyref{QuaZipFile::getFileInfo()}{p.}{classQuaZipFile_ad3f5807329321be21b12c1ba5798b359} to fill this structure. The documentation for this struct was generated from the following file:\begin{DoxyCompactItemize} \item quazip/quazipfileinfo.h\end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/hierarchy.tex0000644000175000017500000000163412070466513022622 0ustar csmallcsmall\section{Class Hierarchy} This inheritance list is sorted roughly, but not completely, alphabetically:\begin{DoxyCompactList} \item \contentsline{section}{JlCompress}{\pageref{classJlCompress}}{} \item \contentsline{section}{QuaChecksum32}{\pageref{classQuaChecksum32}}{} \begin{DoxyCompactList} \item \contentsline{section}{QuaAdler32}{\pageref{classQuaAdler32}}{} \item \contentsline{section}{QuaCrc32}{\pageref{classQuaCrc32}}{} \end{DoxyCompactList} \item \contentsline{section}{QuaZip}{\pageref{classQuaZip}}{} \item \contentsline{section}{QuaZipFile}{\pageref{classQuaZipFile}}{} \item \contentsline{section}{QuaZipFileInfo}{\pageref{structQuaZipFileInfo}}{} \item \contentsline{section}{QuaZipFilePrivate}{\pageref{classQuaZipFilePrivate}}{} \item \contentsline{section}{QuaZipNewInfo}{\pageref{structQuaZipNewInfo}}{} \item \contentsline{section}{QuaZipPrivate}{\pageref{classQuaZipPrivate}}{} \end{DoxyCompactList} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaZipFilePrivate__coll__graph.md50000644000175000017500000000004012070466513027601 0ustar csmallcsmall1f8ac6d56acdc49496bc99c52404e6a3mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/dir_13eff9bb9851318b001ebebd72594ac4.tex0000644000175000017500000000200012070466513026122 0ustar csmallcsmall\section{quazip/ Directory Reference} \label{dir_13eff9bb9851318b001ebebd72594ac4}\index{quazip/ Directory Reference@{quazip/ Directory Reference}} Directory dependency graph for quazip/: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=98pt]{dir_13eff9bb9851318b001ebebd72594ac4_dep} \end{center} \end{figure} \subsection*{Files} \begin{DoxyCompactItemize} \item file {\bfseries JlCompress.cpp} \item file {\bfseries JlCompress.h} \item file {\bfseries qioapi.cpp} \item file {\bfseries quaadler32.cpp} \item file {\bfseries quaadler32.h} \item file {\bfseries quachecksum32.h} \item file {\bfseries quacrc32.cpp} \item file {\bfseries quacrc32.h} \item file {\bfseries quazip.cpp} \item file {\bfseries quazip.h} \item file {\bfseries quazip\_\-global.h} \item file {\bfseries quazipfile.cpp} \item file {\bfseries quazipfile.h} \item file {\bfseries quazipfileinfo.h} \item file {\bfseries quazipnewinfo.cpp} \item file {\bfseries quazipnewinfo.h} \end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaCrc32__inherit__graph.eps0000644000175000017500000001212412070466513026401 0ustar csmallcsmall%!PS-Adobe-3.0 %%Creator: graphviz version 2.28.0 (20110507.0327) %%Title: G %%Pages: (atend) %%BoundingBox: (atend) %%EndComments save %%BeginProlog /DotDict 200 dict def DotDict begin /setupLatin1 { mark /EncodingVector 256 array def EncodingVector 0 ISOLatin1Encoding 0 255 getinterval putinterval EncodingVector 45 /hyphen put % Set up ISO Latin 1 character encoding /starnetISO { dup dup findfont dup length dict begin { 1 index /FID ne { def }{ pop pop } ifelse } forall /Encoding EncodingVector def currentdict end definefont } def /Times-Roman starnetISO def /Times-Italic starnetISO def /Times-Bold starnetISO def /Times-BoldItalic starnetISO def /Helvetica starnetISO def /Helvetica-Oblique starnetISO def /Helvetica-Bold starnetISO def /Helvetica-BoldOblique starnetISO def /Courier starnetISO def /Courier-Oblique starnetISO def /Courier-Bold starnetISO def /Courier-BoldOblique starnetISO def cleartomark } bind def %%BeginResource: procset graphviz 0 0 /coord-font-family /Times-Roman def /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def /InvScaleFactor 1.0 def /set_scale { dup 1 exch div /InvScaleFactor exch def scale } bind def % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def /bold { 2 setlinewidth } bind def /filled { } bind def /unfilled { } bind def /rounded { } bind def /diagonals { } bind def % hooks for setting color /nodecolor { sethsbcolor } bind def /edgecolor { sethsbcolor } bind def /graphcolor { sethsbcolor } bind def /nopcolor {pop pop pop} bind def /beginpage { % i j npages /npages exch def /j exch def /i exch def /str 10 string def npages 1 gt { gsave coordfont setfont 0 0 moveto (\() show i str cvs show (,) show j str cvs show (\)) show grestore } if } bind def /set_font { findfont exch scalefont setfont } def % draw text fitted to its expected width /alignedtext { % width text /text exch def /width exch def gsave width 0 gt { [] 0 setdash text stringwidth pop width exch sub text length div 0 text ashow } if grestore } def /boxprim { % xcorner ycorner xsize ysize 4 2 roll moveto 2 copy exch 0 rlineto 0 exch rlineto pop neg 0 rlineto closepath } bind def /ellipse_path { /ry exch def /rx exch def /y exch def /x exch def matrix currentmatrix newpath x y translate rx ry scale 0 0 1 0 360 arc setmatrix } bind def /endpage { showpage } bind def /showpage { } def /layercolorseq [ % layer color sequence - darkest to lightest [0 0 0] [.2 .8 .8] [.4 .8 .8] [.6 .8 .8] [.8 .8 .8] ] def /layerlen layercolorseq length def /setlayer {/maxlayer exch def /curlayer exch def layercolorseq curlayer 1 sub layerlen mod get aload pop sethsbcolor /nodecolor {nopcolor} def /edgecolor {nopcolor} def /graphcolor {nopcolor} def } bind def /onlayer { curlayer ne {invis} if } def /onlayers { /myupper exch def /mylower exch def curlayer mylower lt curlayer myupper gt or {invis} if } def /curlayer 0 def %%EndResource %%EndProlog %%BeginSetup 14 default-font-family set_font 1 setmiterlimit % /arrowlength 10 def % /arrowwidth 5 def % make sure pdfmark is harmless for PS-interpreters other than Distiller /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % make '<<' and '>>' safe on PS Level 1 devices /languagelevel where {pop languagelevel}{1} ifelse 2 lt { userdict (<<) cvn ([) cvn load put userdict (>>) cvn ([) cvn load put } if %%EndSetup setupLatin1 %%Page: 1 1 %%PageBoundingBox: 36 36 136 120 %%PageOrientation: Portrait 0 0 1 beginpage gsave 36 36 100 84 boxprim clip newpath 1 1 set_scale 0 rotate 40 41 translate % Node1 gsave 0 0 0.74902 nodecolor newpath 16 .5 moveto 16 19.5 lineto 76 19.5 lineto 76 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 16 .5 moveto 16 19.5 lineto 76 19.5 lineto 76 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 24 7.5 moveto 44 (QuaCrc32) alignedtext grestore % Node2 gsave [ /Rect [ 0 56 92 76 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaChecksum32.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 0 56.5 moveto 0 75.5 lineto 92 75.5 lineto 92 56.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 0 56.5 moveto 0 75.5 lineto 92 75.5 lineto 92 56.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 8 63.5 moveto 76 (QuaChecksum32) alignedtext grestore % Node2->Node1 gsave 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 46 45.8 moveto 46 36.91 46 26.78 46 19.75 curveto stroke 0.66667 0.77647 0.43922 edgecolor newpath 42.5 46.08 moveto 46 56.08 lineto 49.5 46.08 lineto closepath fill 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 42.5 46.08 moveto 46 56.08 lineto 49.5 46.08 lineto closepath stroke grestore endpage showpage grestore %%PageTrailer %%EndPage: 1 %%Trailer %%Pages: 1 %%BoundingBox: 36 36 136 120 end restore %%EOF mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaCrc32__coll__graph.eps0000644000175000017500000001212412070466513025670 0ustar csmallcsmall%!PS-Adobe-3.0 %%Creator: graphviz version 2.28.0 (20110507.0327) %%Title: G %%Pages: (atend) %%BoundingBox: (atend) %%EndComments save %%BeginProlog /DotDict 200 dict def DotDict begin /setupLatin1 { mark /EncodingVector 256 array def EncodingVector 0 ISOLatin1Encoding 0 255 getinterval putinterval EncodingVector 45 /hyphen put % Set up ISO Latin 1 character encoding /starnetISO { dup dup findfont dup length dict begin { 1 index /FID ne { def }{ pop pop } ifelse } forall /Encoding EncodingVector def currentdict end definefont } def /Times-Roman starnetISO def /Times-Italic starnetISO def /Times-Bold starnetISO def /Times-BoldItalic starnetISO def /Helvetica starnetISO def /Helvetica-Oblique starnetISO def /Helvetica-Bold starnetISO def /Helvetica-BoldOblique starnetISO def /Courier starnetISO def /Courier-Oblique starnetISO def /Courier-Bold starnetISO def /Courier-BoldOblique starnetISO def cleartomark } bind def %%BeginResource: procset graphviz 0 0 /coord-font-family /Times-Roman def /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def /InvScaleFactor 1.0 def /set_scale { dup 1 exch div /InvScaleFactor exch def scale } bind def % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def /bold { 2 setlinewidth } bind def /filled { } bind def /unfilled { } bind def /rounded { } bind def /diagonals { } bind def % hooks for setting color /nodecolor { sethsbcolor } bind def /edgecolor { sethsbcolor } bind def /graphcolor { sethsbcolor } bind def /nopcolor {pop pop pop} bind def /beginpage { % i j npages /npages exch def /j exch def /i exch def /str 10 string def npages 1 gt { gsave coordfont setfont 0 0 moveto (\() show i str cvs show (,) show j str cvs show (\)) show grestore } if } bind def /set_font { findfont exch scalefont setfont } def % draw text fitted to its expected width /alignedtext { % width text /text exch def /width exch def gsave width 0 gt { [] 0 setdash text stringwidth pop width exch sub text length div 0 text ashow } if grestore } def /boxprim { % xcorner ycorner xsize ysize 4 2 roll moveto 2 copy exch 0 rlineto 0 exch rlineto pop neg 0 rlineto closepath } bind def /ellipse_path { /ry exch def /rx exch def /y exch def /x exch def matrix currentmatrix newpath x y translate rx ry scale 0 0 1 0 360 arc setmatrix } bind def /endpage { showpage } bind def /showpage { } def /layercolorseq [ % layer color sequence - darkest to lightest [0 0 0] [.2 .8 .8] [.4 .8 .8] [.6 .8 .8] [.8 .8 .8] ] def /layerlen layercolorseq length def /setlayer {/maxlayer exch def /curlayer exch def layercolorseq curlayer 1 sub layerlen mod get aload pop sethsbcolor /nodecolor {nopcolor} def /edgecolor {nopcolor} def /graphcolor {nopcolor} def } bind def /onlayer { curlayer ne {invis} if } def /onlayers { /myupper exch def /mylower exch def curlayer mylower lt curlayer myupper gt or {invis} if } def /curlayer 0 def %%EndResource %%EndProlog %%BeginSetup 14 default-font-family set_font 1 setmiterlimit % /arrowlength 10 def % /arrowwidth 5 def % make sure pdfmark is harmless for PS-interpreters other than Distiller /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % make '<<' and '>>' safe on PS Level 1 devices /languagelevel where {pop languagelevel}{1} ifelse 2 lt { userdict (<<) cvn ([) cvn load put userdict (>>) cvn ([) cvn load put } if %%EndSetup setupLatin1 %%Page: 1 1 %%PageBoundingBox: 36 36 136 120 %%PageOrientation: Portrait 0 0 1 beginpage gsave 36 36 100 84 boxprim clip newpath 1 1 set_scale 0 rotate 40 41 translate % Node1 gsave 0 0 0.74902 nodecolor newpath 16 .5 moveto 16 19.5 lineto 76 19.5 lineto 76 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 16 .5 moveto 16 19.5 lineto 76 19.5 lineto 76 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 24 7.5 moveto 44 (QuaCrc32) alignedtext grestore % Node2 gsave [ /Rect [ 0 56 92 76 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaChecksum32.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 0 56.5 moveto 0 75.5 lineto 92 75.5 lineto 92 56.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 0 56.5 moveto 0 75.5 lineto 92 75.5 lineto 92 56.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 8 63.5 moveto 76 (QuaChecksum32) alignedtext grestore % Node2->Node1 gsave 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 46 45.8 moveto 46 36.91 46 26.78 46 19.75 curveto stroke 0.66667 0.77647 0.43922 edgecolor newpath 42.5 46.08 moveto 46 56.08 lineto 49.5 46.08 lineto closepath fill 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 42.5 46.08 moveto 46 56.08 lineto 49.5 46.08 lineto closepath stroke grestore endpage showpage grestore %%PageTrailer %%EndPage: 1 %%Trailer %%Pages: 1 %%BoundingBox: 36 36 136 120 end restore %%EOF mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaAdler32__coll__graph.eps0000644000175000017500000001212612070466513026212 0ustar csmallcsmall%!PS-Adobe-3.0 %%Creator: graphviz version 2.28.0 (20110507.0327) %%Title: G %%Pages: (atend) %%BoundingBox: (atend) %%EndComments save %%BeginProlog /DotDict 200 dict def DotDict begin /setupLatin1 { mark /EncodingVector 256 array def EncodingVector 0 ISOLatin1Encoding 0 255 getinterval putinterval EncodingVector 45 /hyphen put % Set up ISO Latin 1 character encoding /starnetISO { dup dup findfont dup length dict begin { 1 index /FID ne { def }{ pop pop } ifelse } forall /Encoding EncodingVector def currentdict end definefont } def /Times-Roman starnetISO def /Times-Italic starnetISO def /Times-Bold starnetISO def /Times-BoldItalic starnetISO def /Helvetica starnetISO def /Helvetica-Oblique starnetISO def /Helvetica-Bold starnetISO def /Helvetica-BoldOblique starnetISO def /Courier starnetISO def /Courier-Oblique starnetISO def /Courier-Bold starnetISO def /Courier-BoldOblique starnetISO def cleartomark } bind def %%BeginResource: procset graphviz 0 0 /coord-font-family /Times-Roman def /default-font-family /Times-Roman def /coordfont coord-font-family findfont 8 scalefont def /InvScaleFactor 1.0 def /set_scale { dup 1 exch div /InvScaleFactor exch def scale } bind def % styles /solid { [] 0 setdash } bind def /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def /bold { 2 setlinewidth } bind def /filled { } bind def /unfilled { } bind def /rounded { } bind def /diagonals { } bind def % hooks for setting color /nodecolor { sethsbcolor } bind def /edgecolor { sethsbcolor } bind def /graphcolor { sethsbcolor } bind def /nopcolor {pop pop pop} bind def /beginpage { % i j npages /npages exch def /j exch def /i exch def /str 10 string def npages 1 gt { gsave coordfont setfont 0 0 moveto (\() show i str cvs show (,) show j str cvs show (\)) show grestore } if } bind def /set_font { findfont exch scalefont setfont } def % draw text fitted to its expected width /alignedtext { % width text /text exch def /width exch def gsave width 0 gt { [] 0 setdash text stringwidth pop width exch sub text length div 0 text ashow } if grestore } def /boxprim { % xcorner ycorner xsize ysize 4 2 roll moveto 2 copy exch 0 rlineto 0 exch rlineto pop neg 0 rlineto closepath } bind def /ellipse_path { /ry exch def /rx exch def /y exch def /x exch def matrix currentmatrix newpath x y translate rx ry scale 0 0 1 0 360 arc setmatrix } bind def /endpage { showpage } bind def /showpage { } def /layercolorseq [ % layer color sequence - darkest to lightest [0 0 0] [.2 .8 .8] [.4 .8 .8] [.6 .8 .8] [.8 .8 .8] ] def /layerlen layercolorseq length def /setlayer {/maxlayer exch def /curlayer exch def layercolorseq curlayer 1 sub layerlen mod get aload pop sethsbcolor /nodecolor {nopcolor} def /edgecolor {nopcolor} def /graphcolor {nopcolor} def } bind def /onlayer { curlayer ne {invis} if } def /onlayers { /myupper exch def /mylower exch def curlayer mylower lt curlayer myupper gt or {invis} if } def /curlayer 0 def %%EndResource %%EndProlog %%BeginSetup 14 default-font-family set_font 1 setmiterlimit % /arrowlength 10 def % /arrowwidth 5 def % make sure pdfmark is harmless for PS-interpreters other than Distiller /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse % make '<<' and '>>' safe on PS Level 1 devices /languagelevel where {pop languagelevel}{1} ifelse 2 lt { userdict (<<) cvn ([) cvn load put userdict (>>) cvn ([) cvn load put } if %%EndSetup setupLatin1 %%Page: 1 1 %%PageBoundingBox: 36 36 136 120 %%PageOrientation: Portrait 0 0 1 beginpage gsave 36 36 100 84 boxprim clip newpath 1 1 set_scale 0 rotate 40 41 translate % Node1 gsave 0 0 0.74902 nodecolor newpath 12 .5 moveto 12 19.5 lineto 80 19.5 lineto 80 .5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 12 .5 moveto 12 19.5 lineto 80 19.5 lineto 80 .5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 20 7.5 moveto 52 (QuaAdler32) alignedtext grestore % Node2 gsave [ /Rect [ 0 56 92 76 ] /Border [ 0 0 0 ] /Action << /Subtype /URI /URI ($classQuaChecksum32.html) >> /Subtype /Link /ANN pdfmark 0 0 1 nodecolor newpath 0 56.5 moveto 0 75.5 lineto 92 75.5 lineto 92 56.5 lineto closepath fill 1 setlinewidth filled 0 0 0 nodecolor newpath 0 56.5 moveto 0 75.5 lineto 92 75.5 lineto 92 56.5 lineto closepath stroke 0 0 0 nodecolor 10 /Helvetica set_font 8 63.5 moveto 76 (QuaChecksum32) alignedtext grestore % Node2->Node1 gsave 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 46 45.8 moveto 46 36.91 46 26.78 46 19.75 curveto stroke 0.66667 0.77647 0.43922 edgecolor newpath 42.5 46.08 moveto 46 56.08 lineto 49.5 46.08 lineto closepath fill 1 setlinewidth solid 0.66667 0.77647 0.43922 edgecolor newpath 42.5 46.08 moveto 46 56.08 lineto 49.5 46.08 lineto closepath stroke grestore endpage showpage grestore %%PageTrailer %%EndPage: 1 %%Trailer %%Pages: 1 %%BoundingBox: 36 36 136 120 end restore %%EOF mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/classQuaAdler32.tex0000644000175000017500000000724312070466513023537 0ustar csmallcsmall\section{QuaAdler32 Class Reference} \label{classQuaAdler32}\index{QuaAdler32@{QuaAdler32}} Adler32 checksum. {\ttfamily \#include $<$quazip/quaadler32.h$>$} Inheritance diagram for QuaAdler32: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=136pt]{classQuaAdler32__inherit__graph} \end{center} \end{figure} Collaboration diagram for QuaAdler32: \nopagebreak \begin{figure}[H] \begin{center} \leavevmode \includegraphics[width=136pt]{classQuaAdler32__coll__graph} \end{center} \end{figure} \subsection*{Public Member Functions} \begin{DoxyCompactItemize} \item quint32 {\bf calculate} (const QByteArray \&data) \begin{DoxyCompactList}\small\item\em Calculates the checksum for data. \end{DoxyCompactList}\item void {\bf reset} ()\label{classQuaAdler32_a2fe6ac9eb289bafda6a9fd20e6472ab5} \begin{DoxyCompactList}\small\item\em Resets the calculation on a checksun for a stream. \end{DoxyCompactList}\item void {\bf update} (const QByteArray \&buf) \begin{DoxyCompactList}\small\item\em Updates the calculated checksum for the stream. \end{DoxyCompactList}\item quint32 {\bf value} () \begin{DoxyCompactList}\small\item\em Value of the checksum calculated for the stream passed throw \doxyref{update()}{p.}{classQuaAdler32_aba24f7b16aa0cdc26f81a9ad687fc653}. \end{DoxyCompactList}\end{DoxyCompactItemize} \subsection{Detailed Description} Adler32 checksum. This class wrappers the adler32 function with the \doxyref{QuaChecksum32}{p.}{classQuaChecksum32} interface. See \doxyref{QuaChecksum32}{p.}{classQuaChecksum32} for more info. \subsection{Member Function Documentation} \index{QuaAdler32@{QuaAdler32}!calculate@{calculate}} \index{calculate@{calculate}!QuaAdler32@{QuaAdler32}} \subsubsection[{calculate}]{\setlength{\rightskip}{0pt plus 5cm}quint32 QuaAdler32::calculate ( \begin{DoxyParamCaption} \item[{const QByteArray \&}]{data} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaAdler32_a350e84fd000ebfa3c33503336a7b21bb} Calculates the checksum for data. {\itshape data\/} source data \begin{DoxyReturn}{Returns} data checksum \end{DoxyReturn} This function has no efect on the value returned by \doxyref{value()}{p.}{classQuaAdler32_a2022e1db95c23cef220b335e44d74fb1}. Implements {\bf QuaChecksum32} \doxyref{}{p.}{classQuaChecksum32_a14d800fcfd55b2ae11ef07d3924fe0b1}. \index{QuaAdler32@{QuaAdler32}!update@{update}} \index{update@{update}!QuaAdler32@{QuaAdler32}} \subsubsection[{update}]{\setlength{\rightskip}{0pt plus 5cm}void QuaAdler32::update ( \begin{DoxyParamCaption} \item[{const QByteArray \&}]{buf} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaAdler32_aba24f7b16aa0cdc26f81a9ad687fc653} Updates the calculated checksum for the stream. {\itshape buf\/} next portion of data from the stream Implements {\bf QuaChecksum32} \doxyref{}{p.}{classQuaChecksum32_a63a6ed3171f9243214d307da67557f7e}. \index{QuaAdler32@{QuaAdler32}!value@{value}} \index{value@{value}!QuaAdler32@{QuaAdler32}} \subsubsection[{value}]{\setlength{\rightskip}{0pt plus 5cm}quint32 QuaAdler32::value ( \begin{DoxyParamCaption} {} \end{DoxyParamCaption} )\hspace{0.3cm}{\ttfamily [virtual]}}\label{classQuaAdler32_a2022e1db95c23cef220b335e44d74fb1} Value of the checksum calculated for the stream passed throw \doxyref{update()}{p.}{classQuaAdler32_aba24f7b16aa0cdc26f81a9ad687fc653}. \begin{DoxyReturn}{Returns} checksum \end{DoxyReturn} Implements {\bf QuaChecksum32} \doxyref{}{p.}{classQuaChecksum32_afd836e7534194fce08356be6a8336da7}. The documentation for this class was generated from the following files:\begin{DoxyCompactItemize} \item quazip/quaadler32.h\item quazip/quaadler32.cpp\end{DoxyCompactItemize} mudlet-2.1/src/quazip/quazip-0.4.4/doc/latex/doxygen.sty0000644000175000017500000002345512070466513022345 0ustar csmallcsmall\NeedsTeXFormat{LaTeX2e} \ProvidesPackage{doxygen} % Packages used by this style file \RequirePackage{alltt} \RequirePackage{array} \RequirePackage{calc} \RequirePackage{color} \RequirePackage{fancyhdr} \RequirePackage{longtable} \RequirePackage{verbatim} \RequirePackage{ifthen} \RequirePackage[table]{xcolor} % Use helvetica font instead of times roman \RequirePackage{helvet} \RequirePackage{sectsty} \RequirePackage{tocloft} \providecommand{\rmdefault}{phv} \providecommand{\bfdefault}{bc} % Setup fancy headings \pagestyle{fancyplain} \newcommand{\clearemptydoublepage}{% \newpage{\pagestyle{empty}\cleardoublepage}% } \renewcommand{\chaptermark}[1]{% \markboth{#1}{}% } \renewcommand{\sectionmark}[1]{% \markright{\thesection\ #1}% } \fancyhead[LE]{\fancyplain{}{\bfseries\thepage}} \fancyhead[CE]{\fancyplain{}{}} \fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}} \fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}} \fancyhead[CO]{\fancyplain{}{}} \fancyhead[RO]{\fancyplain{}{\bfseries\thepage}} \fancyfoot[LE]{\fancyplain{}{}} \fancyfoot[CE]{\fancyplain{}{}} \fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize Generated on Sat Jan 14 2012 14:54:05 for QuaZIP by Doxygen }} \fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize Generated on Sat Jan 14 2012 14:54:05 for QuaZIP by Doxygen }} \fancyfoot[CO]{\fancyplain{}{}} \fancyfoot[RO]{\fancyplain{}{}} %---------- Internal commands used in this style file ---------------- % Generic environment used by all paragraph-based environments defined % below. Note that the command \title{...} needs to be defined inside % those environments! \newenvironment{DoxyDesc}[1]{% \begin{list}{}% {% \settowidth{\labelwidth}{40pt}% \setlength{\leftmargin}{\labelwidth}% \setlength{\parsep}{0pt}% \setlength{\itemsep}{-4pt}% \renewcommand{\makelabel}{\entrylabel}% }% \item[#1]% }{% \end{list}% } %---------- Commands used by doxygen LaTeX output generator ---------- % Used by
 ... 
\newenvironment{DoxyPre}{% \small% \begin{alltt}% }{% \end{alltt}% \normalsize% } % Used by @code ... @endcode \newenvironment{DoxyCode}{% \footnotesize% \verbatim% }{% \endverbatim% \normalsize% } % Used by @example, @include, @includelineno and @dontinclude \newenvironment{DoxyCodeInclude}{% \DoxyCode% }{% \endDoxyCode% } % Used by @verbatim ... @endverbatim \newenvironment{DoxyVerb}{% \footnotesize% \verbatim% }{% \endverbatim% \normalsize% } % Used by @verbinclude \newenvironment{DoxyVerbInclude}{% \DoxyVerb% }{% \endDoxyVerb% } % Used by numbered lists (using '-#' or
    ...
) \newenvironment{DoxyEnumerate}{% \enumerate% }{% \endenumerate% } % Used by bullet lists (using '-', @li, @arg, or
    ...
) \newenvironment{DoxyItemize}{% \itemize% }{% \enditemize% } % Used by description lists (using
...
) \newenvironment{DoxyDescription}{% \description% }{% \enddescription% } % Used by @image, @dotfile, and @dot ... @enddot % (only if caption is specified) \newenvironment{DoxyImage}{% \begin{figure}[H]% \begin{center}% }{% \end{center}% \end{figure}% } % Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc % (only if no caption is specified) \newenvironment{DoxyImageNoCaption}{% }{% } % Used by @attention \newenvironment{DoxyAttention}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @author and @authors \newenvironment{DoxyAuthor}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @date \newenvironment{DoxyDate}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @invariant \newenvironment{DoxyInvariant}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @note \newenvironment{DoxyNote}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @post \newenvironment{DoxyPostcond}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @pre \newenvironment{DoxyPrecond}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @remark \newenvironment{DoxyRemark}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @return \newenvironment{DoxyReturn}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @since \newenvironment{DoxySince}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @see \newenvironment{DoxySeeAlso}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @version \newenvironment{DoxyVersion}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @warning \newenvironment{DoxyWarning}[1]{% \begin{DoxyDesc}{#1}% }{% \end{DoxyDesc}% } % Used by @internal \newenvironment{DoxyInternal}[1]{% \paragraph*{#1}% }{% } % Used by @par and @paragraph \newenvironment{DoxyParagraph}[1]{% \begin{list}{}% {% \settowidth{\labelwidth}{40pt}% \setlength{\leftmargin}{\labelwidth}% \setlength{\parsep}{0pt}% \setlength{\itemsep}{-4pt}% \renewcommand{\makelabel}{\entrylabel}% }% \item[#1]% }{% \end{list}% } % Used by parameter lists \newenvironment{DoxyParams}[2][]{% \begin{DoxyDesc}{#2}% \begin{description}% \item[] \hspace{\fill} \vspace{-25pt}% \definecolor{tableShade}{HTML}{F8F8F8}% \rowcolors{1}{white}{tableShade}% \arrayrulecolor{gray}% \setlength{\tabcolsep}{0.01\textwidth}% \ifthenelse{\equal{#1}{}} {\begin{longtable}{|>{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% p{0.87\textwidth}|}}% {\ifthenelse{\equal{#1}{1}}% {\begin{longtable}{|>{\centering}p{0.10\textwidth}|% >{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% p{0.75\textwidth}|}}% {\begin{longtable}{|>{\centering}p{0.10\textwidth}|% >{\centering\hspace{0pt}}p{0.15\textwidth}|% >{\raggedleft\hspace{0pt}}p{0.15\textwidth}|% p{0.58\textwidth}|}}% }\hline% }{% \end{longtable}% \end{description}% \end{DoxyDesc}% } % is used for parameters within a detailed function description \newenvironment{DoxyParamCaption}{% \renewcommand{\item}[2][]{##1 {\em ##2}}% }{% } % Used by return value lists \newenvironment{DoxyRetVals}[1]{% \begin{DoxyDesc}{#1}% \begin{description}% \item[] \hspace{\fill} \vspace{-25pt}% \definecolor{tableShade}{HTML}{F8F8F8}% \rowcolors{1}{white}{tableShade}% \arrayrulecolor{gray}% \setlength{\tabcolsep}{0.01\textwidth}% \begin{longtable}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|% p{0.77\textwidth}|}% \hline% }{% \end{longtable}% \end{description}% \end{DoxyDesc}% } % Used by exception lists \newenvironment{DoxyExceptions}[1]{% \begin{DoxyDesc}{#1}% \begin{description}% \item[] \hspace{\fill} \vspace{-25pt}% \definecolor{tableShade}{HTML}{F8F8F8}% \rowcolors{1}{white}{tableShade}% \arrayrulecolor{gray}% \setlength{\tabcolsep}{0.01\textwidth}% \begin{longtable}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|% p{0.77\textwidth}|}% \hline% }{% \end{longtable}% \end{description}% \end{DoxyDesc}% } % Used by template parameter lists \newenvironment{DoxyTemplParams}[1]{% \begin{DoxyDesc}{#1}% \begin{description}% \item[] \hspace{\fill} \vspace{-25pt}% \definecolor{tableShade}{HTML}{F8F8F8}% \rowcolors{1}{white}{tableShade}% \arrayrulecolor{gray}% \setlength{\tabcolsep}{0.01\textwidth}% \begin{longtable}{|>{\raggedleft\hspace{0pt}}p{0.25\textwidth}|% p{0.77\textwidth}|}% \hline% }{% \end{longtable}% \end{description}% \end{DoxyDesc}% } \newcommand{\doxyref}[3]{\textbf{#1} (\textnormal{#2}\,\pageref{#3})} \newenvironment{DoxyCompactList} {\begin{list}{}{ \setlength{\leftmargin}{0.5cm} \setlength{\itemsep}{0pt} \setlength{\parsep}{0pt} \setlength{\topsep}{0pt} \renewcommand{\makelabel}{\hfill}}} {\end{list}} \newenvironment{DoxyCompactItemize} { \begin{itemize} \setlength{\itemsep}{-3pt} \setlength{\parsep}{0pt} \setlength{\topsep}{0pt} \setlength{\partopsep}{0pt} } {\end{itemize}} \newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp} \newlength{\tmplength} \newenvironment{TabularC}[1] { \setlength{\tmplength} {\linewidth/(#1)-\tabcolsep*2-\arrayrulewidth*(#1+1)/(#1)} \par\begin{tabular*}{\linewidth} {*{#1}{|>{\PBS\raggedright\hspace{0pt}}p{\the\tmplength}}|} } {\end{tabular*}\par} \newcommand{\entrylabel}[1]{ {\parbox[b]{\labelwidth-4pt}{\makebox[0pt][l]{\textbf{#1}}\vspace{1.5\baselineskip}}}} \newenvironment{Desc} {\begin{list}{} { \settowidth{\labelwidth}{40pt} \setlength{\leftmargin}{\labelwidth} \setlength{\parsep}{0pt} \setlength{\itemsep}{-4pt} \renewcommand{\makelabel}{\entrylabel} } } {\end{list}} \newenvironment{Indent} {\begin{list}{}{\setlength{\leftmargin}{0.5cm}} \item[]\ignorespaces} {\unskip\end{list}} \setlength{\parindent}{0cm} \setlength{\parskip}{0.2cm} \addtocounter{secnumdepth}{2} \usepackage[T1]{fontenc} \makeatletter \renewcommand{\paragraph}{\@startsection{paragraph}{4}{0ex}% {-1.0ex}% {1.0ex}% {\usefont{OT1}{phv}{bc}{n}\color{darkgray}}} \renewcommand{\subparagraph}{\@startsection{subparagraph}{5}{0ex}% {-1.0ex}% {1.0ex}% {\usefont{OT1}{phv}{bc}{n}\color{darkgray}}} \makeatother \allsectionsfont{\usefont{OT1}{phv}{bc}{n}\selectfont\color{darkgray}} \stepcounter{secnumdepth} \stepcounter{tocdepth} \definecolor{comment}{rgb}{0.5,0.0,0.0} \definecolor{keyword}{rgb}{0.0,0.5,0.0} \definecolor{keywordtype}{rgb}{0.38,0.25,0.125} \definecolor{keywordflow}{rgb}{0.88,0.5,0.0} \definecolor{preprocessor}{rgb}{0.5,0.38,0.125} \definecolor{stringliteral}{rgb}{0.0,0.125,0.25} \definecolor{charliteral}{rgb}{0.0,0.5,0.5} \definecolor{vhdldigit}{rgb}{1.0,0.0,1.0} \definecolor{vhdlkeyword}{rgb}{0.43,0.0,0.43} \definecolor{vhdllogic}{rgb}{1.0,0.0,0.0} \definecolor{vhdlchar}{rgb}{0.0,0.0,0.0} mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/0000755000175000017500000000000012070466513017745 5ustar csmallcsmallmudlet-2.1/src/quazip/quazip-0.4.4/doc/html/quachecksum32_8h_source.html0000644000175000017500000000711212070466513025271 0ustar csmallcsmall QuaZIP: quazip/quachecksum32.h Source File
quachecksum32.h
00001 #ifndef QUACHECKSUM32_H
00002 #define QUACHECKSUM32_H
00003 
00004 #include <QByteArray>
00005 #include "quazip_global.h"
00006 
00008 
00028 class QUAZIP_EXPORT QuaChecksum32
00029 {
00030 
00031 public:
00033 
00038         virtual quint32 calculate(const QByteArray &data) = 0;
00039 
00041         virtual void reset() = 0;
00042 
00044 
00046         virtual void update(const QByteArray &buf) = 0;
00047 
00049 
00051         virtual quint32 value() = 0;
00052 };
00053 
00054 #endif //QUACHECKSUM32_H
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/bc_s.png0000644000175000017500000000130112070466513021354 0ustar csmallcsmallPNG  IHDR /9IDATxKQ9 QuaZIP: QuaZIP - Qt/C++ wrapper for ZIP/UNZIP package
QuaZIP - Qt/C++ wrapper for ZIP/UNZIP package
Powered by SourceForge.net

Overview

QuaZIP is a simple C++ wrapper over Gilles Vollant's ZIP/UNZIP package that can be used to access ZIP archives. It uses Trolltech's Qt toolkit.

If you do not know what Qt is, you have two options:

The choice is yours, but if you are really interested in cross-platform (Windows/Linux/BSD/UNIX/Mac/Others) software development, I would definitely recommend you the second choice ^_^

QuaZIP allows you to access files inside ZIP archives using QIODevice API, and - yes! - that means that you can also use QTextStream, QDataStream or whatever you would like to use on your zipped files.

QuaZIP provides complete abstraction of the ZIP/UNZIP API, for both reading from and writing to ZIP archives.

Download QuaZIP

Downloads are available from QuaZIP project's page at SourceForge.net.

Platforms supported

QuaZIP has been currently tested with Qt 4.0.0 on the following platforms:

  • linux-g++
  • freebsd-g++
  • hpux-acc
  • win32-g++ (MinGW)

No testing has been done on other systems. Of course, patches to make it work on any platform that it currently does not work on are always welcome!

What is new in this version of QuaZIP?

See the NEWS file supplied with the distribution.

Requirements

Just zlib and Qt 4. Well, Qt 4 depends on zlib anyway.

Building, testing and installing

Note:
Instructions given in this section assume that you are using some UNIX dialect, but the build process should be very similar on win32-g++ platform too. On other platforms it's essentially the same process, maybe with some qmake adjustments not specific to QuaZIP itself.

To build the library, run:

$ cd /wherever/quazip/source/is/quazip-x.y.z/quazip
$ qmake [PREFIX=where-to-install]
$ make

Make sure that you have Qt 4 installed with all required headers and utilities (not just library) and that you run qmake utility of the Qt 4, not some other version you may have already installed (you may need to type full path to qmake like /usr/local/qt4/bin/qmake).

To reconfigure (with another PREFIX, for example), just run qmake with appropriate arguments again.

If you need to specify additional include path or libraries, use qmake features (see qmake reference in the Qt documentation). For example:

$ qmake LIBS+=-L/usr/local/zlib/lib INCLUDEPATH+=/usr/local/zlib/include

(note abscence of "-I" before include path)

To check if QuaZIP's basic features work ok on your platform, you may wish to compile simple test programs provided in test directory. Look in the sources of the tests to find out about their requirements. Typically, the test looks something like this:

$ cd /wherever/quazip/source/is/quazip-x.y.z/test/zip
$ qmake
$ make
$ ./zip
$ cd ../unzip
$ cp ../zip/test.zip ./test.zip
$ mkdir out
$ qmake
$ make
$ ./unzip

You should see the zip contents with details as the output of the "./unzip". Ignore message saying you should check the file name for testCase() if you do not want to test locale-aware case-insensitivity. Otherwise, see the sources. In any case, this message appearing means that everything else was fine. Otherwise, you will get some other error message instead. Investigate it or send bug report including message, platform and QuaZIP version used.

To install compiled library:

$ make install

By default, QuaZIP compiles as a DLL, but you have other options:

  • Just copy appropriate source files to your project and use them, but you need to define QUAZIP_STATIC before including any QuaZIP headers (best done as a compiler option). This will save you from possile side effects of importing/exporting QuaZIP symbols.
  • Compile it as a static library using CONFIG += staticlib qmake option. QUAZIP_STATIC is defined automatically by qmake in this case.

Binary compatibility isn't guaranteed even between minor releases, but usually it's preserved, thanks to the Pimpl idiom.

Using

See usage page.

Authors and contacts

This wrapper has been written by Sergey A. Tachenov, AKA Alqualos. This is my first open source project, so it may suck, but I did not find anything like that, so I just had no other choice but to write it.

If you have anything to say to me about QuaZIP library, feel free to do so (read the QuaZip FAQ first, though). I can not promise, though, that I fix all the bugs you report in, add any features you want, or respond to your critics, or respond to your feedback at all. I may be busy, I may be tired of working on QuaZIP, I may be even dead already (you never know...).

To report bugs or to post ideas about what should be done, use SourceForge.net's trackers. If you want to send me a private message, use my e-mail address stachenov@gmail.com.

Do not use e-mail to report bugs, please. Reporting bugs and problems with the SourceForge.net's bug report system has that advantage that it is visible to public, and I can always search for open tickets that were created long ago. It is highly unlikely that I will search my mail for that kind of stuff, so if a bug reported by mail isn't fixed immediately, it will likely be forgotten forever.

Copyright (C) 2005-2011 Sergey A. Tachenov

mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaCrc32__inherit__graph.md50000644000175000017500000000004012070466513026120 0ustar csmallcsmallc5893d01f9e8b7b19610a8cce32f67e4mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipFile.html0000644000175000017500000021405712070466513023703 0ustar csmallcsmall QuaZIP: QuaZipFile Class Reference

A file inside ZIP archive. More...

#include <quazip/quazipfile.h>

Collaboration diagram for QuaZipFile:

List of all members.

Public Member Functions

 QuaZipFile ()
 Constructs a QuaZipFile instance.
 QuaZipFile (QObject *parent)
 Constructs a QuaZipFile instance.
 QuaZipFile (const QString &zipName, QObject *parent=NULL)
 Constructs a QuaZipFile instance.
 QuaZipFile (const QString &zipName, const QString &fileName, QuaZip::CaseSensitivity cs=QuaZip::csDefault, QObject *parent=NULL)
 Constructs a QuaZipFile instance.
 QuaZipFile (QuaZip *zip, QObject *parent=NULL)
 Constructs a QuaZipFile instance.
virtual ~QuaZipFile ()
 Destroys a QuaZipFile instance.
QString getZipName () const
 Returns the ZIP archive file name.
QuaZipgetZip () const
 Returns a pointer to the associated QuaZip object.
QString getFileName () const
 Returns file name.
QuaZip::CaseSensitivity getCaseSensitivity () const
 Returns case sensitivity of the file name.
QString getActualFileName () const
 Returns the actual file name in the archive.
void setZipName (const QString &zipName)
 Sets the ZIP archive file name.
bool isRaw () const
 Returns true if the file was opened in raw mode.
void setZip (QuaZip *zip)
 Binds to the existing QuaZip instance.
void setFileName (const QString &fileName, QuaZip::CaseSensitivity cs=QuaZip::csDefault)
 Sets the file name.
virtual bool open (OpenMode mode)
 Opens a file for reading.
bool open (OpenMode mode, const char *password)
 Opens a file for reading.
bool open (OpenMode mode, int *method, int *level, bool raw, const char *password=NULL)
 Opens a file for reading.
bool open (OpenMode mode, const QuaZipNewInfo &info, const char *password=NULL, quint32 crc=0, int method=Z_DEFLATED, int level=Z_DEFAULT_COMPRESSION, bool raw=false, int windowBits=-MAX_WBITS, int memLevel=DEF_MEM_LEVEL, int strategy=Z_DEFAULT_STRATEGY)
 Opens a file for writing.
virtual bool isSequential () const
 Returns true, but beware!
virtual qint64 pos () const
 Returns current position in the file.
virtual bool atEnd () const
 Returns true if the end of file was reached.
virtual qint64 size () const
 Returns file size.
qint64 csize () const
 Returns compressed file size.
qint64 usize () const
 Returns uncompressed file size.
bool getFileInfo (QuaZipFileInfo *info)
 Gets information about current file.
virtual void close ()
 Closes the file.
int getZipError () const
 Returns the error code returned by the last ZIP/UNZIP API call.
virtual qint64 bytesAvailable () const
 Returns the number of bytes available for reading.

Protected Member Functions

qint64 readData (char *data, qint64 maxSize)
 Implementation of the QIODevice::readData().
qint64 writeData (const char *data, qint64 maxSize)
 Implementation of the QIODevice::writeData().

Friends

class QuaZipFilePrivate

Detailed Description

A file inside ZIP archive.

This is the most interesting class. Not only it provides C++ interface to the ZIP/UNZIP package, but also integrates it with Qt by subclassing QIODevice. This makes possible to access files inside ZIP archive using QTextStream or QDataStream, for example. Actually, this is the main purpose of the whole QuaZIP library.

You can either use existing QuaZip instance to create instance of this class or pass ZIP archive file name to this class, in which case it will create internal QuaZip object. See constructors' descriptions for details. Writing is only possible with the existing instance.

Note that due to the underlying library's limitation it is not possible to use multiple QuaZipFile instances to open several files in the same archive at the same time. If you need to write to multiple files in parallel, then you should write to temporary files first, then pack them all at once when you have finished writing. If you need to read multiple files inside the same archive in parallel, you should extract them all into a temporary directory first.

Sequential or random-access?

At the first thought, QuaZipFile has fixed size, the start and the end and should be therefore considered random-access device. But there is one major obstacle to making it random-access: ZIP/UNZIP API does not support seek() operation and the only way to implement it is through reopening the file and re-reading to the required position, but this is prohibitively slow.

Therefore, QuaZipFile is considered to be a sequential device. This has advantage of availability of the ungetChar() operation (QIODevice does not implement it properly for non-sequential devices unless they support seek()). Disadvantage is a somewhat strange behaviour of the size() and pos() functions. This should be kept in mind while using this class.


Constructor & Destructor Documentation

QuaZipFile::QuaZipFile ( )

Constructs a QuaZipFile instance.

You should use setZipName() and setFileName() or setZip() before trying to call open() on the constructed object.

QuaZipFile::QuaZipFile ( QObject *  parent)

Constructs a QuaZipFile instance.

parent argument specifies this object's parent object.

You should use setZipName() and setFileName() or setZip() before trying to call open() on the constructed object.

QuaZipFile::QuaZipFile ( const QString &  zipName,
QObject *  parent = NULL 
)

Constructs a QuaZipFile instance.

parent argument specifies this object's parent object and zipName specifies ZIP archive file name.

You should use setFileName() before trying to call open() on the constructed object.

QuaZipFile constructed by this constructor can be used for read only access. Use QuaZipFile(QuaZip*,QObject*) for writing.

QuaZipFile::QuaZipFile ( const QString &  zipName,
const QString &  fileName,
QuaZip::CaseSensitivity  cs = QuaZip::csDefault,
QObject *  parent = NULL 
)

Constructs a QuaZipFile instance.

parent argument specifies this object's parent object, zipName specifies ZIP archive file name and fileName and cs specify a name of the file to open inside archive.

QuaZipFile constructed by this constructor can be used for read only access. Use QuaZipFile(QuaZip*,QObject*) for writing.

See also:
QuaZip::setCurrentFile()
QuaZipFile::QuaZipFile ( QuaZip zip,
QObject *  parent = NULL 
)

Constructs a QuaZipFile instance.

parent argument specifies this object's parent object.

zip is the pointer to the existing QuaZip object. This QuaZipFile object then can be used to read current file in the zip or to write to the file inside it.

Warning:
Using this constructor for reading current file can be tricky. Let's take the following example:
 QuaZip zip("archive.zip");
 zip.open(QuaZip::mdUnzip);
 zip.setCurrentFile("file-in-archive");
 QuaZipFile file(&zip);
 file.open(QIODevice::ReadOnly);
 // ok, now we can read from the file
 file.read(somewhere, some);
 zip.setCurrentFile("another-file-in-archive"); // oops...
 QuaZipFile anotherFile(&zip);
 anotherFile.open(QIODevice::ReadOnly);
 anotherFile.read(somewhere, some); // this is still ok...
 file.read(somewhere, some); // and this is NOT
So, what exactly happens here? When we change current file in the zip archive, file that references it becomes invalid (actually, as far as I understand ZIP/UNZIP sources, it becomes closed, but QuaZipFile has no means to detect it).

Summary: do not close zip object or change its current file as long as QuaZipFile is open. Even better - use another constructors which create internal QuaZip instances, one per object, and therefore do not cause unnecessary trouble. This constructor may be useful, though, if you already have a QuaZip instance and do not want to access several files at once. Good example:

 QuaZip zip("archive.zip");
 zip.open(QuaZip::mdUnzip);
 // first, we need some information about archive itself
 QByteArray comment=zip.getComment();
 // and now we are going to access files inside it
 QuaZipFile file(&zip);
 for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) {
   file.open(QIODevice::ReadOnly);
   // do something cool with file here
   file.close(); // do not forget to close!
 }
 zip.close();
QuaZipFile::~QuaZipFile ( ) [virtual]

Destroys a QuaZipFile instance.

Closes file if open, destructs internal QuaZip object (if it exists and is internal, of course).

References close().


Member Function Documentation

QString QuaZipFile::getZipName ( ) const

Returns the ZIP archive file name.

If this object was created by passing QuaZip pointer to the constructor, this function will return that QuaZip's file name (or null string if that object does not have file name yet).

Otherwise, returns associated ZIP archive file name or null string if there are no name set yet.

See also:
setZipName() getFileName()

References QuaZip::getZipName().

QuaZip * QuaZipFile::getZip ( ) const

Returns a pointer to the associated QuaZip object.

Returns NULL if there is no associated QuaZip or it is internal (so you will not mess with it).

QString QuaZipFile::getFileName ( ) const

Returns file name.

This function returns file name you passed to this object either by using QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) or by calling setFileName(). Real name of the file may differ in case if you used case-insensitivity.

Returns null string if there is no file name set yet. This is the case when this QuaZipFile operates on the existing QuaZip object (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used).

See also:
getActualFileName
QuaZip::CaseSensitivity QuaZipFile::getCaseSensitivity ( ) const

Returns case sensitivity of the file name.

This function returns case sensitivity argument you passed to this object either by using QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) or by calling setFileName().

Returns unpredictable value if getFileName() returns null string (this is the case when you did not used setFileName() or constructor above).

See also:
getFileName
QString QuaZipFile::getActualFileName ( ) const

Returns the actual file name in the archive.

This is not a ZIP archive file name, but a name of file inside archive. It is not necessary the same name that you have passed to the QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*), setFileName() or QuaZip::setCurrentFile() - this is the real file name inside archive, so it may differ in case if the file name search was case-insensitive.

Equivalent to calling getCurrentFileName() on the associated QuaZip object. Returns null string if there is no associated QuaZip object or if it does not have a current file yet. And this is the case if you called setFileName() but did not open the file yet. So this is perfectly fine:

 QuaZipFile file("somezip.zip");
 file.setFileName("somefile");
 QString name=file.getName(); // name=="somefile"
 QString actual=file.getActualFileName(); // actual is null string
 file.open(QIODevice::ReadOnly);
 QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows
See also:
getZipName(), getFileName(), QuaZip::CaseSensitivity

References QuaZip::getCurrentFileName(), and QuaZip::getZipError().

void QuaZipFile::setZipName ( const QString &  zipName)

Sets the ZIP archive file name.

Automatically creates internal QuaZip object and destroys previously created internal QuaZip object, if any.

Will do nothing if this file is already open. You must close() it first.

bool QuaZipFile::isRaw ( ) const

Returns true if the file was opened in raw mode.

If the file is not open, the returned value is undefined.

See also:
open(OpenMode,int*,int*,bool,const char*)

Referenced by close().

void QuaZipFile::setZip ( QuaZip zip)

Binds to the existing QuaZip instance.

This function destroys internal QuaZip object, if any, and makes this QuaZipFile to use current file in the zip object for any further operations. See QuaZipFile(QuaZip*,QObject*) for the possible pitfalls.

Will do nothing if the file is currently open. You must close() it first.

void QuaZipFile::setFileName ( const QString &  fileName,
QuaZip::CaseSensitivity  cs = QuaZip::csDefault 
)

Sets the file name.

Will do nothing if at least one of the following conditions is met:

  • ZIP name has not been set yet (getZipName() returns null string).
  • This QuaZipFile is associated with external QuaZip. In this case you should call that QuaZip's setCurrentFile() function instead!
  • File is already open so setting the name is meaningless.
See also:
QuaZip::setCurrentFile
bool QuaZipFile::open ( OpenMode  mode) [virtual]

Opens a file for reading.

Returns true on success, false otherwise. Call getZipError() to get error code.

Note:
Since ZIP/UNZIP API provides buffered reading only, QuaZipFile does not support unbuffered reading. So do not pass QIODevice::Unbuffered flag in mode, or open will fail.
bool QuaZipFile::open ( OpenMode  mode,
const char *  password 
) [inline]

Opens a file for reading.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Argument password specifies a password to decrypt the file. If it is NULL then this function behaves just like open(OpenMode).

References open().

Referenced by open().

bool QuaZipFile::open ( OpenMode  mode,
int *  method,
int *  level,
bool  raw,
const char *  password = NULL 
)

Opens a file for reading.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Argument password specifies a password to decrypt the file.

An integers pointed by method and level will receive codes of the compression method and level used. See unzip.h.

If raw is true then no decompression is performed.

method should not be NULL. level can be NULL if you don't want to know the compression level.

References QuaZip::close(), QuaZip::getMode(), QuaZip::getUnzFile(), QuaZip::getZipError(), QuaZip::hasCurrentFile(), QuaZip::mdUnzip, QuaZip::open(), and QuaZip::setCurrentFile().

bool QuaZipFile::open ( OpenMode  mode,
const QuaZipNewInfo info,
const char *  password = NULL,
quint32  crc = 0,
int  method = Z_DEFLATED,
int  level = Z_DEFAULT_COMPRESSION,
bool  raw = false,
int  windowBits = -MAX_WBITS,
int  memLevel = DEF_MEM_LEVEL,
int  strategy = Z_DEFAULT_STRATEGY 
)

Opens a file for writing.

info argument specifies information about file. It should at least specify a correct file name. Also, it is a good idea to specify correct timestamp (by default, current time will be used). See QuaZipNewInfo.

The password argument specifies the password for crypting. Pass NULL if you don't need any crypting. The crc argument was supposed to be used for crypting too, but then it turned out that it's false information, so you need to set it to 0 unless you want to use the raw mode (see below).

Arguments method and level specify compression method and level. The only method supported is Z_DEFLATED, but you may also specify 0 for no compression. If all of the files in the archive use both method 0 and either level 0 is explicitly specified or data descriptor writing is disabled with QuaZip::setDataDescriptorWritingEnabled(), then the resulting archive is supposed to be compatible with the 1.0 ZIP format version, should you need that. Except for this, level has no other effects with method 0.

If raw is true, no compression is performed. In this case, crc and uncompressedSize field of the info are required.

Arguments windowBits, memLevel, strategy provide zlib algorithms tuning. See deflateInit2() in zlib.

References QuaZipNewInfo::comment, QuaZipNewInfo::dateTime, QuaZipNewInfo::externalAttr, QuaZipNewInfo::extraGlobal, QuaZipNewInfo::extraLocal, QuaZip::getCommentCodec(), QuaZip::getFileNameCodec(), QuaZip::getMode(), QuaZip::getZipFile(), QuaZipNewInfo::internalAttr, QuaZip::isDataDescriptorWritingEnabled(), QuaZip::mdAdd, QuaZip::mdAppend, QuaZip::mdCreate, QuaZipNewInfo::name, and QuaZipNewInfo::uncompressedSize.

qint64 QuaZipFile::pos ( ) const [virtual]

Returns current position in the file.

Implementation of the QIODevice::pos(). When reading, this function is a wrapper to the ZIP/UNZIP unztell(), therefore it is unable to keep track of the ungetChar() calls (which is non-virtual and therefore is dangerous to reimplement). So if you are using ungetChar() feature of the QIODevice, this function reports incorrect value until you get back characters which you ungot.

When writing, pos() returns number of bytes already written (uncompressed unless you use raw mode).

Note:
Although QuaZipFile is a sequential device and therefore pos() should always return zero, it does not, because it would be misguiding. Keep this in mind.

This function returns -1 if the file or archive is not open.

Error code returned by getZipError() is not affected by this function call.

References QuaZip::getUnzFile().

Referenced by bytesAvailable().

bool QuaZipFile::atEnd ( ) const [virtual]

Returns true if the end of file was reached.

This function returns false in the case of error. This means that you called this function on either not open file, or a file in the not open archive or even on a QuaZipFile instance that does not even have QuaZip instance associated. Do not do that because there is no means to determine whether false is returned because of error or because end of file was reached. Well, on the other side you may interpret false return value as "there is no file open to check for end of file and there is no end of file therefore".

When writing, this function always returns true (because you are always writing to the end of file).

Error code returned by getZipError() is not affected by this function call.

References bytesAvailable(), and QuaZip::getUnzFile().

qint64 QuaZipFile::size ( ) const [virtual]

Returns file size.

This function returns csize() if the file is open for reading in raw mode, usize() if it is open for reading in normal mode and pos() if it is open for writing.

Returns -1 on error, call getZipError() to get error code.

Note:
This function returns file size despite that QuaZipFile is considered to be sequential device, for which size() should return bytesAvailable() instead. But its name would be very misguiding otherwise, so just keep in mind this inconsistence.

References csize(), and usize().

Referenced by bytesAvailable().

qint64 QuaZipFile::csize ( ) const

Returns compressed file size.

Equivalent to calling getFileInfo() and then getting compressedSize field, but more convenient and faster.

File must be open for reading before calling this function.

Returns -1 on error, call getZipError() to get error code.

References QuaZip::getMode(), QuaZip::getUnzFile(), and QuaZip::mdUnzip.

Referenced by size().

qint64 QuaZipFile::usize ( ) const

Returns uncompressed file size.

Equivalent to calling getFileInfo() and then getting uncompressedSize field, but more convenient and faster. See getFileInfo() for a warning.

File must be open for reading before calling this function.

Returns -1 on error, call getZipError() to get error code.

References QuaZip::getMode(), QuaZip::getUnzFile(), and QuaZip::mdUnzip.

Referenced by size().

bool QuaZipFile::getFileInfo ( QuaZipFileInfo info)

Gets information about current file.

This function does the same thing as calling QuaZip::getCurrentFileInfo() on the associated QuaZip object, but you can not call getCurrentFileInfo() if the associated QuaZip is internal (because you do not have access to it), while you still can call this function in that case.

File must be open for reading before calling this function.

Returns false in the case of an error.

References QuaZip::getCurrentFileInfo(), QuaZip::getMode(), QuaZip::getZipError(), and QuaZip::mdUnzip.

void QuaZipFile::close ( ) [virtual]

Closes the file.

Call getZipError() to determine if the close was successful.

References QuaZip::close(), QuaZip::getUnzFile(), QuaZip::getZipError(), QuaZip::getZipFile(), QuaZip::isOpen(), and isRaw().

Referenced by ~QuaZipFile().


The documentation for this class was generated from the following files:
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaChecksum32.html0000644000175000017500000002216112070466513024241 0ustar csmallcsmall QuaZIP: QuaChecksum32 Class Reference
QuaChecksum32 Class Reference

Checksum interface. More...

#include <quazip/quachecksum32.h>

Inheritance diagram for QuaChecksum32:

List of all members.

Public Member Functions

virtual quint32 calculate (const QByteArray &data)=0
 Calculates the checksum for data.
virtual void reset ()=0
 Resets the calculation on a checksun for a stream.
virtual void update (const QByteArray &buf)=0
 Updates the calculated checksum for the stream.
virtual quint32 value ()=0
 Value of the checksum calculated for the stream passed throw update().

Detailed Description

Checksum interface.

This is an interface for 32 bit checksums. Classes implementing this interface can calcunate a certin checksum in a single step:

 QChecksum32 *crc32 = new QuaCrc32(); 
 rasoult = crc32->calculate(data);

or by streaming the data:

 QChecksum32 *crc32 = new QuaCrc32(); 
 while(!fileA.atEnd())
     crc32->update(fileA.read(bufSize));
 resoultA = crc32->value();
 crc32->reset();
 while(!fileB.atEnd())
     crc32->update(fileB.read(bufSize));
 resoultB = crc32->value();

Member Function Documentation

virtual quint32 QuaChecksum32::calculate ( const QByteArray &  data) [pure virtual]

Calculates the checksum for data.

data source data

Returns:
data checksum

This function has no efect on the value returned by value().

Implemented in QuaAdler32, and QuaCrc32.

virtual void QuaChecksum32::update ( const QByteArray &  buf) [pure virtual]

Updates the calculated checksum for the stream.

buf next portion of data from the stream

Implemented in QuaAdler32, and QuaCrc32.

virtual quint32 QuaChecksum32::value ( ) [pure virtual]

Value of the checksum calculated for the stream passed throw update().

Returns:
checksum

Implemented in QuaAdler32, and QuaCrc32.


The documentation for this class was generated from the following file:
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/open.png0000644000175000017500000000016612070466513021417 0ustar csmallcsmallPNG  IHDR =IDATx1 ت@@ ]01QXY~Jr?D>n F͐ }\ áIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipFile__coll__graph.md50000644000175000017500000000004012070466513026075 0ustar csmallcsmall3cca548c6e61503dea7d82da54af1f8amudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_3.png0000644000175000017500000000071312070466513023521 0ustar csmallcsmallPNG  IHDR`%2o{bKGDIDATh Eak#1 sL5 ̂TUTa顱 4& `,|}YWBiqap-bJ86&߶5$vRW# `,SӑR;;9to.NUđw8Ma|vu_{EnARmItK'F(AᮑVyb: ߓsp7T'ʑ[)>H{1^\Hَ{Ւ2{DuW#φv yDR:O?FMa|,iZ|4-P @< χ:Zg7bky \,@?_IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaCrc32__coll__graph.map0000644000175000017500000000022412070466513025503 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_6.png0000644000175000017500000000101012070466513023513 0ustar csmallcsmallPNG  IHDRx%bKGDIDATh͑ ak#1 s3ix0<W0 RqTY͏hk9i[Goۦ[ F3!F3!F3>/2-RDuhTucumۖWثp ;VJ"1~h&h&h&h&7|{5t5=>==;uh 됝-(p'hWn ]@mGtș PG'E2|rt槝L\__AW%$ swUPg$v.3k Sv)T92b"B?h~baT1at"U7%v uLgǍ;Ȼ&h&mcK6MLLLhk4MR^iܻ;a<!|LIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipPrivate.html0000644000175000017500000000673212070466513024435 0ustar csmallcsmall QuaZIP: QuaZipPrivate Class Reference
QuaZipPrivate Class Reference

All the internal stuff for the QuaZip class. More...

Collaboration diagram for QuaZipPrivate:

List of all members.

Friends

class QuaZip

Detailed Description

All the internal stuff for the QuaZip class.


The documentation for this class was generated from the following file:
  • quazip/quazip.cpp
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_4.map0000644000175000017500000000025312070466513023512 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipFilePrivate__coll__graph.png0000644000175000017500000001304212070466513027535 0ustar csmallcsmallPNG  IHDRuxbKGDIDATxyxeJH !\eE8gtYufVfDuYEfՙYqqUuvI2ˆá"r6$rwN'}V]4ꮣ?x:UoBubE!B hhh ݻW^ Î;.D ܹVBhjj:vX}}ԅaF0K AAAZVay)0,9X0(ksI@MRU.bI BT^\"ݤd 2$ a[$I| _#ЬnRR &)sEQQ` /T-R2501/sPKאbM p-L$hhRt 8X7x#Ŧ4(rA^ʚyqU隬ǿ]fN~寿zgHJ9aXxJ5buml;e|~NOE\ɱ.WZSU2(Iv|`;0h58%B[ vA? Cϗuc.kيh:?y{omS!0 6T6ܲαn'Bh5p^\q]` wpdq \<ӻҧ>0#4G##=5t3 To$:[ldmivE!v0l#36C!|}^wc8YF8s8V{wnFFα)~f~Mgf0Ț!SsǎJ> IR7nk"to4kWi{Wk6{Oڇ['EY r1[+XV̈-t\#>gaO`JtSzJȩJ)55QKqαn{*FwT,xhf*A<-Fx&m5.;"%ֿpTi=%C&W]J%&OG!lO e)F:qJe J;vT,)E?/(AlK/Ens-X 2wj[u߮ch3E+G. :z79A7Iƺ\#~ښKig <%0saKOeI 1{ix%*SmeG<-L(&Tq2j'uCA>ȼ{zU~1H/uٮv,V|)ɎTM n&QpqzNEJsoA aIȚK+T:j{S$mC-RqƼ_ &掾S^/pGε?0ò459nAeut͹i_0IgQ13S&#z*c'?asmˠM&BI@ĄkۊpdGwfZ]nz0佘N%8s/~:]* tA7o9~**Azy`$k!5?Kr8 Qsy>9bu.T8p;oU,se%v5rc( M~#;$ >#~"#|7E0"?ܑjܘ1B[ԹFqNwAҤ˟-h_lp]3f(̪Фl3 =._fc#~U%: ZTb %Cm|{悴jsf\V]K|$Vo0[?q\{S6}-Q[W,XsCób:jOsPZw3Q8ͫϋwaY]o wh*Ϗ،igy#C-Zu9o5Tk/׸eنǀC! !(AO;<֙U_Ő 9u|;IMEz)Mh!šu2?OrHB=$BGֲkֲuk_.UTZA7P$#μ7P1o鯊0\U?Eä ȿ6?X0S lsZJVo+FAãy*k|y]JlhNYs _ڱ.;gUֲgX!!g23`e"}cƲgϼ;pVܞSu+ ݻ L@dezȯ/8ǼK*byO$(46.gYRƄ!{ۋY]D"-Cҭ~;R<%kVlúd 4CJ/?Q=4CZɲδ?K9ت,NC2L't:u3X>B<ӔUBH,~*}ԅRUU?6fZn{۶mRK3R@kjjjii-[֊ZnE.!?_fN@X"A$cǎڒ%KT5f 444GW\x}ȑ[r0q.z yֵs?0Lkp&iZ]=-DlsΚ~e% [8[kΏѓ# .BYr=otT4 T^\"Y7*fsPYa:ԓ9g>ߚ,M9( D>l52 sq2X0u0[-bpb}g3[1WwV\K z2[8?Q, Aq8;}c\5 }5,T?'DB)[qeu?^V eľ2f; 7kF (OvBjb; vFR' }O˂?]/ձu4"x? kmb}[~<7}~yiqPNfY 6䯨1m߾=//10 khh+Q,Ma&0V#qoH0444n[nM|Q)B 4*u!Zk֬{75gbtZ.]z|Ճum9&ּCF PZZz}ԓO>i*חdcNQ€Si|TY5́o^ߕޜ\mRҘ>(\Z/bgIQL ͅ)RA+!}ԡVG~ =ʹ_|i**0|ҥSԕdPA[b04eqp)3}s/=^euƺ]( [ :mQ\ԃ-| ~5 uDD'-C\#a1\="챵O%4N u8#׮}R,pc>e8NgK"0 V,s͋%92S:te h :͎݃+_Suy@ vM ?? ah悴 ҤI~OAě@/akNa9y K]P?]JT3}=ʫ1D\bkI Aa 1>f a TNap{\^>s vþu(U|6+ӥ4UeΖ"jzPHF{d$dK]0@: dݏ"0z21@_4!(ߡA@dC`~L@0~wKd&1_` M%a@Xz;aeNGGB= yF 8.à5s~rBxyfQ "eal/Y]^x\Hz(ǀ9u}*)ܤ^ sSz}Ϙ߰:!P!T~[N%Q]b'c>e|P0f@3Vݕ׮"B<"Q9 2Lk$eq;CGE2_P:!TVg"}N`ūL/ 4E7ejSػH*$I=@\)R2* (À&W{J3M0 Dcm SLW^rKE5PX:ۚmpd5;)0jg~/Mꀲ), 3qk3R).A 0hei0pk޼|-BR7~$ €wO%vg Uޑʜϛg2pwѶ6Ql\T`GK.FRPc5uer `0lڴIQƉ^ `0\.(MEtx%`s/') ؞={֯_/էQerjPA0 s:1qaaa&@ք ~^!nៗu :'ll!b;3@@@BI~儯s "`㹸EP'FD2r?Ͽ99V @a" r ݓ $Y+\:T?'`:f;(*&֐:Rb6I%[־Tf8w&^0ejX*MDRz510Y*b@dtiA0 ¨0 aaaațDLD;}ឞZS ꤮ .^chhhh3$IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/quazipfileinfo_8h_source.html0000644000175000017500000002070412070466513025642 0ustar csmallcsmall QuaZIP: quazip/quazipfileinfo.h Source File
quazipfileinfo.h
00001 #ifndef QUA_ZIPFILEINFO_H
00002 #define QUA_ZIPFILEINFO_H
00003 
00004 /*
00005 Copyright (C) 2005-2011 Sergey A. Tachenov
00006 
00007 This program is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU Lesser General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or (at
00010 your option) any later version.
00011 
00012 This program is distributed in the hope that it will be useful, but
00013 WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
00015 General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public License
00018 along with this program; if not, write to the Free Software Foundation,
00019 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00020 
00021 See COPYING file for the full LGPL text.
00022 
00023 Original ZIP package is copyrighted by Gilles Vollant, see
00024 quazip/(un)zip.h files for details, basically it's zlib license.
00025  **/
00026 
00027 #include <QByteArray>
00028 #include <QDateTime>
00029 
00030 #include "quazip_global.h"
00031 
00033 
00035 struct QUAZIP_EXPORT QuaZipFileInfo {
00037   QString name;
00039   quint16 versionCreated;
00041   quint16 versionNeeded;
00043   quint16 flags;
00045   quint16 method;
00047   QDateTime dateTime;
00049   quint32 crc;
00051   quint32 compressedSize;
00053   quint32 uncompressedSize;
00055   quint16 diskNumberStart;
00057   quint16 internalAttr;
00059   quint32 externalAttr;
00061   QString comment;
00063   QByteArray extra;
00064 };
00065 
00066 #endif
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaChecksum32__inherit__graph.md50000644000175000017500000000004012070466513027153 0ustar csmallcsmall84ec9abb25cc3d010952b190062cd40bmudlet-2.1/src/quazip/quazip-0.4.4/doc/html/tab_b.png0000644000175000017500000000026212070466513021522 0ustar csmallcsmallPNG  IHDR$[yIDATx ?|SVӈbB#P8O:əD>m{SI'z(!TBމy#WJDp|Å R] 6q]qD.&0=JD=@**IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/functions.html0000644000175000017500000004205412070466513022650 0ustar csmallcsmall QuaZIP: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- a -

- b -

- c -

- d -

- e -

- f -

- g -

- h -

- i -

- m -

- n -

- o -

- p -

- q -

- r -

- s -

- u -

- v -

- w -

- z -

- ~ -

mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_1.md50000644000175000017500000000004012070466513023411 0ustar csmallcsmall521dc5609a23895b8a3757ffc576f343mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipFile__coll__graph.png0000644000175000017500000001217712070466513026212 0ustar csmallcsmallPNG  IHDRb<'bKGD4IDATxyxe߷>c " a[dafיYqWuvDttGqUx<vuIV r4 $}znJuuwYU<}Woշ{C`0\, !v`ǎgΜI)A.ݻ7///>x /-.`I™3g$߿iӦ_zӦMǏohhHc| AKƍ.],KxDss3WohhhllЀrmBL:ŀb`|@dٲeG1:˖- co8G CF7,ʋ0hcjh\t c aaK& $.Cx&%,SvtѰThUб%)"mG:hUбJ6 TYԿӂŊT*"hmT=06?qp_`h;B$&VX3R7!Z`εɦ6xl!1A"1`0ŀb`|g8}dLRxdҫ`xW"f;(UUU4NusO̚O \aViDSN˙#DdP.gC?S([CƄ| 貑ن]7{I݆O=y%J9 s;z\$"AjBo˂k:8zf陪XIB!܁|gnrC1ŕAv2?lbtxa]GFb7{fI3E 5[p_6XgDMCb쒝ts_vq}+>SU9?KBrXzީV?G9 ]p\2.=H7tRgeTܬqHYV~H>:8<$!O 5f𑙐@҅DqФKU굺ַfm΅Df=I41K(Kg%M m%+B s/Qy]M <.qq^M~~r% .`683Hz؆]OOGBIH0@;4 Kߔ_=v.MvYp&Dݴ@礇ȳJ10$>TLø7>26\<0B=Nы,\8G/c죸pFV/Vb@ 1,YrSv:儍υ74r)q#ybe+)~"Z/a]rXz0|`/kY~ n ؆ᲑGwu}`5Z]"ltf?ʍ.;Sglj[8ȂOO3"uN7j5 ly}8 ؤuQ0w9Lvmux9 NP$ a'-3Kz u;EAj*-Zߙ*OcxL5XpP2̾K_^72inG$C҉H l]rzɚu!NyKSXBc`Β%Oǂ"]CaqxRdQvɢlMzn[=brj2I酕Z8LQ6Ĕ3:d|\H``e:RyLxS]](^?SMTש fںjlj,=d(ZQeeh+Z­Fx8ĕ)U,9r9!j^*s$a'F;[Ϗu34R0?U"(R)Đ9Hp\N7xbp ” ]Ԏ+lJH-CvSڵqs)نY$ZnnR"PtަEIl.`v"dh//]`QJ.09붋#1HNM(Vښɀ b"X!G^ 2y* HUc;w^I!1vT2&0RUs{gX =1|dn~ti;B)4 'd%0qGgm](@H`V[9i5 s4|f}L$TOL a`Qfmw~`0y0B@b@$@Dݧ,8,#t 5bӄ tZ67CF{wO]_M%8,n^e#rWlG˨94nwE(Q'߀q췽Gs cr~i p@$JBkdU+?\m'߿3C/Yje.;`H [ҍ}u') 1jo||JθOx+%J׾\i-*ܔ{?ìGU -]fJ-1P+s%c5Y[8'nnQCX/s//~>Jzcu՚8 _-!N~`:-r9! +7|8ŷfR{+u&9E 9")@H̷} Afm(&Rf\9kS➵Yol~%cۈ!7xJĜmWأaq<<67x*Wĭ C$nUyTޢ9嶦U9 y!37&D#17#nf cn!Ja9#,qXGwڤ\jr!_a>$ϼ6EyH,]~/1DCE2e-CGlq`qC쌸$L{.3rnu흥<~p\(FA!Rh$V/c?iWHֿV*[QbSbvyn4Ŵ ()pJĴ!",#oNƚ?W`2"I>M6I -& }wF^F[^ ˗iL Abs6!_egMlF,M}*WkVq[uHOܘ [2L[ɓR) @@U/ I Je\\ Z9GE񠮮[)!i:Ս\Š:jN[^q͍ڗVIީ%5cMlL+GqQ*,HD'I cڗ Ax#%9Qy2O+WKQ 8kA $ˌ]Όs> 4 "{ S¼8֢s'9e@kw?[@100 #}pd0X , C?7ߜ|;ғg.^8^={Wj)H_bt-ZeǓDҚŋu]qI6 qI*Mh4k֬˜{ &.:ŀb`|?ېA^IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_5.png0000644000175000017500000000105212070466513023520 0ustar csmallcsmallPNG  IHDR%㤽bKGDIDATh홱0 #0OZ>=PRRgT쐞 xrFPqlIq̲,"PVP=dz^LTv1kî:c"-i@FZ˱q}A\ QuaZIP: Class Index
Class Index
J | Q
  J  
QuaAdler32   QuaZip   QuaZipFileInfo   QuaZipNewInfo   
JlCompress   QuaChecksum32   QuaZipFile   QuaZipFilePrivate   QuaZipPrivate   
  Q  
QuaCrc32   
J | Q
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaAdler32__coll__graph.map0000644000175000017500000000022412070466513026023 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherits.html0000644000175000017500000001053212070466513022461 0ustar csmallcsmall QuaZIP: Class Hierarchy
Class Hierarchy
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/quacrc32_8h_source.html0000644000175000017500000001014012070466513024231 0ustar csmallcsmall QuaZIP: quazip/quacrc32.h Source File
quacrc32.h
00001 #ifndef QUACRC32_H
00002 #define QUACRC32_H
00003 
00004 #include "quachecksum32.h"
00005 
00007 
00011 class QUAZIP_EXPORT QuaCrc32 : public QuaChecksum32 {
00012 
00013 public:
00014         QuaCrc32();
00015 
00016         quint32 calculate(const QByteArray &data);
00017 
00018         void reset();
00019         void update(const QByteArray &buf);
00020         quint32 value();
00021 
00022 private:
00023         quint32 checksum;
00024 };
00025 
00026 #endif //QUACRC32_H
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipFilePrivate-members.html0000644000175000017500000000433612070466513026663 0ustar csmallcsmall QuaZIP: Member List
QuaZipFilePrivate Member List
This is the complete list of members for QuaZipFilePrivate, including all inherited members.
QuaZipFile (defined in QuaZipFilePrivate)QuaZipFilePrivate [friend]
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/structQuaZipNewInfo.html0000644000175000017500000003737712070466513024620 0ustar csmallcsmall QuaZIP: QuaZipNewInfo Struct Reference
QuaZipNewInfo Struct Reference

Information about a file to be created. More...

#include <quazipnewinfo.h>

List of all members.

Public Member Functions

 QuaZipNewInfo (const QString &name)
 Constructs QuaZipNewInfo instance.
 QuaZipNewInfo (const QString &name, const QString &file)
 Constructs QuaZipNewInfo instance.
void setFileDateTime (const QString &file)
 Sets the file timestamp from the existing file.

Public Attributes

QString name
 File name.
QDateTime dateTime
 File timestamp.
quint16 internalAttr
 File internal attributes.
quint32 externalAttr
 File external attributes.
QString comment
 File comment.
QByteArray extraLocal
 File local extra field.
QByteArray extraGlobal
 File global extra field.
ulong uncompressedSize
 Uncompressed file size.

Detailed Description

Information about a file to be created.

This structure holds information about a file to be created inside ZIP archive. At least name should be set to something correct before passing this structure to QuaZipFile::open(OpenMode,const QuaZipNewInfo&,int,int,bool).


Constructor & Destructor Documentation

QuaZipNewInfo::QuaZipNewInfo ( const QString &  name)

Constructs QuaZipNewInfo instance.

Initializes name with name, dateTime with current date and time. Attributes are initialized with zeros, comment and extra field with null values.

QuaZipNewInfo::QuaZipNewInfo ( const QString &  name,
const QString &  file 
)

Constructs QuaZipNewInfo instance.

Initializes name with name and dateTime with timestamp of the file named file. If the file does not exists or its timestamp is inaccessible (e. g. you do not have read permission for the directory file in), uses current date and time. Attributes are initialized with zeros, comment and extra field with null values.

See also:
setFileDateTime()

References dateTime.


Member Function Documentation

void QuaZipNewInfo::setFileDateTime ( const QString &  file)

Sets the file timestamp from the existing file.

Use this function to set the file timestamp from the existing file. Use it like this:

 QuaZipFile zipFile(&zip);
 QFile file("file-to-add");
 file.open(QIODevice::ReadOnly);
 QuaZipNewInfo info("file-name-in-archive");
 info.setFileDateTime("file-to-add"); // take the timestamp from file
 zipFile.open(QIODevice::WriteOnly, info);

This function does not change dateTime if some error occured (e. g. file is inaccessible).

References dateTime.


Member Data Documentation

File name.

This field holds file name inside archive, including path relative to archive root.

Referenced by QuaZipFile::open().

File timestamp.

This is the last file modification date and time. Will be stored in the archive central directory. It is a good practice to set it to the source file timestamp instead of archive creating time. Use setFileDateTime() or QuaZipNewInfo(const QString&, const QString&).

Referenced by QuaZipFile::open(), QuaZipNewInfo(), and setFileDateTime().

File comment.

Will be encoded using QuaZip::getCommentCodec().

Referenced by QuaZipFile::open().

Uncompressed file size.

This is only needed if you are using raw file zipping mode, i. e. adding precompressed file in the zip archive.

Referenced by QuaZipFile::open().


The documentation for this struct was generated from the following files:
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/dir_13eff9bb9851318b001ebebd72594ac4_dep.md50000644000175000017500000000004012070466513026470 0ustar csmallcsmallab13d57f3a00938eccee7c13470124f3mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaChecksum32-members.html0000644000175000017500000000570412070466513025675 0ustar csmallcsmall QuaZIP: Member List
QuaChecksum32 Member List
This is the complete list of members for QuaChecksum32, including all inherited members.
calculate(const QByteArray &data)=0QuaChecksum32 [pure virtual]
reset()=0QuaChecksum32 [pure virtual]
update(const QByteArray &buf)=0QuaChecksum32 [pure virtual]
value()=0QuaChecksum32 [pure virtual]
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/structQuaZipNewInfo-members.html0000644000175000017500000001054412070466513026233 0ustar csmallcsmall QuaZIP: Member List
QuaZipNewInfo Member List
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/graph_legend.md50000644000175000017500000000004012070466513022765 0ustar csmallcsmall9fbb782f23f919c0064b8f454a56ede8mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_7.png0000644000175000017500000000100612070466513023521 0ustar csmallcsmallPNG  IHDRs%A[bKGDIDATh혻ф a;0t4s 0_"Yp)%#\-൐XXX8u}y۶EQٮeB$xa,K:B}J땔XXXXv0;г_J9wfblvH@z؝G40N}H m|JΪgƖڈC?I<n3]HvCs6Lmw1f]I,Hw(t-Su> QM1Y MYR DL Kҽ8urv g~߽łł;<8iogH)v|DO`Fޏ~ln %U2.%XW]2{Ý<}nIW/5jU(]CQONz!)a&_;[i{5guex,VTv4Mx)w[,y&@y>z~2IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/dir_13eff9bb9851318b001ebebd72594ac4_dep.map0000644000175000017500000000022712070466513026567 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_1.png0000644000175000017500000000427712070466513023530 0ustar csmallcsmallPNG  IHDRX?bKGDtIDATxOLW7cBD4%Dx\VJZF٭"ĥKU6ʭH"'HqV=%6lO 馡$-Ĕ{txy3odx~~H{o<EnIP@`( 0nƻ׳g\چ( ?,m|annI=ܾ}/sF( mm @EB…?[YETTGOϾh4"B[Ά3x?x|aaPx|'4%f+6&˝={v}}ݭlCGimmoܘ/>6f}pΝ_j ŋ{{{]64888::?h<͂GYBH8\'BGGDwutDb]sĉSNm |ʙMI$1f}{;wsob30=VW቉UmY(iq>w_67kkk49yNҎ`qS]VVffOӋs !!Yv{xO?*gRd25=$޺uPǘ :n_l]E*FAhNkkkh   GHkO9<|H.1!.( pMcK*BvٳS Ѩsag\1HXp!660~رc6 *joy|o(XLhl|]iV_ 1M{Ng.]z…ɓ'Ǘ3l!wthG,B4#a2 m7S,,,}ܹFF vbk%Tsn%hؽK/V֪0Q^i?TOjHeJHbR d{pJc  5mXHpc *Ⰷ n-Joa7>+4r~bOg$nd-RpfjbI@P@`( 0  |U=mǏ>=0  n*JAKIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipPrivate__coll__graph.map0000644000175000017500000000021012070466513026717 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/tab_a.png0000644000175000017500000000021412070466513021516 0ustar csmallcsmallPNG  IHDR$[SIDATx흻 @wɡ*MIFL :nN N&_ ɭɾ}ն8~Owv-A4Y)}IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaAdler32-members.html0000644000175000017500000000610512070466513025156 0ustar csmallcsmall QuaZIP: Member List
QuaAdler32 Member List
This is the complete list of members for QuaAdler32, including all inherited members.
calculate(const QByteArray &data)QuaAdler32 [virtual]
QuaAdler32() (defined in QuaAdler32)QuaAdler32
reset()QuaAdler32 [virtual]
update(const QByteArray &buf)QuaAdler32 [virtual]
value()QuaAdler32 [virtual]
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/doxygen.png0000644000175000017500000000754612070466513022144 0ustar csmallcsmallPNG  IHDRh ;-IDATx]{XysZ%ʔNF:FЪքb@;~ӎ"DHZm_4!-2UCe["_3LS|y>_ LZߦajLo}.2$Z);*.d~߳w'0@!ZZeͺwډ?O =\L[gdxr0 RrjJ*.WJN5qM[mޕSb58ļRB5SRus[2< %V'+%$fvĺRK$ C 4+xsQ}f[vZ 6c}!,Lt<ūdxH)/f襧C1v[~ 9%DDKgrN}M9Y3*/i謷%ÓU^#vr'p=]_7ySka-/!Ev902ɖF*, O!1k>QӳdxX:=GD<'fvRKUZjbi`t9cxڪVWsabiw11x%h޶9׉>oծhkG~Nls"^™d2%swW윧Dz W8c>1mBv8܉AZ Turth9kRSf/d1kbA.@+;:j ˫҉|#p4i]V~njxfv$եy| S[;BOKVցa 4x0:DN54>gxpo;Z:ɔbۇ|^T7=$4)L!/u#)9/rq%~a-poE,|gm /9/s|c /u P\a’1,;ueyK\"7-K!3>2amm r7M.(~[2Ʉ]C<b9[)v[~,_@\|8qܴ{}Qޔugr7J]|eڐ`4s5+ҡ\ٕxJ,uds&@yIeD;8nZ={ʘfQU|Xڝ)ض"tV-woJy>6谹 Frf͍ Kb(!@~) F{Ave'3H͍u @A$j"s&&b~twQ J~I J]=;=|S{瑓nʍ9˿˄.{ܴ`b ڞ)j\ΕY_E_.g0u2ݪiDWX'kqVgDO݄E 6 1cZėnNXx(]gL_M!b4+eʤd62[]Am,b@JՄ_,Wrr_g8&(QA4.ajAghSFJhheg;Lcs /RĢ,849:n`,o_~6YIqavʐv>=VEX޾5=uu^/ AeD䆸XjS#^˞3-٣[@vm X W¤v9ѽQ_{3W\؏:pajeI)tܱ8I>xdEd:4kONIq>m1!)[Vb47a@暍̱ p%5P~Z?| 30DN  } Un@ 3'T(,ϗ^.MA8a?UپJ<2S~@=hj3-G|8Y.]XRIT9XA$hIPv!vH}o)Ͷ8rߚ =*^iE«8"< Ht"Бx.ZM!b~ƒ !c bwzqT\ L*a.P7:*(Fp8O@5<917>y1zazs{/Q†9 j}SvYD*n]!rhyakj ʄg͑ d_*ll]^&}hnpȨ[.Y7..OڲX|e%L%L9e tO^ (p 3U%r J v2C z2Sf1]@ȝnp%"nJR2G+Z[?@[PcWKZ=Qi?yE`3+W;ӿfH%x2!%#M?;p)*u;p_z%#M !pWRphϦiE8gF?Kp)_+ǩXP&#j&q=n0Ln>D\J[tsI5)&~J :ÚAB@PKƴdoC)aSteLg.襩?M|ָbٚs+stٛ@`ᰱ*q:htw_Zِ^:cn{ӆݺ`N;כj*K}^4?&=zizkCcPBht'|UE1 ;&5v۵]@kS}pեy &>{f>P~ޞk^IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_3.md50000644000175000017500000000004012070466513023413 0ustar csmallcsmalla304fc926447a90879a7cd82c1947d0cmudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_5.md50000644000175000017500000000004012070466513023415 0ustar csmallcsmallbb506805d0a0a557d4ccbc22245703bemudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipPrivate__coll__graph.md50000644000175000017500000000004012070466513026630 0ustar csmallcsmall4dadbc94c10e818b6d044a538076a620mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/functions_eval.html0000644000175000017500000000663712070466513023666 0ustar csmallcsmall QuaZIP: Class Members - Enumerator
 
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaCrc32__coll__graph.md50000644000175000017500000000004012070466513025407 0ustar csmallcsmallc5893d01f9e8b7b19610a8cce32f67e4mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/quazipfile_8h_source.html0000644000175000017500000003306212070466513024767 0ustar csmallcsmall QuaZIP: quazip/quazipfile.h Source File
quazipfile.h
00001 #ifndef QUA_ZIPFILE_H
00002 #define QUA_ZIPFILE_H
00003 
00004 /*
00005 Copyright (C) 2005-2011 Sergey A. Tachenov
00006 
00007 This program is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU Lesser General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or (at
00010 your option) any later version.
00011 
00012 This program is distributed in the hope that it will be useful, but
00013 WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
00015 General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public License
00018 along with this program; if not, write to the Free Software Foundation,
00019 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00020 
00021 See COPYING file for the full LGPL text.
00022 
00023 Original ZIP package is copyrighted by Gilles Vollant, see
00024 quazip/(un)zip.h files for details, basically it's zlib license.
00025  **/
00026 
00027 #include <QIODevice>
00028 
00029 #include "quazip_global.h"
00030 #include "quazip.h"
00031 #include "quazipnewinfo.h"
00032 
00033 class QuaZipFilePrivate;
00034 
00036 
00073 class QUAZIP_EXPORT QuaZipFile: public QIODevice {
00074   friend class QuaZipFilePrivate;
00075   Q_OBJECT
00076   private:
00077     QuaZipFilePrivate *p;
00078     // these are not supported nor implemented
00079     QuaZipFile(const QuaZipFile& that);
00080     QuaZipFile& operator=(const QuaZipFile& that);
00081   protected:
00083     qint64 readData(char *data, qint64 maxSize);
00085     qint64 writeData(const char *data, qint64 maxSize);
00086   public:
00088 
00091     QuaZipFile();
00093 
00098     QuaZipFile(QObject *parent);
00100 
00109     QuaZipFile(const QString& zipName, QObject *parent =NULL);
00111 
00120     QuaZipFile(const QString& zipName, const QString& fileName,
00121         QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =NULL);
00123 
00171     QuaZipFile(QuaZip *zip, QObject *parent =NULL);
00173 
00176     virtual ~QuaZipFile();
00178 
00187     QString getZipName()const;
00189 
00192     QuaZip* getZip()const;
00194 
00206     QString getFileName() const;
00208 
00219     QuaZip::CaseSensitivity getCaseSensitivity() const;
00221 
00245     QString getActualFileName()const;
00247 
00253     void setZipName(const QString& zipName);
00255 
00259     bool isRaw() const;
00261 
00269     void setZip(QuaZip *zip);
00271 
00282     void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault);
00284 
00291     virtual bool open(OpenMode mode);
00293 
00297     inline bool open(OpenMode mode, const char *password)
00298     {return open(mode, NULL, NULL, false, password);}
00300 
00311     bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =NULL);
00313 
00340     bool open(OpenMode mode, const QuaZipNewInfo& info,
00341         const char *password =NULL, quint32 crc =0,
00342         int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false,
00343         int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY);
00345     virtual bool isSequential()const;
00347 
00368     virtual qint64 pos()const;
00370 
00386     virtual bool atEnd()const;
00388 
00400     virtual qint64 size()const;
00402 
00409     qint64 csize()const;
00411 
00419     qint64 usize()const;
00421 
00431     bool getFileInfo(QuaZipFileInfo *info);
00433 
00435     virtual void close();
00437     int getZipError() const;
00439     virtual qint64 bytesAvailable() const;
00440 };
00441 
00442 #endif
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/quazip__global_8h_source.html0000644000175000017500000001007312070466513025603 0ustar csmallcsmall QuaZIP: quazip/quazip_global.h Source File
quazip_global.h
00001 
00024 #ifndef QUAZIP_GLOBAL_H
00025 #define QUAZIP_GLOBAL_H
00026 
00027 #include <QtCore/qglobal.h>
00028 
00035 #ifdef QUAZIP_STATIC
00036 #define QUAZIP_EXPORT
00037 #else
00038 
00042 #if defined(QUAZIP_BUILD)
00043         #define QUAZIP_EXPORT Q_DECL_EXPORT
00044 #else
00045         #define QUAZIP_EXPORT Q_DECL_IMPORT
00046 #endif
00047 #endif // QUAZIP_STATIC
00048 
00049 #ifdef __GNUC__
00050 #define UNUSED __attribute__((__unused__))
00051 #else
00052 #define UNUSED
00053 #endif
00054 
00055 #endif // QUAZIP_GLOBAL_H
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/files.html0000644000175000017500000000577612070466513021754 0ustar csmallcsmall QuaZIP: File List
File List
Here is a list of all documented files with brief descriptions:
quazip/JlCompress.h [code]
quazip/quaadler32.h [code]
quazip/quachecksum32.h [code]
quazip/quacrc32.h [code]
quazip/quazip.h [code]
quazip/quazip_global.h [code]
quazip/quazipfile.h [code]
quazip/quazipfileinfo.h [code]
quazip/quazipnewinfo.h [code]
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/dir_13eff9bb9851318b001ebebd72594ac4.html0000644000175000017500000001166512070466513026136 0ustar csmallcsmall QuaZIP: quazip/ Directory Reference
quazip Directory Reference
Directory dependency graph for quazip/:
quazip/

Files

file  JlCompress.cpp
file  JlCompress.h [code]
file  qioapi.cpp
file  quaadler32.cpp
file  quaadler32.h [code]
file  quachecksum32.h [code]
file  quacrc32.cpp
file  quacrc32.h [code]
file  quazip.cpp
file  quazip.h [code]
file  quazip_global.h [code]
file  quazipfile.cpp
file  quazipfile.h [code]
file  quazipfileinfo.h [code]
file  quazipnewinfo.cpp
file  quazipnewinfo.h [code]
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/graph_legend.png0000644000175000017500000002767312070466513023111 0ustar csmallcsmallPNG  IHDRbKGD IDATxy\ (摩 rdyyhZ찴_Zxi慕G" *^y$*r1cekfg_G8;{>3;|3!S3B3dz>C3ȇRKêҥl`Jͻr Q!&&~lJWX2b6̂#r,c/Eu֭I&l²={޽{luzX6oމ W(C`2=!2=#O'.}5\+U$kdl/?ΦHc`Þ| cL9_qzŏ*6_:&j]muKnlHjv3Xavapm-c[u@P5GZk;ucxLk,KwoW t3c}@ 埚UjWLg&T0-_WI=L_]H<8eIޑk}&u}~`r`Z31 尿`#,QV}_p:yjѽԖj4iq&J_?I:tw񨮛^m;@EUns}m0`  L܄Lg|Lg|6?0 Bb^hXT*g1Gq%2c΄ڬ ɤI B;Hr)+Sf-9kѢ*qs"Íd lFCפ]|DDD7cHO$`)ۡ.nݧܹ{E~vB:Arvq+waٳ>8$B@@d؎vq+sBP(8p wJD!v4C^&{7V{\`;"0BV¨!0$")zrF ,<ߛ*1pU|`iϡNP+&oVP30>=ې0>=zg|Lg|Lg|Ldz04 l2=!2=!2=!FslCslC=!2=!2=!2=Ƨg2=Ƨg2=Q Ô㯿ѣB`1 ^((,@iݺ͛7_٥tUi֭[Ư7Lr^|idAǎ]]]_NMIZ6y8!p^u_znZZBx`r̙+VdU(R >&n݊޽S%%%4MkUٸׯ$T'\WG-6lC⢊&"nݺph<4x8-ZJ ϐ ϴȫEQCQT'jmY)fŃU#NizLjUKL24mi[zSukIsB}I˜k\дY\p8Z>d '~ʃȎP],Gks7g^PTZ٪\h41G^iG*}Zu㗪U>Mka@iޮ>g;^ݡZWeoGYgбny1 cQۯ2(=Wgn=ъ͉^2RUOQc6Aj;񪞁xVQ2qRn2Z=/ݥ]Iը_m%3}uWT&(t wĀUifխCcQ~ ҿc t3_trMGwa)6zmdyl bH SoǢƽ` 0KXBP]˧֦':a؞_>8:jQ7;̱/kc_bbՏJLfuO-P>v8Ϯy^L &qT >?S~݈*oTNStN_QFcYM`ՕTf/UnZˁT6 Vj=q2J"4qE7vrji'sEdz݅RQJj\t=g3o>áбUˡO`5j ۰}4Z?5A=[>aSV<{0 dz>CX{:YSv&$O/{x,;@L"P,sPBU(Q"GZ"B,)OB10 Chx%kEfBH7\ !j%CieO_?jЌ:^)(()((-**-,,-+Su\,LVN^JPҠka׫,dPr[IM C¾/,,)**+..+)|֣+zLX婝^evW .ZxƍَB;2{:22o0 ämv,3TW*J%R*E*յ޾LqV`娕Z*0˴2kKgϞ#GTlE"!/.@ɵk,P5gS.w+N1"vqGG#89DǎkfUC33seM2Ysww5jH$^^^+Yŋ;$D_aUUw4UZ*R( BRP楎f :'Ng/ОE}af :n_۫geeˏYs# ZlM%&4yB*5ϷbtѿDBvѽBܛ5SU+#fQXX0̅ _4jvDp !% RTUEyޞ=;-V1O/ɒ$yafȧW|U)]q6ww*oy[efbo/Z@@iӶ%Jkb0,U fƼ9F@ < }!ņ})hJ5$ݣ(W\^G]%´hQi^ f 8,?uj fyj#<ʵ_o7@7ΔU*B !TF"Vl .d;n;bD۷>xKXf4psuoM(U%5yF~wPmoθW&eNdf24M&GgڹG9s5׮ehbȑ]{jv\նm-[NҥǏdTl)GwQI ߘިq: GtB6BϞ=JIaZ>MݱnV͚( (N3?:²2Յ inPR=z7X̜ IKSbVNNu+wrl넯i"a뒞lmW<;\^^ދӧM3׮eoL۷ob;|jZM3Nݼ=z _?~8y1̚*MDnlPukVa6m:hfҼP(o~b8RYs,--CԌHE Ԛ5 {%ܧ*3'OKT{@7wgJ`Wdz>}oڴ_rs_¤.rww:*vwԌuӳbG<ӧ&9mp7sʯpDKۼ.+ŋ3w>|U Qq/6o>ϧJJ&N  ].T(@iӸvlGjO/rq:4@3!+((ߔJƍckrn(M_OR4rVIWmH6;d?ٚ{͘IQBx͛"[mroEQԕ+_yzZ>0|n݉]ى"#{o٤I[Iijݺ{PM2쪫qqg;:K?T+fŽ?*Z{bvBiAfp6͛CW۷'/߁&BMYޖO5cvX\>ݾtjL;"Kk2–D˜0b\*ztJ"{ 2rE?zkW _|nQn蟎P)"{F;[#²n ~7)0LSߜ;Wdou-={DZc!߇;bYsb`q䝘ZyO4hPFXX{G)G j採˚J|mq@EM6-;,(gDW beί^U/NN^:|nBdܱc7=xV_:\ܴիBCM7xd7bs\*bh/HV^' L2[kP)v]͡oeyȗlאj%ܹ]K(}t,x}DCcR0`ZM/Y2tƌy*-8^&;WmKټGyw0!߿1A9NI|%2!s*h>t /?Ͽ߂~ 5vPCTmڨi:d"Bϯ^~\g6lGDz%Kmܘ|Ȝ-+rg {}*c] J6nLڶ-E./y7ǏW} a^=o?xkB_)Vv,.~a[Uݑ#.^?I5V+Îs;Z{w~Duφ6ޝXX0a–z8n][+J7693dvvzMy@ мƧO2U{|n B&LtB ǘ1`jsǎI؎ŢIL-pANf:7zUh-޺lE_LC1'c\]2;dAYBqn{r%۱XNZZNXn_=X,GaCҍCBZ݃sBvCѣײ mSUUjZ=ǸOAݽ}֭k5&'*wYT⢬VJKz&&&u<9mۆl Yr~zɥVԇl_XZ"ơc>YfEG'&J؎-;v#GlYQGT~~M[..VDDt0!ǧ.AՌV1O.'e' 3Nf>Z.@9۩藩ʶl7OOF1O[{/I||祤>|_v,qڵw:' Ǐ5vlO+x(ƾ{õoOA'ϧA6RW;\rxÿE?~cy®!C-0#ڵkex#&Ý;O_t<9:;[߯nMy?[Lox_׼bo+wN~MF{4FOԩ;R|+_='ib-OGh4\y/&zK 2M}E;|߿}>U ijZ=Ao?8c'ͷ0ҥ!!m9{f+%eI/D7j[Ox2=N/9PW[;ַo)Sz|۱RzCvY]c1%Roߥk߾=]rv RP_+hsZcuYY={B&L=ZkboEzYE? k퉵+WAgp`;(=}%8U}v,ƺx?}? `;c=xb;M̭hsX{p|\,^5ʡhxS/()XvY2eYd}7rkvP[4 a;.or%}ŊR ?zfrg4UB,I,/Uj2AwMJ^nL]Fk[ xEѡZ3ܢ1q_ ,+ bׅ]w/|gaglU;e[CBڵy3۱b߾KӦ:㏋7&]ڎoЌOĩnF1xU9k[:'XUW5ϯ._O73Ν=lXҥ#GKdd< Y:d|3XjG3ͦM4qbW_e;Y8fzҝ3}Ф?`F[O/SX+wN|۶}p{ӦlǢ/2duaai\\='gC./I޺tQQ٨Q?0wOdIDATחhhRQz\v2߳swi;*4jB Nv6օkO.YwlǢKQQYX=e\(F^ӧsd4^:۹ p2=pTҿ?}g{穽 vPZ04gĈ999pm-U̙K*!r:h4;͜b4O{m:dz~=ܢc?JTѪq=}n 'O6W_v\2e۶miv,ZT޽׭;qˏFSztJ.Kg+PѽZw?ݴ6 p 2=p+Oo^zd鳢gû xvP/oqg嗦}Keσ qɒalRYIb7&=y?hP)Sich^d)~.KN}! (1 x TW izo2U \${&6 8TC=8eJcR77cZMF./é?yɟ>UR6qb`&!\a2nMCw8~=j`e4뉉79RW;w g]ve+ {w0pFcˏ><;#ff>_Νgő=Ǎl0B( &L֊}+9͹4V"H'"O?@Iή1j`9[_˼4~s;7:{bDG^CVkX ߺƟ^4i͑}@Yj۶͛O>z7xp {w>) mW-!q +6&otup{JThҕڳ?xfŊ<۰t@V<8xYxxK[~%7&KJAA9~|/?z݄G0dz-Ϟc]UU4CO 2yu],:c/{aE/4s-,ytEM=<=]MrfS_Ȓd};[j&L6Ŋ~AI)?/9p|ޚmaa> O-EuN|g[٫V%8py>&FUBg-%OK\v rwC`E̩~U5ˈ Zy[Fs6#\ٯߞ:BtIjUTzY33BL; C3rV /LW*Ů N֝p/|PE&N̺zuLBڱSR%vt;kV%=^qtm!g: hgɊ;.BH~f7MJ7ݻۊƧt{ jFY͛&!]?j`Ɋ{X()ռbfz'~{k׶`Ʒ=zmܸ11~\iFI~A&Ojq _YNt̕ d?+o?7lf.wJ^^&_9!$+ $d[o|s??xӦ-[N+""Mc "\q@YB{q x dzCX5w[wfI&Y䗰0I&Co'n9`&"b}F&kߵX,?ر=5;%?[ iA¡L`,VrVIWmH6;d>3LW;cuj$/Ztݹ4:ZeOOɓ{iR*Ex 2=ɘTteюbiAfrwr7I)a͛d7裾ӧj.<&&hٲԩ}j8S ;)ؾop2=Y[},c?)TȞ4hjAZ=?"Z*u׮)?V.]NV^9JY\$|V1_sǭ)op2=y_TVԦeG2jaL2.&9w1qJ}֮=~SKKx~bGAu|$>=%nr+ 7r*W,>~!,möm>{o:BHBc7m86<+)((ݸĶm)%GٳiSڮ$- n pl2= LUѧW7oAݚu3,c޽;Q;gg, nb{!+ :Z{Ȅ G-~1;.,30/Φռrgk~Nqn}.YR üѣX]ZZʕG4mZo꺛^YA8W973l2=W_׼rՃ}:]W܋7~-[6>p?վ}Z-xJG~~f 8 Mr3D%uDMz 4 v<P=dz.2ѕ~qnGkΏ!-~ cR'ZyIxg͚R 5;v=;h{Nc{@OĻ Li5VU*Վ;JKK+-^~/w?oZ%M׼l82O_Zo$7nثW-]*=7תUJKe)psogjjh;8/0JHiKyBnA (FQv ~WeeLWA> ܹcn;vݬqqdN8W_`*`}DzˁII|E4#Bn6 2=!؄ ?R`0dz05 yp2=!M;((jEĠU]\[-6l M{Z'j߄Ǐ8g?̿lN<{[`Y0 P-dzaUpT8P3T]ߺg.su0j-u1b1j-iϐ ϐ ϐ ϐ nwuvvf;;J:pZf;Sjݺ?Q2=>=!2=!¡ԙIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipFile__coll__graph.map0000644000175000017500000000065212070466513026176 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaCrc32__inherit__graph.map0000644000175000017500000000022412070466513026214 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_0.map0000644000175000017500000000024212070466513023504 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_7.map0000644000175000017500000000025512070466513023517 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/usage.html0000644000175000017500000001300112070466513021732 0ustar csmallcsmall QuaZIP: Usage
Usage

This page provides general information on QuaZIP usage. See classes QuaZip and QuaZipFile for the detailed documentation on what can QuaZIP do and what can not. Also, reading comments in the zip.h and unzip.h files (taken from the original ZIP/UNZIP package) is always a good idea too. After all, QuaZIP is just a wrapper with a few convenience extensions and reimplementations.

QuaZip is a class representing ZIP archive, QuaZipFile represents a file inside archive and subclasses QIODevice as well.

Terminology

"QuaZIP" means whole this library, while "QuaZip" (not case difference) is just one class in it.

"ZIP/UNZIP API" means the original API of the Gilles Vollant's ZIP/UNZIP package. It was slightly modified to better integrate with Qt.

"ZIP", "ZIP archive" or "ZIP file" means any ZIP archive. Typically this is a plain file with ".zip" (or ".ZIP") file name suffix.

"A file inside archive", "a file inside ZIP" or something like that means file either being read or written from/to some ZIP archive.

Error handling

Almost any call to ZIP/UNZIP API return some error code. Most of the original API's error checking could be done in this wrapper as well, but it would cause unnecessary code bloating without any benefit. So, QuaZIP only checks for situations that ZIP/UNZIP API can not check for. For example, ZIP/UNZIP API has no "ZIP open mode" concept because read and write modes are completely separated. On the other hand, to avoid creating classes like "QuaZipReader", "QuaZipWriter" or something like that, QuaZIP introduces "ZIP open mode" concept instead, thus making it possible to use one class (QuaZip) for both reading and writing. But this leads to additional open mode checks which are not done in ZIP/UNZIP package.

Therefore, error checking is two-level (QuaZIP's level and ZIP/UNZIP API level), which sometimes can be confusing, so here are some advices on how the error checking should be properly done:

  • Both QuaZip and QuaZipFile have getZipError() function, which return error code of the last ZIP/UNZIP API call. Most function calls reset error code to UNZ_OK on success and set error code on failure. Some functions do not reset error code. Most of them are const and do not access ZIP archive in any way. Some, on the other hand, do access ZIP archive, but do not reset or set error code. For example, QuaZipFile::pos() function. Such functions are explicitly marked in the documentation.
  • Most functions have its own way to report errors, by returning a null string, negative value or false. If such a function returns error value, call getZipError() to get more information about error. See "zip.h" and "unzip.h" of the ZIP/UNZIP package for error codes.
  • If the function returns error-stating value (like false), but getZipError() returns UNZ_OK, it means that you did something obviously wrong. For example, tried to write in the archive open for reading or not open at all. You better just do not do that! Most functions also issue a warning using qWarning() function in such cases. See documentation for a specific function for details on when it should not be called.

I know that this is somewhat messy, but I could not find a better way to do all the error handling.

mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/functions_vars.html0000644000175000017500000001165012070466513023701 0ustar csmallcsmall QuaZIP: Class Members - Variables
 
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/pages.html0000644000175000017500000000331112070466513021730 0ustar csmallcsmall QuaZIP: Related Pages
Related Pages
Here is a list of all related documentation pages:
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/tabs.css0000644000175000017500000000210712070466513021410 0ustar csmallcsmall.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipFile-members.html0000644000175000017500000002260412070466513025326 0ustar csmallcsmall QuaZIP: Member List
QuaZipFile Member List
This is the complete list of members for QuaZipFile, including all inherited members.
atEnd() const QuaZipFile [virtual]
bytesAvailable() const QuaZipFile [virtual]
close()QuaZipFile [virtual]
csize() const QuaZipFile
getActualFileName() const QuaZipFile
getCaseSensitivity() const QuaZipFile
getFileInfo(QuaZipFileInfo *info)QuaZipFile
getFileName() const QuaZipFile
getZip() const QuaZipFile
getZipError() const QuaZipFile
getZipName() const QuaZipFile
isRaw() const QuaZipFile
isSequential() const QuaZipFile [virtual]
open(OpenMode mode)QuaZipFile [virtual]
open(OpenMode mode, const char *password)QuaZipFile [inline]
open(OpenMode mode, int *method, int *level, bool raw, const char *password=NULL)QuaZipFile
open(OpenMode mode, const QuaZipNewInfo &info, const char *password=NULL, quint32 crc=0, int method=Z_DEFLATED, int level=Z_DEFAULT_COMPRESSION, bool raw=false, int windowBits=-MAX_WBITS, int memLevel=DEF_MEM_LEVEL, int strategy=Z_DEFAULT_STRATEGY)QuaZipFile
pos() const QuaZipFile [virtual]
QuaZipFile()QuaZipFile
QuaZipFile(QObject *parent)QuaZipFile
QuaZipFile(const QString &zipName, QObject *parent=NULL)QuaZipFile
QuaZipFile(const QString &zipName, const QString &fileName, QuaZip::CaseSensitivity cs=QuaZip::csDefault, QObject *parent=NULL)QuaZipFile
QuaZipFile(QuaZip *zip, QObject *parent=NULL)QuaZipFile
QuaZipFilePrivate (defined in QuaZipFile)QuaZipFile [friend]
readData(char *data, qint64 maxSize)QuaZipFile [protected]
setFileName(const QString &fileName, QuaZip::CaseSensitivity cs=QuaZip::csDefault)QuaZipFile
setZip(QuaZip *zip)QuaZipFile
setZipName(const QString &zipName)QuaZipFile
size() const QuaZipFile [virtual]
usize() const QuaZipFile
writeData(const char *data, qint64 maxSize)QuaZipFile [protected]
~QuaZipFile()QuaZipFile [virtual]
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/structQuaZipFileInfo.html0000644000175000017500000002307112070466513024730 0ustar csmallcsmall QuaZIP: QuaZipFileInfo Struct Reference
QuaZipFileInfo Struct Reference

Information about a file inside archive. More...

#include <quazipfileinfo.h>

List of all members.

Public Attributes

QString name
 File name.
quint16 versionCreated
 Version created by.
quint16 versionNeeded
 Version needed to extract.
quint16 flags
 General purpose flags.
quint16 method
 Compression method.
QDateTime dateTime
 Last modification date and time.
quint32 crc
 CRC.
quint32 compressedSize
 Compressed file size.
quint32 uncompressedSize
 Uncompressed file size.
quint16 diskNumberStart
 Disk number start.
quint16 internalAttr
 Internal file attributes.
quint32 externalAttr
 External file attributes.
QString comment
 Comment.
QByteArray extra
 Extra field.

Detailed Description

Information about a file inside archive.

Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to fill this structure.


The documentation for this struct was generated from the following file:
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/nav_f.png0000644000175000017500000000023712070466513021546 0ustar csmallcsmallPNG  IHDR8fIDATxIB1 Q;uۿ@h; a !ЋVC |c3sFFPS{PSsVlNF.F.2_UH mIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_7.md50000644000175000017500000000004012070466513023417 0ustar csmallcsmall8e1c8bc28a8271d22c62e3355c4d6457mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_0.png0000644000175000017500000000066612070466513023525 0ustar csmallcsmallPNG  IHDRe%FbKGDkIDATh1 EuOyL xso`VQ z~tAGH)N`_ }aeYʲ\5V6*2}5 Cyϊ(8mu]HS }a/ qʗhƙibO"Pz\\ )v痮N]BAхNU{mpy%hԯ? x/TjA\'@ YǏg xj׀AM<8Bh}qe9.?~ /j}Q}a/ ayj&|49MӗԘ)IHk]/>0`_3o\IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/annotated.html0000644000175000017500000000706712070466513022622 0ustar csmallcsmall QuaZIP: Class List
Class List
Here are the classes, structs, unions and interfaces with brief descriptions:
JlCompressUtility class for typical operations
QuaAdler32Adler32 checksum
QuaChecksum32Checksum interface
QuaCrc32CRC32 checksum
QuaZipZIP archive
QuaZipFileA file inside ZIP archive
QuaZipFileInfoInformation about a file inside archive
QuaZipFilePrivateThe implementation class for QuaZip
QuaZipNewInfoInformation about a file to be created
QuaZipPrivateAll the internal stuff for the QuaZip class
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaCrc32__coll__graph.png0000644000175000017500000000253412070466513025520 0ustar csmallcsmallPNG  IHDRp$bKGDIDATx휽k1u>7)-:BS!k CR::ɔNMbJI 6t x)Mi>.Nϒ|zo(I;I$v 2@:@@@fs~~T6Cltc{{\.ԳRvwwWWWbJCMP`    zqK(qŘ}}/tXt~.}5 2UbaBq䂤wuIzLr-ӫx}nqdqrXkv\GOHKQxɮQaA՛kpf"T93$^^qPܕgq5PPKg"Vf=gnnOIgJ?=dAݱ %mNrF*#\yB] Ԗ9+U#8zq\D|       珕Nxǩbu]Cܾ03 KKK;~D*fo>7ɓϞ͙EAX?^~t.XH9>>94*Eqft:XTno]H }޽alJ탖AdRj0uQ*U~R9`JXϓ{ ޼b*%u,Q. K,}zn{{fHJWqѱ[}lm}ś_J~0LE2:zΝ[?ׯenReB}GND[A}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}#䤑^dnݑjq5a>rzÂX,)]=g.&bQo@\?`>`>`>`a<ϋʕJE=NOAWו f|xGw9<RR|j8qA)Sefr@}$楨Um~c!:) Z<->H |b  pB1;}Ao!iʍC %ZbfbVݶF' rkq/-$[h>q}yBAW@p?      CfFCoLLLLLOOk 8 ߧ?0   hd PIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_2.md50000644000175000017500000000004012070466513023412 0ustar csmallcsmall516630e9457f1fceabe81e76fdbf113dmudlet-2.1/src/quazip/quazip-0.4.4/doc/html/quazipnewinfo_8h_source.html0000644000175000017500000001734612070466513025524 0ustar csmallcsmall QuaZIP: quazip/quazipnewinfo.h Source File
quazipnewinfo.h
00001 #ifndef QUA_ZIPNEWINFO_H
00002 #define QUA_ZIPNEWINFO_H
00003 
00004 /*
00005 Copyright (C) 2005-2011 Sergey A. Tachenov
00006 
00007 This program is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU Lesser General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or (at
00010 your option) any later version.
00011 
00012 This program is distributed in the hope that it will be useful, but
00013 WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
00015 General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public License
00018 along with this program; if not, write to the Free Software Foundation,
00019 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00020 
00021 See COPYING file for the full LGPL text.
00022 
00023 Original ZIP package is copyrighted by Gilles Vollant, see
00024 quazip/(un)zip.h files for details, basically it's zlib license.
00025  **/
00026 
00027 #include <QDateTime>
00028 #include <QString>
00029 
00030 #include "quazip_global.h"
00031 
00033 
00038 struct QUAZIP_EXPORT QuaZipNewInfo {
00040 
00043   QString name;
00045 
00050   QDateTime dateTime;
00052   quint16 internalAttr;
00054   quint32 externalAttr;
00056 
00058   QString comment;
00060   QByteArray extraLocal;
00062   QByteArray extraGlobal;
00064 
00067   ulong uncompressedSize;
00069 
00073   QuaZipNewInfo(const QString& name);
00075 
00083   QuaZipNewInfo(const QString& name, const QString& file);
00085 
00099   void setFileDateTime(const QString& file);
00100 };
00101 
00102 #endif
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/functions_func.html0000644000175000017500000003016112070466513023657 0ustar csmallcsmall QuaZIP: Class Members - Functions
 

- a -

- b -

- c -

- e -

- g -

- h -

- i -

- o -

- p -

- q -

- r -

- s -

- u -

- v -

- w -

- ~ -

mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/dirs.html0000644000175000017500000000331212070466513021573 0ustar csmallcsmall QuaZIP: Directories
Directories
This directory hierarchy is sorted roughly, but not completely, alphabetically:
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipFilePrivate.html0000644000175000017500000000742712070466513025237 0ustar csmallcsmall QuaZIP: QuaZipFilePrivate Class Reference
QuaZipFilePrivate Class Reference

The implementation class for QuaZip. More...

Collaboration diagram for QuaZipFilePrivate:

List of all members.

Friends

class QuaZipFile

Detailed Description

The implementation class for QuaZip.


The documentation for this class was generated from the following file:
  • quazip/quazipfile.cpp
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/quazip_8h_source.html0000644000175000017500000003526712070466513024140 0ustar csmallcsmall QuaZIP: quazip/quazip.h Source File
quazip.h
00001 #ifndef QUA_ZIP_H
00002 #define QUA_ZIP_H
00003 
00004 /*
00005 Copyright (C) 2005-2011 Sergey A. Tachenov
00006 
00007 This program is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU Lesser General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or (at
00010 your option) any later version.
00011 
00012 This program is distributed in the hope that it will be useful, but
00013 WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
00015 General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public License
00018 along with this program; if not, write to the Free Software Foundation,
00019 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00020 
00021 See COPYING file for the full LGPL text.
00022 
00023 Original ZIP package is copyrighted by Gilles Vollant, see
00024 quazip/(un)zip.h files for details, basically it's zlib license.
00025  **/
00026 
00027 #include <QString>
00028 #include <QStringList>
00029 #include <QTextCodec>
00030 
00031 #include "zip.h"
00032 #include "unzip.h"
00033 
00034 #include "quazip_global.h"
00035 #include "quazipfileinfo.h"
00036 
00037 // just in case it will be defined in the later versions of the ZIP/UNZIP
00038 #ifndef UNZ_OPENERROR
00039 // define additional error code
00040 #define UNZ_OPENERROR -1000
00041 #endif
00042 
00043 class QuaZipPrivate;
00044 
00046 
00083 class QUAZIP_EXPORT QuaZip {
00084   friend class QuaZipPrivate;
00085   public:
00087     enum Constants {
00088       MAX_FILE_NAME_LENGTH=256 
00091     };
00093     enum Mode {
00094       mdNotOpen, 
00095       mdUnzip, 
00096       mdCreate, 
00097       mdAppend, 
00105       mdAdd 
00106     };
00108 
00113     enum CaseSensitivity {
00114       csDefault=0, 
00115       csSensitive=1, 
00116       csInsensitive=2 
00117     };
00118   private:
00119     QuaZipPrivate *p;
00120     // not (and will not be) implemented
00121     QuaZip(const QuaZip& that);
00122     // not (and will not be) implemented
00123     QuaZip& operator=(const QuaZip& that);
00124   public:
00126 
00127     QuaZip();
00129     QuaZip(const QString& zipName);
00131 
00132     QuaZip(QIODevice *ioDevice);
00134 
00135     ~QuaZip();
00137 
00173     bool open(Mode mode, zlib_filefunc_def *ioApi =NULL);
00175 
00178     void close();
00180 
00185     void setFileNameCodec(QTextCodec *fileNameCodec);
00187 
00190     void setFileNameCodec(const char *fileNameCodecName);
00192     QTextCodec* getFileNameCodec() const;
00194 
00196     void setCommentCodec(QTextCodec *commentCodec);
00198 
00201     void setCommentCodec(const char *commentCodecName);
00203     QTextCodec* getCommentCodec() const;
00205 
00210     QString getZipName() const;
00212 
00217     void setZipName(const QString& zipName);
00219 
00223     QIODevice *getIoDevice() const;
00225 
00230     void setIoDevice(QIODevice *ioDevice);
00232     Mode getMode() const;
00234     bool isOpen() const;
00236 
00244     int getZipError() const;
00246 
00249     int getEntriesCount() const;
00251     QString getComment() const;
00253 
00257     void setComment(const QString& comment);
00259 
00262     bool goToFirstFile();
00264 
00281     bool goToNextFile();
00283 
00307     bool setCurrentFile(const QString& fileName, CaseSensitivity cs =csDefault);
00309     bool hasCurrentFile() const;
00311 
00326     bool getCurrentFileInfo(QuaZipFileInfo* info)const;
00328 
00334     QString getCurrentFileName()const;
00336 
00351     unzFile getUnzFile();
00353 
00357     zipFile getZipFile();
00359 
00382     void setDataDescriptorWritingEnabled(bool enabled);
00384 
00387     bool isDataDescriptorWritingEnabled() const;
00389 
00395     QStringList getFileNameList() const;
00397 
00403     QList<QuaZipFileInfo> getFileInfoList() const;
00404 };
00405 
00406 #endif
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaAdler32__inherit__graph.md50000644000175000017500000000004012070466513026440 0ustar csmallcsmallf6aef7d7bad2a6a2c0f29520e9cdb67fmudlet-2.1/src/quazip/quazip-0.4.4/doc/html/jquery.js0000644000175000017500000024562212070466513021635 0ustar csmallcsmall/* * jQuery JavaScript Library v1.3.2 * http://jquery.com/ * * Copyright (c) 2009 John Resig * Dual licensed under the MIT and GPL licenses. * http://docs.jquery.com/License * * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) * Revision: 6246 */ (function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div
","
"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); /* * Sizzle CSS Selector Engine - v0.9.3 * Copyright 2009, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */ (function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="

";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0) {I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
").append(M.responseText.replace(//g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function() {G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='
';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); /* * jQuery UI 1.7.2 * * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI */ jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.2",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);;/* * jQuery UI Resizable 1.7.2 * * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Resizables * * Depends: * ui.core.js */ (function(c){c.widget("ui.resizable",c.extend({},c.ui.mouse,{_init:function(){var e=this,j=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(j.aspectRatio),aspectRatio:j.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:j.helper||j.ghost||j.animate?j.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){if(/relative/.test(this.element.css("position"))&&c.browser.opera){this.element.css({position:"relative",top:"auto",left:"auto"})}this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=j.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var k=this.handles.split(",");this.handles={};for(var f=0;f
');if(/sw|se|ne|nw/.test(h)){g.css({zIndex:++j.zIndex})}if("se"==h){g.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[h]=".ui-resizable-"+h;this.element.append(g)}}this._renderAxis=function(p){p=p||this.element;for(var m in this.handles){if(this.handles[m].constructor==String){this.handles[m]=c(this.handles[m],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var n=c(this.handles[m],this.element),o=0;o=/sw|ne|nw|se|n|s/.test(m)?n.outerHeight():n.outerWidth();var l=["padding",/ne|nw|n/.test(m)?"Top":/se|sw|s/.test(m)?"Bottom":/^e$/.test(m)?"Right":"Left"].join("");p.css(l,o);this._proportionallyResize()}if(!c(this.handles[m]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!e.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}e.axis=i&&i[1]?i[1]:"se"}});if(j.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){c(this).removeClass("ui-resizable-autohide");e._handles.show()},function(){if(!e.resizing){c(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var d=function(f){c(f).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){d(this.element);var e=this.element;e.parent().append(this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")})).end().remove()}this.originalElement.css("resize",this.originalResizeStyle);d(this.originalElement)},_mouseCapture:function(e){var f=false;for(var d in this.handles){if(c(this.handles[d])[0]==e.target){f=true}}return this.options.disabled||!!f},_mouseStart:function(f){var i=this.options,e=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(d.is(".ui-draggable")||(/absolute/).test(d.css("position"))){d.css({position:"absolute",top:e.top,left:e.left})}if(c.browser.opera&&(/relative/).test(d.css("position"))){d.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var j=b(this.helper.css("left")),g=b(this.helper.css("top"));if(i.containment){j+=c(i.containment).scrollLeft()||0;g+=c(i.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:j,top:g};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:j,top:g};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:f.pageX,top:f.pageY};this.aspectRatio=(typeof i.aspectRatio=="number")?i.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var h=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",h=="auto"?this.axis+"-resize":h);d.addClass("ui-resizable-resizing");this._propagate("start",f);return true},_mouseDrag:function(d){var g=this.helper,f=this.options,l={},p=this,i=this.originalMousePosition,m=this.axis;var q=(d.pageX-i.left)||0,n=(d.pageY-i.top)||0;var h=this._change[m];if(!h){return false}var k=h.apply(this,[d,q,n]),j=c.browser.msie&&c.browser.version<7,e=this.sizeDiff;if(this._aspectRatio||d.shiftKey){k=this._updateRatio(k,d)}k=this._respectSize(k,d);this._propagate("resize",d);g.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(k);this._trigger("resize",d,this.ui());return false},_mouseStop:function(g){this.resizing=false;var h=this.options,l=this;if(this._helper){var f=this._proportionallyResizeElements,d=f.length&&(/textarea/i).test(f[0].nodeName),e=d&&c.ui.hasScroll(f[0],"left")?0:l.sizeDiff.height,j=d?0:l.sizeDiff.width;var m={width:(l.size.width-j),height:(l.size.height-e)},i=(parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left))||null,k=(parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top))||null;if(!h.animate){this.element.css(c.extend(m,{top:k,left:i}))}l.helper.height(l.size.height);l.helper.width(l.size.width);if(this._helper&&!h.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",g);if(this._helper){this.helper.remove()}return false},_updateCache:function(d){var e=this.options;this.offset=this.helper.offset();if(a(d.left)){this.position.left=d.left}if(a(d.top)){this.position.top=d.top}if(a(d.height)){this.size.height=d.height}if(a(d.width)){this.size.width=d.width}},_updateRatio:function(g,f){var h=this.options,i=this.position,e=this.size,d=this.axis;if(g.height){g.width=(e.height*this.aspectRatio)}else{if(g.width){g.height=(e.width/this.aspectRatio)}}if(d=="sw"){g.left=i.left+(e.width-g.width);g.top=null}if(d=="nw"){g.top=i.top+(e.height-g.height);g.left=i.left+(e.width-g.width)}return g},_respectSize:function(k,f){var i=this.helper,h=this.options,q=this._aspectRatio||f.shiftKey,p=this.axis,s=a(k.width)&&h.maxWidth&&(h.maxWidthk.width),r=a(k.height)&&h.minHeight&&(h.minHeight>k.height);if(g){k.width=h.minWidth}if(r){k.height=h.minHeight}if(s){k.width=h.maxWidth}if(l){k.height=h.maxHeight}var e=this.originalPosition.left+this.originalSize.width,n=this.position.top+this.size.height;var j=/sw|nw|w/.test(p),d=/nw|ne|n/.test(p);if(g&&j){k.left=e-h.minWidth}if(s&&j){k.left=e-h.maxWidth}if(r&&d){k.top=n-h.minHeight}if(l&&d){k.top=n-h.maxHeight}var m=!k.width&&!k.height;if(m&&!k.left&&k.top){k.top=null}else{if(m&&!k.top&&k.left){k.left=null}}return k},_proportionallyResize:function(){var j=this.options;if(!this._proportionallyResizeElements.length){return}var f=this.helper||this.element;for(var e=0;e');var d=c.browser.msie&&c.browser.version<7,f=(d?1:0),g=(d?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+g,height:this.element.outerHeight()+g,position:"absolute",left:this.elementOffset.left-f+"px",top:this.elementOffset.top-f+"px",zIndex:++h.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(f,e,d){return{width:this.originalSize.width+e}},w:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{left:h.left+e,width:f.width-e}},n:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{top:h.top+d,height:f.height-d}},s:function(f,e,d){return{height:this.originalSize.height+d}},se:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},sw:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[f,e,d]))},ne:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},nw:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[f,e,d]))}},_propagate:function(e,d){c.ui.plugin.call(this,e,[d,this.ui()]);(e!="resize"&&this._trigger(e,d,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}));c.extend(c.ui.resizable,{version:"1.7.2",eventPrefix:"resize",defaults:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,cancel:":input,option",containment:false,delay:0,distance:1,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000}});c.ui.plugin.add("resizable","alsoResize",{start:function(e,f){var d=c(this).data("resizable"),g=d.options;_store=function(h){c(h).each(function(){c(this).data("resizable-alsoresize",{width:parseInt(c(this).width(),10),height:parseInt(c(this).height(),10),left:parseInt(c(this).css("left"),10),top:parseInt(c(this).css("top"),10)})})};if(typeof(g.alsoResize)=="object"&&!g.alsoResize.parentNode){if(g.alsoResize.length){g.alsoResize=g.alsoResize[0];_store(g.alsoResize)}else{c.each(g.alsoResize,function(h,i){_store(h)})}}else{_store(g.alsoResize)}},resize:function(f,h){var e=c(this).data("resizable"),i=e.options,g=e.originalSize,k=e.originalPosition;var j={height:(e.size.height-g.height)||0,width:(e.size.width-g.width)||0,top:(e.position.top-k.top)||0,left:(e.position.left-k.left)||0},d=function(l,m){c(l).each(function(){var p=c(this),q=c(this).data("resizable-alsoresize"),o={},n=m&&m.length?m:["width","height","top","left"];c.each(n||["width","height","top","left"],function(r,t){var s=(q[t]||0)+(j[t]||0);if(s&&s>=0){o[t]=s||null}});if(/relative/.test(p.css("position"))&&c.browser.opera){e._revertToRelativePosition=true;p.css({position:"absolute",top:"auto",left:"auto"})}p.css(o)})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.nodeType){c.each(i.alsoResize,function(l,m){d(l,m)})}else{d(i.alsoResize)}},stop:function(e,f){var d=c(this).data("resizable");if(d._revertToRelativePosition&&c.browser.opera){d._revertToRelativePosition=false;el.css({position:"relative"})}c(this).removeData("resizable-alsoresize-start")}});c.ui.plugin.add("resizable","animate",{stop:function(h,m){var n=c(this).data("resizable"),i=n.options;var g=n._proportionallyResizeElements,d=g.length&&(/textarea/i).test(g[0].nodeName),e=d&&c.ui.hasScroll(g[0],"left")?0:n.sizeDiff.height,k=d?0:n.sizeDiff.width;var f={width:(n.size.width-k),height:(n.size.height-e)},j=(parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left))||null,l=(parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top))||null;n.element.animate(c.extend(f,l&&j?{top:l,left:j}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var o={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};if(g&&g.length){c(g[0]).css({width:o.width,height:o.height})}n._updateCache(o);n._propagate("resize",h)}})}});c.ui.plugin.add("resizable","containment",{start:function(e,q){var s=c(this).data("resizable"),i=s.options,k=s.element;var f=i.containment,j=(f instanceof c)?f.get(0):(/parent/.test(f))?k.parent().get(0):f;if(!j){return}s.containerElement=c(j);if(/document/.test(f)||f==document){s.containerOffset={left:0,top:0};s.containerPosition={left:0,top:0};s.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var m=c(j),h=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){h[p]=b(m.css("padding"+o))});s.containerOffset=m.offset();s.containerPosition=m.position();s.containerSize={height:(m.innerHeight()-h[3]),width:(m.innerWidth()-h[1])};var n=s.containerOffset,d=s.containerSize.height,l=s.containerSize.width,g=(c.ui.hasScroll(j,"left")?j.scrollWidth:l),r=(c.ui.hasScroll(j)?j.scrollHeight:d);s.parentData={element:j,left:n.left,top:n.top,width:g,height:r}}},resize:function(f,p){var s=c(this).data("resizable"),h=s.options,e=s.containerSize,n=s.containerOffset,l=s.size,m=s.position,q=s._aspectRatio||f.shiftKey,d={top:0,left:0},g=s.containerElement;if(g[0]!=document&&(/static/).test(g.css("position"))){d=n}if(m.left<(s._helper?n.left:0)){s.size.width=s.size.width+(s._helper?(s.position.left-n.left):(s.position.left-d.left));if(q){s.size.height=s.size.width/h.aspectRatio}s.position.left=h.helper?n.left:0}if(m.top<(s._helper?n.top:0)) {s.size.height=s.size.height+(s._helper?(s.position.top-n.top):s.position.top);if(q){s.size.width=s.size.height*h.aspectRatio}s.position.top=s._helper?n.top:0}s.offset.left=s.parentData.left+s.position.left;s.offset.top=s.parentData.top+s.position.top;var k=Math.abs((s._helper?s.offset.left-d.left:(s.offset.left-d.left))+s.sizeDiff.width),r=Math.abs((s._helper?s.offset.top-d.top:(s.offset.top-n.top))+s.sizeDiff.height);var j=s.containerElement.get(0)==s.element.parent().get(0),i=/relative|absolute/.test(s.containerElement.css("position"));if(j&&i){k-=s.parentData.left}if(k+s.size.width>=s.parentData.width){s.size.width=s.parentData.width-k;if(q){s.size.height=s.size.width/s.aspectRatio}}if(r+s.size.height>=s.parentData.height){s.size.height=s.parentData.height-r;if(q){s.size.width=s.size.height*s.aspectRatio}}},stop:function(e,m){var p=c(this).data("resizable"),f=p.options,k=p.position,l=p.containerOffset,d=p.containerPosition,g=p.containerElement;var i=c(p.helper),q=i.offset(),n=i.outerWidth()-p.sizeDiff.width,j=i.outerHeight()-p.sizeDiff.height;if(p._helper&&!f.animate&&(/relative/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}if(p._helper&&!f.animate&&(/static/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}}});c.ui.plugin.add("resizable","ghost",{start:function(f,g){var d=c(this).data("resizable"),h=d.options,e=d.size;d.ghost=d.originalElement.clone();d.ghost.css({opacity:0.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");d.ghost.appendTo(d.helper)},resize:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost){d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})}},stop:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost&&d.helper){d.helper.get(0).removeChild(d.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(d,l){var n=c(this).data("resizable"),g=n.options,j=n.size,h=n.originalSize,i=n.originalPosition,m=n.axis,k=g._aspectRatio||d.shiftKey;g.grid=typeof g.grid=="number"?[g.grid,g.grid]:g.grid;var f=Math.round((j.width-h.width)/(g.grid[0]||1))*(g.grid[0]||1),e=Math.round((j.height-h.height)/(g.grid[1]||1))*(g.grid[1]||1);if(/^(se|s|e)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e}else{if(/^(ne)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e}else{if(/^(sw)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.left=i.left-f}else{n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e;n.position.left=i.left-f}}}}});var b=function(d){return parseInt(d,10)||0};var a=function(d){return !isNaN(parseInt(d,10))}})(jQuery);; /** * jQuery.ScrollTo - Easy element scrolling using jQuery. * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com * Licensed under GPL license (http://www.opensource.org/licenses/gpl-license.php). * Date: 2/8/2008 * @author Ariel Flesler * @version 1.3.2 */ ;(function($){var o=$.scrollTo=function(a,b,c){o.window().scrollTo(a,b,c)};o.defaults={axis:'y',duration:1};o.window=function(){return $($.browser.safari?'body':'html')};$.fn.scrollTo=function(l,m,n){if(typeof m=='object'){n=m;m=0}n=$.extend({},o.defaults,n);m=m||n.speed||n.duration;n.queue=n.queue&&n.axis.length>1;if(n.queue)m/=2;n.offset=j(n.offset);n.over=j(n.over);return this.each(function(){var a=this,b=$(a),t=l,c,d={},w=b.is('html,body');switch(typeof t){case'number':case'string':if(/^([+-]=)?\d+(px)?$/.test(t)){t=j(t);break}t=$(t,this);case'object':if(t.is||t.style)c=(t=$(t)).offset()}$.each(n.axis.split(''),function(i,f){var P=f=='x'?'Left':'Top',p=P.toLowerCase(),k='scroll'+P,e=a[k],D=f=='x'?'Width':'Height';if(c){d[k]=c[p]+(w?0:e-b.offset()[p]);if(n.margin){d[k]-=parseInt(t.css('margin'+P))||0;d[k]-=parseInt(t.css('border'+P+'Width'))||0}d[k]+=n.offset[p]||0;if(n.over[p])d[k]+=t[D.toLowerCase()]()*n.over[p]}else d[k]=t[p];if(/^\d+$/.test(d[k]))d[k]=d[k]<=0?0:Math.min(d[k],h(D));if(!i&&n.queue){if(e!=d[k])g(n.onAfterFirst);delete d[k]}});g(n.onAfter);function g(a){b.animate(d,m,n.easing,a&&function(){a.call(this,l)})};function h(D){var b=w?$.browser.opera?document.body:document.documentElement:a;return b['scroll'+D]-b['client'+D]}})};function j(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery); mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaCrc32__inherit__graph.png0000644000175000017500000000253412070466513026231 0ustar csmallcsmallPNG  IHDRp$bKGDIDATx휽k1u>7)-:BS!k CR::ɔNMbJI 6t x)Mi>.Nϒ|zo(I;I$v 2@:@@@fs~~T6Cltc{{\.ԳRvwwWWWbJCMP`    zqK(qŘ}}/tXt~.}5 2UbaBq䂤wuIzLr-ӫx}nqdqrXkv\GOHKQxɮQaA՛kpf"T93$^^qPܕgq5PPKg"Vf=gnnOIgJ?=dAݱ %mNrF*#\yB] Ԗ9+U#8zq\D|       珕Nxǩbu]Cܾ03 KKK;~D*fo>7ɓϞ͙EAX?^~t.XH9>>94*Eqft:XTno]H }޽alJ탖AdRj0uQ*U~R9`JXϓ{ ޼b*%u,Q. K,}zn{{fHJWqѱ[}lm}ś_J~0LE2:zΝ[?ׯenReB}GND[A}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}#䤑^dnݑjq5a>rzÂX,)]=g.&bQo@\?`>`>`>`a<ϋʕJE=NOAWו f|xGw9<RR|j8qA)Sefr@}$楨Um~c!:) Z<->H |b  pB1;}Ao!iʍC %ZbfbVݶF' rkq/-$[h>q}yBAW@p?      CfFCoLLLLLOOk 8 ߧ?0   hd PIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_0.md50000644000175000017500000000004012070466513023410 0ustar csmallcsmall87c0f0d7a3432462cbd094e7c615e18emudlet-2.1/src/quazip/quazip-0.4.4/doc/html/JlCompress_8h_source.html0000644000175000017500000001347012070466513024700 0ustar csmallcsmall QuaZIP: quazip/JlCompress.h Source File
JlCompress.h
00001 #ifndef JLCOMPRESSFOLDER_H_
00002 #define JLCOMPRESSFOLDER_H_
00003 
00004 #include "quazip.h"
00005 #include "quazipfile.h"
00006 #include "quazipfileinfo.h"
00007 #include <QString>
00008 #include <QDir>
00009 #include <QFileInfo>
00010 #include <QFile>
00011 
00013 
00017 class QUAZIP_EXPORT JlCompress {
00018 private:
00020 
00026     static bool compressFile(QuaZip* zip, QString fileName, QString fileDest);
00028 
00037     static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive = true);
00039 
00045     static bool extractFile(QuaZip* zip, QString fileName, QString fileDest);
00047 
00051     static bool removeFile(QStringList listFile);
00052 
00053 public:
00055 
00060     static bool compressFile(QString fileCompressed, QString file);
00062 
00067     static bool compressFiles(QString fileCompressed, QStringList files);
00069 
00076     static bool compressDir(QString fileCompressed, QString dir = QString(), bool recursive = true);
00077 
00078 public:
00080 
00087     static QString extractFile(QString fileCompressed, QString fileName, QString fileDest = QString());
00089 
00096     static QStringList extractFiles(QString fileCompressed, QStringList files, QString dir = QString());
00098 
00104     static QStringList extractDir(QString fileCompressed, QString dir = QString());
00106 
00111     static QStringList getFileList(QString fileCompressed);
00112 };
00113 
00114 #endif /* JLCOMPRESSFOLDER_H_ */
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/quaadler32_8h_source.html0000644000175000017500000001041012070466513024551 0ustar csmallcsmall QuaZIP: quazip/quaadler32.h Source File
quaadler32.h
00001 #ifndef QUAADLER32_H
00002 #define QUAADLER32_H
00003 
00004 #include <QByteArray>
00005 
00006 #include "quachecksum32.h"
00007 
00009 
00013 class QUAZIP_EXPORT QuaAdler32 : public QuaChecksum32
00014 {
00015 
00016 public:
00017         QuaAdler32();
00018 
00019         quint32 calculate(const QByteArray &data);
00020 
00021         void reset();
00022         void update(const QByteArray &buf);
00023         quint32 value();
00024 
00025 private:
00026         quint32 checksum;
00027 };
00028 
00029 #endif //QUAADLER32_H
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipPrivate__coll__graph.png0000644000175000017500000000403212070466513026734 0ustar csmallcsmallPNG  IHDRp\zbKGDIDATxOWϙeVXvE6 njjIڤ5!i6zcLL1?hH&6D#֔C VPolq3.왳>g,2CRJn(eDӧOBIq(vxb%VWyq}}}yy90G299߯P$Z777*tuu;wNPpC) 72dQ2I$Io߸q#D"tmfMJ(t{@sCOy%,+ (PΡjgm+f!ݪmiCuCsBE-!V tC)Tp2MDjI,v 4yb>X&/C%S)O32✋kӐ1DϚrFI-%ID4bWoh+ʐ-+gϞea)SeN! 72]F u.PpC) 9YXXD]ZU$uvu J2VfnlʇcOf|neQС ՠLV'}:_J"\n - 6͇!^xSUCAtÐЛ=_u6uTV sbitd& }5{z0v ΌkQ&V6tq2~Đ #K<54~l86[.g&PCo4 *I:oagB`ΌFM|#NtYyfhij "]k$.n_}a^<嫚UMlΉLBp R\B nPx^XT&Ɨ:m/"܅N͡LߜxsCY޷d .hQP).uU5 W5v`UYЧ Bo[[ů@ |gĸ 5K|IXIȸC13Gd >u`CEi 72P8P>J͇B"0_eÀt-R%ӿf85"NohQMd@Fh2!SN,_@*ehQj4Th|Ni Y\!2Te&̇0)1"~iPj,#dL.,P)Si9ٹJn(ea(́|R>j#>ʠ[= ?+" 'ʠ|S<~J= OcsW>PNk'<~ЗlXD,mY!T)^) 헚&~Z|~oM_K>'Kil>ɦLD.}poj(40mc߼*+94uG6 TwdjLî5KRմVcv -uP _QS]CBuG;c > " ;bPOXRA\Sz ~=mӏ|%Tn}W`P_-'-z/ e-%L– bD-ZӇQXӱԴ,IrM H1C [&KO=UM%"]ڗe-Ȕô$ݥ{ZC>տp8Lj#SN566RN/]Dw ;ZV*0C72PpC)pOIZAЮXem(񵭹 n"Oy}r~ dJ5 PĶɅ 3 /o:ͧ 3k_ E.G(ʰfNS^]S](SGZow$C(YY#FcS^3E4tk'Wy :4v8 Jn(ey_~ǎP}3D__s;::FFFhf'@ôzctƹJn(eR?P^ֈIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZip__coll__graph.md50000644000175000017500000000004012070466513025275 0ustar csmallcsmalld04fc6b476641932472c86fd8096968cmudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_4.png0000644000175000017500000000076412070466513023530 0ustar csmallcsmallPNG  IHDRs%A[bKGDIDATh Ua 8#8 |H(~'GkK !  R R Rc]׮m*Rumۦi'le貾y\)# #Y,HY,HY,HY,Ƙ]>TƘ#"NUOra `8$ZFH5g ZpitY]bc,t'+˩lSҿӳ;K K&c#[a̻OmuFS1;Bbi>e mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipPrivate-members.html0000644000175000017500000000514012070466513026055 0ustar csmallcsmall QuaZIP: Member List
QuaZipPrivate Member List
This is the complete list of members for QuaZipPrivate, including all inherited members.
QuaZip (defined in QuaZipPrivate)QuaZipPrivate [friend]
unzFile_fQuaZipPrivate
zipFile_fQuaZipPrivate
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/structQuaZipFileInfo-members.html0000644000175000017500000001163012070466513026356 0ustar csmallcsmall QuaZIP: Member List
QuaZipFileInfo Member List
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaChecksum32__inherit__graph.map0000644000175000017500000000040212070466513027245 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaAdler32__coll__graph.md50000644000175000017500000000004012070466513025727 0ustar csmallcsmallf6aef7d7bad2a6a2c0f29520e9cdb67fmudlet-2.1/src/quazip/quazip-0.4.4/doc/html/nav_h.png0000644000175000017500000000014112070466513021542 0ustar csmallcsmallPNG  IHDR ,@(IDATxݱ 0 A2U !kJrZoIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_6.md50000644000175000017500000000004012070466513023416 0ustar csmallcsmall2fed9c540a17c647243104aeda47c683mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaCrc32-members.html0000644000175000017500000000603512070466513024640 0ustar csmallcsmall QuaZIP: Member List
QuaCrc32 Member List
This is the complete list of members for QuaCrc32, including all inherited members.
calculate(const QByteArray &data)QuaCrc32 [virtual]
QuaCrc32() (defined in QuaCrc32)QuaCrc32
reset()QuaCrc32 [virtual]
update(const QByteArray &buf)QuaCrc32 [virtual]
value()QuaCrc32 [virtual]
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_4.md50000644000175000017500000000004012070466513023414 0ustar csmallcsmallbb94f8389c69fe5653003491edaa81cbmudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaChecksum32__inherit__graph.png0000644000175000017500000000623512070466513027266 0ustar csmallcsmallPNG  IHDRp2cbKGD RIDATx{TWg&^ "K{iqE]*TkX\۲*UV RmxVZ[*VbI2dH7'Nޙ5Lo~} d2a $g !@ -)**BBݻwĈ ʖBBmmmcccbb"F ð͛7V!7g !@|X8NtteɓXfMuG[- q(qȷ9w*!͸iDsYaV]vh;!N0(I&4d׬WyM?XjvOOXvڭhvQKa [AlfD 8o߾ FttN|hMA>C 3 @>C A쬭'&lذv"wj\#Ν;(ÿ L{33׷z^SDʚ6M.G4?N [/8Lvz`1cƁ;Μ^Sq$L&F N||BAӧi>=jEٯ@Iɉiv|me.1zSO23`0h$IT^K/m?};. 3 ð+Wg.ܶ` 0L9=h;wO>Oy'!aOV֡9P,63ܹ/_90`|+GP,Gazeʼn}Z~Aq4HʧF {鑌Li4ݽeeE BC}|FJ7fFNbQ~~>nRaV¦ !Cm2d2;I`9hbFP%+aaa,Ɔ FNG:爈`E}aXx膆~[v*Pi*:BXXLFpO>I}1/Ņ}aX}}[{ͤpc(A A౱Ja L>}|MMKW=Ņ}V~yǎ7x8?sˉ ~xfi频#Uo_.޽S%1qdq9sn ިV}a0={jBHg˖-44֭^~TW9"=o_ӗ_|}7ф9s&N :$zٹsϙSfkCzcm% :cհ4({wu$dJO?@xIBsf5jXateAr>۳riiJ [ V,_bvvՅ 7`kiϾjb++Fܹ%o?v,Pݻ|yZ&XDi{#RI\Y,(%յTT/g^/+[["#Ǯ\w YCC{A\Mh JV֬ZtOOl->꺷jՁg, [ ' dzǮ8sq o6sZ׻da}}ۇ61.ۿxVl-1c˖kp+ғ?n?l-N:ulZZݻ`k ?Yg,[sdxjj(5}SS+u\ZRy9sl->{/{߾%b&,MM`kYuO,!53ƯZu[ϭϮ\49y W {z*W4=Qs)=|_<(7/OpGYY7gc¥|qg?k)nnäI7k>m0u|5tEE 1O歷q}.ܘ=099"/UZxYvy{9jbY|„\ l-|վ޵eK l-Lpeezz8GMuu-8}V^UMMI#G`kᝤg33uׯ[s{~v|FStiTNN,l-QW][?[tOdgOO}K::Z@>3LFuc **NWUQz~~"&''Oٰ˗`kqQϚ͝[zzݺ@ߨuuk[;wV1&#cl-0qsk)7o[ehL`ܽ{>ܷ۶%9>~ٳgJnn۴i+L&/>3(y{來k׮C\ENk׮vq.]>(͛gD#  M|3A>C 3Go:pSbCjP0pǩ <(q MGq(Wi]ѩ'Oc2nڶdV ͂0]ER8q??Jm3ǡ)lͼ-sRF@Kag c=8X7n٦s2Ѭ+'c |cN ¼a}N 98:pmvctV˘ ԱKټnٶ"qDd2)XLc* WuvK d$I#AWQSǰ?|eN/F9CjQ*) c>nڞaiJa ?8,`:t}3 @>C 3 sLV!LZ[[8 $EFFΛ7$IKTTԂ IJJbDDM!@|gڶ9ڸIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classJlCompress.html0000644000175000017500000005263012070466513023750 0ustar csmallcsmall QuaZIP: JlCompress Class Reference
JlCompress Class Reference

Utility class for typical operations. More...

#include <JlCompress.h>

List of all members.

Static Public Member Functions

static bool compressFile (QString fileCompressed, QString file)
 Compress a single file.
static bool compressFiles (QString fileCompressed, QStringList files)
 Compress a list of files.
static bool compressDir (QString fileCompressed, QString dir=QString(), bool recursive=true)
 Compress a whole directory.
static QString extractFile (QString fileCompressed, QString fileName, QString fileDest=QString())
 Extract a single file.
static QStringList extractFiles (QString fileCompressed, QStringList files, QString dir=QString())
 Extract a list of files.
static QStringList extractDir (QString fileCompressed, QString dir=QString())
 Extract a whole archive.
static QStringList getFileList (QString fileCompressed)
 Get the file list.

Detailed Description

Utility class for typical operations.

This class contains a number of useful static functions to perform simple operations, such as mass ZIP packing or extraction.


Member Function Documentation

bool JlCompress::compressFile ( QString  fileCompressed,
QString  file 
) [static]

Compress a single file.

Parameters:
fileCompressedThe name of the archive.
fileThe file to compress.
Returns:
true if success, false otherwise.

OK Comprime il file fileName nel file fileCompressed. Se la funzione fallisce restituisce false e cancella il file che si e tentato di creare.

La funzione fallisce se: * non si riesce ad aprire l'oggetto zip; * la compressione del file fallisce; * non si riesce a chiudere l'oggetto zip;

References QuaZip::close(), QuaZip::getZipError(), QuaZip::mdCreate, and QuaZip::open().

bool JlCompress::compressFiles ( QString  fileCompressed,
QStringList  files 
) [static]

Compress a list of files.

Parameters:
fileCompressedThe name of the archive.
filesThe file list to compress.
Returns:
true if success, false otherwise.

OK Comprime i file specificati in files nel file fileCompressed. Se la funzione fallisce restituisce false e cancella il file che si e tentato di creare.

La funzione fallisce se: * non si riesce ad aprire l'oggetto zip; * la compressione di un file fallisce; * non si riesce a chiudere l'oggetto zip;

References QuaZip::close(), QuaZip::getZipError(), QuaZip::mdCreate, and QuaZip::open().

bool JlCompress::compressDir ( QString  fileCompressed,
QString  dir = QString(),
bool  recursive = true 
) [static]

Compress a whole directory.

Parameters:
fileCompressedThe name of the archive.
dirThe directory to compress.
recursiveWhether to pack the subdirectories as well, or just regular files.
Returns:
true if success, false otherwise.

OK Comprime la cartella dir nel file fileCompressed, se recursive e true allora comprime anche le sotto cartelle. Se la funzione fallisce restituisce false e cancella il file che si e tentato di creare.

La funzione fallisce se: * non si riesce ad aprire l'oggetto zip; * la compressione di un file fallisce; * non si riesce a chiudere l'oggetto zip;

References QuaZip::close(), QuaZip::getZipError(), QuaZip::mdCreate, and QuaZip::open().

QString JlCompress::extractFile ( QString  fileCompressed,
QString  fileName,
QString  fileDest = QString() 
) [static]

Extract a single file.

Parameters:
fileCompressedThe name of the archive.
fileNameThe file to extract.
fileDestThe destination file, assumed to be identical to file if left empty.
Returns:
The list of the full paths of the files extracted, empty on failure.

OK Estrae il file fileName, contenuto nel file fileCompressed, con il nome fileDest. Se fileDest = "" allora il file viene estratto con lo stesso nome con cui e stato compresso. Se la funzione fallisce cancella il file che si e tentato di estrarre. Restituisce il nome assoluto del file estratto.

La funzione fallisce se: * non si riesce ad aprire l'oggetto zip; * l'estrazione del file fallisce; * non si riesce a chiudere l'oggetto zip;

References QuaZip::close(), QuaZip::getZipError(), QuaZip::mdUnzip, and QuaZip::open().

QStringList JlCompress::extractFiles ( QString  fileCompressed,
QStringList  files,
QString  dir = QString() 
) [static]

Extract a list of files.

Parameters:
fileCompressedThe name of the archive.
filesThe file list to extract.
dirThe directory to put the files to, the current directory if left empty.
Returns:
The list of the full paths of the files extracted, empty on failure.

OK Estrae i file specificati in files, contenuti nel file fileCompressed, nella cartella dir. La struttura a cartelle del file compresso viene rispettata. Se dir = "" allora il file viene estratto nella cartella corrente. Se la funzione fallisce cancella i file che si e tentato di estrarre. Restituisce i nomi assoluti dei file estratti.

La funzione fallisce se: * non si riesce ad aprire l'oggetto zip; * l'estrazione di un file fallisce; * non si riesce a chiudere l'oggetto zip;

References QuaZip::close(), QuaZip::getZipError(), QuaZip::mdUnzip, and QuaZip::open().

QStringList JlCompress::extractDir ( QString  fileCompressed,
QString  dir = QString() 
) [static]

Extract a whole archive.

Parameters:
fileCompressedThe name of the archive.
dirThe directory to extract to, the current directory if left empty.
Returns:
The list of the full paths of the files extracted, empty on failure.

OK Estrae il file fileCompressed nella cartella dir. Se dir = "" allora il file viene estratto nella cartella corrente. Se la funzione fallisce cancella i file che si e tentato di estrarre. Restituisce i nomi assoluti dei file estratti.

La funzione fallisce se: * non si riesce ad aprire l'oggetto zip; * la compressione di un file fallisce; * non si riesce a chiudere l'oggetto zip;

References QuaZip::close(), getFileList(), QuaZip::getZipError(), QuaZip::mdUnzip, and QuaZip::open().

QStringList JlCompress::getFileList ( QString  fileCompressed) [static]

Get the file list.

Returns:
The list of the files in the archive, or, more precisely, the list of the entries, including both files and directories if they are present separately.

OK Restituisce la lista dei file resenti nel file compresso fileCompressed. Se la funzione fallisce, restituisce un elenco vuoto.

La funzione fallisce se: * non si riesce ad aprire l'oggetto zip; * la richiesta di informazioni di un file fallisce; * non si riesce a chiudere l'oggetto zip;

References QuaZip::close(), QuaZip::getCurrentFileInfo(), QuaZip::getZipError(), QuaZip::goToFirstFile(), QuaZip::goToNextFile(), QuaZip::mdUnzip, QuaZipFileInfo::name, and QuaZip::open().

Referenced by extractDir().


The documentation for this class was generated from the following files:
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipFilePrivate__coll__graph.map0000644000175000017500000000063312070466513027530 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/faq.html0000644000175000017500000000512412070466513021404 0ustar csmallcsmall QuaZIP: QuaZip FAQ
QuaZip FAQ

Q. Is there any way to use QuaZipFile in Qt where you are supposed to use normal (non-zipped) file, but not through QIODevice API?

A. Usually not. For example, if you are passing file name to some database driver (like SQLite), Qt usually just passes this name down to the 3rd-party library, which is usually does not know anything about QIODevice and therefore there is no way to pass QuaZipFile as normal file. However, if we are talking about some place where you pass file name, and then indirectly use QFile to open it, then it is a good idea to make overloaded method, which accepts QIODevice pointer. Then you would be able to pass QuaZipFile as well as many other nice things such as QBuffer or QProcess.

mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_1.map0000644000175000017500000000057212070466513023513 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/hierarchy.html0000644000175000017500000000530212070466513022611 0ustar csmallcsmall QuaZIP: Class Hierarchy
Class Hierarchy
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZipFilePrivate__coll__graph.md50000644000175000017500000000004012070466513027430 0ustar csmallcsmall8d67fd832bb90332fedcba49da020a67mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/tab_s.png0000644000175000017500000000027512070466513021547 0ustar csmallcsmallPNG  IHDR$[IDATx P@Kg"%(IE|%I7ilm" ӏCۓ\.dOZ̤Br/(#a6 8qaF-EtA4fl]JjJC%!<#īIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaAdler32__inherit__graph.map0000644000175000017500000000022412070466513026534 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/functions_enum.html0000644000175000017500000000477212070466513023701 0ustar csmallcsmall QuaZIP: Class Members - Enumerations
 
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/closed.png0000644000175000017500000000017612070466513021730 0ustar csmallcsmallPNG  IHDR EIDATxA @! Pi/`Є.?,!u zlޖJh1ߘ+vRLx@ (*79H l)IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/graph_legend.html0000644000175000017500000001160612070466513023256 0ustar csmallcsmall QuaZIP: Graph Legend
Graph Legend

This page explains how to interpret the graphs that are generated by doxygen.

Consider the following example:

/*! Invisible class because of truncation */
class Invisible { };

/*! Truncated class, inheritance relation is hidden */
class Truncated : public Invisible { };

/* Class not documented with doxygen comments */
class Undocumented { };

/*! Class that is inherited using public inheritance */
class PublicBase : public Truncated { };

/*! A template class */
template<class T> class Templ { };

/*! Class that is inherited using protected inheritance */
class ProtectedBase { };

/*! Class that is inherited using private inheritance */
class PrivateBase { };

/*! Class that is used by the Inherited class */
class Used { };

/*! Super class that inherits a number of other classes */
class Inherited : public PublicBase,
                  protected ProtectedBase,
                  private PrivateBase,
                  public Undocumented,
                  public Templ<int>
{
  private:
    Used *m_usedClass;
};

This will result in the following graph:

graph_legend.png

The boxes in the above graph have the following meaning:

  • A filled gray box represents the struct or class for which the graph is generated.
  • A box with a black border denotes a documented struct or class.
  • A box with a grey border denotes an undocumented struct or class.
  • A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.

The arrows have the following meaning:

  • A dark blue arrow is used to visualize a public inheritance relation between two classes.
  • A dark green arrow is used for protected inheritance.
  • A dark red arrow is used for private inheritance.
  • A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible.
  • A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance.
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaAdler32__inherit__graph.png0000644000175000017500000000257612070466513026557 0ustar csmallcsmallPNG  IHDRp$bKGD3IDATx=kIgIB ?6¤0\W.WSX$ؠ\B,\PHWefWgޕާ̫wږ>#P01En777Me3lmm---/|j= pq44ѬF ~˲2!XbY0>=Qr7=Y!{V^,HG-~՝i iU0<<a9(53 c$֥Zx1}s7J$BPvC!ixɠ', `T4`+ tsꃟjs]0LzSg<~= Czd;MTjCGd(y%ckxQ0,Ӱ<°ĄSd룢^?S@G-˛@W      |888ПdnTs4 ۶ sbqt* #R9gg|ǏMegϚ7 v˓M%>^n]^vc]8:jNJ}T*M.0<@E ^v:ޫWͦ$>xBTN}T*oy^Vk}ve0% 9?ߛJ N}T}/sdӧÅ~?;nI N^}|<`䂼8>k؃7U*y`Eezݻ/ܾ}XP^P.c޽?<j\!                               4)=`O`]Ȑ~unUgN\nZ=<qHP?;;8r竉||||||"σ 뺋 sss^/dP*666 ?pA>pA>pA>p`_2IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZip.html0000644000175000017500000022136412070466513023102 0ustar csmallcsmall QuaZIP: QuaZip Class Reference
QuaZip Class Reference

ZIP archive. More...

#include <quazip/quazip.h>

Collaboration diagram for QuaZip:

List of all members.

Public Types

enum  Constants { MAX_FILE_NAME_LENGTH = 256 }
 Useful constants. More...
enum  Mode {
  mdNotOpen, mdUnzip, mdCreate, mdAppend,
  mdAdd
}
 Open mode of the ZIP file. More...
enum  CaseSensitivity { csDefault = 0, csSensitive = 1, csInsensitive = 2 }
 Case sensitivity for the file names. More...

Public Member Functions

 QuaZip ()
 Constructs QuaZip object.
 QuaZip (const QString &zipName)
 Constructs QuaZip object associated with ZIP file zipName.
 QuaZip (QIODevice *ioDevice)
 Constructs QuaZip object associated with ZIP file represented by ioDevice.
 ~QuaZip ()
 Destroys QuaZip object.
bool open (Mode mode, zlib_filefunc_def *ioApi=NULL)
 Opens ZIP file.
void close ()
 Closes ZIP file.
void setFileNameCodec (QTextCodec *fileNameCodec)
 Sets the codec used to encode/decode file names inside archive.
void setFileNameCodec (const char *fileNameCodecName)
 Sets the codec used to encode/decode file names inside archive.
QTextCodec * getFileNameCodec () const
 Returns the codec used to encode/decode comments inside archive.
void setCommentCodec (QTextCodec *commentCodec)
 Sets the codec used to encode/decode comments inside archive.
void setCommentCodec (const char *commentCodecName)
 Sets the codec used to encode/decode comments inside archive.
QTextCodec * getCommentCodec () const
 Returns the codec used to encode/decode comments inside archive.
QString getZipName () const
 Returns the name of the ZIP file.
void setZipName (const QString &zipName)
 Sets the name of the ZIP file.
QIODevice * getIoDevice () const
 Returns the device representing this ZIP file.
void setIoDevice (QIODevice *ioDevice)
 Sets the device representing the ZIP file.
Mode getMode () const
 Returns the mode in which ZIP file was opened.
bool isOpen () const
 Returns true if ZIP file is open, false otherwise.
int getZipError () const
 Returns the error code of the last operation.
int getEntriesCount () const
 Returns number of the entries in the ZIP central directory.
QString getComment () const
 Returns global comment in the ZIP file.
void setComment (const QString &comment)
 Sets global comment in the ZIP file.
bool goToFirstFile ()
 Sets the current file to the first file in the archive.
bool goToNextFile ()
 Sets the current file to the next file in the archive.
bool setCurrentFile (const QString &fileName, CaseSensitivity cs=csDefault)
 Sets current file by its name.
bool hasCurrentFile () const
 Returns true if the current file has been set.
bool getCurrentFileInfo (QuaZipFileInfo *info) const
 Retrieves information about the current file.
QString getCurrentFileName () const
 Returns the current file name.
unzFile getUnzFile ()
 Returns unzFile handle.
zipFile getZipFile ()
 Returns zipFile handle.
void setDataDescriptorWritingEnabled (bool enabled)
 Changes the data descriptor writing mode.
bool isDataDescriptorWritingEnabled () const
 Returns the data descriptor default writing mode.
QStringList getFileNameList () const
 Returns a list of files inside the archive.
QList< QuaZipFileInfogetFileInfoList () const
 Returns information list about all files inside the archive.

Friends

class QuaZipPrivate

Detailed Description

ZIP archive.

This class implements basic interface to the ZIP archive. It can be used to read table contents of the ZIP archive and retreiving information about the files inside it.

You can also use this class to open files inside archive by passing pointer to the instance of this class to the constructor of the QuaZipFile class. But see QuaZipFile::QuaZipFile(QuaZip*, QObject*) for the possible pitfalls.

This class is indended to provide interface to the ZIP subpackage of the ZIP/UNZIP package as well as to the UNZIP subpackage. But currently it supports only UNZIP.

The use of this class is simple - just create instance using constructor, then set ZIP archive file name using setFile() function (if you did not passed the name to the constructor), then open() and then use different functions to work with it! Well, if you are paranoid, you may also wish to call close before destructing the instance, to check for errors on close.

You may also use getUnzFile() and getZipFile() functions to get the ZIP archive handle and use it with ZIP/UNZIP package API directly.

This class supports localized file names inside ZIP archive, but you have to set up proper codec with setCodec() function. By default, locale codec will be used, which is probably ok for UNIX systems, but will almost certainly fail with ZIP archives created in Windows. This is because Windows ZIP programs have strange habit of using DOS encoding for file names in ZIP archives. For example, ZIP archive with cyrillic names created in Windows will have file names in IBM866 encoding instead of WINDOWS-1251. I think that calling one function is not much trouble, but for true platform independency it would be nice to have some mechanism for file name encoding auto detection using locale information. Does anyone know a good way to do it?


Member Enumeration Documentation

Useful constants.

Enumerator:
MAX_FILE_NAME_LENGTH 

Maximum file name length. Taken from UNZ_MAXFILENAMEINZIP constant in unzip.c.

Open mode of the ZIP file.

Enumerator:
mdNotOpen 

ZIP file is not open. This is the initial mode.

mdUnzip 

ZIP file is open for reading files inside it.

mdCreate 

ZIP file was created with open() call.

mdAppend 

ZIP file was opened in append mode. This refers to APPEND_STATUS_CREATEAFTER mode in ZIP/UNZIP package and means that zip is appended to some existing file what is useful when that file contains self-extractor code. This is obviously not what you whant to use to add files to the existing ZIP archive.

mdAdd 

ZIP file was opened for adding files in the archive.

Case sensitivity for the file names.

This is what you specify when accessing files in the archive. Works perfectly fine with any characters thanks to Qt's great unicode support. This is different from ZIP/UNZIP API, where only US-ASCII characters was supported.

Enumerator:
csDefault 

Default for platform. Case sensitive for UNIX, not for Windows.

csSensitive 

Case sensitive.

csInsensitive 

Case insensitive.


Constructor & Destructor Documentation

QuaZip::QuaZip ( )

Constructs QuaZip object.

Call setName() before opening constructed object.

QuaZip::QuaZip ( QIODevice *  ioDevice)

Constructs QuaZip object associated with ZIP file represented by ioDevice.

The IO device must be seekable, otherwise an error will occur when opening.

QuaZip::~QuaZip ( )

Destroys QuaZip object.

Calls close() if necessary.

References close(), and isOpen().


Member Function Documentation

bool QuaZip::open ( Mode  mode,
zlib_filefunc_def *  ioApi = NULL 
)

Opens ZIP file.

Argument mode specifies open mode of the ZIP archive. See Mode for details. Note that there is zipOpen2() function in the ZIP/UNZIP API which accepts globalcomment argument, but it does not use it anywhere, so this open() function does not have this argument. See setComment() if you need to set global comment.

If the ZIP file is accessed via explicitly set QIODevice, then this device is opened in the necessary mode. If the device was already opened by some other means, then the behaviour is defined by the device implementation, but generally it is not a very good idea. For example, QFile will at least issue a warning.

Returns:
true if successful, false otherwise.
Note:
ZIP/UNZIP API open calls do not return error code - they just return NULL indicating an error. But to make things easier, quazip.h header defines additional error code UNZ_ERROROPEN and getZipError() will return it if the open call of the ZIP/UNZIP API returns NULL.

Argument ioApi specifies IO function set for ZIP/UNZIP package to use. See unzip.h, zip.h and ioapi.h for details. Note that IO API for QuaZip is different from the original package. The file path argument was changed to be of type voidpf, and QuaZip passes a QIODevice pointer there. This QIODevice is either set explicitly via setIoDevice() or the QuaZip(QIODevice*) constructor, or it is created internally when opening the archive by its file name. The default API (qioapi.cpp) just delegates everything to the QIODevice API. Not only this allows to use a QIODevice instead of file name, but also has a nice side effect of raising the file size limit from 2G to 4G.

In short: just forget about the ioApi argument and you'll be fine.

References isOpen(), mdAdd, mdAppend, mdCreate, mdUnzip, QuaZipPrivate::unzFile_f, and QuaZipPrivate::zipFile_f.

Referenced by JlCompress::compressDir(), JlCompress::compressFile(), JlCompress::compressFiles(), JlCompress::extractDir(), JlCompress::extractFile(), JlCompress::extractFiles(), JlCompress::getFileList(), and QuaZipFile::open().

void QuaZip::close ( )

Closes ZIP file.

Call getZipError() to determine if the close was successful. The underlying QIODevice is also closed, regardless of whether it was set explicitly or not.

References mdAdd, mdAppend, mdCreate, mdNotOpen, mdUnzip, QuaZipPrivate::unzFile_f, and QuaZipPrivate::zipFile_f.

Referenced by QuaZipFile::close(), JlCompress::compressDir(), JlCompress::compressFile(), JlCompress::compressFiles(), JlCompress::extractDir(), JlCompress::extractFile(), JlCompress::extractFiles(), JlCompress::getFileList(), QuaZipFile::open(), and ~QuaZip().

void QuaZip::setFileNameCodec ( QTextCodec *  fileNameCodec)

Sets the codec used to encode/decode file names inside archive.

This is necessary to access files in the ZIP archive created under Windows with non-latin characters in file names. For example, file names with cyrillic letters will be in IBM866 encoding.

void QuaZip::setFileNameCodec ( const char *  fileNameCodecName)

Sets the codec used to encode/decode file names inside archive.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName));

void QuaZip::setCommentCodec ( QTextCodec *  commentCodec)

Sets the codec used to encode/decode comments inside archive.

This codec defaults to locale codec, which is probably ok.

void QuaZip::setCommentCodec ( const char *  commentCodecName)

Sets the codec used to encode/decode comments inside archive.

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Equivalent to calling setCommentCodec(QTextCodec::codecForName(codecName));

QString QuaZip::getZipName ( ) const

Returns the name of the ZIP file.

Returns null string if no ZIP file name has been set, for example when the QuaZip instance is set up to use a QIODevice instead.

See also:
setZipName(), setIoDevice(), getIoDevice()

Referenced by QuaZipFile::getZipName().

void QuaZip::setZipName ( const QString &  zipName)

Sets the name of the ZIP file.

Does nothing if the ZIP file is open.

Does not reset error code returned by getZipError().

See also:
setIoDevice(), getIoDevice(), getZipName()

References isOpen().

QIODevice * QuaZip::getIoDevice ( ) const

Returns the device representing this ZIP file.

Returns null string if no device has been set explicitly, for example when opening a ZIP file by name.

See also:
setIoDevice(), getZipName(), setZipName()
void QuaZip::setIoDevice ( QIODevice *  ioDevice)

Sets the device representing the ZIP file.

Does nothing if the ZIP file is open.

Does not reset error code returned by getZipError().

See also:
getIoDevice(), getZipName(), setZipName()

References isOpen().

int QuaZip::getZipError ( ) const

Returns the error code of the last operation.

Returns UNZ_OK if the last operation was successful.

Error code resets to UNZ_OK every time you call any function that accesses something inside ZIP archive, even if it is const (like getEntriesCount()). open() and close() calls reset error code too. See documentation for the specific functions for details on error detection.

Referenced by QuaZipFile::close(), JlCompress::compressDir(), JlCompress::compressFile(), JlCompress::compressFiles(), JlCompress::extractDir(), JlCompress::extractFile(), JlCompress::extractFiles(), QuaZipFile::getActualFileName(), QuaZipFile::getFileInfo(), JlCompress::getFileList(), and QuaZipFile::open().

int QuaZip::getEntriesCount ( ) const

Returns number of the entries in the ZIP central directory.

Returns negative error code in the case of error. The same error code will be returned by subsequent getZipError() call.

References mdUnzip, and QuaZipPrivate::unzFile_f.

void QuaZip::setComment ( const QString &  comment)

Sets global comment in the ZIP file.

Comment will be written to the archive on close operation.

See also:
open()
bool QuaZip::goToFirstFile ( )

Sets the current file to the first file in the archive.

Returns true on success, false otherwise. Call getZipError() to get the error code.

References mdUnzip, and QuaZipPrivate::unzFile_f.

Referenced by JlCompress::getFileList(), and setCurrentFile().

bool QuaZip::goToNextFile ( )

Sets the current file to the next file in the archive.

Returns true on success, false otherwise. Call getZipError() to determine if there was an error.

Should be used only in QuaZip::mdUnzip mode.

Note:
If the end of file was reached, getZipError() will return UNZ_OK instead of UNZ_END_OF_LIST_OF_FILE. This is to make things like this easier:
 for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) {
   // do something
 }
 if(zip.getZipError()==UNZ_OK) {
   // ok, there was no error
 }

References mdUnzip, and QuaZipPrivate::unzFile_f.

Referenced by JlCompress::getFileList(), and setCurrentFile().

bool QuaZip::setCurrentFile ( const QString &  fileName,
CaseSensitivity  cs = csDefault 
)

Sets current file by its name.

Returns true if successful, false otherwise. Argument cs specifies case sensitivity of the file name. Call getZipError() in the case of a failure to get error code.

This is not a wrapper to unzLocateFile() function. That is because I had to implement locale-specific case-insensitive comparison.

Here are the differences from the original implementation:

  • If the file was not found, error code is UNZ_OK, not UNZ_END_OF_LIST_OF_FILE (see also goToNextFile()).
  • If this function fails, it unsets the current file rather than resetting it back to what it was before the call.

If fileName is null string then this function unsets the current file and return true. Note that you should close the file first if it is open! See QuaZipFile::QuaZipFile(QuaZip*,QObject*) for the details.

Should be used only in QuaZip::mdUnzip mode.

See also:
setFileNameCodec(), CaseSensitivity

References csDefault, csSensitive, getCurrentFileName(), goToFirstFile(), goToNextFile(), MAX_FILE_NAME_LENGTH, mdUnzip, and QuaZipPrivate::unzFile_f.

Referenced by QuaZipFile::open().

bool QuaZip::getCurrentFileInfo ( QuaZipFileInfo info) const

Retrieves information about the current file.

Fills the structure pointed by info. Returns true on success, false otherwise. In the latter case structure pointed by info remains untouched. If there was an error, getZipError() returns error code.

Should be used only in QuaZip::mdUnzip mode.

Does nothing and returns false in any of the following cases.

  • ZIP is not open;
  • ZIP does not have current file;
  • info is NULL;

In all these cases getZipError() returns UNZ_OK since there is no ZIP/UNZIP API call.

References QuaZipFileInfo::comment, QuaZipFileInfo::compressedSize, QuaZipFileInfo::crc, QuaZipFileInfo::dateTime, QuaZipFileInfo::diskNumberStart, QuaZipFileInfo::externalAttr, QuaZipFileInfo::extra, QuaZipFileInfo::flags, hasCurrentFile(), QuaZipFileInfo::internalAttr, isOpen(), mdUnzip, QuaZipFileInfo::method, QuaZipFileInfo::name, QuaZipFileInfo::uncompressedSize, QuaZipPrivate::unzFile_f, QuaZipFileInfo::versionCreated, and QuaZipFileInfo::versionNeeded.

Referenced by QuaZipFile::getFileInfo(), and JlCompress::getFileList().

QString QuaZip::getCurrentFileName ( ) const

Returns the current file name.

Equivalent to calling getCurrentFileInfo() and then getting name field of the QuaZipFileInfo structure, but faster and more convenient.

Should be used only in QuaZip::mdUnzip mode.

References hasCurrentFile(), isOpen(), MAX_FILE_NAME_LENGTH, mdUnzip, and QuaZipPrivate::unzFile_f.

Referenced by QuaZipFile::getActualFileName(), and setCurrentFile().

unzFile QuaZip::getUnzFile ( )

Returns unzFile handle.

You can use this handle to directly call UNZIP part of the ZIP/UNZIP package functions (see unzip.h).

Warning:
When using the handle returned by this function, please keep in mind that QuaZip class is unable to detect any changes you make in the ZIP file state (e. g. changing current file, or closing the handle). So please do not do anything with this handle that is possible to do with the functions of this class. Or at least return the handle in the original state before calling some another function of this class (including implicit destructor calls and calls from the QuaZipFile objects that refer to this QuaZip instance!). So if you have changed the current file in the ZIP archive - then change it back or you may experience some strange behavior or even crashes.

References QuaZipPrivate::unzFile_f.

Referenced by QuaZipFile::atEnd(), QuaZipFile::close(), QuaZipFile::csize(), QuaZipFile::open(), QuaZipFile::pos(), QuaZipFile::readData(), and QuaZipFile::usize().

zipFile QuaZip::getZipFile ( )

Returns zipFile handle.

You can use this handle to directly call ZIP part of the ZIP/UNZIP package functions (see zip.h). Warnings about the getUnzFile() function also apply to this function.

References QuaZipPrivate::zipFile_f.

Referenced by QuaZipFile::close(), QuaZipFile::open(), and QuaZipFile::writeData().

void QuaZip::setDataDescriptorWritingEnabled ( bool  enabled)

Changes the data descriptor writing mode.

According to the ZIP format specification, a file inside archive may have a data descriptor immediately following the file data. This is reflected by a special flag in the local file header and in the central directory. By default, QuaZIP sets this flag and writes the data descriptor unless both method and level were set to 0, in which case it operates in 1.0-compatible mode and never writes data descriptors.

By setting this flag to false, it is possible to disable data descriptor writing, thus increasing compatibility with archive readers that don't understand this feature of the ZIP file format.

Setting this flag affects all the QuaZipFile instances that are opened after this flag is set.

The data descriptor writing mode is enabled by default.

Parameters:
enabledIf true, enable local descriptor writing, disable it otherwise.
See also:
QuaZipFile::setDataDescriptorWritingEnabled()
bool QuaZip::isDataDescriptorWritingEnabled ( ) const

Returns the data descriptor default writing mode.

See also:
setDataDescriptorWritingEnabled()

Referenced by QuaZipFile::open().

QStringList QuaZip::getFileNameList ( ) const

Returns a list of files inside the archive.

Returns:
A list of file names or an empty list if there was an error or if the archive is empty (call getZipError() to figure out which).
See also:
getFileInfoList()
QList< QuaZipFileInfo > QuaZip::getFileInfoList ( ) const

Returns information list about all files inside the archive.

Returns:
A list of QuaZipFileInfo objects or an empty list if there was an error or if the archive is empty (call getZipError() to figure out which).
See also:
getFileNameList()

The documentation for this class was generated from the following files:
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaAdler32.html0000644000175000017500000002105412070466513023526 0ustar csmallcsmall QuaZIP: QuaAdler32 Class Reference
QuaAdler32 Class Reference

Adler32 checksum. More...

#include <quazip/quaadler32.h>

Inheritance diagram for QuaAdler32:
Collaboration diagram for QuaAdler32:

List of all members.

Public Member Functions

quint32 calculate (const QByteArray &data)
 Calculates the checksum for data.
void reset ()
 Resets the calculation on a checksun for a stream.
void update (const QByteArray &buf)
 Updates the calculated checksum for the stream.
quint32 value ()
 Value of the checksum calculated for the stream passed throw update().

Detailed Description

Adler32 checksum.

This class wrappers the adler32 function with the QuaChecksum32 interface. See QuaChecksum32 for more info.


Member Function Documentation

quint32 QuaAdler32::calculate ( const QByteArray &  data) [virtual]

Calculates the checksum for data.

data source data

Returns:
data checksum

This function has no efect on the value returned by value().

Implements QuaChecksum32.

void QuaAdler32::update ( const QByteArray &  buf) [virtual]

Updates the calculated checksum for the stream.

buf next portion of data from the stream

Implements QuaChecksum32.

quint32 QuaAdler32::value ( ) [virtual]

Value of the checksum calculated for the stream passed throw update().

Returns:
checksum

Implements QuaChecksum32.


The documentation for this class was generated from the following files:
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaAdler32__coll__graph.png0000644000175000017500000000257612070466513026046 0ustar csmallcsmallPNG  IHDRp$bKGD3IDATx=kIgIB ?6¤0\W.WSX$ؠ\B,\PHWefWgޕާ̫wږ>#P01En777Me3lmm---/|j= pq44ѬF ~˲2!XbY0>=Qr7=Y!{V^,HG-~՝i iU0<<a9(53 c$֥Zx1}s7J$BPvC!ixɠ', `T4`+ tsꃟjs]0LzSg<~= Czd;MTjCGd(y%ckxQ0,Ӱ<°ĄSd룢^?S@G-˛@W      |888ПdnTs4 ۶ sbqt* #R9gg|ǏMegϚ7 v˓M%>^n]^vc]8:jNJ}T*M.0<@E ^v:ޫWͦ$>xBTN}T*oy^Vk}ve0% 9?ߛJ N}T}/sdӧÅ~?;nI N^}|<`䂼8>k؃7U*y`Eezݻ/ܾ}XP^P.c޽?<j\!                               4)=`O`]Ȑ~unUgN\nZ=<qHP?;;8r竉||||||"σ 뺋 sss^/dP*666 ?pA>pA>pA>p`_2IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZip__coll__graph.map0000644000175000017500000000025712070466513025377 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_6.map0000644000175000017500000000025112070466513023512 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classJlCompress-members.html0000644000175000017500000000752612070466513025404 0ustar csmallcsmall QuaZIP: Member List
JlCompress Member List
This is the complete list of members for JlCompress, including all inherited members.
compressDir(QString fileCompressed, QString dir=QString(), bool recursive=true)JlCompress [static]
compressFile(QString fileCompressed, QString file)JlCompress [static]
compressFiles(QString fileCompressed, QStringList files)JlCompress [static]
extractDir(QString fileCompressed, QString dir=QString())JlCompress [static]
extractFile(QString fileCompressed, QString fileName, QString fileDest=QString())JlCompress [static]
extractFiles(QString fileCompressed, QStringList files, QString dir=QString())JlCompress [static]
getFileList(QString fileCompressed)JlCompress [static]
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZip-members.html0000644000175000017500000002722612070466513024533 0ustar csmallcsmall QuaZIP: Member List
QuaZip Member List
This is the complete list of members for QuaZip, including all inherited members.
CaseSensitivity enum nameQuaZip
close()QuaZip
Constants enum nameQuaZip
csDefault enum valueQuaZip
csInsensitive enum valueQuaZip
csSensitive enum valueQuaZip
getComment() const QuaZip
getCommentCodec() const QuaZip
getCurrentFileInfo(QuaZipFileInfo *info) const QuaZip
getCurrentFileName() const QuaZip
getEntriesCount() const QuaZip
getFileInfoList() const QuaZip
getFileNameCodec() const QuaZip
getFileNameList() const QuaZip
getIoDevice() const QuaZip
getMode() const QuaZip
getUnzFile()QuaZip
getZipError() const QuaZip
getZipFile()QuaZip
getZipName() const QuaZip
goToFirstFile()QuaZip
goToNextFile()QuaZip
hasCurrentFile() const QuaZip
isDataDescriptorWritingEnabled() const QuaZip
isOpen() const QuaZip
MAX_FILE_NAME_LENGTH enum valueQuaZip
mdAdd enum valueQuaZip
mdAppend enum valueQuaZip
mdCreate enum valueQuaZip
mdNotOpen enum valueQuaZip
mdUnzip enum valueQuaZip
Mode enum nameQuaZip
open(Mode mode, zlib_filefunc_def *ioApi=NULL)QuaZip
QuaZip()QuaZip
QuaZip(const QString &zipName)QuaZip
QuaZip(QIODevice *ioDevice)QuaZip
QuaZipPrivate (defined in QuaZip)QuaZip [friend]
setComment(const QString &comment)QuaZip
setCommentCodec(QTextCodec *commentCodec)QuaZip
setCommentCodec(const char *commentCodecName)QuaZip
setCurrentFile(const QString &fileName, CaseSensitivity cs=csDefault)QuaZip
setDataDescriptorWritingEnabled(bool enabled)QuaZip
setFileNameCodec(QTextCodec *fileNameCodec)QuaZip
setFileNameCodec(const char *fileNameCodecName)QuaZip
setIoDevice(QIODevice *ioDevice)QuaZip
setZipName(const QString &zipName)QuaZip
~QuaZip()QuaZip
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaZip__coll__graph.png0000644000175000017500000000404612070466513025406 0ustar csmallcsmallPNG  IHDRp\zbKGDIDATxOGgNR hFT9MMZIm|ah}cLL}cА4雚AۤXSZR*XAA9a/,{{w{{?vf/yaƽ~ofgoppP`0C={*ٳ 0(1nhh(++f%ӃP>PPGGGKK `@kpT4Ca  dp8,s bm4,I- 0 q(ʡJgUe K#lrhV(۠t!d}jbytDe fdSFST]~e匥]^9wwwg5yT S"h-T5ORz9jzgmr=4,e^;(hm3<4t* % 3f(0P` '}}}KKKahh2D]]-{8 #PSYXr9oS:xs!tR %6rht1qJ!pbr@zh"*8=,*Us C=t".>~>"&)-пFϊ%+ C߻:\?ƶAifxsc(y5m†.OǮ]|6] G{&PD6޾xaD4>"-tn<2rcVMWgc1+d 1CKj"׵c<>!,kbB[J }'.8H2 *ĉޅf_΁+dUˉoH oϗT{^u_REcq:l=(afhu'l ;s7 :]^* f(0P`P CIɟNKe1X*՗+CwJхkקR֤sM&Õ`F4Q IChz0B7!i(⑤Frf*ps5!$\P!*kZ4 HZ#/R9A_dIDT%!|ک]e^a! 3f(00fAt1!jY [57E%n΁_W/lXxt]Bp xnZ[pZ/5#T5~@x>r9P*Z&pf$Ra;<'}ϡziPV1 ֶoIETZa5p3۫~ox Ki̞?@(jCkU-s0QnQTqs@"t:/ǕGڷʯ|TN.An?GU|{̻o Ъ ?MGxWx9pU{ e0 (q6VAmz8PB8|Y9 2챥DCi9!+'Vi ~B!I#3g455g/z{{\P|a*VG];P`0C1LIC ҆44OѬFCU}ӼtVbϺ˧* c:ΡJgUe# n=ϚM_dOz҄MsVzR /av/ 3J (f(0P`~v fxg7Cfjjj``@|ggؘl?zH^ˡ0Ca 3\&IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/doxygen.css0000644000175000017500000003007612070466513022142 0ustar csmallcsmall/* The standard CSS for doxygen */ body, table, div, p, dl { font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; font-size: 12px; } /* @group Heading Levels */ h1 { font-size: 150%; } .title { font-size: 150%; font-weight: bold; margin: 10px 2px; } h2 { font-size: 120%; } h3 { font-size: 100%; } dt { font-weight: bold; } div.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; } p.startli, p.startdd, p.starttd { margin-top: 2px; } p.endli { margin-bottom: 0px; } p.enddd { margin-bottom: 4px; } p.endtd { margin-bottom: 2px; } /* @end */ caption { font-weight: bold; } span.legend { font-size: 70%; text-align: center; } h3.version { font-size: 90%; text-align: center; } div.qindex, div.navtab{ background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; margin: 2px; padding: 2px; } div.qindex, div.navpath { width: 100%; line-height: 140%; } div.navtab { margin-right: 15px; } /* @group Link Styling */ a { color: #3D578C; font-weight: normal; text-decoration: none; } .contents a:visited { color: #4665A2; } a:hover { text-decoration: underline; } a.qindex { font-weight: bold; } a.qindexHL { font-weight: bold; background-color: #9CAFD4; color: #ffffff; border: 1px double #869DCA; } .contents a.qindexHL:visited { color: #ffffff; } a.el { font-weight: bold; } a.elRef { } a.code { color: #4665A2; } a.codeRef { color: #4665A2; } /* @end */ dl.el { margin-left: -1cm; } .fragment { font-family: monospace, fixed; font-size: 105%; } pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; word-wrap: break-word; font-size: 9pt; line-height: 125%; } div.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; border: solid thin #333; border-radius: 0.5em; -webkit-border-radius: .5em; -moz-border-radius: .5em; box-shadow: 2px 2px 3px #999; -webkit-box-shadow: 2px 2px 3px #999; -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); } div.groupHeader { margin-left: 16px; margin-top: 12px; font-weight: bold; } div.groupText { margin-left: 16px; font-style: italic; } body { background: white; color: black; margin: 0; } div.contents { margin-top: 10px; margin-left: 10px; margin-right: 5px; } td.indexkey { background-color: #EBEFF6; font-weight: bold; border: 1px solid #C4CFE5; margin: 2px 0px 2px 0; padding: 2px 10px; } td.indexvalue { background-color: #EBEFF6; border: 1px solid #C4CFE5; padding: 2px 10px; margin: 2px 0px; } tr.memlist { background-color: #EEF1F7; } p.formulaDsp { text-align: center; } img.formulaDsp { } img.formulaInl { vertical-align: middle; } div.center { text-align: center; margin-top: 0px; margin-bottom: 0px; padding: 0px; } div.center img { border: 0px; } address.footer { text-align: right; padding-right: 12px; } img.footer { border: 0px; vertical-align: middle; } /* @group Code Colorization */ span.keyword { color: #008000 } span.keywordtype { color: #604020 } span.keywordflow { color: #e08000 } span.comment { color: #800000 } span.preprocessor { color: #806020 } span.stringliteral { color: #002080 } span.charliteral { color: #008080 } span.vhdldigit { color: #ff00ff } span.vhdlchar { color: #000000 } span.vhdlkeyword { color: #700070 } span.vhdllogic { color: #ff0000 } /* @end */ /* .search { color: #003399; font-weight: bold; } form.search { margin-bottom: 0px; margin-top: 0px; } input.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } */ td.tiny { font-size: 75%; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #A3B4D7; } th.dirtab { background: #EBEFF6; font-weight: bold; } hr { height: 0px; border: none; border-top: 1px solid #4A6AAA; } hr.footer { height: 1px; } /* @group Member Descriptions */ table.memberdecls { border-spacing: 0px; padding: 0px; } .mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { background-color: #F9FAFC; border: none; margin: 4px; padding: 1px 0 0 8px; } .mdescLeft, .mdescRight { padding: 0px 8px 4px 8px; color: #555; } .memItemLeft, .memItemRight, .memTemplParams { border-top: 1px solid #C4CFE5; } .memItemLeft, .memTemplItemLeft { white-space: nowrap; } .memItemRight { width: 100%; } .memTemplParams { color: #4665A2; white-space: nowrap; } /* @end */ /* @group Member Details */ /* Styles for detailed member documentation */ .memtemplate { font-size: 80%; color: #4665A2; font-weight: normal; margin-left: 9px; } .memnav { background-color: #EBEFF6; border: 1px solid #A3B4D7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .mempage { width: 100%; } .memitem { padding: 0; margin-bottom: 10px; margin-right: 5px; } .memname { white-space: nowrap; font-weight: bold; margin-left: 6px; } .memproto { border-top: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 6px 0px 6px 0px; color: #253555; font-weight: bold; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); /* opera specific markup */ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); border-top-right-radius: 8px; border-top-left-radius: 8px; /* firefox specific markup */ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; -moz-border-radius-topright: 8px; -moz-border-radius-topleft: 8px; /* webkit specific markup */ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -webkit-border-top-right-radius: 8px; -webkit-border-top-left-radius: 8px; background-image:url('nav_f.png'); background-repeat:repeat-x; background-color: #E2E8F2; } .memdoc { border-bottom: 1px solid #A8B8D9; border-left: 1px solid #A8B8D9; border-right: 1px solid #A8B8D9; padding: 2px 5px; background-color: #FBFCFD; border-top-width: 0; /* opera specific markup */ border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); /* firefox specific markup */ -moz-border-radius-bottomleft: 8px; -moz-border-radius-bottomright: 8px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7); /* webkit specific markup */ -webkit-border-bottom-left-radius: 8px; -webkit-border-bottom-right-radius: 8px; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7)); } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; white-space: nowrap; } .paramname em { font-style: normal; } .params, .retval, .exception, .tparams { border-spacing: 6px 2px; } .params .paramname, .retval .paramname { font-weight: bold; vertical-align: top; } .params .paramtype { font-style: italic; vertical-align: top; } .params .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } /* @end */ /* @group Directory (tree) */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin: 0px; } /* these are for tree view when used as main index */ .directory { font-size: 9pt; font-weight: bold; margin: 5px; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } /* The following two styles can be used to replace the root node title with an image of your choice. Simply uncomment the next two styles, specify the name of your image and be sure to set 'height' to the proper pixel height of your image. */ /* .directory h3.swap { height: 61px; background-repeat: no-repeat; background-image: url("yourimage.gif"); } .directory h3.swap span { display: none; } */ .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } /* these are for tree view when not used as main index */ .directory-alt { font-size: 100%; font-weight: bold; } .directory-alt h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory-alt > h3 { margin-top: 0; } .directory-alt p { margin: 0px; white-space: nowrap; } .directory-alt div { display: none; margin: 0px; } .directory-alt img { vertical-align: -30%; } /* @end */ div.dynheader { margin-top: 8px; } address { font-style: normal; color: #2A3D61; } table.doxtable { border-collapse:collapse; } table.doxtable td, table.doxtable th { border: 1px solid #2D4068; padding: 3px 7px 2px; } table.doxtable th { background-color: #374F7F; color: #FFFFFF; font-size: 110%; padding-bottom: 4px; padding-top: 5px; text-align:left; } .tabsearch { top: 0px; left: 10px; height: 36px; background-image: url('tab_b.png'); z-index: 101; overflow: hidden; font-size: 13px; } .navpath ul { font-size: 11px; background-image:url('tab_b.png'); background-repeat:repeat-x; height:30px; line-height:30px; color:#8AA0CC; border:solid 1px #C2CDE4; overflow:hidden; margin:0px; padding:0px; } .navpath li { list-style-type:none; float:left; padding-left:10px; padding-right:15px; background-image:url('bc_s.png'); background-repeat:no-repeat; background-position:right; color:#364D7C; } .navpath li.navelem a { height:32px; display:block; text-decoration: none; outline: none; } .navpath li.navelem a:hover { color:#6884BD; } .navpath li.footer { list-style-type:none; float:right; padding-left:10px; padding-right:15px; background-image:none; background-repeat:no-repeat; background-position:right; color:#364D7C; font-size: 8pt; } div.summary { float: right; font-size: 8pt; padding-right: 5px; width: 50%; text-align: right; } div.summary a { white-space: nowrap; } div.ingroups { font-size: 8pt; padding-left: 5px; width: 50%; text-align: left; } div.ingroups a { white-space: nowrap; } div.header { background-image:url('nav_h.png'); background-repeat:repeat-x; background-color: #F9FAFC; margin: 0px; border-bottom: 1px solid #C4CFE5; } div.headertitle { padding: 5px 5px 5px 10px; } dl { padding: 0 0 0 10px; } dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug { border-left:4px solid; padding: 0 0 0 6px; } dl.note { border-color: #D0C000; } dl.warning, dl.attention { border-color: #FF0000; } dl.pre, dl.post, dl.invariant { border-color: #00D000; } dl.deprecated { border-color: #505050; } dl.todo { border-color: #00C0E0; } dl.test { border-color: #3030E0; } dl.bug { border-color: #C08050; } #projectlogo { text-align: center; vertical-align: bottom; border-collapse: separate; } #projectlogo img { border: 0px none; } #projectname { font: 300% Tahoma, Arial,sans-serif; margin: 0px; padding: 2px 0px; } #projectbrief { font: 120% Tahoma, Arial,sans-serif; margin: 0px; padding: 0px; } #projectnumber { font: 50% Tahoma, Arial,sans-serif; margin: 0px; padding: 0px; } #titlearea { padding: 0px; margin: 0px; width: 100%; border-bottom: 1px solid #5373B4; } .image { text-align: center; } .dotgraph { text-align: center; } .mscgraph { text-align: center; } .caption { font-weight: bold; } mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_5.map0000644000175000017500000000025112070466513023511 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/classQuaCrc32.html0000644000175000017500000002074212070466513023211 0ustar csmallcsmall QuaZIP: QuaCrc32 Class Reference
QuaCrc32 Class Reference

CRC32 checksum. More...

#include <quazip/quacrc32.h>

Inheritance diagram for QuaCrc32:
Collaboration diagram for QuaCrc32:

List of all members.

Public Member Functions

quint32 calculate (const QByteArray &data)
 Calculates the checksum for data.
void reset ()
 Resets the calculation on a checksun for a stream.
void update (const QByteArray &buf)
 Updates the calculated checksum for the stream.
quint32 value ()
 Value of the checksum calculated for the stream passed throw update().

Detailed Description

CRC32 checksum.

This class wrappers the crc32 function with the QuaChecksum32 interface. See QuaChecksum32 for more info.


Member Function Documentation

quint32 QuaCrc32::calculate ( const QByteArray &  data) [virtual]

Calculates the checksum for data.

data source data

Returns:
data checksum

This function has no efect on the value returned by value().

Implements QuaChecksum32.

void QuaCrc32::update ( const QByteArray &  buf) [virtual]

Updates the calculated checksum for the stream.

buf next portion of data from the stream

Implements QuaChecksum32.

quint32 QuaCrc32::value ( ) [virtual]

Value of the checksum calculated for the stream passed throw update().

Returns:
checksum

Implements QuaChecksum32.


The documentation for this class was generated from the following files:
mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/tab_h.png0000644000175000017500000000030012070466513021521 0ustar csmallcsmallPNG  IHDR$[IDATx `FhY 26@cHw!ϗK1^HtOyGD׎ k9?i7zvPaJ})غwV`ai֍ZPC"P=IENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/dir_13eff9bb9851318b001ebebd72594ac4_dep.png0000644000175000017500000000065112070466513026577 0ustar csmallcsmallPNG  IHDRS;w!`bKGD^IDATh1n0E/8F=Vm(R(Ҟ$$@B`AU#͓f@;$ogp4Ϊ&EQTU5K9kIE's7g}+~AwAs)?9wF2q}] e{^f_⧾\#6}5n?~t\Ÿˬyۺ)Ma,`ִ\s!o.ޖ|94ǃxAsV+MdYe߮4l%'JIENDB`mudlet-2.1/src/quazip/quazip-0.4.4/doc/html/inherit_graph_3.map0000644000175000017500000000022712070466513023512 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/CMakeLists.txt0000644000175000017500000000073212070466513020776 0ustar csmallcsmallproject (QuaZip) cmake_minimum_required(VERSION 2.6) set(qt_min_version "4.5.0") find_package(Qt4 REQUIRED) set(QT_USE_QTGUI false) include(${QT_USE_FILE}) set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)") set(LIB_DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE STRING "Library directory name" FORCE) include_directories(${CMAKE_SOURCE_DIR}) add_subdirectory(quazip) install(FILES FindQuaZip.cmake DESTINATION ${CMAKE_ROOT}/Modules) mudlet-2.1/src/quazip/quazip-0.4.4/COPYING0000644000175000017500000005750612070466513017304 0ustar csmallcsmall GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [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 mudlet-2.1/src/quazip/quazip-0.4.4/test/0000755000175000017500000000000012070466513017213 5ustar csmallcsmallmudlet-2.1/src/quazip/quazip-0.4.4/test/testquazip.h0000644000175000017500000000034612070466513021600 0ustar csmallcsmall#ifndef QUAZIP_TEST_QUAZIP_H #define QUAZIP_TEST_QUAZIP_H #include class TestQuaZip: public QObject { Q_OBJECT private slots: void getFileList_data(); void getFileList(); }; #endif // QUAZIP_TEST_QUAZIP_H mudlet-2.1/src/quazip/quazip-0.4.4/test/qztest.h0000644000175000017500000000076312070466513020724 0ustar csmallcsmall#ifndef QUAZIP_TEST_QZTEST_H #define QUAZIP_TEST_QZTEST_H #include #include extern bool createTestFiles(const QStringList &fileNames, const QString &dir = "tmp"); extern void removeTestFiles(const QStringList &fileNames, const QString &dir = "tmp"); extern bool createTestArchive(const QString &zipName, const QStringList &fileNames, const QString &dir = "tmp"); #endif // QUAZIP_TEST_QZTEST_H mudlet-2.1/src/quazip/quazip-0.4.4/test/testquazipfile.h0000644000175000017500000000064312070466513022440 0ustar csmallcsmall#ifndef QUAZIP_TEST_QUAZIPFILE_H #define QUAZIP_TEST_QUAZIPFILE_H #include #include class TestQuaZipFile: public QObject { Q_OBJECT private slots: void zipUnzip_data(); void zipUnzip(); void bytesAvailable_data(); void bytesAvailable(); void atEnd_data(); void atEnd(); void pos_data(); void pos(); void getZip(); }; #endif // QUAZIP_TEST_QUAZIPFILE_H mudlet-2.1/src/quazip/quazip-0.4.4/test/qztest.cpp0000644000175000017500000001025412070466513021253 0ustar csmallcsmall#include "qztest.h" #include "testquazip.h" #include "testquazipfile.h" #include "testquachecksum32.h" #include "testjlcompress.h" #include #include #include #include #include #include #include bool createTestFiles(const QStringList &fileNames, const QString &dir) { QDir curDir; foreach (QString fileName, fileNames) { QString filePath = QDir(dir).filePath(fileName); QDir testDir = QFileInfo(filePath).dir(); if (!testDir.exists()) { if (!curDir.mkpath(testDir.path())) { qWarning("Couldn't mkpath %s", testDir.path().toUtf8().constData()); return false; } } if (fileName.endsWith('/')) { if (!curDir.mkpath(filePath)) { qWarning("Couldn't mkpath %s", fileName.toUtf8().constData()); return false; } } else { QFile testFile(filePath); if (!testFile.open(QIODevice::WriteOnly | QIODevice::Text)) { qWarning("Couldn't create %s", fileName.toUtf8().constData()); return false; } QTextStream testStream(&testFile); testStream << "This is a test file named " << fileName << endl; } } return true; } bool createTestArchive(const QString &zipName, const QStringList &fileNames, const QString &dir) { QuaZip zip(zipName); if (!zip.open(QuaZip::mdCreate)) { qWarning("Couldn't open %s", zipName.toUtf8().constData()); return false; } foreach (QString fileName, fileNames) { QuaZipFile zipFile(&zip); QString filePath = QDir(dir).filePath(fileName); QFileInfo fileInfo(filePath); if (!zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName, filePath), NULL, 0, fileInfo.isDir() ? 0 : 8)) { qWarning("Couldn't open %s in %s", fileName.toUtf8() .constData(), zipName.toUtf8().constData()); return false; } if (!fileInfo.isDir()) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { qWarning("Couldn't open %s", filePath.toUtf8() .constData()); return false; } while (!file.atEnd()) { char buf[4096]; qint64 l = file.read(buf, 4096); if (l <= 0) { qWarning("Couldn't read %s", filePath.toUtf8() .constData()); return false; } if (zipFile.write(buf, l) != l) { qWarning("Couldn't write to %s in %s", filePath.toUtf8().constData(), zipName.toUtf8().constData()); return false; } } file.close(); } zipFile.close(); } zip.close(); return true; } void removeTestFiles(const QStringList &fileNames, const QString &dir) { QDir curDir; foreach (QString fileName, fileNames) { curDir.remove(QDir(dir).filePath(fileName)); } foreach (QString fileName, fileNames) { QDir fileDir = QFileInfo(QDir(dir).filePath(fileName)).dir(); if (fileDir.exists()) { // Non-empty dirs won't get removed, and that's good. curDir.rmpath(fileDir.path()); } } } int main(int argc, char **argv) { QCoreApplication app(argc, argv); int err = 0; TestQuaZip testQuaZip; err = qMax(err, QTest::qExec(&testQuaZip, app.arguments())); TestQuaZipFile testQuaZipFile; err = qMax(err, QTest::qExec(&testQuaZipFile, app.arguments())); TestQuaChecksum32 testQuaChecksum32; err = qMax(err, QTest::qExec(&testQuaChecksum32, app.arguments())); TestJlCompress testJlCompress; err = qMax(err, QTest::qExec(&testJlCompress, app.arguments())); if (err != 0) { qWarning("There were errors in some of the tests above."); } return err; } mudlet-2.1/src/quazip/quazip-0.4.4/test/testquachecksum32.cpp0000644000175000017500000000047712070466513023305 0ustar csmallcsmall#include "testquachecksum32.h" #include #include #include void TestQuaChecksum32::calculate() { QuaCrc32 crc32; QCOMPARE(crc32.calculate("Wikipedia"), 0xADAAC02Eu); QuaAdler32 adler32; QCOMPARE(adler32.calculate("Wikipedia"), 0x11E60398u); } mudlet-2.1/src/quazip/quazip-0.4.4/test/testquazip.cpp0000644000175000017500000000351012070466513022127 0ustar csmallcsmall#include "testquazip.h" #include "qztest.h" #include #include #include #include #include #include void TestQuaZip::getFileList_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::newRow("simple") << "qzfilelist.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt"); } void TestQuaZip::getFileList() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); qSort(fileNames); QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(fileNames)) { QFAIL("Can't create test file"); } if (!createTestArchive(zipName, fileNames)) { QFAIL("Can't create test archive"); } QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdUnzip)); QVERIFY(testZip.goToFirstFile()); QString firstFile = testZip.getCurrentFileName(); QStringList fileList = testZip.getFileNameList(); qSort(fileList); QCOMPARE(fileList, fileNames); QHash srcInfo; foreach (QString fileName, fileNames) { srcInfo[fileName] = QFileInfo("tmp/" + fileName); } QList destList = testZip.getFileInfoList(); QCOMPARE(destList.size(), srcInfo.size()); for (int i = 0; i < destList.size(); i++) { QCOMPARE(static_cast(destList[i].uncompressedSize), srcInfo[destList[i].name].size()); } // test that we didn't mess up the current file QCOMPARE(testZip.getCurrentFileName(), firstFile); testZip.close(); // clean up removeTestFiles(fileNames); curDir.remove(zipName); } mudlet-2.1/src/quazip/quazip-0.4.4/test/qztest.pro0000644000175000017500000000062412070466513021271 0ustar csmallcsmallTEMPLATE = app QT -= gui CONFIG += qtestlib TARGET = DEPENDPATH += . INCLUDEPATH += . .. LIBS += -lquazip # Input HEADERS += testquazip.h \ testquazipfile.h \ testquachecksum32.h \ testjlcompress.h \ qztest.h SOURCES += testquazip.cpp \ testquazipfile.cpp \ testquachecksum32.cpp \ testjlcompress.cpp \ qztest.cpp mudlet-2.1/src/quazip/quazip-0.4.4/test/qztest.vcproj0000644000175000017500000001141012070466513021767 0ustar csmallcsmall mudlet-2.1/src/quazip/quazip-0.4.4/test/qztest.sln0000644000175000017500000000244312070466513021266 0ustar csmallcsmall Microsoft Visual Studio Solution File, Format Version 10.00 # Visual C++ Express 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qztest", "qztest.vcproj", "{7632B767-D089-4F15-8B1E-C4B3F9EBF592}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "quazip", "..\quazip\quazip.vcproj", "{E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {7632B767-D089-4F15-8B1E-C4B3F9EBF592}.Debug|Win32.ActiveCfg = Debug|Win32 {7632B767-D089-4F15-8B1E-C4B3F9EBF592}.Debug|Win32.Build.0 = Debug|Win32 {7632B767-D089-4F15-8B1E-C4B3F9EBF592}.Release|Win32.ActiveCfg = Release|Win32 {7632B767-D089-4F15-8B1E-C4B3F9EBF592}.Release|Win32.Build.0 = Release|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Debug|Win32.ActiveCfg = Debug|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Debug|Win32.Build.0 = Debug|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Release|Win32.ActiveCfg = Release|Win32 {E4AC5F56-B711-4F0E-BC83-CDE8B6CD53AD}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal mudlet-2.1/src/quazip/quazip-0.4.4/test/testquachecksum32.h0000644000175000017500000000034312070466513022742 0ustar csmallcsmall#ifndef QUAZIP_TEST_QUACHECKSUM32_H #define QUAZIP_TEST_QUACHECKSUM32_H #include class TestQuaChecksum32: public QObject { Q_OBJECT private slots: void calculate(); }; #endif // QUAZIP_TEST_QUACHECKSUM32_H mudlet-2.1/src/quazip/quazip-0.4.4/test/testjlcompress.h0000644000175000017500000000100512070466513022441 0ustar csmallcsmall#ifndef QUAZIP_TEST_JLCOMPRESS_H #define QUAZIP_TEST_JLCOMPRESS_H #include class TestJlCompress: public QObject { Q_OBJECT private slots: void compressFile_data(); void compressFile(); void compressFiles_data(); void compressFiles(); void compressDir_data(); void compressDir(); void extractFile_data(); void extractFile(); void extractFiles_data(); void extractFiles(); void extractDir_data(); void extractDir(); }; #endif // QUAZIP_TEST_JLCOMPRESS_H mudlet-2.1/src/quazip/quazip-0.4.4/test/testquazipfile.cpp0000644000175000017500000001556012070466513022777 0ustar csmallcsmall#include "testquazipfile.h" #include "qztest.h" #include #include #include #include #include #include #include void TestQuaZipFile::zipUnzip_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("fileNameCodec"); QTest::newRow("simple") << "simple.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") << QByteArray(); QTest::newRow("Cyrillic") << "cyrillic.zip" << ( QStringList() << QString::fromUtf8("русское имя файла с пробелами.txt")) << QByteArray("IBM866"); } void TestQuaZipFile::zipUnzip() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(QByteArray, fileNameCodec); QFile testFile(zipName); if (testFile.exists()) { if (!testFile.remove()) { QFAIL("Couldn't remove existing archive to create a new one"); } } if (!createTestFiles(fileNames)) { QFAIL("Couldn't create test files for zipping"); } QuaZip testZip(&testFile); if (!fileNameCodec.isEmpty()) testZip.setFileNameCodec(fileNameCodec); QVERIFY(testZip.open(QuaZip::mdCreate)); QString comment = "Test comment"; testZip.setComment(comment); foreach (QString fileName, fileNames) { QFile inFile("tmp/" + fileName); if (!inFile.open(QIODevice::ReadOnly)) { qDebug("File name: %s", fileName.toUtf8().constData()); QFAIL("Couldn't open input file"); } QuaZipFile outFile(&testZip); QVERIFY(outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileName, inFile.fileName()))); for (qint64 pos = 0, len = inFile.size(); pos < len; ) { char buf[4096]; qint64 readSize = qMin(static_cast(4096), len - pos); qint64 l; if ((l = inFile.read(buf, readSize)) != readSize) { qDebug("Reading %ld bytes from %s at %ld returned %ld", static_cast(readSize), fileName.toUtf8().constData(), static_cast(pos), static_cast(l)); QFAIL("Read failure"); } QVERIFY(outFile.write(buf, readSize)); pos += readSize; } inFile.close(); outFile.close(); QCOMPARE(outFile.getZipError(), ZIP_OK); } testZip.close(); QCOMPARE(testZip.getZipError(), ZIP_OK); // now test unzip QuaZip testUnzip(&testFile); if (!fileNameCodec.isEmpty()) testUnzip.setFileNameCodec(fileNameCodec); QVERIFY(testUnzip.open(QuaZip::mdUnzip)); QCOMPARE(testUnzip.getComment(), comment); QVERIFY(testUnzip.goToFirstFile()); foreach (QString fileName, fileNames) { QCOMPARE(testUnzip.getCurrentFileName(), fileName); testUnzip.goToNextFile(); } testUnzip.close(); QCOMPARE(testUnzip.getZipError(), UNZ_OK); // clean up removeTestFiles(fileNames); testFile.remove(); } void TestQuaZipFile::bytesAvailable_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::newRow("simple") << "test.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt"); } void TestQuaZipFile::bytesAvailable() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QDir curDir; if (!createTestFiles(fileNames)) { QFAIL("Couldn't create test files"); } if (!JlCompress::compressDir(zipName, "tmp")) { QFAIL("Couldn't create test archive"); } QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdUnzip)); foreach (QString fileName, fileNames) { QFileInfo fileInfo("tmp/" + fileName); QVERIFY(testZip.setCurrentFile(fileName)); QuaZipFile zipFile(&testZip); QVERIFY(zipFile.open(QIODevice::ReadOnly)); QCOMPARE(zipFile.bytesAvailable(), fileInfo.size()); QCOMPARE(zipFile.read(1).size(), 1); QCOMPARE(zipFile.bytesAvailable(), fileInfo.size() - 1); QCOMPARE(zipFile.read(fileInfo.size() - 1).size(), static_cast(fileInfo.size() - 1)); QCOMPARE(zipFile.bytesAvailable(), (qint64) 0); } removeTestFiles(fileNames); testZip.close(); curDir.remove(zipName); } void TestQuaZipFile::atEnd_data() { bytesAvailable_data(); } void TestQuaZipFile::atEnd() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QDir curDir; if (!createTestFiles(fileNames)) { QFAIL("Couldn't create test files"); } if (!JlCompress::compressDir(zipName, "tmp")) { QFAIL("Couldn't create test archive"); } QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdUnzip)); foreach (QString fileName, fileNames) { QFileInfo fileInfo("tmp/" + fileName); QVERIFY(testZip.setCurrentFile(fileName)); QuaZipFile zipFile(&testZip); QVERIFY(zipFile.open(QIODevice::ReadOnly)); QCOMPARE(zipFile.atEnd(), false); QCOMPARE(zipFile.read(1).size(), 1); QCOMPARE(zipFile.atEnd(), false); QCOMPARE(zipFile.read(fileInfo.size() - 1).size(), static_cast(fileInfo.size() - 1)); QCOMPARE(zipFile.atEnd(), true); } removeTestFiles(fileNames); testZip.close(); curDir.remove(zipName); } void TestQuaZipFile::pos_data() { bytesAvailable_data(); } void TestQuaZipFile::pos() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QDir curDir; if (!createTestFiles(fileNames)) { QFAIL("Couldn't create test files"); } if (!JlCompress::compressDir(zipName, "tmp")) { QFAIL("Couldn't create test archive"); } QuaZip testZip(zipName); QVERIFY(testZip.open(QuaZip::mdUnzip)); foreach (QString fileName, fileNames) { QFileInfo fileInfo("tmp/" + fileName); QVERIFY(testZip.setCurrentFile(fileName)); QuaZipFile zipFile(&testZip); QVERIFY(zipFile.open(QIODevice::ReadOnly)); QCOMPARE(zipFile.pos(), (qint64) 0); QCOMPARE(zipFile.read(1).size(), 1); QCOMPARE(zipFile.pos(), (qint64) 1); QCOMPARE(zipFile.read(fileInfo.size() - 1).size(), static_cast(fileInfo.size() - 1)); QCOMPARE(zipFile.pos(), fileInfo.size()); } removeTestFiles(fileNames); testZip.close(); curDir.remove(zipName); } void TestQuaZipFile::getZip() { QuaZip testZip; QuaZipFile f1(&testZip); QCOMPARE(f1.getZip(), &testZip); QuaZipFile f2("doesntexist.zip", "someFile"); QCOMPARE(f2.getZip(), static_cast(NULL)); } mudlet-2.1/src/quazip/quazip-0.4.4/test/testjlcompress.cpp0000644000175000017500000001656112070466513023011 0ustar csmallcsmall#include "testjlcompress.h" #include "qztest.h" #include #include #include #include void TestJlCompress::compressFile_data() { QTest::addColumn("zipName"); QTest::addColumn("fileName"); QTest::newRow("simple") << "jlsimplefile.zip" << "test0.txt"; } void TestJlCompress::compressFile() { QFETCH(QString, zipName); QFETCH(QString, fileName); QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(QStringList() << fileName)) { QFAIL("Can't create test file"); } QVERIFY(JlCompress::compressFile(zipName, "tmp/" + fileName)); // get the file list and check it QStringList fileList = JlCompress::getFileList(zipName); QCOMPARE(fileList.count(), 1); QVERIFY(fileList[0] == fileName); removeTestFiles(QStringList() << fileName); curDir.remove(zipName); } void TestJlCompress::compressFiles_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::newRow("simple") << "jlsimplefiles.zip" << (QStringList() << "test0.txt" << "test00.txt"); QTest::newRow("different subdirs") << "jlsubdirfiles.zip" << (QStringList() << "subdir1/test1.txt" << "subdir2/test2.txt"); } void TestJlCompress::compressFiles() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(fileNames)) { QFAIL("Can't create test files"); } QStringList realNamesList, shortNamesList; foreach (QString fileName, fileNames) { QString realName = "tmp/" + fileName; realNamesList += realName; shortNamesList += QFileInfo(realName).fileName(); } QVERIFY(JlCompress::compressFiles(zipName, realNamesList)); // get the file list and check it QStringList fileList = JlCompress::getFileList(zipName); QCOMPARE(fileList, shortNamesList); removeTestFiles(fileNames); curDir.remove(zipName); } void TestJlCompress::compressDir_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::newRow("simple") << "jldir.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt"); } void TestJlCompress::compressDir() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QDir curDir; if (curDir.exists(zipName)) { if (!curDir.remove(zipName)) QFAIL("Can't remove zip file"); } if (!createTestFiles(fileNames, "compressDir_tmp")) { QFAIL("Can't create test files"); } QVERIFY(JlCompress::compressDir(zipName, "compressDir_tmp")); // get the file list and check it QStringList fileList = JlCompress::getFileList(zipName); qSort(fileList); qSort(fileNames); QCOMPARE(fileList, fileNames); removeTestFiles(fileNames, "compressDir_tmp"); curDir.remove(zipName); } void TestJlCompress::extractFile_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("fileToExtract"); QTest::addColumn("destName"); QTest::newRow("simple") << "jlextfile.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") << "testdir2/test2.txt" << "test2.txt"; } void TestJlCompress::extractFile() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(QString, fileToExtract); QFETCH(QString, destName); QDir curDir; if (!curDir.mkpath("jlext/jlfile")) { QFAIL("Couldn't mkpath jlext/jlfile"); } if (!createTestFiles(fileNames)) { QFAIL("Couldn't create test files"); } if (!JlCompress::compressDir(zipName, "tmp")) { QFAIL("Couldn't create test archive"); } QVERIFY(!JlCompress::extractFile(zipName, fileToExtract, "jlext/jlfile/" + destName).isEmpty()); QFileInfo destInfo("jlext/jlfile/" + destName), srcInfo("tmp/" + fileToExtract); QCOMPARE(destInfo.size(), srcInfo.size()); curDir.remove("jlext/jlfile/" + destName); curDir.rmpath("jlext/jlfile"); removeTestFiles(fileNames); curDir.remove(zipName); } void TestJlCompress::extractFiles_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::addColumn("filesToExtract"); QTest::newRow("simple") << "jlextfiles.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt") << (QStringList() << "testdir2/test2.txt" << "testdir1/test1.txt"); } void TestJlCompress::extractFiles() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QFETCH(QStringList, filesToExtract); QDir curDir; if (!curDir.mkpath("jlext/jlfiles")) { QFAIL("Couldn't mkpath jlext/jlfiles"); } if (!createTestFiles(fileNames)) { QFAIL("Couldn't create test files"); } if (!JlCompress::compressDir(zipName, "tmp")) { QFAIL("Couldn't create test archive"); } QVERIFY(!JlCompress::extractFiles(zipName, filesToExtract, "jlext/jlfiles").isEmpty()); foreach (QString fileName, filesToExtract) { QFileInfo fileInfo("jlext/jlfiles/" + fileName); QCOMPARE(fileInfo.size(), QFileInfo("tmp/" + fileName).size()); curDir.remove("jlext/jlfiles/" + fileName); curDir.rmpath(fileInfo.dir().path()); } curDir.rmpath("jlext/jlfiles"); removeTestFiles(fileNames); curDir.remove(zipName); } void TestJlCompress::extractDir_data() { QTest::addColumn("zipName"); QTest::addColumn("fileNames"); QTest::newRow("simple") << "jlextdir.zip" << ( QStringList() << "test0.txt" << "testdir1/test1.txt" << "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt"); QTest::newRow("separate dir") << "sepdir.zip" << ( QStringList() << "laj/" << "laj/lajfile.txt"); } void TestJlCompress::extractDir() { QFETCH(QString, zipName); QFETCH(QStringList, fileNames); QDir curDir; if (!curDir.mkpath("jlext/jldir")) { QFAIL("Couldn't mkpath jlext/jldir"); } if (!createTestFiles(fileNames)) { QFAIL("Couldn't create test files"); } if (!createTestArchive(zipName, fileNames)) { QFAIL("Couldn't create test archive"); } QStringList extracted; QCOMPARE((extracted = JlCompress::extractDir(zipName, "jlext/jldir")) .count(), fileNames.count()); foreach (QString fileName, fileNames) { QString fullName = "jlext/jldir/" + fileName; QFileInfo fileInfo(fullName); if (!fileInfo.isDir()) QCOMPARE(fileInfo.size(), QFileInfo("tmp/" + fileName).size()); curDir.remove(fullName); curDir.rmpath(fileInfo.dir().path()); QString absolutePath = fileInfo.absoluteFilePath(); if (fileInfo.isDir() && !absolutePath.endsWith('/')) absolutePath += '/'; QVERIFY(extracted.contains(absolutePath)); } curDir.rmpath("jlext/jldir"); removeTestFiles(fileNames); curDir.remove(zipName); } mudlet-2.1/src/quazip/quazip-0.4.4/quazip.pro0000644000175000017500000000012212070466513020262 0ustar csmallcsmallTEMPLATE=subdirs SUBDIRS=quazip test/unzip test/zip test/jlcompress test/checksum mudlet-2.1/src/quazip/quazip-0.4.4/includes.pri0000644000175000017500000000025212070466513020555 0ustar csmallcsmallOBJECTS_DIR = .obj MOC_DIR = .moc unix { isEmpty(PREFIX): PREFIX=/usr/local } win32 { isEmpty(PREFIX): warning("PREFIX unspecified, make install won't work") } mudlet-2.1/src/quazip/quazip-0.4.4/Doxyfile0000644000175000017500000021561412070466513017753 0ustar csmallcsmall# Doxyfile 1.7.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = QuaZIP # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = quazip-0-4-4 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = NO # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.cpp \ *.h \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = quazip/unzip.h \ quazip/zip.h \ quazip/ioapi.h \ quazip/crypt.h \ test/ # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.moc/* */release/* */debug/* */moc_*.cpp # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is adviced to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the # mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called Helvetica to the output # directory and reference it in all dot files that doxygen generates. # When you want a differently looking font you can specify the font name # using DOT_FONTNAME. You need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES mudlet-2.1/src/dlgComposer.h0000644000175000017500000000335211513237311015374 0ustar csmallcsmall#ifndef DLGCOMPOSER_H #define DLGCOMPOSER_H /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn - KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ class Host; #include "ui_composer.h" #include class dlgComposer : public QMainWindow , public Ui::composer { Q_OBJECT public: dlgComposer( Host * ); void init( QString title, QString txt ); Host * mpHost; public slots: void save(); void cancel(); }; #endif // DLGCOMPOSER_H mudlet-2.1/src/main.cpp0000644000175000017500000002520612076170616014410 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "mudlet.h" #include "TConsole.h" #include "FontManager.h" #include #include #include #include #include #include #define MUDLET_HOME "/usr/local/share/mudlet/" using namespace std; TConsole * spDebugConsole = 0; //#ifdef QT_DEBUG // QFile debugStreamFile("C:\\mudletDebugStream.txt");; // QTextStream debugStream(&debugStreamFile); //#endif void debugOutput(QtMsgType type, const char *msg) { //debugStream << msg << endl; ; // switch (type) // { // case QtDebugMsg: // cout << msg << endl; // /*if( mudlet::mpDebugConsole ) // { // ;//mudlet::mpDebugConsole->print( msg ); // } // else // { // fprintf(stderr, "Debug: %s\n", msg); // }*/ // break; // case QtWarningMsg: // fprintf(stderr, "Warning: %s\n", msg); // break; // case QtCriticalMsg: // fprintf(stderr, "Critical: %s\n", msg); // break; // case QtFatalMsg: // fprintf(stderr, "Fatal: %s\n", msg); // abort(); // break; // } } QStringList gSysErrors; extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; int main(int argc, char *argv[]) { // #ifdef QT_DEBUG // debugStreamFile.open(QFile::WriteOnly | QFile::Truncate); // #endif //FIXME qInstallMsgHandler( debugOutput ); spDebugConsole = 0; QGL::setPreferredPaintEngine(QPaintEngine::Raster);//faster map drawing on ubuntu Q_INIT_RESOURCE(mudlet_alpha); QApplication app(argc, argv); app.setApplicationName("Mudlet"); QPixmap pixmap(":/Mudlet_splashscreen_main.png"); QSplashScreen splash(pixmap); splash.show(); splash.showMessage("Loading profiles ..."); app.processEvents(); //qt_ntfs_permission_lookup++; // turn permission checking on on NTFS file systems QString directory = QDir::homePath()+"/.config/mudlet"; QDir dir; if( ! dir.exists( directory ) ) { dir.mkpath( directory ); } // QFile file_doc(":/mudlet_documentation.html"); // QFile file_doc_old; // file_doc_old.setFileName( directory+"/mudlet_documentation.html" ); // if( file_doc_old.exists() ) // { //NOTE: B. von Roeder found out that the removal of old versions may *sometimes* fail on windows 7 due permission issues // if( ! file_doc_old.setPermissions( QFile::WriteOwner | QFile::ReadOwner | QFile::ReadUser | QFile::WriteUser | QFile::ReadOther | QFile::WriteOther ) ) // { // cout << "[ERROR] could not set file permissions of the old version of the manual" << endl; // gSysErrors << "[ERROR] could not set file permissions of the old version of the manual"; // } // string old_man_path = directory.toLatin1().data(); // old_man_path += "/mudlet_documentation.html"; // bool ok=file_doc_old.remove(); // if( ok ) // { // cout << "[INFO] deleted old version of the manual: " << old_man_path << endl; // } // else // { // cout << "[ERROR] could not remove old version of the manual: " << old_man_path << endl; // QString _m = "[ERROR] could not remove old version of the manual: "; // _m.append( old_man_path.c_str() ); // gSysErrors << _m; // } // } // else // { // gSysErrors << "[INFO] no old version of the manual found"; // } // if( file_doc.copy( directory+"/mudlet_documentation.html" ) ) // { // cout << "[OK] successfully copied new version of the manual" << endl; // QString _m = "[INFO] local manual: "; // _m.append( directory ); // gSysErrors << _m; // } // else // { // cout << "[ERROR] copy of new version of the manual failed" << endl; // gSysErrors << "[ERROR] copy of new version of the manual failed"; // } // QFile file_lua(":/LuaGlobal.lua"); // QFile file_lua_old( directory+"/LuaGlobal.lua" ); // if( ! file_lua_old.setPermissions( QFile::WriteOwner | QFile::ReadOwner | QFile::ReadUser | QFile::WriteUser | QFile::ReadOther | QFile::WriteOther ) ) // { // cout << "[ERROR] failed to set file permissions for the old version of LuaGlobal.lua" << endl; // gSysErrors << "[ERROR] failed to set file permissions for the old version of LuaGlobal.lua"; // } // else // { // cout << "[OK] successfully set file permissions for the old version of LuaGlobal.lua" << endl; // } // if( file_lua_old.remove() ) // { // cout << "[OK] old LuaGlobal.lua removed successfully" << endl; // gSysErrors << "[INFO] old LuaGlobal.lua removed successfully"; // } // else // { // cout << "[ERROR] failed to remove the old version of LuaGlobal.lua" << endl; // gSysErrors << "[ERROR] failed to remove the old version of LuaGlobal.lua"; // } // if( file_lua.copy( directory+"/LuaGlobal.lua" ) ) // { // cout << "[OK] new version of LuaGlobal.lua copied successfully" << endl; // gSysErrors << "[INFO] LuaGlobal.lua restored successfully"; // QFile file_lua_new(directory+"/LuaGlobal.lua"); // if( ! file_lua_new.setPermissions( QFile::WriteOwner | QFile::ReadOwner | QFile::ReadUser | QFile::WriteUser | QFile::ReadOther | QFile::WriteOther ) ) // { // cout << "[ERROR] failed to set file permissions for the new version of LuaGlobal.lua" << endl; // gSysErrors << "[ERROR] failed to set file permissions for the new version of LuaGlobal.lua"; // } // else // { // cout << "[OK] successfully set file permissions for the new version of LuaGlobal.lua" << endl; // } // } // QFile file_db(":/db.lua"); // QFile file_db_old( directory+"/db.lua" ); // if( ! file_db_old.setPermissions( QFile::WriteOwner | QFile::ReadOwner | QFile::ReadUser | QFile::WriteUser | QFile::ReadOther | QFile::WriteOther ) ) // { // cout << "[ERROR] failed to set file permissions for the old version of db.lua" << endl; // gSysErrors << "[ERROR] failed to set file permissions for the old version of db.lua"; // } // else // { // cout << "[OK] successfully set file permissions for the old version of db.lua" << endl; // } // if( file_db_old.remove() ) // { // cout << "[OK] old db.lua removed successfully" << endl; // gSysErrors << "[INFO] old db.lua removed successfully"; // } // else // { // cout << "[ERROR] failed to remove the old version of db.lua" << endl; // gSysErrors << "[ERROR] failed to remove the old version of db.lua"; // } // if( file_db.copy( directory+"/db.lua" ) ) // { // cout << "[OK] new version of db.lua copied successfully" << endl; // gSysErrors << "[INFO] db.lua restored successfully"; // QFile file_db_new(directory+"/db.lua"); // if( ! file_db_new.setPermissions( QFile::WriteOwner | QFile::ReadOwner | QFile::ReadUser | QFile::WriteUser | QFile::ReadOther | QFile::WriteOther ) ) // { // cout << "[ERROR] failed to set file permissions for the new version of db.lua" << endl; // gSysErrors << "[ERROR] failed to set file permissions for the new version of db.lua"; // } // else // { // cout << "[OK] successfully set file permissions for the new version of db.lua" << endl; // } // } QFile file_f1(":/fonts/ttf-bitstream-vera-1.10/COPYRIGHT.TXT"); file_f1.copy( directory+"/COPYRIGHT.TXT" ); QFile file_f2(":/fonts/ttf-bitstream-vera-1.10/RELEASENOTES.TXT"); file_f2.copy( directory+"/RELEASENOTES.TXT" ); QFile file_f3(":/fonts/ttf-bitstream-vera-1.10/VeraMoIt.ttf"); file_f3.copy( directory+"/VeraMoIt.ttf" ); QFile file_f4(":/fonts/ttf-bitstream-vera-1.10/local.conf"); file_f4.copy( directory+"/local.conf" ); QFile file_f5(":/fonts/ttf-bitstream-vera-1.10/VeraMoBd.ttf"); file_f5.copy( directory+"/VeraMoBd.ttf" ); QFile file_f6(":/fonts/ttf-bitstream-vera-1.10/VeraMoBd.ttf"); file_f6.copy( directory+"/VeraMoBd.ttf" ); QFile file_f7(":/fonts/ttf-bitstream-vera-1.10/README.TXT"); file_f7.copy( directory+"/README.TXT" ); QFile file_f8(":/fonts/ttf-bitstream-vera-1.10/VeraMoBI.ttf"); file_f8.copy( directory+"/VeraMoBI.ttf" ); QFile file_f9(":/fonts/ttf-bitstream-vera-1.10/VeraMono.ttf"); file_f9.copy( directory+"/VeraMono.ttf" ); /*QFile file_f(":/fonts/ttf-bitstream-vera-1.10/"); file_f.copy( directory+"/" ); QFile file_f(":/fonts/ttf-bitstream-vera-1.10/"); file_f.copy( directory+"/" ); QFile file_f(":/fonts/ttf-bitstream-vera-1.10/"); file_f.copy( directory+"/" ); */ splash.showMessage("All data has been loaded successfully.\n\nHave fun!"); QTime t; t.start(); while( t.elapsed() < 1500 ); splash.finish( mudlet::self() ); mudlet::debugMode = false; HostManager::self(); FontManager fm; fm.addFonts(); QString home = QDir::homePath()+"/.config/mudlet"; QString homeLink = QDir::homePath()+"/mudlet-data"; QFile::link(home, homeLink); mudlet::self()->show(); app.exec(); } mudlet-2.1/src/TTextEdit.h0000644000175000017500000001425011624306130014772 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn KoehnHeiko@googlemail.com * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _T_TEXTEDIT_H #define _T_TEXTEDIT_H //#include #include #include #include #include //#include #include #include #include #include "mudlet.h" #include "TBuffer.h" class Host; class TConsole; class TTextEdit : public QWidget { Q_OBJECT public: TTextEdit( TConsole *, QWidget *, TBuffer * pB, Host * pH, bool isDebugConsole, bool isSplitScreen ); void paintEvent( QPaintEvent* ); void contextMenuEvent ( QContextMenuEvent * event ); void drawForeground(QPainter &, const QRect & ); void drawFrame(QPainter &, const QRect & ); void drawBackground( QPainter &, const QRect &, const QColor & ); void updateLastLine(); void drawCharacters( QPainter & painter, const QRect & rect, QString & text, bool isBold, bool isUnderline, bool isItalics, QColor & fgColor, QColor & bgColor ); std::string getCurrentTime(); void showNewLines(); void forceUpdate(); void needUpdate( int, int ); void scrollTo( int ); void scrollUp( int lines ); void scrollDown( int lines ); void wheelEvent( QWheelEvent * e ); void resizeEvent( QResizeEvent * event ); void mousePressEvent( QMouseEvent * ); void mouseReleaseEvent( QMouseEvent * ); void mouseMoveEvent( QMouseEvent * ); void showEvent ( QShowEvent * event ); void updateScreenView(); void highlight(); void unHighlight( QRegion & ); void swap( QPoint & p1, QPoint & p2 ); void focusInEvent( QFocusEvent * event ); int imageTopLine(); int bufferScrollUp( int lines ); int bufferScrollDown( int lines ); bool isTailMode(); void copySelectionToClipboard(); void setConsoleFgColor( int r, int g, int b ){mFgColor = QColor(r,g,b);} void setConsoleBgColor( int r, int g, int b ){mBgColor = QColor(r,g,b);} void setIsMiniConsole(){ mIsMiniConsole = true; } void copySelectionToClipboardHTML(); QColor mBgColor; int mCursorY; QFont mDisplayFont; QColor mFgColor; int mFontAscent; int mFontDescent; bool mIsCommandPopup; bool mIsTailMode; QMap mPopupCommands; int mScrollVector; QRegion mSelectedRegion; bool mShowTimeStamps; int mWrapAt; int mWrapIndentCount; qreal mLetterSpacing; signals: public slots: void slot_toggleTimeStamps(); void slot_copySelectionToClipboard(); void slot_scrollBarMoved( int ); void slot_popupMenu(); void slot_copySelectionToClipboardHTML(); private: void initDefaultSettings(); QFont mCommandLineFont; QFont mCommandSeperator; int mFontHeight; int mFontWidth; bool mForceUpdate; bool mHighlight_on; bool mHighlightingBegin; bool mHighlightingEnd; bool mInit_OK; bool mInversOn; bool mIsDebugConsole; bool mIsMiniConsole; bool mIsSplitScreen; int mLastRenderBottom; int mLeftMargin; bool mMouseTracking; int mOldScrollPos; QPoint mP_aussen; QPoint mPA; bool mPainterInit; QPoint mPB; TBuffer * mpBuffer; TConsole * mpConsole; Host * mpHost; QScrollBar * mpScrollBar; int mScreenHeight; QPixmap mScreenMap; int mScreenWidth; bool mScrollUp; int mTopMargin; bool mUpdateSlice; }; #endif mudlet-2.1/src/dlgHelpDialog.h0000644000175000017500000000314611513237311015616 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _dlg_help_dialog_h #define _dlg_help_dialog_h #include "ui_help_dialog.h" class dlgHelpDialog : public QMainWindow , public Ui::helpDialog { Q_OBJECT public: dlgHelpDialog(QWidget * parent = 0); }; #endif mudlet-2.1/src/TAlias.cpp0000644000175000017500000002726212070466512014642 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include "TAlias.h" #include "Host.h" #include "HostManager.h" #include "mudlet.h" #include "TDebug.h" using namespace std; TAlias::TAlias( TAlias * parent, Host * pHost ) : Tree( parent ) , mpHost( pHost ) , mModuleMember(false) , mModuleMasterFolder(false) , mNeedsToBeCompiled( true ) , exportItem(true) , mIsTempAlias( false ) { } TAlias::TAlias( QString name, Host * pHost ) : Tree(0) , mName( name ) , mpHost( pHost ) , mModuleMember(false) , mModuleMasterFolder(false) , mNeedsToBeCompiled( true ) , exportItem(true) , mIsTempAlias( false ) { } TAlias::~TAlias() { if( ! mpHost ) { return; } mpHost->getAliasUnit()->unregisterAlias(this); } void TAlias::setName( QString name ) { if( ! mIsTempAlias ) { mpHost->getAliasUnit()->mLookupTable.remove( mName, this ); } mName = name; mpHost->getAliasUnit()->mLookupTable.insertMulti( name, this ); } bool TAlias::match( QString & toMatch ) { if( ! isActive() ) { if( isFolder() ) { if( shouldBeActive() ) { bool matchCondition = false; typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TAlias * pChild = *it; if( pChild->match( toMatch ) ) matchCondition = true; } return matchCondition; } } return false; } bool matchCondition = false; //bool ret = false; //bool conditionMet = false; pcre * re = mpRegex; if( re == NULL ) return false; //regex compile error //const char *error; char * subject = (char *) malloc(strlen(toMatch.toLocal8Bit().data())+1); strcpy( subject, toMatch.toLocal8Bit().data() ); unsigned char *name_table; //int erroffset; //int find_all; int namecount; int name_entry_size; int subject_length = strlen( subject ); int rc, i; std::list captureList; std::list posList; int ovector[300]; // 100 capture groups max (can be increase nbGroups=1/3 ovector //cout <<" LINE="< 0 ) { rc = pcre_exec( re, 0, subject, subject_length, 0, 0, ovector, 100 ); } else goto MUD_ERROR; if( rc < 0 ) { switch(rc) { case PCRE_ERROR_NOMATCH: goto MUD_ERROR; default: goto MUD_ERROR; } } if( rc > 0 ) { if( mudlet::debugMode ) {TDebug(QColor(Qt::cyan),QColor(Qt::black))<<"Alias name="<>0;} } if( rc == 0 ) { qDebug()<<"CRITICAL ERROR: SHOULD NOT HAPPEN->pcre_info() got wrong num of cap groups ovector only has room for %d captured substrings\n"; } if( rc < 0 ) { goto MUD_ERROR; } matchCondition = true; // alias has matched for( i=0; i < rc; i++ ) { char * substring_start = subject + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; std::string match; if( substring_length < 1 ) { captureList.push_back( match ); posList.push_back( -1 ); continue; } match.append( substring_start, substring_length ); captureList.push_back( match ); posList.push_back( ovector[2*i] ); if( mudlet::debugMode ) {TDebug(QColor(Qt::darkCyan),QColor(Qt::black))<<"Alias: capture group #"<<(i+1)<<" = ">>0; TDebug(QColor(Qt::darkMagenta),QColor(Qt::black))<<"<"<\n">>0;} } (void)pcre_fullinfo( re, NULL, PCRE_INFO_NAMECOUNT, &namecount ); if( namecount <= 0 ) { //cout << "no named substrings detected" << endl; } else { unsigned char *tabptr; (void)pcre_fullinfo( re, NULL, PCRE_INFO_NAMETABLE, &name_table ); (void)pcre_fullinfo( re, NULL, PCRE_INFO_NAMEENTRYSIZE, &name_entry_size ); tabptr = name_table; for( i = 0; i < namecount; i++ ) { //int n = (tabptr[0] << 8) | tabptr[1]; tabptr += name_entry_size; } } //TODO: add named groups seperately later as Lua::namedGroups for(;;) { int options = 0; int start_offset = ovector[1]; if( ovector[0] == ovector[1] ) { if( ovector[0] >= subject_length ) { goto END; } options = PCRE_NOTEMPTY | PCRE_ANCHORED; } rc = pcre_exec( re, NULL, subject, subject_length, start_offset, options, ovector, 30 ); if( rc == PCRE_ERROR_NOMATCH ) { if( options == 0 ) break; ovector[1] = start_offset + 1; continue; } if( rc < 0 ) { goto END; } if( rc == 0 ) { qDebug()<<"CRITICAL ERROR: SHOULD NOT HAPPEN->pcre_info() got wrong num of cap groups ovector only has room for %d captured substrings\n"; } for( i = 0; i < rc; i++ ) { char * substring_start = subject + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; std::string match; if( substring_length < 1 ) { captureList.push_back( match ); posList.push_back( -1 ); continue; } match.append( substring_start, substring_length ); captureList.push_back( match ); posList.push_back( ovector[2*i] ); if( mudlet::debugMode ) {TDebug(QColor(Qt::darkCyan),QColor(Qt::black))<<"capture group #"<<(i+1)<<" = ">>0; TDebug(QColor(Qt::darkMagenta),QColor(Qt::black))<<"<"<\n">>0;} } } END: { TLuaInterpreter * pL = mpHost->getLuaInterpreter(); pL->setCaptureGroups( captureList, posList ); // call lua trigger function with number of matches and matches itselves as arguments execute(); pL->clearCaptureGroups(); } MUD_ERROR: typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TAlias * pChild = *it; if( pChild->match( toMatch ) ) matchCondition = true; } free( subject ); return matchCondition; } void TAlias::setRegexCode( QString code ) { mRegexCode = code; const char *error; char * pattern = (char *) malloc( strlen( code.toLocal8Bit().data() ) + 48 ); strcpy( pattern, code.toLocal8Bit().data() ); int erroffset; pcre * re; re = pcre_compile( pattern, 0, &error, &erroffset, NULL); if( re == NULL ) { mOK_init = false; } else { mOK_init = true; } mpRegex = re; } TAlias& TAlias::clone(const TAlias& b) { mName = b.mName; mCommand = b.mCommand; mRegexCode = b.mRegexCode; mpRegex = b.mpRegex; mScript = b.mScript; mIsFolder = b.mIsFolder; mpHost = b.mpHost; mNeedsToBeCompiled = b.mNeedsToBeCompiled; return *this; } bool TAlias::isClone(TAlias &b) const { return (mName == b.mName && mCommand == b.mCommand && mRegexCode == b.mRegexCode && mpRegex == b.mpRegex && mScript == b.mScript && mIsFolder == b.mIsFolder && mpHost == b.mpHost && mNeedsToBeCompiled == b.mNeedsToBeCompiled ); } bool TAlias::registerAlias() { if( ! mpHost ) { qDebug() << "ERROR: TAlias::registerTrigger() pHost=0"; return false; } return mpHost->getAliasUnit()->registerAlias( this ); } void TAlias::compileAll() { mNeedsToBeCompiled = true; if( ! compileScript() ) { if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::red))<<"ERROR: Lua compile error. compiling script of alias:"<>0;} mOK_code = false; } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TAlias * pChild = *it; pChild->compileAll(); } } void TAlias::compile() { if( mNeedsToBeCompiled ) { if( ! compileScript() ) { if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::red))<<"ERROR: Lua compile error. compiling script of alias:"<>0;} mOK_code = false; } } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TAlias * pChild = *it; pChild->compile(); } } bool TAlias::setScript( QString & script ) { mScript = script; mNeedsToBeCompiled = true; mOK_code = compileScript(); return mOK_code; } bool TAlias::compileScript() { mFuncName = QString("Alias")+QString::number( mID ); QString code = QString("function ")+ mFuncName + QString("()\n") + mScript + QString("\nend\n"); QString error; if( mpHost->mLuaInterpreter.compile( code, error ) ) { mNeedsToBeCompiled = false; mOK_code = true; return true; } else { mOK_code = false; setError( error ); return false; } } void TAlias::execute() { if( mCommand.size() > 0 ) { mpHost->send( mCommand ); } if( mNeedsToBeCompiled ) { if( ! compileScript() ) { return; } } mpHost->mLuaInterpreter.call( mFuncName, mName ); } mudlet-2.1/src/dlgOptionsAreaTimers.h0000644000175000017500000000331611513237311017215 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _dlgOptionsAreaTimers_h #define _dlgOptionsAreaTimers_h #include "ui_options_area_timers.h" #include #include "TTimer.h" class dlgOptionsAreaTimers: public QWidget , public Ui::options_area_timers { Q_OBJECT public: dlgOptionsAreaTimers(QWidget *); signals: public slots: }; #endif mudlet-2.1/src/THighlighter.h0000644000175000017500000000232011513237311015472 0ustar csmallcsmall#ifndef THIGHLIGHTER_H #define THIGHLIGHTER_H #include #include #include class QTextDocument; class THighlighter : public QSyntaxHighlighter { Q_OBJECT public: THighlighter(QTextDocument *parent = 0); void setSearchPattern( QString p ); protected: void highlightBlock(const QString &text); private: struct HighlightingRule { QRegExp pattern; QTextCharFormat format; }; QString mSearchPattern; QVector highlightingRules; QRegExp commentStartExpression; QRegExp commentEndExpression; QRegExp stringStart; QRegExp stringEnd; QTextCharFormat keywordFormat; QTextCharFormat searchFormat; QTextCharFormat classFormat; QTextCharFormat singleLineCommentFormat; QTextCharFormat multiLineCommentFormat; QTextCharFormat quotationFormat; QTextCharFormat functionFormat; //bool isString; }; #endif // THIGHLIGHTER_H mudlet-2.1/src/TSplitter.cpp0000644000175000017500000000035511513237311015403 0ustar csmallcsmall#include "TSplitter.h" #include TSplitter::TSplitter(Qt::Orientation o, QWidget * p ) : QSplitter( o, p ) { } QSplitterHandle * TSplitter::createHandle() { return new TSplitterHandle( orientation(), this ); } mudlet-2.1/src/KeyUnit.h0000644000175000017500000000632411647202526014520 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _KEY_UNIT_H #define _KEY_UNIT_H #include "TKey.h" #include #include #include #include class TKey; class Host; class KeyUnit { friend class XMLexport; friend class XMLimport; public: KeyUnit( Host * pHost ); std::list getKeyRootNodeList() { QMutexLocker locker(& mKeyUnitLock); return mKeyRootNodeList; } TKey * getKey( int id ); void compileAll(); bool enableKey( QString & name ); bool disableKey( QString & name ); bool registerKey( TKey * pT ); void unregisterKey( TKey * pT ); void reParentKey( int childID, int oldParentID, int newParentID, int parentPosition = -1, int childPosition = -1 ); qint64 getNewID(); QString getKeyName( int keyCode, int modifier ); void setupKeyNames(); void uninstall( QString ); void _uninstall( TKey * pChild, QString packageName ); bool processDataStream( int, int ); QMutex mKeyUnitLock; QList uninstallList; private: KeyUnit(){;} TKey * getKeyPrivate( int id ); void addKeyRootNode( TKey * pT, int parentPosition = -1, int childPosition = -1 ); void addKey( TKey * pT ); void removeKeyRootNode( TKey * pT ); void removeKey( TKey *); Host * mpHost; QMap mKeyMap; std::list mKeyRootNodeList; qint64 mMaxID; bool mModuleMember; QMap mKeys; }; #endif mudlet-2.1/src/Tree.h0000644000175000017500000002104212020507607014013 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef __TREE__H #define __TREE__H #include #include #include #include #include #include template class Tree { public: Tree(); Tree( T * parent ); virtual ~Tree(); T * getParent() { return mpParent; } std::list * getChildrenList(); bool hasChildren() { return (mpMyChildrenList->size() > 0); } int getChildCount() { return mpMyChildrenList->size(); } void DumpFamily(); void Dump(); void setFullyExpanded() { FullyExpanded = true; } bool isFullyExpanded() { return FullyExpanded; } qint64 getID() { return mID; } void setID( qint64 id ) { mID=id; } void addChild( T * newChild, int parentPostion = -1, int parentPosition = -1 ); bool popChild( T * removeChild ); void setParent( T * parent ); void enableFamily(); void disableFamily(); bool isActive(); bool activate(); void deactivate(); bool setIsActive( bool ); bool shouldBeActive(); void setShouldBeActive( bool b ); bool ancestorsActive(); // Returns true if all the ancesters of this node are active. If there are no ancestors it also returns true. T * mpParent; std::list * mpMyChildrenList; qint64 mID; QString & getError(); void setError( QString ); bool state(); QString getPackageName() { return mPackageName; } void setPackageName( QString n ){ mPackageName = n; } void setModuleName( QString n ){ mModuleName = n;} QString getModuleName() {return mModuleName;} bool FullyExpanded; QString mPackageName; QString mModuleName; protected: virtual bool canBeActivated(); bool mOK_init; bool mOK_code; private: bool mActive; bool mUserActiveState; QString mErrorMessage; }; template Tree::Tree() : mpParent( 0 ) , mpMyChildrenList( new std::list ) , mID( 0 ) , mOK_init( true ) , mOK_code( true ) , mActive( false ) , mUserActiveState( false ) { } template Tree::Tree( T * pParent ) : mpParent( pParent ) , mpMyChildrenList( new std::list ) , mID( 0 ) , mOK_init( true ) , mOK_code( true ) , mActive( false ) , mUserActiveState( false ) { if( pParent ) { pParent->addChild( (T*)( this ) ); } else mpParent=0; } template Tree::~Tree() { while( mpMyChildrenList->size() > 0 ) { typename std::list::iterator it = mpMyChildrenList->begin(); T * pChild = *it; delete pChild; } delete mpMyChildrenList; if( mpParent != 0 ) { mpParent->popChild( (T*)this ); // tell parent about my death if( std::uncaught_exception() ) { std::cout << "ERROR: Hook destructed during stack rewind because of an uncaught exception." << std::endl; } } } template bool Tree::ancestorsActive() { Tree * node(mpParent); while(node) { if(!node->isActive()) { return false; } node=node->mpParent; } return true; } template bool Tree::shouldBeActive() { return mUserActiveState; } template void Tree::setShouldBeActive( bool b ) { mUserActiveState = b; } template bool Tree::setIsActive( bool b ) { setShouldBeActive( b ); if( b ) { return activate(); } else { mActive = false; return false; } } template inline bool Tree::state() { return ( mOK_init && mOK_code ); } template inline bool Tree::canBeActivated() { return ( shouldBeActive() && state() ); } template bool Tree::activate() { if( canBeActivated() ) { mActive = true; return true; } mActive = false; return false; } template void Tree::deactivate() { mActive = false; } template bool Tree::isActive() { return (mActive && canBeActivated()); } template void Tree::enableFamily() { activate(); typedef typename std::list::const_iterator IT; for( IT it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++ ) { (*it)->enableFamily(); } } template void Tree::disableFamily() { deactivate(); typedef typename std::list::const_iterator IT; for( IT it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++ ) { (*it)->disableFamily(); } } template void Tree::addChild( T * newChild, int parentPosition, int childPosition ) { if( ( parentPosition == -1 ) || ( childPosition >= static_cast(mpMyChildrenList->size()) ) ) { mpMyChildrenList->push_back( newChild ); } else { // insert item at proper position int cnt = 0; typedef typename std::list::iterator IT; for( IT it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it ++ ) { if( cnt >= childPosition ) { mpMyChildrenList->insert( it, newChild ); break; } cnt++; } } } template void Tree::setParent( T * pParent ) { mpParent = pParent; } template bool Tree::popChild( T * pChild ) { typedef typename std::list::const_iterator IT; for( IT it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++ ) { if( *it == pChild ) { mpMyChildrenList->remove( pChild ); return true; } } return false; } template std::list * Tree::getChildrenList() { return mpMyChildrenList; } template QString & Tree::getError() { return mErrorMessage; } template void Tree::setError( QString error ) { mErrorMessage = error; } template void Tree::DumpFamily() { Dump(); typedef typename std::list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++ ) { T * pChild = *it; if( pChild ) pChild->DumpFamily(); } } template void Tree::Dump() { std::cout << "My ID=" << mID << " my parent="<< mpParent << std::endl; std::cout << " my children are:"; typedef typename std::list::const_iterator IT; for( IT it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++ ) { std::cout << " dumping:"<mID << ", "; } std::cout << "ende dump()"<< std::endl; } #endif mudlet-2.1/src/TTreeWidget.cpp0000644000175000017500000002154111513237311015640 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "TTreeWidget.h" #include #include "Host.h" #include "HostManager.h" #include "TDebug.h" TTreeWidget::TTreeWidget( QWidget * pW ) : QTreeWidget( pW ) { setSelectionMode( QAbstractItemView::SingleSelection ); setSelectionBehavior( QAbstractItemView::SelectRows ); setDragEnabled( true ); setAcceptDrops( true ); setDropIndicatorShown( true ); viewport()->setAcceptDrops( true ); setDragDropMode( QAbstractItemView::InternalMove ); mIsDropAction = false; mpHost = 0; mOldParentID = 0; mIsTriggerTree = false; mIsScriptTree = false; mIsTimerTree = false; mIsAliasTree = false; mIsActionTree = false; mIsKeyTree = false; } void TTreeWidget::setIsAliasTree() { mIsAliasTree = true; mIsTriggerTree = false; mIsScriptTree = false; mIsTimerTree = false; mIsActionTree = false; mIsKeyTree = false; } void TTreeWidget::setIsTriggerTree() { mIsTriggerTree = true; mIsAliasTree = false; mIsScriptTree = false; mIsTimerTree = false; mIsActionTree = false; mIsKeyTree = false; } void TTreeWidget::setIsActionTree() { mIsTriggerTree = false; mIsAliasTree = false; mIsScriptTree = false; mIsTimerTree = false; mIsKeyTree = false; mIsActionTree = true; } void TTreeWidget::setIsKeyTree() { mIsTriggerTree = false; mIsAliasTree = false; mIsScriptTree = false; mIsTimerTree = false; mIsActionTree = false; mIsKeyTree = true; } void TTreeWidget::setIsTimerTree() { mIsTimerTree = true; mIsTriggerTree = false; mIsScriptTree = false; mIsAliasTree = false; mIsActionTree = false; mIsKeyTree = false; } void TTreeWidget::setIsScriptTree() { mIsScriptTree = true; mIsTriggerTree = false; mIsAliasTree = false; mIsTimerTree = false; mIsActionTree = false; mIsKeyTree = false; } void TTreeWidget::setHost( Host * pH ) { mpHost = pH; } void TTreeWidget::rowsAboutToBeRemoved( const QModelIndex & parent, int start, int end ) { if( parent.isValid() ) { mOldParentID = parent.data( Qt::UserRole ).toInt(); } else mOldParentID = 0; if( mOldParentID == 0 ) { mOldParentID = parent.sibling( start, 0 ).data( Qt::UserRole ).toInt(); } if( parent.isValid() ) { QModelIndex child = parent.child( start, 0 ); mChildID = child.data( Qt::UserRole ).toInt(); if( mChildID == 0 ) { if( parent.isValid() ) { child = parent.model()->index( start, 0, QModelIndex() ); } if( child.isValid() ) { mChildID = child.data( Qt::UserRole ).toInt(); } else mChildID = 0; } } //QTreeWidget::rowsAboutToBeRemoved( parent, start, end ); } void TTreeWidget::rowsInserted( const QModelIndex & parent, int start, int end ) { // determine position in parent list if( mIsDropAction ) { QModelIndex child = parent.child( start, 0 ); int parentPosition = parent.row(); int childPosition = child.row(); if( mChildID == 0 ) { if( ! parent.model() ) goto END; if( ! mpHost ) goto END; mChildID = parent.model()->index( start, 0 ).data( Qt::UserRole ).toInt(); } int newParentID = parent.data( Qt::UserRole ).toInt(); if( mIsTriggerTree ) mpHost->getTriggerUnit()->reParentTrigger( mChildID, mOldParentID, newParentID, parentPosition, childPosition ); if( mIsAliasTree ) mpHost->getAliasUnit()->reParentAlias( mChildID, mOldParentID, newParentID, parentPosition, childPosition ); if( mIsKeyTree ) mpHost->getKeyUnit()->reParentKey( mChildID, mOldParentID, newParentID, parentPosition, childPosition ); if( mIsTimerTree ) { mpHost->getTimerUnit()->reParentTimer( mChildID, mOldParentID, newParentID, parentPosition, childPosition ); TTimer * pTChild = mpHost->getTimerUnit()->getTimer( mChildID ); //TTimer * pTnewParent = mpHost->getTimerUnit()->getTimer( newParentID ); if( pTChild ) { QIcon icon; if( pTChild->isOffsetTimer() ) { if( pTChild->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-on.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-off.png")), QIcon::Normal, QIcon::Off); } } else { if( pTChild->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } QTreeWidgetItem * pParent = itemFromIndex( parent ); if( ! pParent ) goto END; for( int i=0; ichildCount(); i++ ) { QTreeWidgetItem * pItem = pParent->child(i); if( ! pItem ) goto END; int id = pItem->data(0, Qt::UserRole).toInt(); if( id == mChildID ) { pItem->setIcon(0, icon); } } } } if( mIsScriptTree ) mpHost->getScriptUnit()->reParentScript( mChildID, mOldParentID, newParentID, parentPosition, childPosition ); if( mIsActionTree ) { mpHost->getActionUnit()->reParentAction( mChildID, mOldParentID, newParentID, parentPosition, childPosition ); mpHost->getActionUnit()->updateToolbar(); } mChildID = 0; mOldParentID = 0; mIsDropAction = false; } END: QTreeWidget::rowsInserted( parent, start, end ); } Qt::DropActions TTreeWidget::supportedDropActions() const { return Qt::MoveAction; } void TTreeWidget::dragEnterEvent(QDragEnterEvent *event) { mIsDropAction = true; QTreeWidget::dragEnterEvent( event ); } void TTreeWidget::dropEvent(QDropEvent *event) { QTreeWidgetItem * pItem = itemAt( event->pos() ); if( ! pItem ) { event->setDropAction( Qt::IgnoreAction ); event->ignore(); } if( pItem == topLevelItem(0) ) { if( (dropIndicatorPosition() == QAbstractItemView::AboveItem ) || (dropIndicatorPosition() == QAbstractItemView::BelowItem ) ) { event->setDropAction( Qt::IgnoreAction ); event->ignore(); } } mIsDropAction = true; QTreeWidget::dropEvent( event ); return; } void TTreeWidget::beginInsertRows ( const QModelIndex & parent, int first, int last ) { } void TTreeWidget::dragMoveEvent( QDragMoveEvent * e ) { QTreeWidget::dragMoveEvent( e ); } void TTreeWidget::startDrag( Qt::DropActions supportedActions ) { QTreeWidget::startDrag( supportedActions ); } bool TTreeWidget::dropMimeData ( QTreeWidgetItem * parent, int index, const QMimeData * data, Qt::DropAction action ) { return QTreeWidget::dropMimeData( parent, index, data, action ); } mudlet-2.1/src/TBuffer.h0000644000175000017500000002436711624306130014463 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn (KoehnHeiko@googlemail.com) * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include "Host.h" #include #ifndef TBUFFER_H #define TBUFFER_H class Host; class TChar { public: TChar(); TChar( int, int, int, int, int, int, bool, bool, bool, int _link = 0 ); TChar( Host * ); TChar( const TChar & copy ); bool operator==( const TChar & c ); int fgR; int fgG; int fgB; int bgR; int bgG; int bgB; bool italics; bool bold; bool underline; int link; bool invers; }; class Host; const QChar cLF = QChar('\n'); const QChar cSPACE = QChar(' '); struct TMxpElement { QString name; QString href; QString hint; }; class TBuffer { public: TBuffer( Host * pH ); QPoint insert( QPoint &, QString text, int,int,int, int, int, int, bool bold, bool italics, bool underline ); bool insertInLine( QPoint & cursor, QString & what, TChar & format ); void expandLine( int y, int count, TChar & ); int wrap( int startLine, int screenWidth, int indentSize, TChar & format ); int wrapLine( int startLine, int screenWidth, int indentSize, TChar & format ); void addLink( bool, QString & text, QStringList & command, QStringList & hint, TChar format ); // void appendLink( QString & text, // int sub_start, // int sub_end, // int fgColorR, // int fgColorG, // int fgColorB, // int bgColorR, // int bgColorG, // int bgColorB, // bool bold, // bool italics, // bool underline ); QString bufferToHtml( QPoint P1, QPoint P2 ); int size(){ return static_cast(buffer.size()); } QString & line( int n ); int find( int line, QString what, int pos ); int wrap( int ); QStringList split( int line, QString splitter ); QStringList split( int line, QRegExp splitter ); bool replace( int line, QString what, QString with ); bool replaceInLine( QPoint & start, QPoint & end, QString & with, TChar & format ); bool deleteLine( int ); bool deleteLines( int from, int to ); bool applyFormat( QPoint &, QPoint &, TChar & format ); bool applyUnderline( QPoint & P_begin, QPoint & P_end, bool bold ); bool applyBold( QPoint & P_begin, QPoint & P_end, bool bold ); bool applyLink( QPoint & P_begin, QPoint & P_end, QString linkText, QStringList &, QStringList & ); bool applyItalics( QPoint & P_begin, QPoint & P_end, bool bold ); bool applyFgColor( QPoint &, QPoint &, int, int, int ); bool applyBgColor( QPoint &, QPoint &, int, int, int ); void appendBuffer( TBuffer chunk ); bool moveCursor( QPoint & where ); QPoint & insertText( QString & what, QPoint & where ); int getLastLineNumber(); QStringList getEndLines( int ); void clear(); void resetFontSpecs(); QPoint getEndPos(); void translateToPlainText( std::string & s ); void append( QString & chunk, int sub_start, int sub_end, int, int, int, int, int, int, bool bold, bool italics, bool underline, int linkID=0 ); void appendLine( QString & chunk, int sub_start, int sub_end, int, int, int, int, int, int, bool bold, bool italics, bool underline, int linkID=0 ); int lookupColor( QString & s, int pos ); void set_text_properties(int tag); void setWrapAt( int i ){ mWrapAt = i; } void setWrapIndent( int i ){ mWrapIndent = i; } void updateColors(); TBuffer copy( QPoint &, QPoint & ); TBuffer cut( QPoint &, QPoint & ); void paste( QPoint &, TBuffer ); std::deque bufferLine; std::deque< std::deque > buffer; QStringList timeBuffer; QStringList lineBuffer; QList promptBuffer; QList dirty; QMap mLinkStore; QMap mHintStore; int mLinkID; int mLinesLimit; int mBatchDeleteSize; int newLines; int mUntriggered; int mWrapAt; int mWrapIndent; void setBufferSize( int s, int batch ); void messen(); int speedTP; int speedSequencer; int speedAppend; int msLength; int msPos; int mCursorY; bool mMXP; bool mAssemblingToken; std::string currentToken; int openT; int closeT; QMap mMXP_Elements; TMxpElement mCurrentElement; bool mMXP_LINK_MODE; bool mIgnoreTag; std::string mSkip; bool mParsingVar; char mOpenMainQuote; bool mMXP_SEND_NO_REF_MODE; std::string mAssembleRef; private: inline void shrinkBuffer(); inline int calcWrapPos( int line, int begin, int end ); void handleNewLine(); bool gotESC; bool gotHeader; QString code; int codeRet; std::string tempLine; bool mWaitingForHighColorCode; bool mHighColorModeForeground; bool mHighColorModeBackground; bool mIsHighColorMode; bool mIsDefaultColor; bool isUserScrollBack; int currentFgColorProperty; QString mFormatSequenceRest; QColor mBlack; int mBlackR; int mBlackG; int mBlackB; QColor mLightBlack; int mLightBlackR; int mLightBlackG; int mLightBlackB; QColor mRed; int mRedR; int mRedG; int mRedB; QColor mLightRed; int mLightRedR; int mLightRedG; int mLightRedB; QColor mLightGreen; int mLightGreenR; int mLightGreenG; int mLightGreenB; QColor mGreen; int mGreenR; int mGreenG; int mGreenB; QColor mLightBlue; int mLightBlueR; int mLightBlueG; int mLightBlueB; QColor mBlue; int mBlueR; int mBlueG; int mBlueB; QColor mLightYellow; int mLightYellowR; int mLightYellowG; int mLightYellowB; QColor mYellow; int mYellowR; int mYellowG; int mYellowB; QColor mLightCyan; int mLightCyanR; int mLightCyanG; int mLightCyanB; QColor mCyan; int mCyanR; int mCyanG; int mCyanB; QColor mLightMagenta; int mLightMagentaR; int mLightMagentaG; int mLightMagentaB; QColor mMagenta; int mMagentaR; int mMagentaG; int mMagentaB; QColor mLightWhite; int mLightWhiteR; int mLightWhiteG; int mLightWhiteB; QColor mWhite; int mWhiteR; int mWhiteG; int mWhiteB; QColor mFgColor; int fgColorR; int fgColorLightR; int fgColorG; int fgColorLightG; int fgColorB; int fgColorLightB; int bgColorR; int bgColorG; int bgColorB; QColor mBgColor; Host * mpHost; int maxx; int maxy; bool hadLF; int mLastLine; bool mCursorMoved; QTime mTime; bool mBold; bool mItalics; bool mUnderline; bool mFgColorCode; bool mBgColorCode; int mFgColorR; int mFgColorG; int mFgColorB; int mBgColorR; int mBgColorG; int mBgColorB; QString mMudLine; std::deque mMudBuffer; int mCode[1024];//FIXME: potential overflow bug }; #endif mudlet-2.1/src/exitstreewidget.h0000644000175000017500000000340112020507607016333 0ustar csmallcsmall#ifndef EXITSTREEWIDGET_H #define EXITSTREEWIDGET_H /*************************************************************************** * Copyright (C) 2012 by Vadim Peretokin * * vadim.peretokin@mudlet.org * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include class Host; class ExitsTreeWidget : public QTreeWidget { Q_OBJECT public: ExitsTreeWidget( QWidget * pW ); void keyPressEvent ( QKeyEvent * event ); private: signals: public slots: }; #endif // EXITSTREEWIDGET_H mudlet-2.1/src/TEasyButtonBar.cpp0000644000175000017500000001617212070466512016331 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "Host.h" #include "HostManager.h" #include "TEasyButtonBar.h" #include "mudlet.h" TEasyButtonBar::TEasyButtonBar( TAction * pA, QString name, QWidget * pW ) : QWidget( pW ) , mpTAction( pA ) , mVerticalOrientation( false ) , mpWidget( new QWidget ) , mName( name ) , mRecordMove( false ) , mpLayout( 0 ) , mItemCount( 0 ) , mpBar( pW ) { mButtonList.clear(); QVBoxLayout * layout = new QVBoxLayout; setLayout( layout ); layout->setContentsMargins(0,0,0,0); layout->setMargin(0); layout->setSpacing(0); layout->addWidget( mpWidget ); if( ! mpTAction->mUseCustomLayout ) { mpLayout = new QGridLayout( mpWidget ); setContentsMargins(0,0,0,0); mpLayout->setContentsMargins(0,0,0,0); mpLayout->setMargin(0); mpLayout->setSpacing(0); QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred); mpWidget->setSizePolicy( sizePolicy ); } else { mpWidget->setMinimumHeight( mpTAction->mSizeY ); mpWidget->setMaximumHeight( mpTAction->mSizeY ); mpWidget->setMinimumWidth( mpTAction->mSizeX ); mpWidget->setMaximumWidth( mpTAction->mSizeX ); mpWidget->setGeometry( mpTAction->mPosX, mpTAction->mPosY, mpTAction->mSizeX, mpTAction->mSizeY ); } setStyleSheet( mpTAction->css ); mpWidget->setStyleSheet( mpTAction->css ); } void TEasyButtonBar::addButton( TFlipButton * pB ) { if( ! mpTAction->mUseCustomLayout ) { QSize size = pB->minimumSizeHint(); if( pB->mpTAction->getButtonRotation() > 0 ) { size.transpose(); pB->setMaximumSize( size ); } //pB->setMinimumSize( size ); } else { qDebug()<<"setting up custom sizes"; QSize size = QSize(pB->mpTAction->mSizeX, pB->mpTAction->mSizeY ); pB->setMaximumSize( size ); pB->setMinimumSize( size ); pB->setParent( mpWidget ); pB->setGeometry( pB->mpTAction->mPosX, pB->mpTAction->mPosY, pB->mpTAction->mSizeX, pB->mpTAction->mSizeY ); } pB->setStyleSheet( pB->mpTAction->css ); pB->setFlat( pB->mpTAction->getButtonFlat() ); int rotation = pB->mpTAction->getButtonRotation(); switch( rotation ) { case 0: pB->setOrientation( Qt::Horizontal ); break; case 1: pB->setOrientation( Qt::Vertical ); break; case 2: pB->setOrientation( Qt::Vertical ); pB->setMirrored( true ); break; } if( ! mpTAction->mUseCustomLayout ) { // tool bar mButtonColumns > 0 -> autolayout // case == 0: use individual button placment for user defined layouts int columns = mpTAction->getButtonColumns(); if( columns <= 0 ) columns = 1; if( columns > 0 ) { mItemCount++; int row = mItemCount / columns; int col = mItemCount % columns; if( mVerticalOrientation ) { mpLayout->addWidget( pB, row, col ); } else { mpLayout->addWidget( pB, col, row ); } } } else { pB->move( pB->mpTAction->mPosX, pB->mpTAction->mPosY ); } connect( pB, SIGNAL(released()), this, SLOT(slot_pressed()) ); mButtonList.push_back( pB ); pB->setChecked( (pB->mpTAction->mButtonState==2) ); } void TEasyButtonBar::finalize() { if( mpTAction->mUseCustomLayout ) { return; } QWidget * fillerWidget = new QWidget; QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding ); fillerWidget->setSizePolicy( sizePolicy ); //fillerWidget->setMinimumHeight(1); //fillerWidget->setMinimumWidth(1); int columns = mpTAction->getButtonColumns(); if( columns <= 0 ) columns = 1; if( mpLayout ) { mpLayout->addWidget( fillerWidget, ++mItemCount/columns, mItemCount%columns ); } } void TEasyButtonBar::slot_pressed() { TFlipButton * pB = dynamic_cast( sender() ); if( ! pB ) { return; } TAction * pA = pB->mpTAction; pB->showMenu(); if( pA->mButtonState == 2 ) { pA->mButtonState = 1; pB->setChecked( false ); } else { pA->mButtonState = 2; pB->setChecked( true ); } if( pB->isChecked() ) pA->mpHost->mpConsole->mButtonState = 1; else pA->mpHost->mpConsole->mButtonState = 0; QStringList sL; pA->_execute( sL ); } void TEasyButtonBar::clear() { QWidget * pW = new QWidget; typedef std::list::iterator IT; for( IT it = mButtonList.begin(); it != mButtonList.end(); it++ ) { disconnect( *it, SIGNAL(released()), this, SLOT(slot_pressed()) ); } mButtonList.clear(); mpWidget->deleteLater(); mpWidget = pW; if( ! mpTAction->mUseCustomLayout ) { mpLayout = new QGridLayout; mpWidget->setLayout( mpLayout ); mpLayout->setContentsMargins(0,0,0,0); mpLayout->setSpacing(0); mpLayout->setMargin(0); QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); mpWidget->setSizePolicy( sizePolicy ); mpWidget->setContentsMargins(0,0,0,0); mpLayout->setMargin(0); } else { mpLayout = 0; mpWidget->setMinimumHeight( mpTAction->mSizeY ); mpWidget->setMaximumHeight( mpTAction->mSizeY ); mpWidget->setMinimumWidth( mpTAction->mSizeX ); mpWidget->setMaximumWidth( mpTAction->mSizeX ); mpWidget->setGeometry( mpTAction->mPosX, mpTAction->mPosY, mpTAction->mSizeX, mpTAction->mSizeY ); } layout()->addWidget( pW ); setStyleSheet( mpTAction->css ); mpWidget->setStyleSheet( mpTAction->css ); } mudlet-2.1/src/TEasyButtonBar.h0000644000175000017500000000475711513237311015776 0ustar csmallcsmall#ifndef TEASYBUTTONBAR_H #define TEASYBUTTONBAR_H /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include "TFlipButton.h" #include "TAction.h" class Host; class TFlipButton; class TAction; class TEasyButtonBar : public QWidget { Q_OBJECT public: TEasyButtonBar( TAction *, QString, QWidget * pW = 0 ); void addButton( TFlipButton * pW ); void setVerticalOrientation(){ mVerticalOrientation = true; } void setHorizontalOrientation(){ mVerticalOrientation = false; } void clear(); void finalize(); TAction * mpTAction; void recordMove(){ mRecordMove = true; } //private: bool mVerticalOrientation; QWidget * mpWidget; QString mName; bool mRecordMove; QGridLayout * mpLayout; int mItemCount; QWidget * mpBar; std::list mButtonList; signals: public slots: void slot_pressed(); }; #endif // TEASYBUTTONBAR_H mudlet-2.1/src/dlgNotepad.cpp0000644000175000017500000000464311513237311015536 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn - KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "dlgNotepad.h" #include #include "TDebug.h" #include "Host.h" dlgNotepad::dlgNotepad( Host * pH ) : mpHost( pH ) { setupUi(this); } void dlgNotepad::save() { QString directoryFile = QDir::homePath()+"/.config/mudlet/profiles/"+mpHost->getName(); QString fileName = directoryFile + "/notes.txt"; QDir dirFile; if( ! dirFile.exists( directoryFile ) ) { dirFile.mkpath( directoryFile ); } QFile file; file.setFileName( fileName ); file.open( QIODevice::WriteOnly ); QTextStream fileStream; fileStream.setDevice( &file ); fileStream << notesEdit->toPlainText(); file.close(); } void dlgNotepad::restore() { QString directoryFile = QDir::homePath()+"/.config/mudlet/profiles/"+mpHost->getName(); QString fileName = directoryFile + "/notes.txt"; QDir dirFile; QFile file; file.setFileName( fileName ); file.open( QIODevice::ReadOnly ); QTextStream fileStream; fileStream.setDevice( &file ); QString txt = fileStream.readAll(); notesEdit->setPlainText(txt); } mudlet-2.1/src/TTrigger.cpp0000644000175000017500000014374412070466512015220 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn KoehnHeiko@googlemail.com * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "TTrigger.h" #include "Host.h" #include "HostManager.h" #include #include "mudlet.h" #include "TDebug.h" #include #include #include #include using namespace std; const QString nothing = ""; TTrigger::TTrigger( TTrigger * parent, Host * pHost ) : Tree( parent ) , mTriggerContainsPerlRegex( false ) , mPerlSlashGOption( false ) , mFilterTrigger( false ) , mSoundTrigger( false ) , mStayOpen( 0 ) , mColorTrigger( false ) , mColorTriggerFg( false ) , mColorTriggerBg( false ) , mKeepFiring( 0 ) , mpHost( pHost ) , mIsTempTrigger( false ) , mModuleMember(false) , mModuleMasterFolder(false) , mNeedsToBeCompiled( true ) , mTriggerType( REGEX_SUBSTRING ) , exportItem(true) , mIsLineTrigger( false ) , mStartOfLineDelta( 0 ) , mLineDelta( 3 ) , mConditionLineDelta( 0 ) , mIsMultiline( false ) , mpLua( mpHost->getLuaInterpreter() ) , mFgColor( QColor(255,0,0) ) , mBgColor( QColor(255,255,0) ) , mIsColorizerTrigger( false ) { } TTrigger::TTrigger( QString name, QStringList regexList, QList regexProperyList, bool isMultiline, Host * pHost ) : Tree(0) , mTriggerContainsPerlRegex( false ) , mPerlSlashGOption( false ) , mFilterTrigger( false ) , mSoundTrigger( false ) , mStayOpen( 0 ) , mColorTrigger( false ) , mColorTriggerFg( false ) , mColorTriggerBg( false ) , mKeepFiring( 0 ) , mpHost( pHost ) , mName( name ) , mIsTempTrigger( false ) , mModuleMember(false) , mModuleMasterFolder(false) , mRegexCodeList( regexList ) , mRegexCodePropertyList( regexProperyList ) , mNeedsToBeCompiled( true ) , exportItem(true) , mTriggerType( REGEX_SUBSTRING ) , mIsLineTrigger( false ) , mStartOfLineDelta( 0 ) , mLineDelta( 3 ) , mConditionLineDelta( 0 ) , mIsMultiline( isMultiline ) , mpLua( mpHost->getLuaInterpreter() ) , mFgColor( QColor(255,0,0) ) , mBgColor( QColor(255,255,0) ) , mIsColorizerTrigger( false ) { setRegexCodeList( regexList, regexProperyList ); } TTrigger::~TTrigger() { if( ! mpHost ) { return; } mpHost->getTriggerUnit()->unregisterTrigger( this ); } void TTrigger::setName( QString name ) { if( ! mIsTempTrigger ) { mpHost->getTriggerUnit()->mLookupTable.remove( mName, this ); } mName = name; mpHost->getTriggerUnit()->mLookupTable.insertMulti( name, this ); } //FIXME: sperren, wenn code nicht compiliert werden kann *ODER* regex falsch bool TTrigger::setRegexCodeList( QStringList regexList, QList propertyList ) { regexList.replaceInStrings( "\n", "" ); mRegexCodeList.clear(); mRegexMap.clear(); mRegexCodePropertyList.clear(); mLuaConditionMap.clear(); mColorPatternList.clear(); mTriggerContainsPerlRegex = false; if( propertyList.size() != regexList.size() ) { //FIXME: ronny hat das irgendwie geschafft qDebug()<<"[CRITICAL ERROR (plz report):] Trigger name="<>0; TDebug(QColor(Qt::red),QColor(Qt::gray))<>0; } setError( QString( "Pattern '" )+QString(pattern)+QString( "' failed to compile. Correct the pattern.") ); state = false; //printf("PCRE compilation failed at offset %d: %s\n", erroffset, error); } else { if( mudlet::debugMode ) { TDebug(QColor(Qt::white),QColor(Qt::darkGreen))<<"[OK]: REGEX_COMPILE OK\n">>0; } } mRegexMap[i] = re; mTriggerContainsPerlRegex = true; } if( propertyList[i] == REGEX_LUA_CODE ) { std::string funcName; std::stringstream func; func << "trigger" << mID << "condition" << i; funcName = func.str(); QString code = QString("function ")+funcName.c_str()+QString("()\n")+regexList[i]+QString("\nend\n"); QString error; if( ! mpLua->compile( code, error ) ) { setError( QString("pattern type Lua condition function '")+regexList[i]+QString("' failed to compile.")+error); state = false; } else { mLuaConditionMap[i] = funcName; } } if( propertyList[i] == REGEX_COLOR_PATTERN ) { QRegExp regex = QRegExp("FG(\\d+)BG(\\d+)"); int _pos = regex.indexIn( regexList[i] ); if( _pos == -1 ) { mColorPatternList.push_back( 0 ); state = false; continue; } int ansiFg = regex.cap(1).toInt(); int ansiBg = regex.cap(2).toInt(); if( ! setupColorTrigger( ansiFg, ansiBg ) ) { mColorPatternList.push_back( 0 ); state = false; continue; } // else // { // qDebug()<<"[OK] color pattern initialized:"<>0;} return false; //regex compile error } int numberOfCaptureGroups = 0; unsigned char *name_table; int namecount; int name_entry_size; int subject_length = strlen( subject ); int rc, i; std::list captureList; std::list posList; //int numOfCaptureGroups = pcre_info( re, 0, 0 )*3; int ovector[300]; // 100 capture groups max (can be increase nbGroups=1/3 ovector //qDebug() <<"TTrigger::match_perl() regex="<>0;} } if( rc == 0 ) { qDebug()<<"CRITICAL ERROR: SHOULD NOT HAPPEN->pcre_info() got wrong num of cap groups ovector only has room for %d captured substrings\n"; } if( rc < 0 ) { return false; } for( i=0; i < rc; i++ ) { char * substring_start = subject + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; std::string match; if( substring_length < 1 ) { captureList.push_back( match ); posList.push_back( -1 ); continue; } match.append( substring_start, substring_length ); captureList.push_back( match ); posList.push_back( ovector[2*i] + posOffset ); if( mudlet::debugMode ){ TDebug(QColor(Qt::darkCyan),QColor(Qt::black))<<"capture group #"<<(i+1)<<" = ">>0; TDebug(QColor(Qt::darkMagenta),QColor(Qt::black))<<"<"<\n">>0;} } (void)pcre_fullinfo( re, NULL, PCRE_INFO_NAMECOUNT, &namecount); if( namecount <= 0 ) { ; } else { unsigned char *tabptr; (void)pcre_fullinfo( re, NULL, PCRE_INFO_NAMETABLE, &name_table); (void)pcre_fullinfo( re, NULL, PCRE_INFO_NAMEENTRYSIZE, &name_entry_size); tabptr = name_table; for( i = 0; i < namecount; i++ ) { //int n = (tabptr[0] << 8) | tabptr[1]; //printf("GOT:(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); tabptr += name_entry_size; } } //TODO: add named groups seperately later as Lua::namedGroups if( mIsColorizerTrigger || mFilterTrigger ) { numberOfCaptureGroups = captureList.size(); } for( ; mPerlSlashGOption ; ) { int options = 0; int start_offset = ovector[1]; if( ovector[0] == ovector[1] ) { if( ovector[0] >= subject_length ) { goto END; } options = PCRE_NOTEMPTY | PCRE_ANCHORED; } rc = pcre_exec( re, NULL, subject, subject_length, start_offset, options, ovector, 30 ); if( rc == PCRE_ERROR_NOMATCH ) { if( options == 0 ) break; ovector[1] = start_offset + 1; continue; } if( rc < 0 ) { goto END; } if( rc == 0 ) { qDebug()<<"CRITICAL ERROR: SHOULD NOT HAPPEN->pcre_info() got wrong num of cap groups ovector only has room for %d captured substrings\n"; } for( i = 0; i < rc; i++ ) { char * substring_start = subject + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; std::string match; if( substring_length < 1 ) { captureList.push_back( match ); posList.push_back( -1 ); continue; } match.append( substring_start, substring_length ); captureList.push_back( match ); posList.push_back( ovector[2*i] + posOffset ); if( mudlet::debugMode ) { TDebug(QColor(Qt::darkCyan),QColor(Qt::black))<<" capture group #"<<(i+1)<<" = ">>0; TDebug(QColor(Qt::darkMagenta),QColor(Qt::black))<<"<"<\n">>0; } } } END: { if( mIsColorizerTrigger ) { int r1 = mBgColor.red(); int g1 = mBgColor.green(); int b1 = mBgColor.blue(); int r2 = mFgColor.red(); int g2 = mFgColor.green(); int b2 = mFgColor.blue(); int total = captureList.size(); TConsole * pC = mpHost->mpConsole; pC->deselect(); std::list::iterator its = captureList.begin(); std::list::iterator iti = posList.begin(); for( int i=1; iti!=posList.end(); ++iti, ++its, i++ ) { int begin = *iti; std::string & s = *its; int length = s.size(); if( total > 1 ) { // skip complete match in Perl /g option type of triggers // to enable people to highlight capture groups if there are any // otherwise highlight complete expression match if( i % numberOfCaptureGroups != 1 ) { pC->selectSection( begin, length ); pC->setBgColor( r1, g1, b1 ); pC->setFgColor( r2, g2, b2 ); } } else { pC->selectSection( begin, length ); pC->setBgColor( r1, g1, b1 ); pC->setFgColor( r2, g2, b2 ); } } pC->reset(); } if( mIsMultiline ) { updateMultistates( regexNumber, captureList, posList ); return true; } else { TLuaInterpreter * pL = mpHost->getLuaInterpreter(); pL->setCaptureGroups( captureList, posList ); execute(); pL->clearCaptureGroups(); if( mFilterTrigger ) { if( captureList.size() > 1 ) { int total = captureList.size(); std::list::iterator its = captureList.begin(); std::list::iterator iti = posList.begin(); for( int i=1; iti!=posList.end(); ++iti, ++its, i++ ) { int begin = *iti; std::string & s = *its; if( total > 1 ) { // skip complete match in Perl /g option type of triggers // to enable people to highlight capture groups if there are any // otherwise highlight complete expression match if( i % numberOfCaptureGroups != 1 ) { filter( s, begin ); } } else { filter( s, begin ); } } } } return true; } } return true; //ERROR: // return false; } bool TTrigger::match_begin_of_line_substring( QString & toMatch, QString & regex, int regexNumber, int posOffset ) { if( toMatch.startsWith( regex ) ) { std::list captureList; std::list posList; captureList.push_back( regex.toLatin1().data() ); posList.push_back( 0 + posOffset ); if( mudlet::debugMode ){ TDebug(QColor(Qt::darkCyan),QColor(Qt::black))<<"Trigger name="<>0;} if( mIsColorizerTrigger ) { int r1 = mBgColor.red(); int g1 = mBgColor.green(); int b1 = mBgColor.blue(); int r2 = mFgColor.red(); int g2 = mFgColor.green(); int b2 = mFgColor.blue(); TConsole * pC = mpHost->mpConsole; std::list::iterator its = captureList.begin(); std::list::iterator iti = posList.begin(); for( ; iti!=posList.end(); ++iti, ++its ) { int begin = *iti; std::string & s = *its; int length = s.size(); pC->selectSection( begin, length ); pC->setBgColor( r1, g1, b1 ); pC->setFgColor( r2, g2, b2 ); } pC->reset(); } if( mIsMultiline ) { updateMultistates( regexNumber, captureList, posList ); return true; } else { TLuaInterpreter * pL = mpHost->getLuaInterpreter(); pL->setCaptureGroups( captureList, posList ); // call lua trigger function with number of matches and matches itselves as arguments execute(); pL->clearCaptureGroups(); if( mFilterTrigger ) { if( captureList.size() > 0 ) { filter( captureList.front(), posList.front() ); } } return true; } } return false; } inline void TTrigger::updateMultistates( int regexNumber, std::list & captureList, std::list & posList ) { if( regexNumber == 0 ) { // wird automatisch auf #1 gesetzt TMatchState * pCondition = new TMatchState( mRegexCodeList.size(), mConditionLineDelta ); mConditionMap[pCondition] = pCondition; pCondition->multiCaptureList.push_back( captureList ); pCondition->multiCapturePosList.push_back( posList ); if( mudlet::debugMode ) { TDebug(QColor(Qt::darkYellow),QColor(Qt::black)) << "match state " << mConditionMap.size() << "/" << mConditionMap.size() <<" condition #" << regexNumber << "=true (" << regexNumber << "/" << mRegexCodeList.size() << ") regex=" << mRegexCodeList[regexNumber] <<"\n" >> 0; } } else { int k=0; for( map::iterator it=mConditionMap.begin(); it!=mConditionMap.end(); it++ ) { k++; if( (*it).second->nextCondition() == regexNumber ) { if( mudlet::debugMode ) { TDebug(QColor(Qt::darkYellow),QColor(Qt::black)) << "match state " << k << "/" << mConditionMap.size() <<" condition #" << regexNumber << "=true (" << regexNumber << "/" << mRegexCodeList.size() << ") regex=" << mRegexCodeList[regexNumber] <<"\n" >> 0; } (*it).second->conditionMatched(); (*it).second->multiCaptureList.push_back( captureList ); (*it).second->multiCapturePosList.push_back( posList ); } } } } inline void TTrigger::filter( std::string & capture, int & posOffset ) { if( capture.size() < 1 ) return; char * filterSubject = (char *) malloc( capture.size() + 2048 ); if( filterSubject ) { strcpy( filterSubject, capture.c_str() ); } else { return; } QString text = capture.c_str(); typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { (*it)->match( filterSubject, text, -1, posOffset ); } free( filterSubject ); } bool TTrigger::match_substring( QString & toMatch, QString & regex, int regexNumber, int posOffset ) { int where = toMatch.indexOf( regex ); if( where != -1 ) { std::list captureList; std::list posList; captureList.push_back( regex.toLatin1().data() ); posList.push_back( where + posOffset ); if( mPerlSlashGOption ) { while( (where = toMatch.indexOf( regex, where + 1 )) != -1 ) { captureList.push_back( regex.toLatin1().data() ); posList.push_back( where + posOffset ); } } if( mudlet::debugMode ) {TDebug(QColor(Qt::cyan),QColor(Qt::black))<<"Trigger name="<>0;} if( mIsColorizerTrigger ) { int r1 = mBgColor.red(); int g1 = mBgColor.green(); int b1 = mBgColor.blue(); int r2 = mFgColor.red(); int g2 = mFgColor.green(); int b2 = mFgColor.blue(); TConsole * pC = mpHost->mpConsole; pC->deselect(); std::list::iterator its = captureList.begin(); std::list::iterator iti = posList.begin(); for( ; iti!=posList.end(); ++iti, ++its ) { int begin = *iti; std::string & s = *its; int length = s.size(); pC->selectSection( begin, length ); pC->setBgColor( r1, g1, b1 ); pC->setFgColor( r2, g2, b2 ); } pC->reset(); } if( mIsMultiline ) { updateMultistates( regexNumber, captureList, posList ); return true; } else { TLuaInterpreter * pL = mpHost->getLuaInterpreter(); pL->setCaptureGroups( captureList, posList ); // call lua trigger function with number of matches and matches itselves as arguments execute(); pL->clearCaptureGroups(); if( mFilterTrigger ) { if( captureList.size() > 0 ) { filter( captureList.front(), posList.front() ); } } return true; } } return false; } bool TTrigger::match_color_pattern( int line, int regexNumber ) { if( regexNumber >= mColorPatternList.size() ) return false; if( line == -1 ) return false; //bool bgColorMatch = false; //bool fgColorMatch = false; bool canExecute = false; std::list captureList; std::list posList; if( line >= static_cast(mpHost->mpConsole->buffer.buffer.size()) ) return false; std::deque & bufferLine = mpHost->mpConsole->buffer.buffer[line]; QString & lineBuffer = mpHost->mpConsole->buffer.lineBuffer[line]; typedef std::deque::iterator IT; int pos = 0; //bool fgColorChange = false; int matchBegin = -1; bool matching = false; TColorTable * pCT = mColorPatternList[regexNumber]; if( ! pCT ) return false; //no color pattern created int mFgR = pCT->fgR; int mFgG = pCT->fgG; int mFgB = pCT->fgB; int mBgR = pCT->bgR; int mBgG = pCT->bgG; int mBgB = pCT->bgB; for( IT it=bufferLine.begin(); it!=bufferLine.end(); it++, pos++ ) { if( ( (*it).fgR == mFgR ) && ( (*it).fgG == mFgG ) && ( (*it).fgB == mFgB ) && ( (*it).bgR == mBgR ) && ( (*it).bgG == mBgG ) && ( (*it).bgB == mBgB ) ) { if( matchBegin == -1 ) matchBegin = pos; matching = true; } else { matching = false; } if( ( ! matching ) || ( matching && ( pos+1 >= static_cast(bufferLine.size()) ) ) ) { if( matchBegin > -1 ) { std::string got; if( matching ) got = lineBuffer.mid(matchBegin, pos-matchBegin+1).toLatin1().data(); else got = lineBuffer.mid(matchBegin, pos-matchBegin).toLatin1().data(); captureList.push_back( got ); posList.push_back( matchBegin ); matchBegin = -1; canExecute = true; matching = false; } } } if( canExecute ) { if( mIsColorizerTrigger ) { int r1 = mBgColor.red(); int g1 = mBgColor.green(); int b1 = mBgColor.blue(); int r2 = mFgColor.red(); int g2 = mFgColor.green(); int b2 = mFgColor.blue(); TConsole * pC = mpHost->mpConsole; pC->deselect(); std::list::iterator its = captureList.begin(); std::list::iterator iti = posList.begin(); for( ; iti!=posList.end(); ++iti, ++its ) { int begin = *iti; std::string & s = *its; cout<<"CTgot<"< bis:"<selectSection( begin, length ); pC->setBgColor( r1, g1, b1 ); pC->setFgColor( r2, g2, b2 ); } pC->reset(); } if( mIsMultiline ) { updateMultistates( regexNumber, captureList, posList ); return true; } else { TLuaInterpreter * pL = mpHost->getLuaInterpreter(); pL->setCaptureGroups( captureList, posList ); // call lua trigger function with number of matches and matches itselves as arguments execute(); pL->clearCaptureGroups(); if( mFilterTrigger ) { if( captureList.size() > 0 ) { typedef std::list::iterator IT; typedef std::list::iterator IT2; IT it1 = captureList.begin(); IT2 it2 = posList.begin(); for( ; it1!=captureList.end(); it1++, it2++ ) { filter( *it1, *it2 ); } } } return true; } } return false; } bool TTrigger::match_line_spacer( int regexNumber ) { if( mIsMultiline ) { int k=0; for( map::iterator it=mConditionMap.begin(); it!=mConditionMap.end(); it++ ) { k++; if( (*it).second->nextCondition() == regexNumber ) { if( (*it).second->lineSpacerMatch( mRegexCodeList.value(regexNumber).toInt() ) ) { if( mudlet::debugMode ) { TDebug(QColor(Qt::yellow),QColor(Qt::black))<<"Trigger name="<>0; TDebug(QColor(Qt::darkYellow),QColor(Qt::black)) << "match state " << k << "/" << mConditionMap.size() <<" condition #" << regexNumber << "=true (" << regexNumber+1 << "/" << mRegexCodeList.size() << ") line spacer=" << mRegexCodeList.value(regexNumber) <<"lines\n" >> 0; } (*it).second->conditionMatched(); std::list captureList; std::list posList; (*it).second->multiCaptureList.push_back( captureList ); (*it).second->multiCapturePosList.push_back( posList ); } } } } return true; //line spacers don't make sense outside of AND triggers -> ignore them } bool TTrigger::match_lua_code( int regexNumber ) { if( mLuaConditionMap.find( regexNumber ) == mLuaConditionMap.end() ) return false; if( mpLua->callConditionFunction( mLuaConditionMap[regexNumber], mName ) ) { if( mudlet::debugMode ){ TDebug(QColor(Qt::yellow),QColor(Qt::black))<<"Trigger name="<>0;} if( mIsMultiline ) { std::list captureList; std::list posList; updateMultistates( regexNumber, captureList, posList ); return true; } execute(); return true; } return false; } bool TTrigger::match_exact_match( QString & toMatch, QString & line, int regexNumber, int posOffset ) { QString text = toMatch; if( text.endsWith(QChar('\n')) ) text.chop(1); //TODO: speed optimization if( text == line ) { std::list captureList; std::list posList; captureList.push_back( line.toLatin1().data() ); posList.push_back( 0 + posOffset ); if( mudlet::debugMode ) {TDebug(QColor(Qt::yellow),QColor(Qt::black))<<"Trigger name="<>0;} if( mIsColorizerTrigger ) { int r1 = mBgColor.red(); int g1 = mBgColor.green(); int b1 = mBgColor.blue(); int r2 = mFgColor.red(); int g2 = mFgColor.green(); int b2 = mFgColor.blue(); TConsole * pC = mpHost->mpConsole; std::list::iterator its = captureList.begin(); std::list::iterator iti = posList.begin(); for( ; iti!=posList.end(); ++iti, ++its ) { int begin = *iti; std::string & s = *its; int length = s.size(); pC->selectSection( begin, length ); pC->setBgColor( r1, g1, b1 ); pC->setFgColor( r2, g2, b2 ); } pC->reset(); } if( mIsMultiline ) { updateMultistates( regexNumber, captureList, posList ); return true; } else { TLuaInterpreter * pL = mpHost->getLuaInterpreter(); pL->setCaptureGroups( captureList, posList ); // call lua trigger function with number of matches and matches itselves as arguments execute(); pL->clearCaptureGroups(); if( mFilterTrigger ) { if( captureList.size() > 0 ) { filter( captureList.front(), posList.front() ); } } return true; } } return false; } bool TTrigger::match( char * subject, QString & toMatch, int line, int posOffset ) { bool ret = false; if( isActive() ) { if( mIsLineTrigger ) { if( --mStartOfLineDelta < 0 ) { execute(); if( --mLineDelta <= 0 ) { deactivate(); mpHost->getTriggerUnit()->mCleanupList.push_back( this ); } return true; } return false; } if( toMatch.size() < 1 ) { return false; } bool conditionMet = false; int highestCondition = 0; if( mIsMultiline ) { //int matchStateCnt = 0; for( map::iterator it=mConditionMap.begin(); it!=mConditionMap.end(); ++it ) { (*it).second->newLineArrived(); int next = (*it).second->nextCondition(); if( next > highestCondition ) { highestCondition = next; } } } int size = mRegexCodePropertyList.size(); for( int i=0; ; i++ ) { if( i >= size ) break; ret = false; switch( mRegexCodePropertyList.value(i) ) { case REGEX_SUBSTRING: ret = match_substring( toMatch, mRegexCodeList[i], i, posOffset ); break; case REGEX_PERL: ret = match_perl( subject, toMatch, i, posOffset ); break; case REGEX_BEGIN_OF_LINE_SUBSTRING: ret = match_begin_of_line_substring( toMatch, mRegexCodeList[i], i, posOffset ); break; case REGEX_EXACT_MATCH: ret = match_exact_match( toMatch, mRegexCodeList[i], i, posOffset ); break; case REGEX_LUA_CODE: ret = match_lua_code( i ); break; case REGEX_LINE_SPACER: ret = match_line_spacer( i ); break; case REGEX_COLOR_PATTERN: ret = match_color_pattern( line, i ); break; } // policy: one match is enough to fire on OR-trigger, but in the case of // an AND-trigger all conditions have to be met in order to fire the trigger if( ! mIsMultiline ) { if( ret ) { conditionMet = true; mKeepFiring = mStayOpen; break; } } else { if( ( ! ret ) && ( i >= highestCondition ) ) break; } } // in the case of multiline triggers: check our state if( mIsMultiline ) { int k = 0; //bool triggerFires = false; conditionMet = false; //invalidate conditionMet as it has no meaning for multiline triggers list removeList; for( map::iterator it=mConditionMap.begin(); it!=mConditionMap.end(); ++it ) { k++; //qDebug()<<"TMatchState #"<mNextCondition<<"/"<<(*it).second->mNumberOfConditions<<")"; if( (*it).second->isComplete() ) { mKeepFiring = mStayOpen; if( mudlet::debugMode ){ TDebug(QColor(Qt::yellow),QColor(Qt::darkMagenta))<<"multiline trigger name="<>0;} removeList.push_back( (*it).first ); conditionMet = true; TLuaInterpreter * pL = mpHost->getLuaInterpreter(); pL->setMultiCaptureGroups( (*it).second->multiCaptureList, (*it).second->multiCapturePosList ); execute(); pL->clearCaptureGroups(); if( mFilterTrigger ) { std::list< std::list > multiCaptureList; multiCaptureList = (*it).second->multiCaptureList; if( multiCaptureList.size() > 0 ) { std::list< std::list >::iterator mit = multiCaptureList.begin(); for( ; mit!=multiCaptureList.end(); mit++, k++ ) { int total = (*mit).size(); std::list::iterator its = (*mit).begin(); for( int i=1; its!=(*mit).end(); ++its, i++ ) { std::string s = *its; int p = 0; if( total > 1 ) { if( i % total != 1 ) { filter( s, p ); } } else { filter( s, p ); } } } } } } if( ! (*it).second->newLine() ) { removeList.push_back( (*it).first ); } } for( list::iterator it=removeList.begin(); it!=removeList.end(); it++ ) { if( mConditionMap.find( *it ) != mConditionMap.end() ) { delete mConditionMap[*it]; if( mudlet::debugMode ) { TDebug(QColor(Qt::darkBlue),QColor(Qt::black))<< "removing condition from conditon table.\n">>0; } mConditionMap.erase( *it ); } } } // definition trigger chain: a folder is part of a trigger chain if it has a regex defined // a trigger chain only lets data pass if the condition matches or in case of multiline all // all conditions are fullfilled // // a folder can also be a simple structural element in which case all data passes through // if at least one regex is defined a folder is considered a trigger chain otherwise a structural element if( ! mFilterTrigger ) { if( conditionMet || ( mRegexCodeList.size() < 1 ) ) { typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TTrigger * pChild = *it; ret = pChild->match( subject, toMatch, line ); if( ret ) conditionMet = true; } } } if( ( mKeepFiring > 0 ) && ( ! conditionMet ) ) { mKeepFiring--; if( ( mKeepFiring == mStayOpen ) || ( mpMyChildrenList->size() == 0 ) ) { execute(); } bool conditionMet = false; typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TTrigger * pChild = *it; ret = pChild->match( subject, toMatch, line ); if( ret ) conditionMet = true; } return true; } return conditionMet; } return false; } // Die Musternummer wird ID im color-pattern lookup table TColorTable * TTrigger::createColorPattern( int ansiFg, int ansiBg ) { /* Mudlet simplified ANSI color codes ----------------------------------- 0 default text color 1 light black 2 dark black 3 light red 4 dark red 5 light green 6 dark green 7 light yellow 8 dark yellow 9 light blue 10 dark blue 11 light magenta 12 dark magenta 13 light cyan 14 dark cyan 15 light white 16 dark white */ bool invalidColorCode = false; int fgColorR = 0; int fgColorG = 0; int fgColorB = 0; int bgColorR = 0; int bgColorG = 0; int bgColorB = 0; int tag = ansiFg; if( tag <= 16 ) { QColor c; switch( tag ) { case 0: c = mpHost->mFgColor; break; case 1: c = mpHost->mLightBlack; break; case 2: c = mpHost->mBlack; break; case 3: c = mpHost->mLightRed; break; case 4: c = mpHost->mRed; break; case 5: c = mpHost->mLightGreen; break; case 6: c = mpHost->mGreen; break; case 7: c = mpHost->mLightYellow; break; case 8: c = mpHost->mYellow; break; case 9: c = mpHost->mLightBlue; break; case 10: c = mpHost->mBlue; break; case 11: c = mpHost->mLightMagenta; break; case 12: c = mpHost->mMagenta; break; case 13: c = mpHost->mLightCyan; break; case 14: c = mpHost->mCyan; break; case 15: c = mpHost->mLightWhite; break; case 16: c = mpHost->mWhite; break; } fgColorR = c.red(); fgColorG = c.green(); fgColorB = c.blue(); } else { if( tag < 232 ) { tag-=16; // because color 1-15 behave like normal ANSI colors // 6x6 RGB color space int r = tag / 36; int g = (tag-(r*36)) / 6; int b = (tag-(r*36))-(g*6); fgColorR = r*42; fgColorG = g*42; fgColorB = b*42; } else if( tag < 256 ) { // black + 23 tone grayscale from dark to light gray tag -= 232; fgColorR = tag*10; fgColorG = tag*10; fgColorB = tag*10; } else { //return invalid color error invalidColorCode = true; } } tag = ansiBg; if( tag <= 16 ) { QColor c; switch( tag ) { case 0: c = mpHost->mBgColor; break; case 1: c = mpHost->mLightBlack; break; case 2: c = mpHost->mBlack; break; case 3: c = mpHost->mLightRed; break; case 4: c = mpHost->mRed; break; case 5: c = mpHost->mLightGreen; break; case 6: c = mpHost->mGreen; break; case 7: c = mpHost->mLightYellow; break; case 8: c = mpHost->mYellow; break; case 9: c = mpHost->mLightBlue; break; case 10: c = mpHost->mBlue; break; case 11: c = mpHost->mLightMagenta; break; case 12: c = mpHost->mMagenta; break; case 13: c = mpHost->mLightCyan; break; case 14: c = mpHost->mCyan; break; case 15: c = mpHost->mLightWhite; break; case 16: c = mpHost->mWhite; break; } bgColorR = c.red(); bgColorG = c.green(); bgColorB = c.blue(); } else { if( tag < 232 ) { tag-=16; // because color 1-15 behave like normal ANSI colors // 6x6 RGB color space int r = tag / 36; int g = (tag-(r*36)) / 6; int b = (tag-(r*36))-(g*6); bgColorR = r*42; bgColorG = g*42; bgColorB = b*42; } else if( tag < 256 ) { // black + 23 tone grayscale from dark to light gray tag -= 232; bgColorR = tag*10; bgColorG = tag*10; bgColorB = tag*10; } else { //return invalid color error invalidColorCode = true; } } if( invalidColorCode ) return 0; TColorTable * pCT = new TColorTable; if( !pCT ) return 0; pCT->ansiBg = ansiBg; pCT->ansiFg = ansiFg; pCT->bgB = bgColorB; pCT->bgG = bgColorG; pCT->bgR = bgColorR; pCT->fgB = fgColorB; pCT->fgG = fgColorG; pCT->fgR = fgColorR; return pCT; } bool TTrigger::setupColorTrigger( int ansiFg, int ansiBg ) { TColorTable * pCT = createColorPattern( ansiFg, ansiBg ); if( ! pCT ) return false; mColorPatternList.push_back( pCT ); return true; } bool TTrigger::setupTmpColorTrigger( int ansiFg, int ansiBg ) { TColorTable * pCT = createColorPattern( ansiFg, ansiBg ); if( ! pCT ) return false; QString code; code = QString("FG%1BG%2").arg(ansiFg).arg(ansiBg); mRegexCodeList << code; mRegexCodePropertyList << REGEX_COLOR_PATTERN; mColorPatternList.push_back( pCT ); return true; } bool TTrigger::isFilterChain() { if( ( mRegexCodeList.size() > 0 ) && ( hasChildren() ) ) { return true; } else { return false; } } bool TTrigger::registerTrigger() { if( ! mpHost ) { return false; } return mpHost->getTriggerUnit()->registerTrigger(this); } void TTrigger::compileAll() { mNeedsToBeCompiled = true; if( ! compileScript() ) { if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::red))<<"ERROR: Lua compile error. compiling script of Trigger:"<>0;} mOK_code = false; } setRegexCodeList( mRegexCodeList, mRegexCodePropertyList ); typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TTrigger * pChild = *it; pChild->compileAll(); } } void TTrigger::compile() { if( mNeedsToBeCompiled ) { if( ! compileScript() ) { if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::red))<<"ERROR: Lua compile error. compiling script of Trigger:"<>0;} mOK_code = false; } } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TTrigger * pChild = *it; pChild->compile(); } } bool TTrigger::setScript( QString & script ) { mScript = script; mNeedsToBeCompiled = true; mOK_code = compileScript(); return mOK_code; } bool TTrigger::compileScript() { mFuncName = QString("Trigger")+QString::number( mID ); QString code = QString("function ")+ mFuncName + QString("()\n") + mScript + QString("\nend\n"); QString error; if( mpLua->compile( code, error ) ) { mNeedsToBeCompiled = false; mOK_code = true; return true; } else { mOK_code = false; setError( error ); return false; } } void TTrigger::execute() { if( mSoundTrigger ) { mudlet::self()->playSound( mSoundFile ); } if( mCommand.size() > 0 ) { mpHost->send( mCommand ); } if( mNeedsToBeCompiled ) { if( ! compileScript() ) { return; } } if( mIsMultiline ) { mpLua->callMulti( mFuncName, mName ); } else { mpLua->call( mFuncName, mName ); } } void TTrigger::enableTrigger( QString & name ) { if( mName == name ) { setIsActive( true ); } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TTrigger * pChild = *it; pChild->enableTrigger( name ); } } void TTrigger::disableTrigger( QString & name ) { if( mName == name ) { setIsActive( false ); } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TTrigger * pChild = *it; pChild->disableTrigger( name ); } } TTrigger * TTrigger::killTrigger( QString & name ) { if( mName == name ) { setIsActive( false ); } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TTrigger * pChild = *it; pChild->killTrigger( name ); } return 0; } bool TTrigger::serialize( QDataStream & ofs ) { ofs << mName; ofs << mScript; ofs << mRegexCodeList; ofs << mRegexCodePropertyList; ofs << mID; ofs << mIsFolder; ofs << mTriggerType; ofs << mIsTempTrigger; ofs << mIsMultiline; ofs << mConditionLineDelta; ofs << (qint64)mpMyChildrenList->size(); bool ret = true; typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TTrigger * pChild = *it; ret = pChild->serialize( ofs ); } return ret; } bool TTrigger::restore( QDataStream & ifs, bool initMode ) { ifs >> mName; ifs >> mScript; QStringList regexList; QList propertyList; ifs >> regexList; ifs >> propertyList; setRegexCodeList( regexList, propertyList ); ifs >> mID; ifs >> mIsFolder; ifs >> mTriggerType; ifs >> mIsTempTrigger; ifs >> mIsMultiline; ifs >> mConditionLineDelta; qint64 children; ifs >> children; mID = mpHost->getTriggerUnit()->getNewID(); //if( initMode ) qDebug()<<"TTrigger::restore() mName="< #include #include #include #include class Host; class TMap; class dlgMapper : public QWidget , public Ui::mapper { Q_OBJECT public: dlgMapper( QWidget *, Host *, TMap * ); void downloadMap(); void updateAreaComboBox(); TMap * mpMap; Host * mpHost; QNetworkAccessManager * mpDownloader; QProgressDialog * mpProgressDialog; QNetworkReply * mpReply; public slots: void slot_bubbles(); void slot_info(); void slot_toggleShowRoomIDs(int s); void slot_toggleStrongHighlight( int v ); void show2dView(); void slot_togglePanel(); void setDownloadProgress( qint64, qint64 ); void cancel(); void replyFinished( QNetworkReply * ); void goRoom(); void choseRoom( QListWidgetItem * ); void slot_roomSize(int d); void slot_lineSize(int d); }; #endif // DLGMAPPER_H mudlet-2.1/src/TLuaInterpreter.h0000644000175000017500000004647012076170616016230 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn KoehnHeiko@googlemail.com * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef LUA_INTERPRETER_H #define LUA_INTERPRETER_H #include #include #include #include #include #include #include #include extern "C" { #include #include #include } #include #include #include #include #include //#include "TTrigger.h" //#include "Host.h" #define SERVEROUTPUT 1 #define USERCOMMAND 2 #define PROMPT 3 #define RAWDATA 4 class TLuaMainThread; class TLuaThread; class TGatekeeperThread; class Host; class TTrigger; class TEvent; class TLuaInterpreter : public QThread { friend class TForkedProcess; Q_OBJECT public: TLuaInterpreter( Host * mpHost, int id ); void startLuaExecThread(); void threadLuaInterpreterExec( std::string code ); void initLuaGlobals(); bool call( QString & function, QString & mName ); bool callMulti( QString & function, QString & mName ); bool callConditionFunction( std::string & function, QString & mName ); bool call_luafunction( void * ); bool compile( QString & ); bool compile( QString & code, QString & error ); bool compileScript( QString & ); void setAtcpTable( QString &, QString & ); void setGMCPTable( QString &, QString & ); void setChannel102Table( int & var, int & arg ); bool compileAndExecuteScript( QString & ); void loadGlobal(); //void execLuaCode( QString code ); QString get_lua_string( QString & stringName ); int check_for_mappingscript( ); void set_lua_string( const QString & varName, QString & varValue ); void set_lua_table( QString & tableName, QStringList & variableList ); void setCaptureGroups( const std::list &, const std::list & ); void setMultiCaptureGroups( const std::list< std::list > & captureList, const std::list< std::list > & posList ); void startLuaSessionInterpreter(); void adjustCaptureGroups( int x, int a ); void clearCaptureGroups(); bool callEventHandler( QString & function, TEvent * pE ); int startTempTimer( double, QString & ); int startTempAlias( QString &, QString & ); int startTempTrigger( QString &, QString & ); int startTempBeginOfLineTrigger( QString &, QString & ); int startTempExactMatchTrigger( QString &, QString & ); int startTempLineTrigger( int, int, QString & ); int startTempRegexTrigger( QString &, QString & ); int startTempColorTrigger( int, int, QString & ); int startPermRegexTrigger( QString & name, QString & parent, QStringList & regex, QString & function ); int startPermSubstringTrigger( QString & name, QString & parent, QStringList & regex, QString & function ); int startPermBeginOfLineStringTrigger( QString & name, QString & parent, QStringList & regex, QString & function ); int startPermTimer( QString & name, QString & parent, double timeout, QString & function ); int startPermAlias( QString & name, QString & parent, QString & regex, QString & function ); TGatekeeperThread * mpGatekeeperThread; QNetworkAccessManager * mpFileDownloader; static int setMergeTables(lua_State * L); static int addSupportedTelnetOption( lua_State * ); static int setDoor( lua_State * ); static int getDoors( lua_State * ); static int setExitWeight( lua_State * ); static int getExitWeights( lua_State * ); static int uninstallPackage( lua_State * ); static int setMapZoom( lua_State * L ); static int createMapImageLabel( lua_State * ); static int exportAreaImage( lua_State * ); static int installPackage( lua_State * ); static int lockExit( lua_State * ); static int lockSpecialExit( lua_State * ); static int hasExitLock( lua_State * ); static int hasSpecialExitLock( lua_State * ); static int getMapLabels( lua_State * ); static int getMapLabel( lua_State * ); static int highlightRoom( lua_State * ); static int unHighlightRoom( lua_State * ); static int createMapLabel( lua_State * ); static int deleteMapLabel( lua_State * ); static int getRooms( lua_State * ); static int isLockedRoom( lua_State * ); static int connectToServer( lua_State *L ); static int sendIrc( lua_State * ); static int showUnzipProgress( lua_State * ); static int setAppStyleSheet( lua_State * ); static int setMainWindowSize( lua_State * L ); static int registerAnonymousEventHandler( lua_State * L ); static int setRoomChar( lua_State * ); static int getRoomChar( lua_State * ); static int deleteArea( lua_State * ); static int deleteRoom( lua_State * ); static int getRoomAreaName( lua_State * ); static int addAreaName( lua_State *L ); static int getRoomIDbyHash( lua_State *L ); static int setRoomIDbyHash( lua_State *L ); static int sendSocket( lua_State * L ); static int openUrl( lua_State * ); static int getRoomsByPosition( lua_State * ); static int getRoomEnv( lua_State * ); static int downloadFile( lua_State * ); static int setRoomUserData( lua_State * ); static int getRoomUserData( lua_State * ); static int searchRoomUserData( lua_State * ); static int clearRoomUserData( lua_State * ); static int addSpecialExit( lua_State * ); static int getSpecialExits( lua_State * ); static int getSpecialExitsSwap( lua_State * ); static int appendCmdLine( lua_State * ); static int clearSpecialExits( lua_State * ); static int solveRoomCollisions( lua_State * ); static int setGridMode( lua_State * L ); static int getCustomEnvColorTable( lua_State * L ); static int setRoomName( lua_State * ); static int getRoomName( lua_State * ); static int setRoomEnv( lua_State * ); static int setCustomEnvColor( lua_State * ); static int roomLocked( lua_State * ); static int setAreaName( lua_State * ); static int setRoomColor( lua_State * ); static int getRoomCoordinates( lua_State * ); static int setRoomCoordinates( lua_State * ); static int roomExists( lua_State * ); static int addRoom( lua_State * ); static int setExit( lua_State * ); static int createRoomID( lua_State * ); static int setRoomArea( lua_State * ); static int getRoomArea( lua_State * ); static int denyCurrentSend( lua_State * ); static int tempBeginOfLineTrigger( lua_State * ); static int tempExactMatchTrigger( lua_State * ); static int centerview( lua_State *L ); static int getAreaTable( lua_State *L ); static int getAreaTableSwap( lua_State *L ); static int getPath( lua_State * ); static int getAreaRooms( lua_State * ); static int clearCmdLine( lua_State * ); static int printCmdLine( lua_State * ); static int searchRoom( lua_State * ); static int resetProfile( lua_State * ); static int createMapper( lua_State * ); static int sendTelnetChannel102( lua_State *L ); static int isPrompt( lua_State * L ); static int feedTriggers( lua_State * ); static int Wait( lua_State * L ); static int Send( lua_State * L ); static int sendRaw( lua_State * L ); static int Echo( lua_State * L ); static int select( lua_State * L ); static int getMainConsoleWidth( lua_State * L ); static int selectSection( lua_State * L ); static int replace( lua_State * L ); static int deselect( lua_State * L ); static int getRoomExits( lua_State * L ); static int lockRoom( lua_State * L ); static int hasFocus( lua_State * L ); static int setFgColor( lua_State * L ); static int setBgColor( lua_State * L ); static int tempTimer( lua_State * L ); static int openUserWindow( lua_State * L ); static int echoUserWindow( lua_State * L ); static int clearUserWindow( lua_State * L ); static int enableTimer( lua_State * L ); static int disableTimer( lua_State * L ); static int killTimer( lua_State * L ); static int moveCursor( lua_State * L ); static int insertHTML( lua_State * L ); static int insertText( lua_State * L ); static int getLines( lua_State * L ); static int enableTrigger( lua_State * L ); static int disableTrigger( lua_State * L ); static int tempTrigger( lua_State * L ); static int tempRegexTrigger( lua_State * L ); static int tempButtonToolbar( lua_State * L ); static int tempButton( lua_State * L ); static int tempComplexRegexTrigger( lua_State * L ); static int killTrigger( lua_State * L ); static int getLineCount( lua_State * L ); static int getLineNumber( lua_State * L ); static int getColumnNumber( lua_State * L ); static int getBufferTable( lua_State * L ); static int getBufferLine( lua_State * L ); static int selectCaptureGroup( lua_State * L ); static int tempLineTrigger( lua_State * L ); static int raiseEvent( lua_State * L ); static int deleteLine( lua_State * L ); static int copy( lua_State * L ); static int cut( lua_State * L ); static int paste( lua_State * L ); static int pasteWindow( lua_State * L ); static int setRoomWeight( lua_State * L ); static int getRoomWeight( lua_State * L ); static int gotoRoom( lua_State * L ); static int setMapperView( lua_State * L ); static int enableKey( lua_State * ); static int disableKey( lua_State * ); static int debug( lua_State * L ); static int setWindowWrap( lua_State * ); static int setWindowWrapIndent( lua_State * ); static int reset( lua_State * ); static int moveCursorEnd( lua_State * ); static int getLastLineNumber( lua_State * ); static int getNetworkLatency( lua_State * ); static int appendBuffer( lua_State * ); static int createBuffer( lua_State * ); static int showUserWindow( lua_State * ); static int hideUserWindow( lua_State * ); static int closeUserWindow( lua_State * ); static int resizeUserWindow( lua_State * ); static int createStopWatch( lua_State * ); static int stopStopWatch( lua_State * ); static int getStopWatchTime( lua_State * ); static int startStopWatch( lua_State * ); static int resetStopWatch( lua_State * ); static int createMiniConsole( lua_State * ); static int createLabel( lua_State * ); static int moveWindow( lua_State * ); static int setTextFormat( lua_State * ); static int setBackgroundImage( lua_State * ); static int setBackgroundColor( lua_State * ); static int createButton( lua_State * ); static int setLabelClickCallback( lua_State * ); static int setLabelOnEnter( lua_State * ); static int setLabelOnLeave( lua_State * ); static int getMainWindowSize( lua_State * ); static int setMiniConsoleFontSize( lua_State * ); static int getCurrentLine( lua_State * ); static int selectCurrentLine( lua_State * ); static int spawn( lua_State * ); static int getButtonState( lua_State * ); static int showToolBar( lua_State * ); static int hideToolBar( lua_State * ); static int loadRawFile( lua_State * ); static int setBold( lua_State * ); static int setItalics( lua_State * ); static int setUnderline( lua_State * ); static int disconnect( lua_State * ); static int reconnect( lua_State * ); static int getMudletHomeDir( lua_State * ); static int setTriggerStayOpen( lua_State * ); static int wrapLine( lua_State * ); static int getFgColor( lua_State * ); static int getBgColor( lua_State * ); static int tempColorTrigger( lua_State * ); static int isAnsiFgColor( lua_State * ); static int isAnsiBgColor( lua_State * ); static int playSoundFile( lua_State * ); static int setBorderTop( lua_State * ); static int setBorderBottom( lua_State * ); static int setBorderLeft( lua_State * ); static int setBorderRight( lua_State * ); static int setBorderColor( lua_State * ); static int setConsoleBufferSize( lua_State * ); static int startLogging( lua_State *L ); static int calcFontWidth( int size ); static int calcFontHeight( int size ); static int calcFontSize( lua_State * ); static int permRegexTrigger( lua_State * ); static int permSubstringTrigger( lua_State * ); static int permTimer( lua_State * ); static int permAlias( lua_State * ); static int exists( lua_State * ); static int isActive( lua_State * ); static int tempAlias( lua_State * ); static int enableAlias( lua_State * ); static int disableAlias( lua_State * ); static int killAlias( lua_State * ); static int permBeginOfLineStringTrigger( lua_State * ); static int setLabelStyleSheet( lua_State * ); static int getTime( lua_State * ); static int invokeFileDialog( lua_State * ); static int getTimestamp( lua_State * ); static int setLink( lua_State * ); static int echoLink( lua_State * ); static int insertLink( lua_State * ); static int echoPopup( lua_State * ); static int insertPopup( lua_State * ); static int setPopup( lua_State * ); static int sendATCP( lua_State * ); static int sendGMCP( lua_State * ); static int saveMap( lua_State * L ); static int loadMap( lua_State * L ); static int setExitStub( lua_State * L ); static int connectExitStub( lua_State * L ); static int getExitStubs( lua_State * L ); static int getModulePriority( lua_State * L ); static int setModulePriority( lua_State * L ); static int updateMap(lua_State * L); static int addMapEvent(lua_State * L); static int removeMapEvent(lua_State * L); static int getMapEvents(lua_State * L); static int addMapMenu(lua_State * L); static int removeMapMenu(lua_State * L); static int getMapMenus(lua_State * L); std::list mCaptureGroupList; std::list mCaptureGroupPosList; std::list< std::list > mMultiCaptureGroupList; std::list< std::list > mMultiCaptureGroupPosList; void logError( std::string & e, QString &, QString & function ); static std::map luaInterpreterMap; QMap downloadMap; signals: void signalOpenUserWindow( int, QString ); void signalEchoUserWindow( int, QString, QString ); void signalClearUserWindow( int, QString ); void signalEnableTimer( int, QString ); void signalDisableTimer( int, QString ); void signalNewJob( QString ); void signalEchoMessage( int, QString ); void signalSelect( int, QString, int ); void signalSelectSection( int, int, int ); void signalReplace( int, QString ); void signalSetFgColor( int, int, int, int ); void signalSetBgColor( int, int, int, int ); void signalTempTimer( int, double, QString, QString ); void signalNewCommand( int, QString ); //signal of the lua thread unit command dispatcher for the main event loop to post events void signalNewLuaCodeToExecute( QString ); public slots: void replyFinished(QNetworkReply * reply ); void slotOpenUserWindow( int, QString ); void slotEchoUserWindow( int, QString, QString ); void slotClearUserWindow( int, QString ); void slotEnableTimer( int, QString ); void slotDisableTimer( int, QString ); void slotReplace( int, QString ); void slotEchoMessage( int, QString ); void slotNewCommand( int, QString ); void slotTempTimer( int hostID, double timeout, QString function, QString timerName ); void slotPurge(); void slotDeleteSender(); //void slotNewEcho(int,QString); //public: private: lua_State * getLuaExecutionUnit( int unit ); lua_State* pGlobalLua; TLuaMainThread * mpLuaSessionThread; Host * mpHost; int mHostID; //std::list mCaptureList; QList objectsToDelete; QTimer purgeTimer; lua_State * pGlobalLuaAliasExecutionUnit; lua_State * pGlobalLuaTriggerExecutionUnit; lua_State * pGlobalLuaGuiExecutionUnit; lua_State * pGlobalLuaScriptExecutionUnit; lua_State * pGlobalLuaTimerExecutionUnit; }; /* class TLuaThread : public QThread { public: TLuaThread( TLuaInterpreter * s){ rs=s; } void run(){ rs->threadRunLuaScript();} private: TLuaInterpreter * rs; }; */ class TLuaMainThread : public QThread { public: TLuaMainThread( TLuaInterpreter * pL ){ pLuaInterpreter = pL; } void run() { std::cout << "TLuaMainThread::run() called. Initializing Gatekeeper..."<initLuaGlobals(); exit=false; while( ! exit ) { if( ! mJobQueue.empty() ) { pLuaInterpreter->threadLuaInterpreterExec( getJob() ); } else { msleep(100); } } std::cout << "TLuaMainThread::run() done exit." << std::endl; } std::string getJob() { mutex.lock(); std::string job = mJobQueue.front(); mJobQueue.pop(); mutex.unlock(); return job; } void postJob(QString code) { std::cout << "posting new job <"<"< mJobQueue; bool exit; }; /* class TLuaTimer : public QThread { public: TLuaTimer( TLuaInterpreter * _rs, int _msec,int _session, QString _func, QString _p) { rs=_rs; msec = _msec; session = _session; function = _func; parameters = _p; } void run() { qDebug()<<"TLuaTimer::run() goingin to sleep for "<mpLuaSessionThread->postJob(code); qDebug()<<"TLuaTimer::run() exiting thread"; } private: TLuaInterpreter * rs; int msec; int session; QString function; QString parameters; }; */ #endif mudlet-2.1/src/en_US.dic0000644000175000017500000251750311513237311014451 0ustar csmallcsmall62118 0/nm 1/n1 2/nm 3/nm 4/nm 5/nm 6/nm 7/nm 8/nm 9/nm 0th/pt 1st/p 1th/tc 2nd/p 2th/tc 3rd/p 3th/tc 4th/pt 5th/pt 6th/pt 7th/pt 8th/pt 9th/pt a A AA AAA Aachen/M aardvark/SM Aaren/M Aarhus/M Aarika/M Aaron/M AB aback abacus/SM abaft Abagael/M Abagail/M abalone/SM abandoner/M abandon/LGDRS abandonment/SM abase/LGDSR abasement/S abaser/M abashed/UY abashment/MS abash/SDLG abate/DSRLG abated/U abatement/MS abater/M abattoir/SM Abba/M Abbe/M abb/S abbess/SM Abbey/M abbey/MS Abbie/M Abbi/M Abbot/M abbot/MS Abbott/M abbr abbrev abbreviated/UA abbreviates/A abbreviate/XDSNG abbreviating/A abbreviation/M Abbye/M Abby/M ABC/M Abdel/M abdicate/NGDSX abdication/M abdomen/SM abdominal/YS abduct/DGS abduction/SM abductor/SM Abdul/M ab/DY abeam Abelard/M Abel/M Abelson/M Abe/M Aberdeen/M Abernathy/M aberrant/YS aberrational aberration/SM abet/S abetted abetting abettor/SM Abeu/M abeyance/MS abeyant Abey/M abhorred abhorrence/MS abhorrent/Y abhorrer/M abhorring abhor/S abidance/MS abide/JGSR abider/M abiding/Y Abidjan/M Abie/M Abigael/M Abigail/M Abigale/M Abilene/M ability/IMES abjection/MS abjectness/SM abject/SGPDY abjuration/SM abjuratory abjurer/M abjure/ZGSRD ablate/VGNSDX ablation/M ablative/SY ablaze abler/E ables/E ablest able/U abloom ablution/MS Ab/M ABM/S abnegate/NGSDX abnegation/M Abner/M abnormality/SM abnormal/SY aboard abode/GMDS abolisher/M abolish/LZRSDG abolishment/MS abolitionism/SM abolitionist/SM abolition/SM abominable abominably abominate/XSDGN abomination/M aboriginal/YS aborigine/SM Aborigine/SM aborning abortionist/MS abortion/MS abortiveness/M abortive/PY abort/SRDVG Abo/SM! abound/GDS about/S aboveboard aboveground above/S abracadabra/S abrader/M abrade/SRDG Abraham/M Abrahan/M Abra/M Abramo/M Abram/SM Abramson/M Abran/M abrasion/MS abrasiveness/S abrasive/SYMP abreaction/MS abreast abridge/DSRG abridged/U abridger/M abridgment/SM abroad abrogate/XDSNG abrogation/M abrogator/SM abruptness/SM abrupt/TRYP ABS abscess/GDSM abscissa/SM abscission/SM absconder/M abscond/SDRZG abseil/SGDR absence/SM absenteeism/SM absentee/MS absentia/M absentmindedness/S absentminded/PY absent/SGDRY absinthe/SM abs/M absoluteness/SM absolute/NPRSYTX absolution/M absolutism/MS absolutist/SM absolve/GDSR absolver/M absorb/ASGD absorbed/U absorbency/MS absorbent/MS absorber/SM absorbing/Y absorption/MS absorptive absorptivity/M abstainer/M abstain/GSDRZ abstemiousness/MS abstemious/YP abstention/SM abstinence/MS abstinent/Y abstractedness/SM abstracted/YP abstracter/M abstractionism/M abstractionist/SM abstraction/SM abstractness/SM abstractor/MS abstract/PTVGRDYS abstruseness/SM abstruse/PRYT absurdity/SM absurdness/SM absurd/PRYST Abuja abundance/SM abundant/Y abused/E abuse/GVZDSRB abuser/M abuses/E abusing/E abusiveness/SM abusive/YP abut/LS abutment/SM abutted abutter/MS abutting abuzz abysmal/Y abyssal Abyssinia/M Abyssinian abyss/SM AC acacia/SM academe/MS academia/SM academical/Y academicianship academician/SM academic/S academy/SM Acadia/M acanthus/MS Acapulco/M accede/SDG accelerated/U accelerate/NGSDXV accelerating/Y acceleration/M accelerator/SM accelerometer/SM accented/U accent/SGMD accentual/Y accentuate/XNGSD accentuation/M acceptability/SM acceptability's/U acceptableness/SM acceptable/P acceptably/U acceptance/SM acceptant acceptation/SM accepted/Y accepter/M accepting/PY acceptor/MS accept/RDBSZVG accessed/A accessibility/IMS accessible/IU accessibly/I accession/SMDG accessors accessory/SM access/SDMG accidence/M accidentalness/M accidental/SPY accident/MS acclaimer/M acclaim/SDRG acclamation/MS acclimate/XSDGN acclimation/M acclimatisation acclimatise/DG acclimatization/AMS acclimatized/U acclimatize/RSDGZ acclimatizes/A acclivity/SM accolade/GDSM accommodated/U accommodate/XVNGSD accommodating/Y accommodation/M accommodativeness/M accommodative/P accompanied/U accompanier/M accompaniment/MS accompanist/SM accompany/DRSG accomplice/MS accomplished/U accomplisher/M accomplishment/SM accomplish/SRDLZG accordance/SM accordant/Y accorder/M according/Y accordionist/SM accordion/MS accord/SZGMRD accost/SGD accountability/MS accountability's/U accountableness/M accountable/U accountably/U accountancy/SM accountant/MS account/BMDSGJ accounted/U accounting/M accouter/GSD accouterments accouterment's accoutrement/M Accra/M accreditation/SM accredited/U accredit/SGD accretion/SM accrual/MS accrue/SDG acct acculturate/XSDVNG acculturation/M accumulate/VNGSDX accumulation/M accumulativeness/M accumulative/YP accumulator/MS accuracy/IMS accurate/IY accurateness/SM accursedness/SM accursed/YP accusal/M accusation/SM accusative/S accusatory accused/M accuser/M accuse/SRDZG accusing/Y accustomedness/M accustomed/P accustom/SGD ac/DRG aced/M acerbate/DSG acerbic acerbically acerbity/MS ace/SM acetaminophen/S acetate/MS acetic acetone/SM acetonic acetylene/MS Acevedo/M Achaean/M Achebe/M ached/A ache/DSG achene/SM Achernar/M aches/A Acheson/M achievable/U achieved/UA achieve/LZGRSDB achievement/SM achiever/M Achilles aching/Y achoo achromatic achy/TR acidic acidification/M acidify/NSDG acidity/SM acidness/M acidoses acidosis/M acid/SMYP acidulous acing/M Ackerman/M acknowledgeable acknowledgedly acknowledged/U acknowledge/GZDRS acknowledger/M acknowledgment/SAM ACLU Ac/M ACM acme/SM acne/MDS acolyte/MS Aconcagua/M aconite/MS acorn/SM Acosta/M acoustical/Y acoustician/M acoustic/S acoustics/M acquaintance/MS acquaintanceship/S acquainted/U acquaint/GASD acquiesce/GSD acquiescence/SM acquiescent/Y acquirable acquire/ASDG acquirement/SM acquisition's/A acquisition/SM acquisitiveness/MS acquisitive/PY acquit/S acquittal/MS acquittance/M acquitted acquitter/M acquitting acreage/MS acre/MS acridity/MS acridness/SM acrid/TPRY acrimoniousness/MS acrimonious/YP acrimony/MS acrobatically acrobatic/S acrobatics/M acrobat/SM acronym/SM acrophobia/SM Acropolis/M acropolis/SM across acrostic/SM Acrux/M acrylate/M acrylic/S ACT Actaeon/M Acta/M ACTH acting/S actinic actinide/SM actinium/MS actinometer/MS action/DMSGB actions/AI action's/IA activate/AXCDSNGI activated/U activation/AMCI activator/SM active/APY actively/I activeness/MS actives activism/MS activist/MS activities/A activity/MSI Acton/M actor/MAS actress/SM act's Acts act/SADVG actuality/SM actualization/MAS actualize/GSD actualizes/A actual/SY actuarial/Y actuary/MS actuate/GNXSD actuation/M actuator/SM acuity/MS acumen/SM acupressure/S acupuncture/SM acupuncturist/S acuteness/MS acute/YTSRP acyclic acyclically acyclovir/S AD adage/MS adagio/S Adah/M Adair/M Adaline/M Ada/M adamant/SY Adamo/M Adam/SM Adamson/M Adana/M Adan/M adaptability/MS adaptable/U adaptation/MS adaptedness/M adapted/P adapter/M adapting/A adaption adaptively adaptiveness/M adaptive/U adaptivity adapt/SRDBZVG Adara/M ad/AS ADC Adda/M Addams addenda addend/SM addendum/M adder/M Addia/M addiction/MS addictive/P addict/SGVD Addie/M Addi/M Addison/M additional/Y addition/MS additive/YMS additivity addle/GDS addressability addressable/U addressed/A addressee/SM addresser/M addresses/A address/MDRSZGB Addressograph/M adduce/GRSD adducer/M adduct/DGVS adduction/M adductor/M Addy/M add/ZGBSDR Adelaida/M Adelaide/M Adela/M Adelbert/M Adele/M Adelheid/M Adelice/M Adelina/M Adelind/M Adeline/M Adella/M Adelle/M Adel/M Ade/M Adena/M Adenauer/M adenine/SM Aden/M adenoidal adenoid/S adeptness/MS adept/RYPTS adequacy/IMS adequate/IPY adequateness's/I adequateness/SM Adey/M Adham/M Adhara/M adherence/SM adherent/YMS adherer/M adhere/ZGRSD adhesion/MS adhesiveness/MS adhesive/PYMS adiabatic adiabatically Adiana/M Adidas/M adieu/S Adi/M Adina/M adis adipose/S Adirondack/SM adj adjacency/MS adjacent/Y adjectival/Y adjective/MYS adjoin/SDG adjoint/M adjourn/DGLS adjournment/SM adjudge/DSG adjudicate/VNGXSD adjudication/M adjudicator/SM adjudicatory adjunct/VSYM adjuration/SM adjure/GSD adjustable/U adjustably adjust/DRALGSB adjusted/U adjuster's/A adjuster/SM adjustive adjustment/MAS adjustor's adjutant/SM Adkins/M Adlai/M Adler/M adman/M admen administer/GDJS administrable administrate/XSDVNG administration/M administrative/Y administrator/MS administratrix/M admirableness/M admirable/P admirably admiral/SM admiralty/MS Admiralty/S admiration/MS admirer/M admire/RSDZBG admiring/Y admissibility/ISM admissible/I admissibly admission/AMS admit/AS admittance/MS admitted/A admittedly admitting/A admix/SDG admixture/SM Adm/M Ad/MN admonisher/M admonish/GLSRD admonishing/Y admonishment/SM admonition/MS admonitory adobe/MS adolescence/MS adolescent/SYM Adolf/M Adolfo/M Adolphe/M Adolph/M Adolpho/M Adolphus/M Ado/M ado/MS Adonis/SM adopted/AU adopter/M adoption/MS adoptive/Y adopt/RDSBZVG adopts/A adorableness/SM adorable/P adorably Adora/M adoration/SM adore/DSRGZB Adoree/M Adore/M adorer/M adoring/Y adorned/U Adorne/M adornment/SM adorn/SGLD ADP Adrea/M adrenalin adrenaline/MS Adrenalin/MS adrenal/YS Adria/MX Adriana/M Adriane/M Adrian/M Adrianna/M Adrianne/M Adriano/M Adriatic Adriena/M Adrien/M Adrienne/M adrift adroitness/MS adroit/RTYP ads ad's adsorbate/M adsorbent/S adsorb/GSD adsorption/MS adsorptive/Y adulate/GNDSX adulation/M adulator/SM adulatory adulterant/SM adulterated/U adulterate/NGSDX adulteration/M adulterer/SM adulteress/MS adulterous/Y adultery/SM adulthood/MS adult/MYPS adultness/M adumbrate/XSDVGN adumbration/M adumbrative/Y adv advance/DSRLZG advancement/MS advancer/M advantage/GMEDS advantageous/EY advantageousness/M Adventist/M adventist/S adventitiousness/M adventitious/PY adventive/Y Advent/SM advent/SVM adventurer/M adventuresome adventure/SRDGMZ adventuress/SM adventurousness/SM adventurous/YP adverbial/MYS adverb/SM adversarial adversary/SM adverse/DSRPYTG adverseness/MS adversity/SM advert/GSD advertised/U advertise/JGZSRDL advertisement/SM advertiser/M advertising/M advertorial/S advice/SM Advil/M advisability/SIM advisable/I advisableness/M advisably advisedly/I advised/YU advisee/MS advisement/MS adviser/M advise/ZRSDGLB advisor/S advisor's advisory/S advocacy/SM advocate/NGVDS advocation/M advt adze's adz/MDSG Aegean aegis/SM Aelfric/M Aeneas Aeneid/M aeolian Aeolus/M aeon's aerate/XNGSD aeration/M aerator/MS aerialist/MS aerial/SMY Aeriela/M Aeriell/M Aeriel/M aerie/SRMT aeroacoustic aerobatic/S aerobically aerobic/S aerodrome/SM aerodynamically aerodynamic/S aerodynamics/M aeronautical/Y aeronautic/S aeronautics/M aerosolize/D aerosol/MS aerospace/SM Aeschylus/M Aesculapius/M Aesop/M aesthete/S aesthetically aestheticism/MS aesthetics/M aesthetic/U aether/M aetiology/M AF AFAIK afar/S AFB AFC AFDC affability/MS affable/TR affably affair/SM affectation/MS affectedness/EM affected/UEYP affect/EGSD affecter/M affecting/Y affectionate/UY affectioned affection/EMS affectioning affective/MY afferent/YS affiance/GDS affidavit/SM affiliated/U affiliate/EXSDNG affiliation/EM affine affinity/SM affirm/ASDG affirmation/SAM affirmative/SY affix/SDG afflatus/MS afflict/GVDS affliction/SM afflictive/Y affluence/SM affluent/YS afford/DSBG afforest/A afforestation/SM afforested afforesting afforests affray/MDSG affricate/VNMS affrication/M affricative/M affright affront/GSDM Afghani/SM Afghanistan/M afghan/MS Afghan/SM aficionado/MS afield afire aflame afloat aflutter afoot afore aforementioned aforesaid aforethought/S afoul Afr afraid/U afresh Africa/M African/MS Afrikaans/M Afrikaner/SM afro Afrocentric Afrocentrism/S Afro/MS afterbirth/M afterbirths afterburner/MS aftercare/SM aftereffect/MS afterglow/MS afterimage/MS afterlife/M afterlives aftermath/M aftermaths aftermost afternoon/SM aftershave/S aftershock/SM afters/M aftertaste/SM afterthought/MS afterward/S afterworld/MS Afton/M aft/ZR Agace/M again against Agamemnon/M agapae agape/S agar/MS Agassiz/M Agata/M agate/SM Agatha/M Agathe/M agave/SM agedness/M aged/PY age/GJDRSMZ ageism/S ageist/S agelessness/MS ageless/YP agency/SM agenda/MS agent/AMS agented agenting agentive ageratum/M Aggie/M Aggi/M agglomerate/XNGVDS agglomeration/M agglutinate/VNGXSD agglutination/M agglutinin/MS aggrandize/LDSG aggrandizement/SM aggravate/SDNGX aggravating/Y aggravation/M aggregated/U aggregate/EGNVD aggregately aggregateness/M aggregates aggregation/SM aggregative/Y aggression/SM aggressively aggressiveness/S aggressive/U aggressor/MS aggrieved/Y aggrieve/GDS Aggy/SM aghast agile/YTR agility/MS agitated/Y agitate/XVNGSD agitation/M agitator/SM agitprop/MS Aglaia/M agleam aglitter aglow Ag/M Agna/M Agnella/M Agnese/M Agnes/M Agnesse/M Agneta/M Agnew/M Agni/M Agnola/M agnosticism/MS agnostic/SM ago agog agonizedly/S agonized/Y agonize/ZGRSD agonizing/Y agony/SM agoraphobia/MS agoraphobic/S Agosto/M Agra/M agrarianism/MS agrarian/S agreeable/EP agreeableness/SME agreeably/E agreeing/E agree/LEBDS agreement/ESM agreer/S Agretha/M agribusiness/SM Agricola/M agriculturalist/S agricultural/Y agriculture/MS agriculturist/SM Agrippa/M Agrippina/M agrochemicals agronomic/S agronomist/SM agronomy/MS aground Aguascalientes/M ague/MS Aguie/M Aguilar/M Aguinaldo/M Aguirre/M Aguistin/M Aguste/M Agustin/M ah Ahab/M Aharon/M aha/S ahead ahem/S Ahmadabad Ahmad/M Ahmed/M ahoy/S Ahriman/M AI Aida/M Aidan/M aided/U aide/MS aider/M AIDS aid/ZGDRS Aigneis/M aigrette/SM Aiken/M Aila/M Ailbert/M Ailee/M Aileen/M Aile/M Ailene/M aileron/MS Ailey/M Ailina/M Aili/SM ail/LSDG ailment/SM Ailsun/M Ailyn/M Aimee/M Aime/M aimer/M Aimil/M aimlessness/MS aimless/YP aim/ZSGDR Aindrea/M Ainslee/M Ainsley/M Ainslie/M ain't Ainu/M airbag/MS airbase/S airborne airbrush/SDMG Airbus/M airbus/SM aircraft/MS aircrew/M airdrop/MS airdropped airdropping Airedale/SM Aires airfare/S airfield/MS airflow/SM airfoil/MS airframe/MS airfreight/SGD airhead/MS airily airiness/MS airing/M airlessness/S airless/P airlift/MDSG airliner/M airline/SRMZ airlock/MS airmail/DSG airman/M airmass air/MDRTZGJS airmen airpark airplane/SM airplay/S airport/MS airship/MS airsickness/SM airsick/P airspace/SM airspeed/SM airstrip/MS airtightness/M airtight/P airtime airwaves airway/SM airworthiness/SM airworthy/PTR airy/PRT Aisha/M aisle/DSGM aitch/MS ajar Ajax/M Ajay/M AK aka Akbar/M Akihito/M akimbo Akim/M akin Akita/M Akkad/M Akron/M Aksel/M AL Alabama/M Alabaman/S Alabamian/MS alabaster/MS alack/S alacrity/SM Aladdin/M Alaine/M Alain/M Alair/M Alameda/M Alamogordo/M Alamo/SM ala/MS Ala/MS Alanah/M Alana/M Aland/M Alane/M alanine/M Alan/M Alanna/M Alano/M Alanson/M Alard/M Alaric/M Alar/M alarming/Y alarmist/MS alarm/SDG Alasdair/M Alaska/M Alaskan/S alas/S Alastair/M Alasteir/M Alaster/M Alayne/M albacore/SM alba/M Alba/M Albania/M Albanian/SM Albany/M albatross/SM albedo/M Albee/M albeit Alberich/M Alberik/M Alberio/M Alberta/M Albertan/S Albertina/M Albertine/M Albert/M Alberto/M Albie/M Albigensian Albina/M albinism/SM albino/MS Albion/M Albireo/M alb/MS Albrecht/M albumen/M albumin/MS albuminous album/MNXS Albuquerque/M Alcatraz/M Alcestis/M alchemical alchemist/SM alchemy/MS Alcibiades/M Alcmena/M Alcoa/M alcoholically alcoholic/MS alcoholism/SM alcohol/MS Alcott/M alcove/MSD Alcuin/M Alcyone/M Aldan/M Aldebaran/M aldehyde/M Alden/M Alderamin/M alderman/M aldermen alder/SM alderwoman alderwomen Aldin/M Aldis/M Aldo/M Aldon/M Aldous/M Aldrich/M Aldric/M Aldridge/M Aldrin/M Aldus/M Aldwin/M aleatory Alecia/M Aleck/M Alec/M Aleda/M alee Aleece/M Aleen/M alehouse/MS Aleichem/M Alejandra/M Alejandrina/M Alejandro/M Alejoa/M Aleksandr/M Alembert/M alembic/SM ale/MVS Alena/M Alene/M aleph/M Aleppo/M Aler/M alerted/Y alertness/MS alert/STZGPRDY Alessandra/M Alessandro/M Aleta/M Alethea/M Aleutian/S Aleut/SM alewife/M alewives Alexa/M Alexander/SM Alexandra/M Alexandre/M Alexandria/M Alexandrian/S Alexandrina/M Alexandr/M Alexandro/MS Alexei/M Alexia/M Alexina/M Alexine/M Alexio/M Alexi/SM Alex/M alfalfa/MS Alfa/M Alfie/M Alfi/M Alf/M Alfonse/M Alfons/M Alfonso/M Alfonzo/M Alford/M Alfreda/M Alfred/M Alfredo/M alfresco Alfy/M algae algaecide algal alga/M algebraic algebraical/Y algebraist/M algebra/MS Algenib/M Algeria/M Algerian/MS Alger/M Algernon/M Algieba/M Algiers/M alginate/SM ALGOL Algol/M Algonquian/SM Algonquin/SM algorithmic algorithmically algorithm/MS Alhambra/M Alhena/M Alia/M alias/GSD alibi/MDSG Alica/M Alicea/M Alice/M Alicia/M Alick/M Alic/M Alida/M Alidia/M Alie/M alienable/IU alienate/SDNGX alienation/M alienist/MS alien/RDGMBS Alighieri/M alight/DSG aligned/U aligner/SM align/LASDG alignment/SAM Alika/M Alikee/M alikeness/M alike/U alimentary aliment/SDMG alimony/MS Ali/MS Alina/M Aline/M alinement's Alioth/M aliquot/S Alisa/M Alisander/M Alisha/M Alison/M Alissa/M Alistair/M Alister/M Alisun/M aliveness/MS alive/P Alix/M aliyah/M aliyahs Aliza/M Alkaid/M alkalies alkali/M alkaline alkalinity/MS alkalize/SDG alkaloid/MS alkyd/S alkyl/M Allahabad/M Allah/M Alla/M Allan/M Allard/M allay/GDS Allayne/M Alleen/M allegation/SM alleged/Y allege/SDG Allegheny/MS allegiance/SM allegiant allegoric allegoricalness/M allegorical/YP allegorist/MS allegory/SM Allegra/M allegretto/MS allegri allegro/MS allele/SM alleluia/S allemande/M Allendale/M Allende/M Allene/M Allen/M Allentown/M allergenic allergen/MS allergic allergically allergist/MS allergy/MS alleviate/SDVGNX alleviation/M alleviator/MS Alley/M alley/MS Alleyn/M alleyway/MS Allhallows alliance/MS Allianora/M Allie/M allier allies/M alligator/DMGS Alli/MS Allina/M Allin/M Allison/M Allissa/M Allister/M Allistir/M alliterate/XVNGSD alliteration/M alliterative/Y Allix/M allocable/U allocatable allocate/ACSDNGX allocated/U allocation/AMC allocative allocator/AMS allophone/MS allophonic allotment/MS allotments/A allotrope/M allotropic allots/A allot/SDL allotted/A allotter/M allotting/A allover/S allowableness/M allowable/P allowably allowance/GSDM allowed/Y allowing/E allow/SBGD allows/E alloyed/U alloy/SGMD all/S allspice/MS Allstate/M Allsun/M allude/GSD allure/GLSD allurement/SM alluring/Y allusion/MS allusiveness/MS allusive/PY alluvial/S alluvions alluvium/MS Allx/M ally/ASDG Allyce/M Ally/MS Allyn/M Allys Allyson/M alma Almach/M Almaden/M almagest Alma/M almanac/MS Almaty/M Almeda/M Almeria/M Almeta/M almightiness/M Almighty/M almighty/P Almira/M Almire/M almond/SM almoner/MS almost Al/MRY alms/A almshouse/SM almsman/M alnico Alnilam/M Alnitak/M aloe/MS aloft aloha/SM Aloin/M Aloise/M Aloisia/M aloneness/M alone/P along alongshore alongside Alon/M Alonso/M Alonzo/M aloofness/MS aloof/YP aloud Aloysia/M Aloysius/M alpaca/SM Alpert/M alphabetical/Y alphabetic/S alphabetization/SM alphabetizer/M alphabetize/SRDGZ alphabet/SGDM alpha/MS alphanumerical/Y alphanumeric/S Alphard/M Alphecca/M Alpheratz/M Alphonse/M Alphonso/M Alpine alpine/S alp/MS Alps already Alric/M alright Alsace/M Alsatian/MS also Alsop/M Alston/M Altaic/M Altai/M Altair/M Alta/M altar/MS altarpiece/SM alterable/UI alteration/MS altercate/NX altercation/M altered/U alternate/SDVGNYX alternation/M alternativeness/M alternative/YMSP alternator/MS alter/RDZBG Althea/M although altimeter/SM Altiplano/M altitude/SM altogether/S Alton/M alto/SM Altos/M altruism/SM altruistic altruistically altruist/SM alt/RZS ALU Aludra/M Aluin/M Aluino/M alumina/SM aluminum/MS alumnae alumna/M alumni alumnus/MS alum/SM alundum Alva/M Alvan/M Alvarado/M Alvarez/M Alvaro/M alveolar/Y alveoli alveolus/M Alvera/M Alverta/M Alvie/M Alvina/M Alvinia/M Alvin/M Alvira/M Alvis/M Alvy/M alway/S Alwin/M Alwyn/M Alyce/M Alyda/M Alyosha/M Alysa/M Alyse/M Alysia/M Alys/M Alyson/M Alyss Alyssa/M Alzheimer/M AM AMA Amabelle/M Amabel/M Amadeus/M Amado/M amain Amalea/M Amalee/M Amaleta/M amalgamate/VNGXSD amalgamation/M amalgam/MS Amalia/M Amalie/M Amalita/M Amalle/M Amanda/M Amandie/M Amandi/M Amandy/M amanuenses amanuensis/M Amara/M amaranth/M amaranths amaretto/S Amargo/M Amarillo/M amaryllis/MS am/AS amasser/M amass/GRSD Amata/M amateurishness/MS amateurish/YP amateurism/MS amateur/SM Amati/M amatory amazed/Y amaze/LDSRGZ amazement/MS amazing/Y amazonian Amazonian amazon/MS Amazon/SM ambassadorial ambassador/MS ambassadorship/MS ambassadress/SM ambergris/SM Amberly/M amber/MS Amber/YM ambiance/MS ambidexterity/MS ambidextrous/Y ambience's ambient/S ambiguity/MS ambiguously/U ambiguousness/M ambiguous/YP ambition/GMDS ambitiousness/MS ambitious/PY ambit/M ambivalence/SM ambivalent/Y amble/GZDSR Amble/M ambler/M ambrose Ambrose/M ambrosial/Y ambrosia/SM Ambrosi/M Ambrosio/M Ambrosius/M Ambros/M ambulance/MS ambulant/S ambulate/DSNGX ambulation/M ambulatory/S Ambur/M ambuscade/MGSRD ambuscader/M ambusher/M ambush/MZRSDG Amby/M Amdahl/M ameba's Amelia/M Amelie/M Amelina/M Ameline/M ameliorate/XVGNSD amelioration/M Amelita/M amenability/SM amenably amended/U amender/M amendment/SM amen/DRGTSB amend/SBRDGL amends/M Amenhotep/M amenity/MS amenorrhea/M Amerada/M Amerasian/S amercement/MS amerce/SDLG Americana/M Americanism/SM Americanization/SM americanized Americanize/SDG American/MS America/SM americium/MS Amerigo/M Amerindian/MS Amerind/MS Amer/M Amery/M Ameslan/M Ame/SM amethystine amethyst/MS Amharic/M Amherst/M amiability/MS amiableness/M amiable/RPT amiably amicability/SM amicableness/M amicable/P amicably amide/SM amid/S amidships amidst Amie/M Amiga/M amigo/MS Amii/M Amil/M Ami/M amines aminobenzoic amino/M amir's Amish amiss Amitie/M Amity/M amity/SM Ammamaria/M Amman/M Ammerman/M ammeter/MS ammo/MS ammoniac ammonia/MS ammonium/M Am/MR ammunition/MS amnesiac/MS amnesia/SM amnesic/S amnesty/GMSD amniocenteses amniocentesis/M amnion/SM amniotic Amoco/M amoeba/SM amoebic amoeboid amok/MS among amongst Amontillado/M amontillado/MS amorality/MS amoral/Y amorousness/SM amorous/PY amorphousness/MS amorphous/PY amortization/SUM amortized/U amortize/SDG Amory/M Amos amount/SMRDZG amour/MS Amparo/M amperage/SM Ampere/M ampere/MS ampersand/MS Ampex/M amphetamine/MS amphibian/SM amphibiousness/M amphibious/PY amphibology/M amphitheater/SM amphorae amphora/M ampleness/M ample/PTR amplification/M amplifier/M amplify/DRSXGNZ amplitude/MS ampoule's amp/SGMDY ampule/SM amputate/DSNGX amputation/M amputee/SM Amritsar/M ams Amsterdam/M amt Amtrak/M amuck's amulet/SM Amundsen/M Amur/M amused/Y amuse/LDSRGVZ amusement/SM amuser/M amusingness/M amusing/YP Amway/M Amye/M amylase/MS amyl/M Amy/M Anabal/M Anabaptist/SM Anabella/M Anabelle/M Anabel/M anabolic anabolism/MS anachronism/SM anachronistic anachronistically Anacin/M anaconda/MS Anacreon/M anaerobe/SM anaerobic anaerobically anaglyph/M anagrammatic anagrammatically anagrammed anagramming anagram/MS Anaheim/M Analects/M analgesia/MS analgesic/S Analiese/M Analise/M Anallese/M Anallise/M analogical/Y analogize/SDG analogousness/MS analogous/YP analog/SM analogue/SM analogy/MS anal/Y analysand/MS analyses analysis/AM analyst/SM analytical/Y analyticity/S analytic/S analytics/M analyzable/U analyze/DRSZGA analyzed/U analyzer/M Ana/M anamorphic Ananias/M anapaest's anapestic/S anapest/SM anaphora/M anaphoric anaphorically anaplasmosis/M anarchic anarchical/Y anarchism/MS anarchistic anarchist/MS anarchy/MS Anastasia/M Anastasie/M Anastassia/M anastigmatic anastomoses anastomosis/M anastomotic anathema/MS anathematize/GSD Anatola/M Anatole/M Anatolia/M Anatolian Anatollo/M Anatol/M anatomic anatomical/YS anatomist/MS anatomize/GSD anatomy/MS Anaxagoras/M Ancell/M ancestor/SMDG ancestral/Y ancestress/SM ancestry/SM Anchorage/M anchorage/SM anchored/U anchorite/MS anchoritism/M anchorman/M anchormen anchorpeople anchorperson/S anchor/SGDM anchorwoman anchorwomen anchovy/MS ancientness/MS ancient/SRYTP ancillary/S an/CS Andalusia/M Andalusian Andaman andante/S and/DZGS Andean/M Andeee/M Andee/M Anderea/M Andersen/M Anders/N Anderson/M Andes Andie/M Andi/M andiron/MS Andonis/M Andorra/M Andover/M Andra/SM Andrea/MS Andreana/M Andree/M Andrei/M Andrej/M Andre/SM Andrew/MS Andrey/M Andria/M Andriana/M Andriette/M Andris androgenic androgen/SM androgynous androgyny/SM android/MS Andromache/M Andromeda/M Andropov/M Andros/M Andrus/M Andy/M anecdotal/Y anecdote/SM anechoic anemia/SM anemically anemic/S anemometer/MS anemometry/M anemone/SM anent aneroid Anestassia/M anesthesia/MS anesthesiologist/MS anesthesiology/SM anesthetically anesthetic/SM anesthetist/MS anesthetization/SM anesthetizer/M anesthetize/ZSRDG Anet/M Anetta/M Anette/M Anett/M aneurysm/MS anew Angara/M Angela/M Angeleno/SM Angele/SM angelfish/SM Angelia/M angelic angelical/Y Angelica/M angelica/MS Angelico/M Angelika/M Angeli/M Angelina/M Angeline/M Angelique/M Angelita/M Angelle/M Angel/M angel/MDSG Angelo/M Angelou/M Ange/M anger/GDMS Angevin/M Angie/M Angil/M angina/MS angiography angioplasty/S angiosperm/MS Angkor/M angle/GMZDSRJ angler/M Angles angleworm/MS Anglia/M Anglicanism/MS Anglican/MS Anglicism/SM Anglicization/MS anglicize/SDG Anglicize/SDG angling/M Anglo/MS Anglophile/SM Anglophilia/M Anglophobe/MS Anglophobia/M Angola/M Angolan/S angora/MS Angora/MS angrily angriness/M angry/RTP angst/MS ngstrm/M angstrom/MS Anguilla/M anguish/DSMG angularity/MS angular/Y Angus/M Angy/M Anheuser/M anhydride/M anhydrite/M anhydrous/Y Aniakchak/M Ania/M Anibal/M Anica/M aniline/SM animadversion/SM animadvert/DSG animalcule/MS animal/MYPS animated/A animatedly animately/I animateness/MI animates/A animate/YNGXDSP animating/A animation/AMS animator/SM animism/SM animistic animist/S animized animosity/MS animus/SM anionic/S anion/MS aniseed/MS aniseikonic anise/MS anisette/SM anisotropic anisotropy/MS Anissa/M Anita/M Anitra/M Anjanette/M Anjela/M Ankara/M ankh/M ankhs anklebone/SM ankle/GMDS anklet/MS Annabal/M Annabela/M Annabella/M Annabelle/M Annabell/M Annabel/M Annadiana/M Annadiane/M Annalee/M Annaliese/M Annalise/M annalist/MS annal/MNS Anna/M Annamaria/M Annamarie/M Annapolis/M Annapurna/M anneal/DRSZG annealer/M Annecorinne/M annelid/MS Anneliese/M Annelise/M Anne/M Annemarie/M Annetta/M Annette/M annexation/SM annexe/M annex/GSD Annice/M Annie/M annihilate/XSDVGN annihilation/M annihilator/MS Anni/MS Annissa/M anniversary/MS Ann/M Annmaria/M Annmarie/M Annnora/M Annora/M annotated/U annotate/VNGXSD annotation/M annotator/MS announced/U announcement/SM announcer/M announce/ZGLRSD annoyance/MS annoyer/M annoying/Y annoy/ZGSRD annualized annual/YS annuitant/MS annuity/MS annular/YS annuli annulled annulling annulment/MS annul/SL annulus/M annum annunciate/XNGSD annunciation/M Annunciation/S annunciator/SM Anny/M anode/SM anodic anodize/GDS anodyne/SM anoint/DRLGS anointer/M anointment/SM anomalousness/M anomalous/YP anomaly/MS anomic anomie/M anon/S anonymity/MS anonymousness/M anonymous/YP anopheles/M anorak/SM anorectic/S anorexia/SM anorexic/S another/M Anouilh/M Ansell/M Ansel/M Anselma/M Anselm/M Anselmo/M Anshan/M ANSI/M Ansley/M ans/M Anson/M Anstice/M answerable/U answered/U answerer/M answer/MZGBSDR antacid/MS Antaeus/M antagonism/MS antagonistic antagonistically antagonist/MS antagonized/U antagonize/GZRSD antagonizing/U Antananarivo/M antarctic Antarctica/M Antarctic/M Antares anteater/MS antebellum antecedence/MS antecedent/SMY antechamber/SM antedate/GDS antediluvian/S anteing antelope/MS ante/MS antenatal antennae antenna/MS anterior/SY anteroom/SM ant/GSMD Anthea/M Anthe/M anthem/MGDS anther/MS Anthia/M Anthiathia/M anthill/S anthologist/MS anthologize/GDS anthology/SM Anthony/M anthraces anthracite/MS anthrax/M anthropic anthropocentric anthropogenic anthropoid/S anthropological/Y anthropologist/MS anthropology/SM anthropometric/S anthropometry/M anthropomorphic anthropomorphically anthropomorphism/SM anthropomorphizing anthropomorphous antiabortion antiabortionist/S antiaircraft antibacterial/S antibiotic/SM antibody/MS anticancer Antichrist/MS anticipated/U anticipate/XVGNSD anticipation/M anticipative/Y anticipatory anticked anticking anticlerical/S anticlimactic anticlimactically anticlimax/SM anticline/SM anticlockwise antic/MS anticoagulant/S anticoagulation/M anticommunism/SM anticommunist/SM anticompetitive anticyclone/MS anticyclonic antidemocratic antidepressant/SM antidisestablishmentarianism/M antidote/DSMG Antietam/M antifascist/SM antiformant antifreeze/SM antifundamentalist/M antigenic antigenicity/SM antigen/MS antigone Antigone/M Antigua/M antiheroes antihero/M antihistamine/MS antihistorical antiknock/MS antilabor Antillean Antilles antilogarithm/SM antilogs antimacassar/SM antimalarial/S antimatter/SM antimicrobial/S antimissile/S antimony/SM anting/M Antin/M antinomian antinomy/M antinuclear Antioch/M antioxidant/MS antiparticle/SM Antipas/M antipasti antipasto/MS antipathetic antipathy/SM antipersonnel antiperspirant/MS antiphonal/SY antiphon/SM antipodal/S antipodean/S antipode/MS Antipodes antipollution/S antipoverty antiquarianism/MS antiquarian/MS antiquary/SM antiquate/NGSD antiquation/M antique/MGDS antiquity/SM antiredeposition antiresonance/M antiresonator anti/S antisemitic antisemitism/M antisepses antisepsis/M antiseptically antiseptic/S antiserum/SM antislavery/S antisocial/Y antispasmodic/S antisubmarine antisymmetric antisymmetry antitank antitheses antithesis/M antithetic antithetical/Y antithyroid antitoxin/MS antitrust/MR antivenin/MS antiviral/S antivivisectionist/S antiwar antler/SDM Antofagasta/M Antoine/M Antoinette/M Antonella/M Antone/M Antonetta/M Antonia/M Antonie/M Antonietta/M Antoni/M Antonina/M Antonin/M Antonino/M Antoninus/M Antonio/M Antonius/M Anton/MS Antonovics/M Antony/M antonymous antonym/SM antral antsy/RT Antwan/M Antwerp/M Anubis/M anus/SM anvil/MDSG anxiety/MS anxiousness/SM anxious/PY any Anya/M anybody/S anyhow Any/M anymore anyone/MS anyplace anything/S anytime anyway/S anywhere/S anywise AOL/M aorta/MS aortic AP apace apache/MS Apache/MS Apalachicola/M apartheid/SM apart/LP apartment/MS apartness/M apathetic apathetically apathy/SM apatite/MS APB aped/A apelike ape/MDRSG Apennines aper/A aperiodic aperiodically aperiodicity/M aperitif/S aperture/MDS apex/MS aphasia/SM aphasic/S aphelia aphelion/SM aphid/MS aphonic aphorism/MS aphoristic aphoristically aphrodisiac/SM Aphrodite/M Apia/M apiarist/SM apiary/SM apical/YS apices's apiece apishness/M apish/YP aplenty aplomb/SM APO Apocalypse/M apocalypse/MS apocalyptic apocryphalness/M apocryphal/YP apocrypha/M Apocrypha/M apogee/MS apolar apolitical/Y Apollinaire/M Apollonian Apollo/SM apologetically/U apologetic/S apologetics/M apologia/SM apologist/MS apologize/GZSRD apologizer/M apologizes/A apologizing/U apology/MS apoplectic apoplexy/SM apostasy/SM apostate/SM apostatize/DSG apostleship/SM apostle/SM apostolic apostrophe/SM apostrophized apothecary/MS apothegm/MS apotheoses apotheosis/M apotheosized apotheosizes apotheosizing Appalachia/M Appalachian/MS appalling/Y appall/SDG Appaloosa/MS appaloosa/S appanage/M apparatus/SM apparel/SGMD apparency apparently/I apparentness/M apparent/U apparition/SM appealer/M appealing/UY appeal/SGMDRZ appear/AEGDS appearance/AMES appearer/S appease/DSRGZL appeased/U appeasement/MS appeaser/M appellant/MS appellate/VNX appellation/M appellative/MY appendage/MS appendectomy/SM appendices appendicitis/SM appendix/SM append/SGZDR appertain/DSG appetite/MVS appetizer/SM appetizing/YU Appia/M Appian/M applauder/M applaud/ZGSDR applause/MS applecart/M applejack/MS Apple/M apple/MS applesauce/SM Appleseed/M Appleton/M applet/S appliance/SM applicabilities applicability/IM applicable/I applicably applicant/MS applicate/V application/MA applicative/Y applicator/MS applier/SM appliqud appliqu/MSG apply/AGSDXN appointee/SM appoint/ELSADG appointer/MS appointive appointment/ASEM Appolonia/M Appomattox/M apportion/GADLS apportionment/SAM appose/SDG appositeness/MS apposite/XYNVP apposition/M appositive/SY appraisal/SAM appraised/A appraisees appraiser/M appraises/A appraise/ZGDRS appraising/Y appreciable/I appreciably/I appreciated/U appreciate/XDSNGV appreciation/M appreciativeness/MI appreciative/PIY appreciator/MS appreciatory apprehend/DRSG apprehender/M apprehensible apprehension/SM apprehensiveness/SM apprehensive/YP apprentice/DSGM apprenticeship/SM apprise/DSG apprizer/SM apprizingly apprizings approachability/UM approachable/UI approach/BRSDZG approacher/M approbate/NX approbation/EMS appropriable appropriated/U appropriately/I appropriateness/SMI appropriate/XDSGNVYTP appropriation/M appropriator/SM approval/ESM approve/DSREG approved/U approver's/E approver/SM approving/YE approx approximate/XGNVYDS approximation/M approximative/Y appurtenance/MS appurtenant/S APR apricot/MS Aprilette/M April/MS Apr/M apron/SDMG apropos apse/MS apsis/M apter aptest aptitude/SM aptness/SMI aptness's/U apt/UPYI Apuleius/M aquaculture/MS aqualung/SM aquamarine/SM aquanaut/SM aquaplane/GSDM aquarium/MS Aquarius/MS aqua/SM aquatically aquatic/S aquavit/SM aqueduct/MS aqueous/Y aquiculture's aquifer/SM Aquila/M aquiline Aquinas/M Aquino/M Aquitaine/M AR Arabela/M Arabele/M Arabella/M Arabelle/M Arabel/M arabesque/SM Arabia/M Arabian/MS Arabic/M arability/MS Arabist/MS arable/S Arab/MS Araby/M Araceli/M arachnid/MS arachnoid/M arachnophobia Arafat/M Araguaya/M Araldo/M Aral/M Ara/M Aramaic/M Aramco/M Arapahoes Arapahoe's Arapaho/MS Ararat/M Araucanian/M Arawakan/M Arawak/M arbiter/MS arbitrage/GMZRSD arbitrager/M arbitrageur/S arbitrament/MS arbitrarily arbitrariness/MS arbitrary/P arbitrate/SDXVNG arbitration/M arbitrator/SM arbor/DMS arboreal/Y arbores arboretum/MS arborvitae/MS arbutus/SM ARC arcade/SDMG Arcadia/M Arcadian arcana/M arcane/P arc/DSGM archaeological/Y archaeologist/SM archaically archaic/P Archaimbaud/M archaism/SM archaist/MS archaize/GDRSZ archaizer/M Archambault/M archangel/SM archbishopric/SM archbishop/SM archdeacon/MS archdiocesan archdiocese/SM archduchess/MS archduke/MS Archean archenemy/SM archeologist's archeology/MS archer/M Archer/M archery/MS archetypal archetype/SM archfiend/SM archfool Archibald/M Archibaldo/M Archibold/M Archie/M archiepiscopal Archimedes/M arching/M archipelago/SM architect/MS architectonic/S architectonics/M architectural/Y architecture/SM architrave/MS archival archive/DRSGMZ archived/U archivist/MS Arch/MR archness/MS arch/PGVZTMYDSR archway/SM Archy/M arclike ARCO/M arcsine arctangent Arctic/M arctic/S Arcturus/M Ardabil Arda/MH Ardath/M Ardeen/M Ardelia/M Ardelis/M Ardella/M Ardelle/M ardency/M Ardene/M Ardenia/M Arden/M ardent/Y Ardine/M Ardisj/M Ardis/M Ardith/M ardor/SM Ardra/M arduousness/SM arduous/YP Ardyce/M Ardys Ardyth/M areal area/SM areawide are/BS Arel/M arenaceous arena/SM aren't Arequipa/M Ares Aretha/M Argentina/M Argentinean/S Argentine/SM Argentinian/S argent/MS arginine/MS Argonaut/MS argonaut/S argon/MS Argonne/M Argo/SM argosy/SM argot/SM arguable/IU arguably/IU argue/DSRGZ arguer/M argumentation/SM argumentativeness/MS argumentative/YP argument/SM Argus/M argyle/S Ariadne/M Ariana/M Arianism/M Arianist/SM aria/SM Aridatha/M aridity/SM aridness/M arid/TYRP Ariela/M Ariella/M Arielle/M Ariel/M Arie/SM Aries/S aright Ari/M Arin/M Ario/M Ariosto/M arise/GJSR arisen Aristarchus/M Aristides aristocracy/SM aristocratic aristocratically aristocrat/MS Aristophanes/M Aristotelean Aristotelian/M Aristotle/M arithmetical/Y arithmetician/SM arithmetic/MS arithmetize/SD Arius/M Ariz/M Arizona/M Arizonan/S Arizonian/S Arjuna/M Arkansan/MS Arkansas/M Arkhangelsk/M Ark/M ark/MS Arkwright/M Arlana/M Arlan/M Arlee/M Arleen/M Arlena/M Arlene/M Arlen/M Arleta/M Arlette/M Arley/M Arleyne/M Arlie/M Arliene/M Arlina/M Arlinda/M Arline/M Arlington/M Arlin/M Arluene/M Arly/M Arlyne/M Arlyn/M Armada/M armada/SM armadillo/MS Armageddon/SM Armagnac/M armament/EAS armament's/E Armand/M Armando/M Arman/M arm/ASEDG Armata/M armature/MGSD armband/SM armchair/MS Armco/M armed/U Armenia/M Armenian/MS armer/MES armful/SM armhole/MS arming/M Arminius/M Armin/M armistice/MS armless armlet/SM armload/M Armonk/M armored/U armorer/M armorial/S armory/DSM armor/ZRDMGS Armour/M armpit/MS armrest/MS arm's Armstrong/M Ar/MY army/SM Arnaldo/M Arneb/M Arne/M Arney/M Arnhem/M Arnie/M Arni/M Arnold/M Arnoldo/M Arno/M Arnuad/M Arnulfo/M Arny/M aroma/SM aromatherapist/S aromatherapy/S aromatically aromaticity/M aromaticness/M aromatic/SP Aron/M arose around arousal/MS aroused/U arouse/GSD ARPA/M Arpanet/M ARPANET/M arpeggio/SM arrack/M Arragon/M arraignment/MS arraign/SDGL arrangeable/A arranged/EA arrangement/AMSE arranger/M arranges/EA arrange/ZDSRLG arranging/EA arrant/Y arras/SM arrayer array/ESGMD arrear/SM arrest/ADSG arrestee/MS arrester/MS arresting/Y arrestor/MS Arrhenius/M arrhythmia/SM arrhythmic arrhythmical Arri/M arrival/MS arriver/M arrive/SRDG arrogance/MS arrogant/Y arrogate/XNGDS arrogation/M Arron/M arrowhead/SM arrowroot/MS arrow/SDMG arroyo/MS arr/TV arsenal/MS arsenate/M arsenic/MS arsenide/M arsine/MS arsonist/MS arson/SM Artair/M Artaxerxes/M artefact's Arte/M Artemas Artemis/M Artemus/M arterial/SY arteriolar arteriole/SM arterioscleroses arteriosclerosis/M artery/SM artesian artfulness/SM artful/YP Arther/M arthritic/S arthritides arthritis/M arthrogram/MS arthropod/SM arthroscope/S arthroscopic Arthurian Arthur/M artichoke/SM article/GMDS articulable/I articular articulated/EU articulately/I articulateness/IMS articulates/I articulate/VGNYXPSD articulation/M articulator/SM articulatory Artie/M artifact/MS artificer/M artifice/ZRSM artificiality/MS artificialness/M artificial/PY artillerist artilleryman/M artillerymen artillery/SM artiness/MS artisan/SM artiste/SM artistically/I artistic/I artist/MS artistry/SM artlessness/MS artless/YP Art/M art/SM artsy/RT Artur/M Arturo/M Artus/M artwork/MS Arty/M arty/TPR Aruba/M arum/MS Arvie/M Arvin/M Arv/M Arvy/M Aryan/MS Aryn/M as As A's Asa/M Asama/M asap ASAP asbestos/MS Ascella/M ascend/ADGS ascendancy/MS ascendant/SY ascender/SM Ascension/M ascension/SM ascent/SM ascertain/DSBLG ascertainment/MS ascetically asceticism/MS ascetic/SM ASCII ascot/MS ascribe/GSDB ascription/MS ascriptive Ase/M aseptically aseptic/S asexuality/MS asexual/Y Asgard/M ashame/D ashamed/UY Ashanti/M Ashbey/M Ashby/M ashcan/SM Ashely/M Asher/M Asheville/M Ashia/M Ashien/M Ashil/M Ashkenazim Ashkhabad/M Ashla/M Ashland/M Ashlan/M ashlar/GSDM Ashlee/M Ashleigh/M Ashlen/M Ashley/M Ashlie/M Ashli/M Ashlin/M Ashly/M ashman/M ash/MNDRSG Ashmolean/M Ash/MRY ashore ashram/SM Ashton/M ashtray/MS Ashurbanipal/M ashy/RT Asia/M Asian/MS Asiatic/SM aside/S Asilomar/M Asimov asinine/Y asininity/MS askance ask/DRZGS asked/U asker/M askew/P ASL aslant asleep Asmara/M asocial/S Asoka/M asparagus/MS aspartame/S ASPCA aspect/SM Aspell/M aspen/M Aspen/M asperity/SM asper/M aspersion/SM asphalt/MDRSG asphodel/MS asphyxia/MS asphyxiate/GNXSD asphyxiation/M aspic/MS Aspidiske/M aspidistra/MS aspirant/MS aspirate/NGDSX aspirational aspiration/M aspirator/SM aspire/GSRD aspirer/M aspirin/SM asplenium asp/MNRXS Asquith/M Assad/M assailable/U assailant/SM assail/BGDS Assamese/M Assam/M assassinate/DSGNX assassination/M assassin/MS assaulter/M assaultive/YP assault/SGVMDR assayer/M assay/SZGRD assemblage/MS assemble/ADSREG assembled/U assembler/EMS assemblies/A assembly/EAM assemblyman/M assemblymen Assembly/MS assemblywoman assemblywomen assent/SGMRD assert/ADGS asserter/MS assertional assertion/AMS assertiveness/SM assertive/PY assess/BLSDG assessed/A assesses/A assessment/SAM assessor/MS asset/SM asseverate/XSDNG asseveration/M asshole/MS! assiduity/SM assiduousness/SM assiduous/PY assign/ALBSGD assignation/MS assigned/U assignee/MS assigner/MS assignment/MAS assignor/MS assigns/CU assimilate/VNGXSD assimilationist/M assimilation/M Assisi/M assistance/SM assistantship/SM assistant/SM assisted/U assister/M assist/RDGS assize/MGSD ass/MNS assn assoc associable associated/U associate/SDEXNG associateship associational association/ME associative/Y associativity/S associator/MS assonance/SM assonant/S assorter/M assort/LRDSG assortment/SM asst assuaged/U assuage/SDG assumability assumer/M assume/SRDBJG assuming/UA assumption/SM assumptive assurance/AMS assure/AGSD assuredness/M assured/PYS assurer/SM assuring/YA Assyria/M Assyrian/SM Assyriology/M Astaire/SM Astarte/M astatine/MS aster/ESM asteria asterisked/U asterisk/SGMD astern asteroidal asteroid/SM asthma/MS asthmatic/S astigmatic/S astigmatism/SM astir astonish/GSDL astonishing/Y astonishment/SM Aston/M Astoria/M Astor/M astounding/Y astound/SDG astraddle Astrakhan/M astrakhan/SM astral/SY Astra/M astray astride Astrid/M astringency/SM astringent/YS Astrix/M astrolabe/MS astrologer/MS astrological/Y astrologist/M astrology/SM astronautical astronautic/S astronautics/M astronaut/SM astronomer/MS astronomic astronomical/Y astronomy/SM astrophysical astrophysicist/SM astrophysics/M Astroturf/M AstroTurf/S Asturias/M astuteness/MS astute/RTYP Asuncin/M asunder Aswan/M asylum/MS asymmetric asymmetrical/Y asymmetry/MS asymptomatic asymptomatically asymptote/MS asymptotically asymptotic/Y asynchronism/M asynchronous/Y asynchrony at Atacama/M Atahualpa/M Atalanta/M Atari/M Atatrk/M atavism/MS atavistic atavist/MS ataxia/MS ataxic/S atelier/SM atemporal ate/S Athabasca/M Athabascan's Athabaskan/MS Athabaska's atheism/SM atheistic atheist/SM Athena/M Athene/M Athenian/SM Athens/M atheroscleroses atherosclerosis/M athirst athlete/MS athletically athleticism/M athletic/S athletics/M athwart atilt Atkins/M Atkinson/M Atlanta/M Atlante/MS atlantes Atlantic/M Atlantis/M atlas/SM Atlas/SM At/M Atman ATM/M atmosphere/DSM atmospherically atmospheric/S atoll/MS atomically atomicity/M atomic/S atomics/M atomistic atomization/SM atomize/GZDRS atomizer/M atom/SM atonality/MS atonal/Y atone/LDSG atonement/SM atop ATP Atreus/M atria atrial Atria/M atrium/M atrociousness/SM atrocious/YP atrocity/SM atrophic atrophy/DSGM atropine/SM Atropos/M Ats attach/BLGZMDRS attached/UA attacher/M attach/S attachment/ASM attacker/M attack/GBZSDR attainabilities attainability/UM attainableness/M attainable/U attainably/U attain/AGSD attainder/MS attained/U attainer/MS attainment/MS attar/MS attempt/ADSG attempter/MS attendance/MS attendant/SM attended/U attendee/SM attender/M attend/SGZDR attentional attentionality attention/IMS attentiveness/IMS attentive/YIP attenuated/U attenuate/SDXGN attenuation/M attenuator/MS attestation/SM attested/U attester/M attest/GSDR Attic Attica/M attic/MS Attila/M attire/SDG attitude/MS attitudinal/Y attitudinize/SDG Attlee/M attn Attn attorney/SM attractant/SM attract/BSDGV attraction/MS attractivenesses attractiveness/UM attractive/UYP attractor/MS attributable/U attribute/BVNGRSDX attributed/U attributer/M attributional attribution/M attributive/SY attrition/MS Attucks attune/SDG atty ATV/S atwitter Atwood/M atypical/Y Aube/M Auberge/M aubergine/MS Auberon/M Auberta/M Aubert/M Aubine/M Aubree/M Aubrette/M Aubrey/M Aubrie/M Aubry/M auburn/SM Auckland/M auctioneer/SDMG auction/MDSG audaciousness/SM audacious/PY audacity/MS Auden/M audibility/MSI audible/I audibles audibly/I Audie/M audience/MS Audi/M audiogram/SM audiological audiologist/MS audiology/SM audiometer/MS audiometric audiometry/M audiophile/SM audio/SM audiotape/S audiovisual/S audited/U audition/MDSG auditorium/MS auditor/MS auditory/S audit/SMDVG Audra/M Audre/M Audrey/M Audrie/M Audrye/M Audry/M Audubon/M Audy/M Auerbach/M Augean auger/SM aught/S Augie/M Aug/M augmentation/SM augmentative/S augment/DRZGS augmenter/M augur/GDMS augury/SM Augusta/M Augustan/S Auguste/M Augustina/M Augustine/M Augustinian/S Augustin/M augustness/SM Augusto/M August/SM august/STPYR Augustus/M Augy/M auk/MS Au/M Aundrea/M auntie/MS aunt/MYS aunty's aural/Y Aura/M aura/SM Aurea/M Aurelea/M Aurelia/M Aurelie/M Aurelio/M Aurelius/M Aurel/M aureole/GMSD aureomycin Aureomycin/M Auria/M auric auricle/SM auricular Aurie/M Auriga/M Aurilia/M Aurlie/M Auroora/M auroral Aurora/M aurora/SM Aurore/M Aurthur/M Auschwitz/M auscultate/XDSNG auscultation/M auspice/SM auspicious/IPY auspiciousnesses auspiciousness/IM Aussie/MS Austen/M austereness/M austere/TYRP austerity/SM Austina/M Austine/M Austin/SM austral Australasia/M Australasian/S australes Australia/M Australian/MS Australis/M australites Australoid Australopithecus/M Austria/M Austrian/SM Austronesian authentically authenticated/U authenticate/GNDSX authentication/M authenticator/MS authenticity/MS authentic/UI author/DMGS authoress/S authorial authoritarianism/MS authoritarian/S authoritativeness/SM authoritative/PY authority/SM authorization/MAS authorize/AGDS authorized/U authorizer/SM authorizes/U authorship/MS autism/MS autistic/S autobahn/MS autobiographer/MS autobiographic autobiographical/Y autobiography/MS autoclave/SDGM autocollimator/M autocorrelate/GNSDX autocorrelation/M autocracy/SM autocratic autocratically autocrat/SM autodial/R autodidact/MS autofluorescence autograph/MDG autographs autoignition/M autoimmune autoimmunity/S autoloader automaker/S automata's automate/NGDSX automatically automatic/S automation/M automatism/SM automatize/DSG automaton/SM automobile/GDSM automorphism/SM automotive autonavigator/SM autonomic/S autonomous/Y autonomy/MS autopilot/SM autopsy/MDSG autoregressive autorepeat/GS auto/SDMG autostart autosuggestibility/M autotransformer/M autoworker/S autumnal/Y Autumn/M autumn/MS aux auxiliary/S auxin/MS AV availability/USM availableness/M available/U availably avail/BSZGRD availing/U avalanche/MGSD Avalon/M Ava/M avant avarice/SM avariciousness/M avaricious/PY avast/S avatar/MS avaunt/S avdp Aveline/M Ave/MS avenged/U avenger/M avenge/ZGSRD Aventine/M Aventino/M avenue/MS average/DSPGYM Averell/M Averill/M Averil/M Avernus/M averred averrer averring Averroes/M averseness/M averse/YNXP aversion/M avers/V avert/GSD Averyl/M Avery/M ave/S aves/C Avesta/M avg avian/S aviary/SM aviate/NX aviation/M aviator/SM aviatrices aviatrix/SM Avicenna/M Avictor/M avidity/MS avid/TPYR Avie/M Avigdor/M Avignon/M Avila/M avionic/S avionics/M Avior/M Avis avitaminoses avitaminosis/M Avivah/M Aviva/M Aviv/M avocado/MS avocational avocation/SM Avogadro/M avoidable/U avoidably/U avoidance/SM avoider/M avoid/ZRDBGS avoirdupois/MS Avon/M avouch/GDS avowal/EMS avowed/Y avower/M avow/GEDS Avram/M Avril/M Avrit/M Avrom/M avuncular av/ZR AWACS await/SDG awake/GS awakened/U awakener/M awakening/S awaken/SADG awarder/M award/RDSZG awareness/MSU aware/TRP awash away/PS aweigh awe/SM awesomeness/SM awesome/PY awestruck awfuller awfullest awfulness/SM awful/YP aw/GD awhile/S awkwardness/MS awkward/PRYT awl/MS awning/DM awn/MDJGS awoke awoken AWOL awry/RT ax/DRSZGM axehead/S Axel/M Axe/M axeman axial/Y axillary axiological/Y axiology/M axiomatically axiomatic/S axiomatization/MS axiomatize/GDS axiom/SM axion/SM axis/SM axle/MS axletree/MS Ax/M axolotl/SM axon/SM ayah/M ayahs Ayala/M ayatollah ayatollahs aye/MZRS Ayers Aylmar/M Aylmer/M Aymara/M Aymer/M Ayn/M AZ azalea/SM Azania/M Azazel/M Azerbaijan/M azimuthal/Y azimuth/M azimuths Azores Azov/M AZT Aztecan Aztec/MS azure/MS BA Baal/SM baa/SDG Babara/M Babar's Babbage/M Babbette/M Babbie/M babbitt/GDS Babbitt/M babbler/M babble/RSDGZ Babb/M Babcock/M Babel/MS babel/S babe/SM Babette/M Babita/M Babka/M baboon/MS Bab/SM babushka/MS babyhood/MS babyish Babylonia/M Babylonian/SM Babylon/MS babysat babysit/S babysitter/S babysitting baby/TDSRMG Bacall/M Bacardi/M baccalaureate/MS baccarat/SM bacchanalia Bacchanalia/M bacchanalian/S bacchanal/SM Bacchic Bacchus/M bachelorhood/SM bachelor/SM Bach/M bacillary bacilli bacillus/MS backache/SM backarrow backbencher/M backbench/ZR backbiter/M backbite/S backbitten backbit/ZGJR backboard/SM backbone/SM backbreaking backchaining backcloth/M backdate/GDS backdrop/MS backdropped backdropping backed/U backer/M backfield/SM backfill/SDG backfire/GDS backgammon/MS background/SDRMZG back/GZDRMSJ backhanded/Y backhander/M backhand/RDMSZG backhoe/S backing/M backlash/GRSDM backless backlogged backlogging backlog/MS backorder backpacker/M backpack/ZGSMRD backpedal/DGS backplane/MS backplate/SM backrest/MS backscatter/SMDG backseat/S backside/SM backslapper/MS backslapping/M backslash/DSG backslider/M backslide/S backslid/RZG backspace/GSD backspin/SM backstabber/M backstabbing backstage backstair/S backstitch/GDSM backstop/MS backstopped backstopping backstreet/M backstretch/SM backstroke/GMDS backtalk/S backtrack/SDRGZ backup/SM Backus/M backwardness/MS backward/YSP backwash/SDMG backwater/SM backwood/S backwoodsman/M backwoodsmen backyard/MS baconer/M Bacon/M bacon/SRM bacterial/Y bacteria/MS bactericidal bactericide/SM bacteriologic bacteriological bacteriologist/MS bacteriology/SM bacterium/M Bactria/M badder baddest baddie/MS bade Baden/M badge/DSRGMZ badger/DMG badinage/DSMG badland/S Badlands/M badman/M badmen badminton/MS badmouth/DG badmouths badness/SM bad/PSNY Baedeker/SM Baez/M Baffin/M bafflement/MS baffler/M baffle/RSDGZL baffling/Y bagatelle/MS bagel/SM bagful/MS baggageman baggagemen baggage/SM bagged/M bagger/SM baggily bagginess/MS bagging/M baggy/PRST Baghdad/M bagpiper/M bagpipe/RSMZ Bagrodia/MS bag/SM baguette/SM Baguio/M bah Baha'i Bahama/MS Bahamanian/S Bahamian/MS Baha'ullah Bahia/M Bahrain/M bahs Baikal/M Bailey/SM bail/GSMYDRB Bailie/M bailiff/SM bailiwick/MS Baillie/M Bail/M bailout/MS bailsman/M bailsmen Baily/M Baird/M bairn/SM baiter/M bait/GSMDR baize/GMDS Baja/M baked/U bakehouse/M Bakelite/M baker/M Baker/M Bakersfield/M bakery/SM bakeshop/S bake/ZGJDRS baking/M baklava/M baksheesh/SM Baku/M Bakunin/M balaclava/MS balalaika/MS balanced/A balancedness balancer/MS balance's balance/USDG Balanchine/M Balboa/M balboa/SM balcony/MSD balderdash/MS Balder/M baldfaced Bald/MR baldness/MS bald/PYDRGST baldric/SM Balduin/M Baldwin/M baldy Balearic/M baleen/MS balefuller balefullest balefulness/MS baleful/YP Bale/M bale/MZGDRS baler/M Balfour/M Bali/M Balinese balkanization balkanize/DG Balkan/SM balker/M balk/GDRS Balkhash/M balkiness/M balky/PRT balladeer/MS ballade/MS balladry/MS ballad/SM Ballard/SM ballast/SGMD ballcock/S ballerina/MS baller/M balletic ballet/MS ballfields ballgame/S ball/GZMSDR ballistic/S ballistics/M Ball/M balloonist/S balloon/RDMZGS balloter/M ballot/MRDGS ballpark/SM ballplayer/SM ballpoint/SM ballroom/SM ballsy/TR ballyhoo/SGMD balminess/SM balm/MS balmy/PRT baloney/SM balsam/GMDS balsamic balsa/MS Balthazar/M Baltic/M Baltimore/M Baluchistan/M baluster/MS balustrade/SM Balzac/M Ba/M Bamako/M Bamberger/M Bambie/M Bambi/M bamboo/SM bamboozle/GSD Bamby/M Banach/M banality/MS banal/TYR banana/SM Bancroft/M bandager/M bandage/RSDMG bandanna/SM bandbox/MS bandeau/M bandeaux band/EDGS bander/M banding/M bandit/MS banditry/MS bandmaster/MS bandoleer/SM bandpass band's bandsman/M bandsmen bandstand/SM bandstop Bandung/M bandwagon/MS bandwidth/M bandwidths bandy/TGRSD banefuller banefullest baneful/Y bane/MS Bangalore/M banger/M bang/GDRZMS bangkok Bangkok/M Bangladeshi/S Bangladesh/M bangle/MS Bangor/M Bangui/M bani banisher/M banishment/MS banish/RSDGL banister/MS Banjarmasin/M banjoist/SM banjo/MS Banjul/M bankbook/SM bankcard/S banker/M bank/GZJDRMBS banking/M Bank/MS banknote/S bankroll/DMSG bankruptcy/MS bankrupt/DMGS Banky/M Ban/M banned/U Banneker/M banner/SDMG banning/U Bannister/M bannister's bannock/SM banns banqueter/M banquet/SZGJMRD banquette/MS ban/SGMD banshee/MS bans/U bantam/MS bantamweight/MS banterer/M bantering/Y banter/RDSG Banting/M Bantu/SM banyan/MS banzai/S baobab/SM Baotou/M baptismal/Y baptism/SM Baptiste/M baptistery/MS baptist/MS Baptist/MS baptistry's baptized/U baptizer/M baptize/SRDZG baptizes/U Barabbas/M Barbabas/M Barbabra/M Barbadian/S Barbados/M Barbaraanne/M Barbara/M Barbarella/M barbarianism/MS barbarian/MS barbaric barbarically barbarism/MS barbarity/SM barbarize/SDG Barbarossa/M barbarousness/M barbarous/PY Barbary/M barb/DRMSGZ barbecue/DRSMG barbed/P Barbee/M barbell/SM barbel/MS Barbe/M barbeque's barber/DMG barbered/U Barber/M barberry/MS barbershop/MS Barbette/M Barbey/M Barbie/M Barbi/M barbital/M barbiturate/MS Barbour/M Barbra/M Barb/RM Barbuda/M barbwire/SM Barby/M barcarole/SM Barcelona/M Barclay/M Bardeen/M Barde/M bardic Bard/M bard/MDSG bareback/D barefacedness/M barefaced/YP barefoot/D barehanded bareheaded barelegged bareness/MS Barents/M bare/YSP barfly/SM barf/YDSG bargainer/M bargain/ZGSDRM barge/DSGM bargeman/M bargemen bargepole/M barhopped barhopping barhop/S Bari/M baritone/MS barium/MS barked/C barkeeper/M barkeep/SRZ barker/M Barker/M bark/GZDRMS Barkley/M barks/C barleycorn/MS barley/MS Barlow/M barmaid/SM barman/M barmen Bar/MH Barnabas Barnabe/M Barnaby/M barnacle/MDS Barnard/M Barnaul/M Barnebas/M Barnes Barnett/M Barney/M barnful barn/GDSM Barnhard/M Barnie/M Barn/M barnsful barnstorm/DRGZS barnstormer/M Barnum/M barnyard/MS Barny/M Baroda/M barometer/MS barometric barometrically baronage/MS baroness/MS baronetcy/SM baronet/MS baronial Baron/M baron/SM barony/SM baroque/SPMY barque's Barquisimeto/M barracker/M barrack/SDRG barracuda/MS barrage/MGSD Barranquilla/M barred/ECU barre/GMDSJ barrel/SGMD barrenness/SM barren/SPRT Barrera/M Barret/M barrette/SM Barrett/M barricade/SDMG Barrie/M barrier/MS barring/R barrio/SM Barri/SM barrister/MS Barr/M Barron/M barroom/SM barrow/MS Barry/M Barrymore/MS bars/ECU barstool/SM Barstow/M Bartel/M bartender/M bartend/ZR barterer/M barter/SRDZG bar/TGMDRS Barthel/M Barth/M Bartholdi/M Bartholemy/M Bartholomeo/M Bartholomeus/M Bartholomew/M Bartie/M Bartlet/M Bartlett/M Bart/M Bartk/M Bartolemo/M Bartolomeo/M Barton/M Bartram/M Barty/M barycenter barycentre's barycentric Bary/M baryon/SM Baryram/M Baryshnikov/M basaltic basalt/SM basal/Y Bascom/M bas/DRSTG baseball/MS baseband baseboard/MS base/CGRSDL baseless baseline/SM Basel/M basely Base/M baseman/M basemen basement/CSM baseness/MS baseplate/M base's basetting bashfulness/MS bashful/PY bash/JGDSR Basho/M Basia/M BASIC basically basic/S Basie/M basilar Basile/M basilica/SM Basilio/M basilisk/SM Basilius/M Basil/M basil/MS basin/DMS basinful/S basis/M basketball/MS basketry/MS basket/SM basketwork/SM bask/GSD basophilic Basque/SM Basra/M Basseterre/M basset/GMDS Bassett/M bassinet/SM bassist/MS Bass/M basso/MS bassoonist/MS bassoon/MS bass/SM basswood/SM bastardization/MS bastardized/U bastardize/SDG bastard/MYS bastardy/MS baste/NXS baster/M Bastian/M Bastien/M Bastille/M basting/M bastion/DM bast/SGZMDR Basutoland/M Bataan/M Batavia/M batch/MRSDG bated/U bate/KGSADC bater/AC Bates bathe bather/M bathetic bathhouse/SM bath/JMDSRGZ bathmat/S Batholomew/M bathos/SM bathrobe/MS bathroom/SDM baths Bathsheba/M bathtub/MS bathwater bathyscaphe's bathysphere/MS batik/DMSG Batista/M batiste/SM Bat/M batman/M Batman/M batmen baton/SM Batsheva/M batsman/M bat/SMDRG batsmen battalion/MS batted batten/SDMG batter/SRDZG battery/MS batting/MS battledore/MS battledress battlefield/SM battlefront/SM battle/GMZRSDL battleground/SM Battle/M battlement/SMD battler/M battleship/MS batty/RT Batu/M batwings bauble/SM Baudelaire/M baud/M Baudoin/M Baudouin/M Bauer/M Bauhaus/M baulk/GSDM Bausch/M bauxite/SM Bavaria/M Bavarian/S bawdily bawdiness/MS bawd/SM bawdy/PRST bawler/M bawl/SGDR Baxie/M Bax/M Baxter/M Baxy/M Bayamon Bayard/M bayberry/MS Bayda/M Bayer/M Bayes Bayesian bay/GSMDY Baylor/M Bay/MR bayonet/SGMD Bayonne/M bayou/MS Bayreuth/M bazaar/MS bazillion/S bazooka/MS BB BBB BBC bbl BBQ BBS BC BCD bdrm beachcomber/SM beachhead/SM Beach/M beach/MSDG beachwear/M beacon/DMSG beading/M Beadle/M beadle/SM bead/SJGMD beadsman/M beadworker beady/TR beagle/SDGM beaker/M beak/ZSDRM Beale/M Bealle/M Bea/M beam/MDRSGZ beanbag/SM bean/DRMGZS beanie/SM Bean/M beanpole/MS beanstalk/SM bearable/U bearably/U beard/DSGM bearded/P beardless Beard/M Beardmore/M Beardsley/M bearer/M bearing/M bearishness/SM bearish/PY bearlike Bear/M Bearnaise/M Bearnard/M bearskin/MS bear/ZBRSJG Beasley/M beasties beastings/M beastliness/MS beastly/PTR beast/SJMY beatable/U beatably/U beaten/U beater/M beatific beatifically beatification/M beatify/GNXDS beating/M beatitude/MS Beatlemania/M Beatles/M beatnik/SM beat/NRGSBZJ Beatrice/M Beatrisa/M Beatrix/M Beatriz/M Beauchamps Beaufort/M Beaujolais/M Beau/M Beaumarchais/M Beaumont/M beau/MS Beauregard/M beauteousness/M beauteous/YP beautician/MS beautification/M beautifier/M beautifully/U beautifulness/M beautiful/PTYR beautify/SRDNGXZ beaut/SM beauty/SM Beauvoir/M beaux's beaver/DMSG Beaverton/M Bebe/M bebop/MS becalm/GDS became because Becca/M Bechtel/M Becka/M Becker/M Becket/M Beckett/M beck/GSDM Beckie/M Becki/M beckon/SDG Beck/RM Becky/M becloud/SGD become/GJS becoming/UY Becquerel/M bedaub/GDS bedazzle/GLDS bedazzlement/SM bedbug/SM bedchamber/M bedclothes bedded bedder/MS bedding/MS bedeck/DGS Bede/M bedevil/DGLS bedevilment/SM bedfast bedfellow/MS Bedford/M bedimmed bedimming bedim/S bedizen/DGS bedlam/MS bedlinen bedmaker/SM bedmate/MS bed/MS Bedouin/SM bedpan/SM bedpost/SM bedraggle/GSD bedridden bedrock/SM bedroll/SM bedroom/DMS bedsheets bedside/MS bedsit bedsitter/M bedsore/MS bedspread/SM bedspring/SM bedstead/SM bedstraw/M bedtime/SM Beebe/M beebread/MS Beecher/M beech/MRSN beechnut/MS beechwood beefburger/SM beefcake/MS beef/GZSDRM beefiness/MS beefsteak/MS beefy/TRP beehive/MS beekeeper/MS beekeeping/SM beeline/MGSD Beelzebub/M Bee/M bee/MZGJRS been/S beeper/M beep/GZSMDR Beerbohm/M beer/M beermat/S beery/TR beeswax/DSMG Beethoven/M beetle/GMRSD Beeton/M beetroot/M beet/SM beeves/M befall/SGN befell befit/SM befitted befitting/Y befogged befogging befog/S before beforehand befoul/GSD befriend/DGS befuddle/GLDS befuddlement/SM began beget/S begetting beggar/DYMSG beggarliness/M beggarly/P beggary/MS begged begging Begin/M beginner/MS beginning/MS begin/S begone/S begonia/SM begot begotten begrime/SDG begrudge/GDRS begrudging/Y beg/S beguilement/SM beguiler/M beguile/RSDLZG beguiling/Y beguine/SM begum/MS begun behalf/M behalves Behan/M behave/GRSD behavioral/Y behaviorism/MS behavioristic/S behaviorist/S behavior/SMD behead/GSD beheld behemoth/M behemoths behest/SM behindhand behind/S beholder/M behold/ZGRNS behoofs behoove/SDJMG behooving/YM Behring/M Beiderbecke/M beige/MS Beijing Beilul/M being/M Beirut/M Beitris/M bejewel/SDG Bekesy/M Bekki/M be/KS belabor/MDSG Bela/M Belarus belate/D belatedness/M belated/PY Belau/M belay/GSD belch/GSD beleaguer/GDS Belem/M Belfast/M belfry/SM Belgian/MS Belgium/M Belg/M Belgrade/M Belia/M Belicia/M belie belief/ESUM belier/M believability's believability/U believable/U believably/U believed/U believe/EZGDRS believer/MUSE believing/U Belinda/M Belita/M belittlement/MS belittler/M belittle/RSDGL Belize/M belladonna/MS Bella/M Bellamy/M Bellanca/M Bellatrix/M bellboy/MS belled/A Belle/M belle/MS belletristic belletrist/SM Belleville/M bellflower/M bell/GSMD bellhop/MS bellicoseness/M bellicose/YP bellicosity/MS belligerence/SM belligerency/MS belligerent/SMY Bellina/M belling/A Bellini/M Bell/M bellman/M bellmen Bellovin/M bellow/DGS Bellow/M bellows/M bells/A bellwether/MS Bellwood/M bellyacher/M bellyache/SRDGM bellybutton/MS bellyfull bellyful/MS belly/SDGM Bel/M Belmont/M Belmopan/M Beloit/M belong/DGJS belonging/MP Belorussian/S Belorussia's belove/D beloved/S below/S Belshazzar/M belted/U belt/GSMD belting/M Belton/M Beltran/M Beltsville/M beltway/SM beluga/SM Belushi/M Belva/M belvedere/M Belvia/M bely/DSRG beman Be/MH bemire/SDG bemoan/GDS bemused/Y bemuse/GSDL bemusement/SM Benacerraf/M Benares's bencher/M benchmark/GDMS bench/MRSDG bend/BUSG bended Bender/M bender/MS Bendick/M Bendicty/M Bendite/M Bendix/M beneath Benedetta/M Benedetto/M Benedick/M Benedicta/M Benedictine/MS benediction/MS Benedict/M Benedicto/M benedictory Benedikta/M Benedikt/M benefaction/MS benefactor/MS benefactress/S benefice/MGSD beneficence/SM beneficent/Y beneficialness/M beneficial/PY beneficiary/MS benefiter/M benefit/SRDMZG Benelux/M Benet/M Benetta/M Benetton/M benevolence/SM benevolentness/M benevolent/YP Bengali/M Bengal/SM Benghazi/M Bengt/M Beniamino/M benightedness/M benighted/YP benignant benignity/MS benign/Y Beninese Benin/M Benita/M Benito/M Benjamen/M Benjamin/M Benjie/M Benji/M Benjy/M Ben/M Bennett/M Bennie/M Benni/M Bennington/M Benn/M Benny/M Benoite/M Benoit/M Benson/M Bentham/M Bentlee/M Bentley/MS Bent/M Benton/M bents bent/U bentwood/SM benumb/SGD Benyamin/M Benzedrine/M benzene/MS benzine/SM Benz/M Beograd's Beowulf/M bequeath/GSD bequeaths bequest/MS berate/GSD Berber/MS bereave/GLSD bereavement/MS bereft Berenice/M Beret/M beret/SM Bergen/M Bergerac/M Berger/M Berget/M Berglund/M Bergman/M Berg/NRM berg/NRSM Bergson/M Bergsten/M Bergstrom/M beribbon/D beriberi/SM Beringer/M Bering/RM Berkeley/M berkelium/SM Berke/M Berkie/M Berkley/M Berkly/M Berkowitz/M Berkshire/SM Berky/M Berk/YM Berle/M Berliner/M Berlin/SZRM Berlioz/M Berlitz/M Berman/M Ber/MG berm/SM Bermuda/MS Bermudan/S Bermudian/S Bernadene/M Bernadette/M Bernadina/M Bernadine/M Berna/M Bernardina/M Bernardine/M Bernardino/M Bernard/M Bernardo/M Bernarr/M Bernays/M Bernbach/M Bernelle/M Berne's Bernese Bernete/M Bernetta/M Bernette/M Bernhard/M Bernhardt/M Bernice/M Berniece/M Bernie/M Berni/M Bernini/M Bernita/M Bern/M Bernoulli/M Bernstein/M Berny/M Berra/M Berrie/M Berri/M berrylike Berry/M berry/SDMG berserker/M berserk/SR Berta/M Berte/M Bertha/M Berthe/M berth/MDGJ berths Bertie/M Bertillon/M Berti/M Bertina/M Bertine/M Bert/M Berton/M Bertram/M Bertrand/M Bertrando/M Berty/M Beryle/M beryllium/MS Beryl/M beryl/SM Berzelius/M bes beseecher/M beseeching/Y beseech/RSJZG beseem/GDS beset/S besetting beside/S besieger/M besiege/SRDZG besmear/GSD besmirch/GSD besom/GMDS besot/S besotted besotting besought bespangle/GSD bespatter/SGD bespeak/SG bespectacled bespoke bespoken Bess Bessel/M Bessemer/M Bessie/M Bessy/M best/DRSG bestiality/MS bestial/Y bestiary/MS bestirred bestirring bestir/S Best/M bestowal/SM bestow/SGD bestrew/DGS bestrewn bestridden bestride/SG bestrode bestseller/MS bestselling bestubble/D betaken betake/SG beta/SM betatron/M betcha Betelgeuse/M betel/MS Bethanne/M Bethany/M bethel/M Bethe/M Bethena/M Bethesda/M Bethina/M bethink/GS Bethlehem/M beth/M Beth/M bethought Bethune betide/GSD betimes bet/MS betoken/GSD betook betrayal/SM betrayer/M betray/SRDZG betrothal/SM betrothed/U betroth/GD betroths Betsey/M Betsy/M Betta/M Betteanne/M Betteann/M Bette/M betterment/MS better/SDLG Bettie/M Betti/M Bettina/M Bettine/M betting bettor/SM Bettye/M Betty/SM betweenness/M between/SP betwixt Beulah/M Bevan/M bevel/SJGMRD beverage/MS Beverie/M Beverlee/M Beverley/M Beverlie/M Beverly/M Bevin/M Bevon/M Bev's Bevvy/M bevy/SM bewail/GDS beware/GSD bewhisker/D bewigged bewildered/PY bewildering/Y bewilder/LDSG bewilderment/SM bewitching/Y bewitch/LGDS bewitchment/SM bey/MS beyond/S bezel/MS bf B/GT Bhopal/M Bhutanese Bhutan/M Bhutto/M Bialystok/M Bianca/M Bianco/M Bianka/M biannual/Y bias/DSMPG biased/U biathlon/MS biaxial/Y bibbed Bibbie/M bibbing Bibbye/M Bibby/M Bibi/M bible/MS Bible/MS biblical/Y biblicists bibliographer/MS bibliographical/Y bibliographic/S bibliography/MS bibliophile/MS Bib/M bib/MS bibulous bicameral bicameralism/MS bicarb/MS bicarbonate/MS bicentenary/S bicentennial/S bicep/S biceps/M bichromate/DM bickerer/M bickering/M bicker/SRDZG biconcave biconnected biconvex bicuspid/S bicycler/M bicycle/RSDMZG bicyclist/SM biddable bidden/U bidder/MS Biddie/M bidding/MS Biddle/M Biddy/M biddy/SM bider/M bide/S bidet/SM Bidget/M bid/GMRS bidiagonal bidirectional/Y bids/A biennial/SY biennium/SM Bienville/M Bierce/M bier/M bifocal/S bifurcate/SDXGNY bifurcation/M bigamist/SM bigamous bigamy/SM Bigelow/M Bigfoot bigged bigger biggest biggie/SM bigging biggish bighead/MS bigheartedness/S bighearted/P bighorn/MS bight/SMDG bigmouth/M bigmouths bigness/SM bigoted/Y bigot/MDSG bigotry/MS big/PYS bigwig/MS biharmonic bijection/MS bijective/Y bijou/M bijoux bike/MZGDRS biker/M bikini/SMD Biko/M bilabial/S bilateralness/M bilateral/PY bilayer/S Bilbao/M bilberry/MS Bilbo/M bile/SM bilge/GMDS biliary Bili/M bilinear bilingualism/SM bilingual/SY biliousness/SM bilious/P bilker/M bilk/GZSDR billboard/MDGS biller/M billet/MDGS billfold/MS billiard/SM Billie/M Billi/M billing/M billingsgate/SM Billings/M billionaire/MS billion/SHM billionths bill/JGZSBMDR Bill/JM billow/DMGS billowy/RT billposters Billye/M Billy/M billy/SM Bil/MY bi/M Bi/M bimbo/MS bimetallic/S bimetallism/MS Bimini/M bimodal bimolecular/Y bimonthly/S binary/S binaural/Y binder/M bindery/MS binding/MPY bindingness/M bind/JDRGZS bindle/M binds/AU bindweed/MS binge/MS bing/GNDM Bingham/M Binghamton/M Bing/M bingo/MS Bini/M Bink/M Binky/M binnacle/MS binned Binnie/M Binni/M binning Binny/M binocular/SY binodal binomial/SYM bin/SM binuclear biochemical/SY biochemist/MS biochemistry/MS biodegradability/S biodegradable biodiversity/S bioengineering/M bioethics biofeedback/SM biographer/M biographic biographical/Y biograph/RZ biography/MS biog/S Bioko/M biol biological/SY biologic/S biologist/SM biology/MS biomass/SM biomedical biomedicine/M biometric/S biometrics/M biometry/M biomolecule/S biomorph bionically bionic/S bionics/M biophysical/Y biophysicist/SM biophysic/S biophysics/M biopic/S biopsy/SDGM biorhythm/S BIOS bioscience/S biosphere/MS biostatistic/S biosynthesized biotechnological biotechnologist biotechnology/SM biotic biotin/SM bipartisan bipartisanship/MS bipartite/YN bipartition/M bipedal biped/MS biplane/MS bipolar bipolarity/MS biracial Birch/M birch/MRSDNG birdbath/M birdbaths birdbrain/SDM birdcage/SM birder/M birdhouse/MS birdieing Birdie/M birdie/MSD birdlike birdlime/MGDS Bird/M birdseed/MS Birdseye/M bird/SMDRGZ birdsong birdtables birdwatch/GZR birefringence/M birefringent biretta/SM Birgit/M Birgitta/M Birkenstock/M Birk/M Birmingham/M Biro/M Biron/M birthday/SM birthmark/MS birth/MDG birthplace/SM birthrate/MS birthright/MS birth's/A births/A birthstone/SM bis Biscay/M Biscayne/M biscuit/MS bisect/DSG bisection/MS bisector/MS biserial bisexuality/MS bisexual/YMS Bishkek bishop/DGSM Bishop/M bishopric/SM Bismarck/M Bismark/M bismuth/M bismuths bison/M bisque/SM Bissau/M bistable bistate bistro/SM bisyllabic bitblt/S bitchily bitchiness/MS bitch/MSDG bitchy/PTR biter/M bite/S biting/Y bitmap/SM bit/MRJSZG BITNET/M bit's/C bits/C bitser/M bitted bitten bitterness/SM bittern/SM bitternut/M bitter/PSRDYTG bitterroot/M bittersweet/YMSP bitting bitty/PRT bitumen/MS bituminous bitwise bivalent/S bivalve/MSD bivariate bivouacked bivouacking bivouac/MS biweekly/S biyearly bizarreness/M bizarre/YSP Bizet/M biz/M bizzes Bjorn/M bk b/KGD Bk/M blabbed blabber/GMDS blabbermouth/M blabbermouths blabbing blab/S blackamoor/SM blackball/SDMG blackberry/GMS blackbirder/M blackbird/SGDRM blackboard/SM blackbody/S Blackburn/M blackcurrant/M blackener/M blacken/GDR Blackfeet Blackfoot/M blackguard/MDSG blackhead/SM blacking/M blackish blackjack/SGMD blackleg/M blacklist/DRMSG blackmail/DRMGZS blackmailer/M Blackman/M Blackmer/M blackness/MS blackout/SM Blackpool/M Black's black/SJTXPYRDNG blacksmith/MG blacksmiths blacksnake/MS blackspot Blackstone/M blackthorn/MS blacktop/MS blacktopped blacktopping Blackwell/MS bladder/MS bladdernut/M bladderwort/M blade/DSGM blah/MDG blahs Blaine/M Blaire/M Blair/M Blakelee/M Blakeley/M Blake/M Blakey/M blame/DSRBGMZ blamelessness/SM blameless/YP blamer/M blameworthiness/SM blameworthy/P Blanca/M Blancha/M Blanchard/M blanch/DRSG Blanche/M blancher/M Blanch/M blanc/M blancmange/SM blandishment/MS blandish/SDGL blandness/MS bland/PYRT Blane/M Blankenship/M blanketing/M blanket/SDRMZG blankness/MS blank/SPGTYRD Blanton/M Blantyre/M blare/DSG blarney/DMGS blas blasphemer/M blaspheme/RSDZG blasphemousness/M blasphemous/PY blasphemy/SM blaster/M blasting/M blastoff/SM blast/SMRDGZ blatancy/SM blatant/YP blather/DRGS blatting Blatz/M Blavatsky/M Blayne/M blaze/DSRGMZ blazer/M blazing/Y blazoner/M blazon/SGDR bl/D bldg bleach/DRSZG bleached/U bleacher/M bleakness/MS bleak/TPYRS blear/GDS blearily bleariness/SM bleary/PRT bleater/M bleat/RDGS bleeder/M bleed/ZRJSG Bleeker/M bleep/GMRDZS blemish/DSMG blemished/U blench/DSG blender/M blend/GZRDS Blenheim/M blessedness/MS blessed/PRYT blessing/M bless/JGSD Blevins/M blew Bligh/M blighter/M blight/GSMDR blimey/S blimp/MS blinded/U blinder/M blindfold/SDG blinding/MY blind/JGTZPYRDS blindness/MS blindside/SDG blinker/MDG blinking/U blink/RDGSZ blinks/M Blinnie/M Blinni/M Blinny/M blintze/M blintz/SM blip/MS blipped blipping Blisse/M blissfulness/MS blissful/PY Bliss/M bliss/SDMG blistering/Y blister/SMDG blistery Blithe/M blitheness/SM blither/G blithesome blithe/TYPR blitz/GSDM blitzkrieg/SM blizzard/MS bloater/M bloat/SRDGZ blobbed blobbing blob/MS Bloch/M blockader/M blockade/ZMGRSD blockage/MS blockbuster/SM blockbusting/MS blocker/MS blockhead/MS blockhouse/SM block's block/USDG blocky/R bloc/MS Bloemfontein/M bloke/SM Blomberg/M Blomquist/M Blondelle/M Blondell/M blonde's Blondie/M blondish blondness/MS blond/SPMRT Blondy/M bloodbath bloodbaths bloodcurdling bloodhound/SM bloodied/U bloodiness/MS bloodlessness/SM bloodless/PY bloodletting/MS bloodline/SM bloodmobile/MS bloodroot/M bloodshed/SM bloodshot blood/SMDG bloodsport/S bloodstain/MDS bloodstock/SM bloodstone/M bloodstream/SM bloodsucker/SM bloodsucking/S bloodthirstily bloodthirstiness/MS bloodthirsty/RTP bloodworm/M bloodymindedness bloody/TPGDRS bloomer/M Bloomer/M Bloomfield/M Bloomington/M Bloom/MR bloom/SMRDGZ blooper/M bloop/GSZRD blossom/DMGS blossomy blotch/GMDS blotchy/RT blot/MS blotted blotter/MS blotting blotto blouse/GMSD blower/M blowfish/M blowfly/MS blowgun/SM blow/GZRS blowing/M blown/U blowout/MS blowpipe/SM blowtorch/SM blowup/MS blowy/RST blowzy/RT BLT blubber/GSDR blubbery Blucher/M bludgeon/GSMD blueback Bluebeard/M bluebell/MS blueberry/SM bluebill/M bluebird/MS bluebonnet/SM bluebook/M bluebottle/MS bluebush bluefish/SM bluegill/SM bluegrass/MS blueing's blueish bluejacket/MS bluejeans blue/JMYTGDRSP blueness/MS bluenose/MS bluepoint/SM blueprint/GDMS bluer/M bluest/M bluestocking/SM bluesy/TR bluet/MS bluffer/M bluffness/MS bluff/SPGTZYRD bluing/M bluishness/M bluish/P Blumenthal/M Blum/M blunderbuss/MS blunderer/M blunder/GSMDRJZ blundering/Y bluntness/MS blunt/PSGTYRD blurb/GSDM blur/MS blurred/Y blurriness/S blurring/Y blurry/RPT blurt/GSRD blusher/M blushing/UY blush/RSDGZ blusterer/M blustering/Y blusterous bluster/SDRZG blustery blvd Blvd Blythe/M BM BMW/M BO boarded boarder/SM boardgames boardinghouse/SM boarding/SM board/IS boardroom/MS board's boardwalk/SM boar/MS boa/SM boaster/M boastfulness/MS boastful/YP boast/SJRDGZ boatclubs boater/M boathouse/SM boating/M boatload/SM boatman/M boat/MDRGZJS boatmen boatswain/SM boatyard/SM bobbed Bobbee/M Bobbe/M Bobbette/M Bobbie/M Bobbi/M bobbing/M bobbin/MS Bobbitt/M bobble/SDGM Bobbsey/M Bobbye/M Bobby/M bobby/SM bobbysoxer's bobcat/MS Bobette/M Bobina/M Bobine/M Bobinette/M Bob/M bobolink/SM Bobrow/M bobsledded bobsledder/MS bobsledding/M bobsled/MS bobsleigh/M bobsleighs bobs/M bob/SM bobtail/SGDM bobwhite/SM Boca/M Boccaccio/M boccie/SM bock/GDS bockwurst bodega/MS Bodenheim/M bode/S Bodhidharma/M bodhisattva Bodhisattva/M bodice/SM bodied/M bodiless bodily boding/M bodkin/SM bod/SGMD bodybuilder/SM bodybuilding/S body/DSMG bodyguard/MS bodying/M bodysuit/S bodyweight bodywork/SM Boeing/M Boeotia/M Boeotian Boer/M Bogartian/M Bogart/M Bogey/M bogeyman/M bogeymen bogey/SGMD bogged bogging boggle/SDG boggling/Y boggy/RT bogie's bog/MS Bogot/M bogus bogyman bogymen bogy's Boheme/M bohemianism/S bohemian/S Bohemian/SM Bohemia/SM Bohr/M Boigie/M boiled/AU boiler/M boilermaker/MS boilerplate/SM boil/JSGZDR boils/A Boise/M Bois/M boisterousness/MS boisterous/YP bola/SM boldface/SDMG boldness/MS bold/YRPST bole/MS bolero/MS Boleyn/M bolivares Bolivar/M bolivar/MS Bolivia/M Bolivian/S bollard/SM bollix/GSD boll/MDSG Bologna/M bologna/MS bolometer/MS bolo/MS boloney's Bolshevik/MS Bolshevism/MS Bolshevistic/M Bolshevist/MS Bolshoi/M bolsterer/M bolster/SRDG bolted/U bolter/M bolt/MDRGS Bolton/M bolts/U Boltzmann/M bolus/SM bombardier/MS bombard/LDSG bombardment/SM bombastic bombastically bombast/RMS Bombay/M bomber/M bombproof bomb/SGZDRJ bombshell/SM Bo/MRZ bona bonanza/MS Bonaparte/M Bonaventure/M bonbon/SM bondage/SM bonder/M bondholder/SM Bondie/M bond/JMDRSGZ Bond/M bondman/M bondmen Bondon/M bonds/A bondsman/M bondsmen bondwoman/M bondwomen Bondy/M boned/U bonehead/SDM boneless Bone/M bone/MZDRSG boner/M bonfire/MS bong/GDMS bongo/MS Bonham/M bonhomie/MS Boniface/M boniness/MS Bonita/M bonito/MS bonjour bonkers Bonnee/M Bonner/M bonneted/U bonnet/SGMD Bonneville/M Bonnibelle/M bonnie Bonnie/M Bonni/M Bonn/RM Bonny/M bonny/RT bonsai/SM Bontempo/M bonus/SM bony/RTP bonzes boob/DMSG booby/SM boodle/GMSD boogeyman's boogieing boogie/SD boo/GSDH boohoo/GDS bookbinder/M bookbindery/SM bookbinding/M bookbind/JRGZ bookcase/MS booked/U bookend/SGD Booker/M book/GZDRMJSB bookie/SM booking/M bookishness/M bookish/PY bookkeeper/M bookkeep/GZJR bookkeeping/M booklet/MS bookmaker/MS bookmaking/MS bookmark/MDGS bookmobile/MS bookplate/SM bookseller/SM bookshelf/M bookshelves bookshop/MS bookstall/MS bookstore/SM bookwork/M bookworm/MS Boolean boolean/S Boole/M boom/DRGJS boomerang/MDSG boomer/M boomtown/S boondocks boondoggle/DRSGZ boondoggler/M Boone/M Boonie/M boonies boon/MS Boony/M boorishness/SM boorish/PY boor/MS boosterism booster/M boost/SGZMRD boot/AGDS bootblack/MS bootee/MS Boote/M Botes Boothe/M booth/M Booth/M booths bootie's bootlaces bootlegged/M bootlegger/SM bootlegging/M bootleg/S Bootle/M bootless Boot/M bootprints boot's bootstrapped bootstrapping bootstrap/SM booty/SM booze/DSRGMZ boozer/M boozy/TR bopped bopping bop/S borate/MSD borax/MS Bordeaux/M bordello/MS Borden/M borderer/M border/JRDMGS borderland/SM borderline/MS Bordie/M Bord/MN Bordon/M Bordy/M Borealis/M Boreas/M boredom/MS boreholes borer/M bore/ZGJDRS Borges Borgia/M Borg/M boric boring/YMP Boris Bork/M born/AIU Borneo/M borne/U Born/M Borodin/M boron/SM borosilicate/M borough/M boroughs Borroughs/M borrower/M borrowing/M borrow/JZRDGBS borscht/SM borstal/MS Boru/M borzoi/MS Bosch/M Bose/M bosh/MS Bosnia/M Bosnian/S bosom's bosom/SGUD bosomy/RT boson/SM Bosporus/M boss/DSRMG bossily bossiness/MS bossism/MS bossy/PTSR Bostitch/M Bostonian/SM Boston/MS bosun's Boswell/MS botanical/SY botanic/S botanist/SM botany/SM botcher/M botch/SRDGZ botfly/M bother/DG bothersome bothy/M both/ZR bot/S Botswana/M Botticelli/M bottle/GMZSRD bottleneck/GSDM bottler/M bottomlessness/M bottomless/YP bottommost bottom/SMRDG botulin/M botulinus/M botulism/SM Boucher/M boudoir/MS bouffant/S bougainvillea/SM bough/MD boughs bought/N bouillabaisse/MS bouillon/MS boulder/GMDS Boulder/M boulevard/MS bouncer/M bounce/SRDGZ bouncily bouncing/Y bouncy/TRP boundary/MS bound/AUDI boundedness/MU bounded/UP bounden bounder/AM bounders bounding boundlessness/SM boundless/YP bounds/IA bounteousness/MS bounteous/PY bountifulness/SM bountiful/PY bounty/SDM bouquet/SM Bourbaki/M bourbon/SM Bourbon/SM bourgeoisie/SM bourgeois/M Bourke/M Bourne/M Bournemouth/M boutique/MS bout/MS boutonnire/MS Bouvier Bovary/M bovine/YS Bowditch/M bowdlerization/MS bowdlerize/GRSD bowed/U bowel/GMDS Bowell/M Bowen/M bower/DMG Bowers Bowery/M Bowes bowie Bowie/M bowing/M bowlder's bowlegged bowleg/SM bowler/M bowlful/S bowl/GZSMDR bowline/MS bowling/M bowman/M Bowman/M bowmen bowser/M bowsprit/SM bows/R bowstring/GSMD bow/SZGNDR bowwow/DMGS boxcar/SM box/DRSJZGM boxer/M boxful/M boxing/M boxlike boxtops boxwood/SM boxy/TPR Boyce/M Boycey/M Boycie/M boycotter/M boycott/RDGS Boyd/M Boyer/M boyfriend/MS boyhood/SM boyishness/MS boyish/PY Boyle/M Boy/MR boy/MRS boyscout boysenberry/SM bozo/SM bpi bps BR brace/DSRJGM braced/U bracelet/MS bracer/M brachia brachium/M bracken/SM bracketed/U bracketing/M bracket/SGMD brackishness/SM brackish/P bract/SM Bradan/M bradawl/M Bradbury/M Bradburys bradded bradding Braddock/M Brade/M Braden/M Bradford/M Bradley/M Bradly/M Brad/MYN Bradney/M Bradshaw/M brad/SM Bradstreet/M Brady/M brae/SM braggadocio/SM braggart/SM bragged bragger/MS braggest bragging Bragg/M brag/S Brahe/M Brahma/MS Brahmanism/MS Brahman/SM Brahmaputra/M Brahmin's Brahms braider/M braiding/M braid/RDSJG braille/DSG Braille/GDSM Brainard/SM braincell/S brainchild/M brainchildren brain/GSDM braininess/MS brainlessness/M brainless/YP Brain/M brainpower/M brainstorm/DRMGJS brainstorming/M brainteaser/S brainteasing brainwasher/M brainwashing/M brainwash/JGRSD brainwave/S brainy/RPT braise/SDG brake/DSGM brakeman/M brakemen/M bramble/DSGM brambling/M brambly/RT Bram/M Brampton/M bra/MS Brana/M branched/U branching/M branchlike Branch/M branch/MDSJG Branchville/M Brandais/M Brandea/M branded/U Brandeis/M Brandel/M Brande/M Brandenburg/M Branden/M brander/GDM Brander/M Brandice/M Brandie/M Brandi/M Brandise/M brandish/GSD Brand/MRN Brando/M Brandon/M brand/SMRDGZ Brandt/M Brandtr/M brandy/GDSM Brandy/M Brandyn/M brandywine Braniff/M Bran/M branned branning Brannon/M bran/SM Brantley/M Brant/M Braque/M brashness/MS brash/PYSRT Brasilia brasserie/SM brass/GSDM brassiere/MS brassily brassiness/SM brassy/RSPT Bratislava/M brat/SM Brattain/M bratty/RT bratwurst/MS Braun/M bravadoes bravado/M brave/DSRGYTP braveness/MS bravery/MS bravest/M bravo/SDG bravura/SM brawler/M brawl/MRDSGZ brawniness/SM brawn/MS brawny/TRP brayer/M Bray/M bray/SDRG braze/GZDSR brazenness/MS brazen/PYDSG brazer/M brazier/SM Brazilian/MS Brazil/M Brazos/M Brazzaville/M breacher/M breach/MDRSGZ breadbasket/SM breadboard/SMDG breadbox/S breadcrumb/S breadfruit/MS breadline/MS bread/SMDHG breadth/M breadths breadwinner/MS breakables breakable/U breakage/MS breakaway/MS breakdown/MS breaker/M breakfaster/M breakfast/RDMGZS breakfront/S breaking/M breakneck breakout/MS breakpoint/SMDG break/SZRBG breakthroughs breakthrough/SM breakup/SM breakwater/SM bream/SDG Breanne/M Brear/M breastbone/MS breastfed breastfeed/G breasting/M breast/MDSG breastplate/SM breaststroke/SM breastwork/MS breathable/U breathalyser/S Breathalyzer/SM breathe breather/M breathing/M breathlessness/SM breathless/PY breaths breathtaking/Y breathy/TR breath/ZBJMDRSG Brecht/M Breckenridge/M bred/DG bredes breeching/M breech/MDSG breeder/I breeder's breeding/IM breeds/I breed/SZJRG Bree/M Breena/M breeze/GMSD breezeway/SM breezily breeziness/SM breezy/RPT Bremen/M bremsstrahlung/M Brena/M Brenda/M Brendan/M Brenden/M Brendin/M Brendis/M Brendon/M Bren/M Brenna/M Brennan/M Brennen/M Brenner/M Brenn/RNM Brent/M Brenton/M Bresenham/M Brest/M brethren Bret/M Breton Brett/M breve/SM brevet/MS brevetted brevetting breviary/SM brevity/MS brew/DRGZS brewer/M Brewer/M brewery/MS brewing/M brewpub/S Brew/RM Brewster/M Brezhnev/M Bria/M Briana/M Brian/M Brianna/M Brianne/M Briano/M Briant/M briar's bribe/GZDSR briber/M bribery/MS Brice/M brickbat/SM brick/GRDSM bricklayer/MS bricklaying/SM brickmason/S brickwork/SM brickyard/M bridal/S Bridalveil/M bridegroom/MS Bride/M bride/MS bridesmaid/MS Bridewell/M bridgeable/U bridged/U bridgehead/MS Bridgeport/M Bridger/M Bridges bridge/SDGM Bridget/M Bridgetown/M Bridgette/M Bridgett/M Bridgewater/M bridgework/MS bridging/M Bridgman/M Bridie/M bridled/U bridle/SDGM bridleway/S briefcase/SM briefed/C briefing/M briefness/MS briefs/C brief/YRDJPGTS Brien/M Brier/M brier/MS Brie/RSM Brietta/M brigade/GDSM brigadier/MS Brigadoon brigandage/MS brigand/MS brigantine/MS Brigg/MS Brigham/M brightener/M brighten/RDZG bright/GXTPSYNR Bright/M brightness/SM Brighton/M Brigida/M Brigid/M Brigit/M Brigitta/M Brigitte/M Brig/M brig/SM brilliance/MS brilliancy/MS brilliantine/MS brilliantness/M brilliant/PSY Brillo Brillouin/M brimful brimless brimmed brimming brim/SM brimstone/MS Brina/M Brindisi/M brindle/DSM brine/GMDSR briner/M Briney/M bringer/M bring/RGZS brininess/MS Brinkley/M brinkmanship/SM brink/MS Brinna/M Brinn/M Briny/M briny/PTSR brioche/SM Brion/M briquet's briquette/MGSD Brisbane/M brisket/SM briskness/MS brisk/YRDPGTS bristle/DSGM bristly/TR Bristol/M bristol/S Britain/M Brita/M Britannia/M Britannic Britannica/M britches Briticism/MS Britisher/M Britishly/M British/RYZ Brit/MS Britney/M Britni/M Briton/MS Britta/M Brittaney/M Brittani/M Brittan/M Brittany/MS Britte/M Britten/M Britteny/M brittleness/MS brittle/YTPDRSG Britt/MN Brittne/M Brittney/M Brittni/M Brnaba/M Brnaby/M Brno/M broach/DRSG broacher/M broadband broadcaster/M broadcast/RSGZJ broadcasts/A broadcloth/M broadcloths broaden/JGRDZ broadleaved broadloom/SM broadminded/P broadness/S broadsheet/MS broadside/SDGM broadsword/MS broad/TXSYRNP Broadway/SM Brobdingnagian Brobdingnag/M brocade/DSGM broccoli/MS brochette/SM brochure/SM Brockie/M Brock/M Brocky/M Broddie/M Broddy/M Broderick/M Broderic/M Brodie/M Brod/M Brody/M brogan/MS Broglie/M brogue/MS broiler/M broil/RDSGZ brokenhearted/Y brokenness/MS broken/YP brokerage/MS broker/DMG broke/RGZ Brok/M bromide/MS bromidic bromine/MS bronchial bronchi/M bronchiolar bronchiole/MS bronchiolitis bronchitic/S bronchitis/MS broncho's bronchus/M broncobuster/SM bronco/SM bronc/S Bron/M Bronnie/M Bronny/M Bronson/M Bronte brontosaur/SM brontosaurus/SM Bronx/M bronzed/M bronze/SRDGM bronzing/M brooch/MS brooder/M broodiness/M brooding/Y broodmare/SM brood/SMRDGZ broody/PTR Brookdale/M Brooke/M Brookfield/M Brookhaven/M brooklet/MS Brooklyn/M Brookmont/M brook/SGDM brookside Brook/SM broom/SMDG broomstick/MS Bros Brose/M bro/SH bros/S brothel/MS brother/DYMG brotherhood/SM brotherliness/MS brotherly/P broths broth/ZMR brougham/MS brought brouhaha/MS browbeat/NSG brow/MS Brownell/M Browne/M Brownian/M Brownie/MS brownie/MTRS browning/M Browning/M brownish Brown/MG brownness/MS brownout/MS brownstone/MS Brownsville/M brown/YRDMSJGTP browse browser/M brows/SRDGZ brr Br/TMN Brubeck/M brucellosis/M Bruce/M Brucie/M Bruckner/M Bruegel/M Brueghel's bruin/MS bruised/U bruise/JGSRDZ bruiser/M Bruis/M bruit/DSG Brumidi/M Brummel/M brunch/MDSG Brunei/M Brunelleschi/M brunet/S brunette/SM Brunhilda/M Brunhilde/M Bruno/M Brunswick/M brunt/GSMD brusher/M brushfire/MS brushlike brush/MSRDG brushoff/S brushwood/SM brushwork/MS brushy/R brusqueness/MS brusque/PYTR Brussels brutality/SM brutalization/SM brutalized/U brutalizes/AU brutalize/SDG brutal/Y brute/DSRGM brutishness/SM brutish/YP Brutus/M Bruxelles/M Bryana/M Bryan/M Bryant/M Bryanty/M Bryce/M Bryna/M Bryn/M Brynna/M Brynne/M Brynner/M Brynn/RM Bryon/M Brzezinski/M B's BS BSA BSD Btu BTU BTW bu bubblegum/S bubbler/M bubble/RSDGM bubbly/TRS Buber/M bub/MS buboes bubo/M bubonic buccaneer/GMDS Buchanan/M Bucharest/M Buchenwald/M Buchwald/M buckaroo/SM buckboard/SM bucker/M bucketful/MS bucket/SGMD buckeye/SM buck/GSDRM buckhorn/M Buckie/M Buckingham/M buckled/U buckler/MDG buckle/RSDGMZ buckles/U Buckley/M buckling's buckling/U Buck/M Buckner/M buckram/GSDM bucksaw/SM buckshot/MS buckskin/SM buckteeth bucktooth/DM buckwheat/SM Bucky/M bucolically bucolic/S Budapest/M budded Buddha/MS Buddhism/SM Buddhist/SM Buddie/M budding/S Budd/M buddy/GSDM Buddy/M budge/GDS budgerigar/MS budgetary budgeter/M budget/GMRDZS budgie/MS budging/U Bud/M bud/MS Budweiser/MS Buehring/M Buena/M buffaloes Buffalo/M buffalo/MDG buff/ASGD buffered/U bufferer/M buffer/RDMSGZ buffet/GMDJS bufflehead/M buffoonery/MS buffoonish buffoon/SM buff's Buffy/M Buford/M bugaboo/SM Bugatti/M bugbear/SM bug/CS bugeyed bugged/C buggered buggering bugger/SCM! buggery/M bugging/C buggy/RSMT bugle/GMDSRZ bugler/M bug's Buick/M builder/SM building/SM build/SAG buildup/MS built/AUI Buiron/M Bujumbura/M Bukhara/M Bukharin/M Bulawayo/M Bulba/M bulb/DMGS bulblet bulbous Bulfinch/M Bulganin/M Bulgaria/M Bulgarian/S bulge/DSGM bulgy/RT bulimarexia/S bulimia/MS bulimic/S bulk/GDRMS bulkhead/SDM bulkiness/SM bulky/RPT bulldogged bulldogger bulldogging bulldog/SM bulldoze/GRSDZ bulldozer/M bullet/GMDS bulletin/SGMD bulletproof/SGD bullfighter/M bullfighting/M bullfight/SJGZMR bullfinch/MS bullfrog/SM bullhead/DMS bullheadedness/SM bullheaded/YP bullhide bullhorn/SM bullied/M bullion/SM bullishness/SM bullish/PY bull/MDGS Bullock/M bullock/MS bullpen/MS bullring/SM bullseye bullshit/MS! bullshitted/! bullshitter/S! bullshitting/! bullwhackers Bullwinkle/M bullyboy/MS bullying/M bully/TRSDGM bulrush/SM Bultmann/M bulwark/GMDS bumblebee/MS bumble/JGZRSD bumbler/M bumbling/Y Bumbry/M bummed/M bummer/MS bummest bumming/M bumper/DMG bump/GZDRS bumpiness/MS bumpkin/MS Bumppo/M bumptiousness/SM bumptious/PY bumpy/PRT bum/SM Bunche/M bunch/MSDG bunchy/RT buncombe's bunco's Bundestag/M bundled/U bundle/GMRSD bundler/M Bundy/M bungalow/MS bungee/SM bung/GDMS bunghole/MS bungle/GZRSD bungler/M bungling/Y Bunin/M bunion/SM bunk/CSGDR Bunker/M bunker's/C bunker/SDMG bunkhouse/SM bunkmate/MS bunko's bunk's bunkum/SM Bunnie/M Bunni/M Bunny/M bunny/SM Bunsen/SM bun/SM bunt/GJZDRS bunting/M Buuel/M Bunyan/M buoyancy/MS buoyant/Y buoy/SMDG Burbank/M burbler/M burble/RSDG burbs Burch/M burden's burdensomeness/M burdensome/PY burden/UGDS burdock/SM bureaucracy/MS bureaucratically bureaucratic/U bureaucratization/MS bureaucratize/SDG bureaucrat/MS bureau/MS burgeon/GDS burger/M Burger/M Burgess/M burgess/MS burgher/M burgh/MRZ burghs burglarize/GDS burglarproof/DGS burglar/SM burglary/MS burgle/SDG burgomaster/SM Burgoyne/M Burg/RM burg/SZRM Burgundian/S Burgundy/MS burgundy/S burial/ASM buried/U burier/M Burke/M Burk/SM burlap/MS burler/M burlesquer/M burlesque/SRDMYG burley/M Burlie/M burliness/SM Burlingame/M Burlington/M Burl/M burl/SMDRG burly/PRT Burma/M Burmese bur/MYS burnable/S Burnaby/M Burnard/M burned/U Burne/MS burner/M Burnett/M burn/GZSDRBJ burning/Y burnisher/M burnish/GDRSZ burnoose/MS burnout/MS Burns Burnside/MS burnt/YP burp/SGMD burr/GSDRM Burris/M burrito/S Burr/M burro/SM Burroughs/M burrower/M burrow/GRDMZS bursae bursa/M Bursa/M bursar/MS bursary/MS bursitis/MS burster/M burst/SRG Burtie/M Burt/M Burton/M Burty/M Burundian/S Burundi/M bury/ASDG busboy/MS busby/SM Busch/M buses/A busgirl/S bus/GMDSJ bushel/MDJSG Bushido/M bushiness/MS bushing/M bush/JMDSRG bushland Bush/M bushman/M bushmaster/SM bushmen Bushnell/M bushwhacker/M bushwhacking/M bushwhack/RDGSZ bushy/PTR busily businesslike businessman/M businessmen business/MS businesspeople businessperson/S businesswoman/M businesswomen busker/M busk/GRM buskin/SM bus's/A buss/D bustard/MS buster/M bustle/GSD bustling/Y bust/MSDRGZ busty/RT busybody/MS busy/DSRPTG busyness/MS busywork/SM but/ACS butane/MS butcherer/M butcher/MDRYG butchery/MS Butch/M butch/RSZ butene/M Butler/M butler/SDMG butted/A butte/MS butterball/MS buttercup/SM buttered/U butterfat/MS Butterfield/M butterfingered butterfingers/M butterfly/MGSD buttermilk/MS butternut/MS butter/RDMGZ butterscotch/SM buttery/TRS butting/M buttock/SGMD buttoner/M buttonhole/GMRSD buttonholer/M button's button/SUDG buttonweed buttonwood/SM buttress/MSDG butt/SGZMDR butyl/M butyrate/M buxomness/M buxom/TPYR Buxtehude/M buyback/S buyer/M buyout/S buy/ZGRS buzzard/MS buzz/DSRMGZ buzzer/M buzzword/SM buzzy bx bxs byelaw's Byelorussia's bye/MZS Byers/M bygone/S bylaw/SM byliner/M byline/RSDGM BYOB bypass/GSDM bypath/M bypaths byplay/S byproduct/SM Byram/M Byran/M Byrann/M Byrd/M byre/SM Byrle/M Byrne/M byroad/MS Byrom/M Byronic Byronism/M Byron/M bystander/SM byte/SM byway/SM byword/SM byzantine Byzantine/S Byzantium/M by/ZR C ca CA cabala/MS caballed caballero/SM caballing cabal/SM cabana/MS cabaret/SM cabbage/MGSD cabbed cabbing cabby's cabdriver/SM caber/M Cabernet/M cabinetmaker/SM cabinetmaking/MS cabinet/MS cabinetry/SM cabinetwork/MS cabin/GDMS cablecast/SG cable/GMDS cablegram/SM cabochon/MS caboodle/SM caboose/MS Cabot/M Cabrera/M Cabrini/M cabriolet/MS cab/SMR cabstand/MS cacao/SM cacciatore cache/DSRGM cachepot/MS cachet/MDGS Cacilia/M Cacilie/M cackler/M cackle/RSDGZ cackly CACM cacophonist cacophonous cacophony/SM cacti cactus/M CAD cadaverous/Y cadaver/SM caddishness/SM caddish/PY Caddric/M caddy/GSDM cadence/CSM cadenced cadencing cadent/C cadenza/MS cadet/SM Cadette/S cadge/DSRGZ cadger/M Cadillac/MS Cadiz/M Cad/M cadmium/MS cadre/SM cad/SM caducei caduceus/M Caedmon/M Caesar/MS caesura/SM caf/MS cafeteria/SM caffeine/SM caftan/SM caged/U Cage/M cage/MZGDRS cager/M cagey/P cagier cagiest cagily caginess/MS Cagney/M Cahokia/M cahoot/MS Cahra/M CAI Caiaphas/M caiman's Caine/M Cain/MS Cairistiona/M cairn/SDM Cairo/M caisson/SM caitiff/MS Caitlin/M Caitrin/M cajole/LGZRSD cajolement/MS cajoler/M cajolery/SM Cajun/MS cake/MGDS cakewalk/SMDG calabash/SM calaboose/MS Calais/M calamari/S calamine/GSDM calamitousness/M calamitous/YP calamity/MS cal/C calcareousness/M calcareous/PY calciferous calcification/M calcify/XGNSD calcimine/GMSD calcine/SDG calcite/SM calcium/SM Calcomp/M CalComp/M CALCOMP/M calculability/IM calculable/IP calculate/AXNGDS calculated/PY calculatingly calculating/U calculation/AM calculative calculator/SM calculi calculus/M Calcutta/M caldera/SM Calder/M Calderon/M caldron's Caldwell/M Caleb/M Caledonia/M Cale/M calendar/MDGS calender/MDGS calf/M calfskin/SM Calgary/M Calhoun/M Caliban/M caliber/SM calibrated/U calibrater's calibrate/XNGSD calibrating/A calibration/M calibrator/MS calicoes calico/M Calida/M Calif/M California/M Californian/MS californium/SM calif's Caligula/M Cali/M caliper/SDMG caliphate/SM caliph/M caliphs calisthenic/S calisthenics/M Callaghan/M call/AGRDBS Callahan/M calla/MS Calla/MS Callao/M callback/S Callean/M called/U callee/M caller/MS Calley/M Callida/M Callie/M calligrapher/M calligraphic calligraphist/MS calligraph/RZ calligraphy/MS Calli/M calling/SM Calliope/M calliope/SM callisthenics's Callisto/M callosity/MS callousness/SM callous/PGSDY callowness/MS callow/RTSP callus/SDMG Cally/M calming/Y calmness/MS calm/PGTYDRS Cal/MY Caloocan/M caloric/S calorie/SM calorific calorimeter/MS calorimetric calorimetry/M Caltech/M Calumet/M calumet/MS calumniate/NGSDX calumniation/M calumniator/SM calumnious calumny/MS calvary/M Calvary/M calve/GDS Calvert/M calves/M Calvinism/MS Calvinistic Calvinist/MS Calvin/M Calv/M calyces's Calypso/M calypso/SM calyx/MS Ca/M CAM Camacho/M Camala/M camaraderie/SM camber/DMSG cambial cambium/SM Cambodia/M Cambodian/S Cambrian/S cambric/MS Cambridge/M camcorder/S Camden/M camelhair's Camella/M Camellia/M camellia/MS Camel/M Camelopardalis/M Camelot/M camel/SM Camembert/MS cameo/GSDM camerae cameraman/M cameramen camera/MS camerawoman camerawomen Cameron/M Cameroonian/S Cameroon/SM came/N Camey/M Camila/M Camile/M Camilla/M Camille/M Cami/M Camino/M camion/M camisole/MS Cam/M cammed Cammie/M Cammi/M cam/MS Cammy/M Camoens/M camomile's camouflage/DRSGZM camouflager/M campaigner/M campaign/ZMRDSG campanile/SM campanological campanologist/SM campanology/MS Campbell/M Campbellsport/M camper/SM campesinos campest campfire/SM campground/MS camphor/MS Campinas/M camping/S Campos camp's camp/SCGD campsite/MS campus/GSDM campy/RT Camry/M camshaft/SM Camus/M Canaanite/SM Canaan/M Canada/M Canadianism/SM Canadian/S Canad/M Canaletto/M canalization/MS canalize/GSD canal/SGMD canap/S canard/MS Canaries canary/SM canasta/SM Canaveral/M Canberra/M cancan/SM cancelate/D canceled/U canceler/M cancellation/MS cancel/RDZGS cancer/MS Cancer/MS cancerous/Y Cancun/M Candace/M candelabra/S candelabrum/M Candice/M candidacy/MS Candida/M candidate/SM candidature/S Candide/M candidly/U candidness/SM candid/TRYPS Candie/M Candi/SM candle/GMZRSD candlelight/SMR candlelit candlepower/SM candler/M candlestick/SM Candlewick/M candlewick/MS candor/MS Candra/M candy/GSDM Candy/M canebrake/SM caner/M cane/SM canine/S caning/M Canis/M canister/SGMD cankerous canker/SDMG Can/M can/MDRSZGJ cannabis/MS canned cannelloni canner/SM cannery/MS Cannes cannibalism/MS cannibalistic cannibalization/SM cannibalize/GSD cannibal/SM cannily/U canninesses canniness/UM canning/M cannister/SM cannonade/SDGM cannonball/SGDM Cannon/M cannon/SDMG cannot canny/RPUT canoe/DSGM canoeist/SM Canoga/M canonic canonicalization canonicalize/GSD canonical/SY canonist/M canonization/MS canonized/U canonize/SDG canon/SM Canopus/M canopy/GSDM canst can't cantabile/S Cantabrigian cantaloupe/MS cantankerousness/SM cantankerous/PY cantata/SM cant/CZGSRD canted/IA canteen/MS Canterbury/M canter/CM cantered cantering canticle/SM cantilever/SDMG canto/MS cantonal Cantonese/M Canton/M cantonment/SM canton/MGSLD Cantor/M cantor/MS Cantrell/M cant's cants/A Cantu/M Canute/M canvasback/MS canvas/RSDMG canvasser/M canvass/RSDZG canyon/MS CAP capability/ISM capableness/IM capable/PI capabler capablest capably/I capaciousness/MS capacious/PY capacitance/SM capacitate/V capacitive/Y capacitor/MS capacity/IMS caparison/SDMG Capek/M Capella/M caper/GDM capeskin/SM cape/SM Capet/M Capetown/M Caph/M capillarity/MS capillary/S Capistrano/M capitalism/SM capitalistic capitalistically capitalist/SM capitalization/SMA capitalized/AU capitalizer/M capitalize/RSDGZ capitalizes/A capital/SMY capita/M Capitan/M capitation/CSM Capitoline/M Capitol/MS capitol/SM capitulate/AXNGSD capitulation/MA caplet/S cap/MDRSZB Capone/M capon/SM capo/SM Capote/M capped/UA capping/M cappuccino/MS Cappy/M Capra/M Caprice/M caprice/MS capriciousness/MS capricious/PY Capricorn/MS Capri/M caps/AU capsicum/MS capsize/SDG capstan/MS capstone/MS capsular capsule/MGSD capsulize/GSD captaincy/MS captain/SGDM caption/GSDRM captiousness/SM captious/PY captivate/XGNSD captivation/M captivator/SM captive/MS captivity/SM Capt/M captor/SM capture/AGSD capturer/MS capt/V Capulet/M Caputo/M Caracalla/M Caracas/M caracul's carafe/SM Caralie/M Cara/M caramelize/SDG caramel/MS carapace/SM carapaxes carat/SM Caravaggio/M caravan/DRMGS caravaner/M caravansary/MS caravanserai's caravel/MS caraway/MS carbide/MS carbine/MS carbohydrate/MS carbolic Carboloy/M carbonaceous carbonate/SDXMNG carbonation/M Carbondale/M Carbone/MS carbonic carboniferous Carboniferous carbonization/SAM carbonizer/AS carbonizer's carbonizes/A carbonize/ZGRSD carbon/MS carbonyl/M carborundum Carborundum/MS carboy/MS carbuncle/SDM carbuncular carburetor/MS carburetter/S carburettor/SM carcase/MS carcass/SM Carce/M carcinogenic carcinogenicity/MS carcinogen/SM carcinoma/SM cardamom/MS cardboard/MS card/EDRSG Cardenas/M carder/MS carder's/E cardholders cardiac/S Cardiff/M cardigan/SM cardinality/SM cardinal/SYM carding/M Cardin/M Cardiod/M cardiogram/MS cardiograph/M cardiographs cardioid/M cardiologist/SM cardiology/MS cardiomegaly/M cardiopulmonary cardiovascular card's cardsharp/ZSMR CARE cared/U careen/DSG careerism/M careerist/MS career/SGRDM carefree carefuller carefullest carefulness/MS careful/PY caregiver/S carelessness/MS careless/YP Care/M Carena/M Caren/M carer/M care/S Caresa/M Caressa/M Caresse/M caresser/M caressing/Y caressive/Y caress/SRDMVG caretaker/SM caret/SM careworn Carey/M carfare/MS cargoes cargo/M carhopped carhopping carhop/SM Caria/M Caribbean/S Carib/M caribou/MS caricature/GMSD caricaturisation caricaturist/MS caricaturization Carie/M caries/M carillonned carillonning carillon/SM Caril/M Carilyn/M Cari/M Carina/M Carine/M caring/U Carin/M Cariotta/M carious Carissa/M Carita/M Caritta/M carjack/GSJDRZ Carla/M Carlee/M Carleen/M Carlene/M Carlen/M Carletonian/M Carleton/M Carley/M Carlie/M Carlina/M Carline/M Carling/M Carlin/M Carlita/M Carl/MNG carload/MSG Carlo/SM Carlota/M Carlotta/M Carlsbad/M Carlson/M Carlton/M Carlye/M Carlyle/M Carly/M Carlyn/M Carlynne/M Carlynn/M Carma/M Carmela/M Carmelia/M Carmelina/M Carmelita/M Carmella/M Carmelle/M Carmel/M Carmelo/M Carmencita/M Carmen/M Carmichael/M Carmina/M Carmine/M carmine/MS Carmita/M Car/MNY Carmon/M carnage/MS carnality/SM carnal/Y Carnap/M carnation/IMS Carnegie/M carnelian/SM Carney/M carney's carnival/MS carnivore/SM carnivorousness/MS carnivorous/YP Carnot/M Carny/M carny/SDG carob/SM Carola/M Carolan/M Carolann/M Carolee/M Carole/M caroler/M Carolina/MS Caroline/M Carolingian Carolinian/S Carolin/M Caroljean/M Carol/M carol/SGZMRD Carolus/M Carolyne/M Carolyn/M Carolynn/M Caro/M carom/GSMD Caron/M carotene/MS carotid/MS carousal/MS carousel/MS carouser/M carouse/SRDZG carpal/SM Carpathian/MS carpel/SM carpenter/DSMG carpentering/M Carpenter/M carpentry/MS carper/M carpetbagged carpetbagger/MS carpetbagging carpetbag/MS carpeting/M carpet/MDJGS carpi/M carping/Y carp/MDRSGZ carpool/DGS carport/MS carpus/M carrageen/M Carree/M carrel/SM carriage/SM carriageway/SM Carrie/M carrier/M Carrier/M Carrillo/M Carri/M carrion/SM Carrissa/M Carr/M Carroll/M Carrol/M carrot/MS carroty/RT carrousel's carryall/MS Carry/MR carryout/S carryover/S carry/RSDZG carsickness/SM carsick/P Carson/M cartage/MS cartel/SM carte/M carter/M Carter/M Cartesian Carthage/M Carthaginian/S carthorse/MS Cartier/M cartilage/MS cartilaginous cartload/MS cart/MDRGSZ Cart/MR cartographer/MS cartographic cartography/MS carton/GSDM cartoon/GSDM cartoonist/MS cartridge/SM cartwheel/MRDGS Cartwright/M Carty/RM Caruso/M carve/DSRJGZ carven carver/M Carver/M carving/M caryatid/MS Caryl/M Cary/M Caryn/M car/ZGSMDR casaba/SM Casablanca/M Casals/M Casandra/M Casanova/SM Casar/M casbah/M cascade/MSDG Cascades/M cascara/MS casebook/SM case/DSJMGL cased/U caseharden/SGD casein/SM caseload/MS Case/M casement/SM caseworker/M casework/ZMRS Casey/M cashbook/SM cashew/MS cash/GZMDSR cashier/SDMG cashless Cash/M cashmere/MS Casie/M Casi/M casing/M casino/MS casket/SGMD cask/GSDM Caspar/M Casper/M Caspian Cass Cassandra/SM Cassandre/M Cassandry/M Cassatt/M Cassaundra/M cassava/MS casserole/MGSD cassette/SM Cassey/M cassia/MS Cassie/M Cassi/M cassino's Cassiopeia/M Cassite/M Cassius/M cassock/SDM Cassondra/M cassowary/SM Cassy/M Castaneda/M castanet/SM castaway/SM castellated caste/MHS caster/M cast/GZSJMDR castigate/XGNSD castigation/M castigator/SM Castile's Castillo/M casting/M castle/GMSD castoff/S Castor/M castor's castrate/DSNGX castration/M Castries/M Castro/M casts/A casualness/SM casual/SYP casualty/SM casuistic casuist/MS casuistry/SM cataclysmal cataclysmic cataclysm/MS catacomb/MS catafalque/SM Catalan/MS catalepsy/MS cataleptic/S Catalina/M cataloger/M catalog/SDRMZG Catalonia/M catalpa/SM catalysis/M catalyst/SM catalytic catalytically catalyze/DSG catamaran/MS catapult/MGSD cataract/MS Catarina/M catarrh/M catarrhs catastrophe/SM catastrophic catastrophically catatonia/MS catatonic/S Catawba/M catbird/MS catboat/SM catcall/SMDG catchable/U catchall/MS catch/BRSJLGZ catcher/M catchment/SM catchpenny/S catchphrase/S catchup/MS catchword/MS catchy/TR catechism/MS catechist/SM catechize/SDG catecholamine/MS categoric categorical/Y categorization/MS categorized/AU categorize/RSDGZ category/MS Cate/M catenate/NF catenation/MF catercorner caterer/M cater/GRDZ Caterina/M catering/M Caterpillar caterpillar/SM caterwaul/DSG catfish/MS catgut/SM Catha/M Catharina/M Catharine/M catharses catharsis/M cathartic/S Cathay/M cathedral/SM Cathee/M Catherina/M Catherine/M Catherin/M Cather/M Cathe/RM catheterize/GSD catheter/SM Cathie/M Cathi/M Cathleen/M Cathlene/M cathode/MS cathodic catholicism Catholicism/SM catholicity/MS catholic/MS Catholic/S Cathrine/M Cathrin/M Cathryn/M Cathyleen/M Cathy/M Catie/M Catiline/M Cati/M Catina/M cationic cation/MS catkin/SM Catlaina/M Catlee/M catlike Catlin/M catnapped catnapping catnap/SM catnip/MS Cato/M Catrina/M Catriona/M Catskill/SM cat/SMRZ catsup's cattail/SM catted cattery/M cattily cattiness/SM catting cattle/M cattleman/M cattlemen Catt/M catty/PRST Catullus/M CATV catwalk/MS Caty/M Caucasian/S Caucasoid/S Caucasus/M Cauchy/M caucus/SDMG caudal/Y caught/U cauldron/MS cauliflower/MS caulker/M caulk/JSGZRD causality/SM causal/YS causate/XVN causation/M causative/SY cause/DSRGMZ caused/U causeless causerie/MS causer/M causeway/SGDM caustically causticity/MS caustic/YS cauterization/SM cauterized/U cauterize/GSD cautionary cautioner/M caution/GJDRMSZ cautiousness's/I cautiousness/SM cautious/PIY cavalcade/MS cavalierness/M cavalier/SGYDP cavalryman/M cavalrymen cavalry/MS caveat/SM caveatted caveatting cave/GFRSD caveman/M cavemen Cavendish/M caver/M cavern/GSDM cavernous/Y cave's caviar/MS caviler/M cavil/SJRDGZ caving/MS cavity/MFS cavort/SDG Cavour/M caw/SMDG Caxton/M Caye/M Cayenne/M cayenne/SM Cayla/M Cayman/M cayman/SM cay's cay/SC Cayuga/M cayuse/SM Caz/M Cazzie/M c/B CB CBC Cb/M CBS cc Cchaddie/M CCTV CCU CD CDC/M Cd/M CDT Ce cease/DSCG ceasefire/S ceaselessness/SM ceaseless/YP ceasing/U Ceausescu/M Cebuano/M Cebu/M ceca cecal Cecelia/M Cece/M Cecile/M Ceciley/M Cecilia/M Cecilio/M Cecilius/M Cecilla/M Cecil/M Cecily/M cecum/M cedar/SM ceded/A cede/FRSDG ceder's/F ceder/SM cedes/A cedilla/SM ceding/A Ced/M Cedric/M ceilidh/M ceiling/MDS Ceil/M celandine/MS Celanese/M Celebes's celebrant/MS celebratedness/M celebrated/P celebrate/XSDGN celebration/M celebrator/MS celebratory celebrity/MS Cele/M Celene/M celerity/SM celery/SM Celesta/M celesta/SM Celeste/M celestial/YS Celestia/M Celestina/M Celestine/M Celestyna/M Celestyn/M Celia/M celibacy/MS celibate/SM Celie/M Celina/M Celinda/M Celine/M Celinka/M Celisse/M Celka/M cellarer/M cellar/RDMGS Celle/M cell/GMDS Cellini/M cellist/SM Cello/M cello/MS cellophane/SM cellphone/S cellular/SY cellulite/S celluloid/SM cellulose/SM Celsius/S Celtic/SM Celt/MS cementa cementer/M cementum/SM cement/ZGMRDS cemetery/MS cenobite/MS cenobitic cenotaph/M cenotaphs Cenozoic censer/MS censored/U censor/GDMS censorial censoriousness/MS censorious/YP censorship/MS censure/BRSDZMG censurer/M census/SDMG centaur/SM Centaurus/M centavo/SM centenarian/MS centenary/S centennial/YS center/AC centerboard/SM centered centerer/S centerfold/S centering/SM centerline/SM centerpiece/SM center's Centigrade centigrade/S centigram/SM centiliter/MS centime/SM centimeter/SM centipede/MS Centralia/M centralism/M centralist/M centrality/MS centralization/CAMS centralize/CGSD centralizer/SM centralizes/A central/STRY centrefold's Centrex CENTREX/M centric/F centrifugal/SY centrifugate/NM centrifugation/M centrifuge/GMSD centripetal/Y centrist/MS centroid/MS cent/SZMR centurion/MS century/MS CEO cephalic/S Cepheid Cepheus/M ceramicist/S ceramic/MS ceramist/MS cerate/MD Cerberus/M cereal/MS cerebellar cerebellum/MS cerebra cerebral/SY cerebrate/XSDGN cerebration/M cerebrum/MS cerement/SM ceremonial/YSP ceremoniousness/MS ceremoniousness's/U ceremonious/YUP ceremony/MS Cerenkov/M Ceres/M Cerf/M cerise/SM cerium/MS cermet/SM CERN/M certainer certainest certainty/UMS certain/UY cert/FS certifiable certifiably certificate/SDGM certification/AMC certified/U certifier/M certify/DRSZGNX certiorari/M certitude/ISM cerulean/MS Cervantes/M cervical cervices/M cervix/M Cesarean cesarean/S Cesare/M Cesar/M Cesaro/M cesium/MS cessation/SM cession/FAMSK Cessna/M cesspit/M cesspool/SM Cesya/M cetacean/S cetera/S Cetus/M Ceylonese Ceylon/M Cezanne/S cf CF CFC Cf/M CFO cg Chablis/SM Chaddie/M Chadd/M Chaddy/M Chadian/S Chad/M Chadwick/M chafe/GDSR chafer/M chaffer/DRG chafferer/M Chaffey/M chaff/GRDMS chaffinch/SM Chagall/M chagrin/DGMS Chaim/M chainlike chain's chainsaw/SGD chain/SGUD chairlady/M chairlift/MS chairman/MDGS chairmanship/MS chairmen chairperson/MS chair/SGDM chairwoman/M chairwomen chaise/SM chalcedony/MS Chaldea/M Chaldean/M chalet/SM chalice/DSM chalkboard/SM chalk/DSMG chalkiness/S chalkline chalky/RPT challenged/U challenger/M challenge/ZGSRD challenging/Y challis/SM Chalmers chamberer/M Chamberlain/M chamberlain/MS chambermaid/MS chamberpot/S Chambers/M chamber/SZGDRM chambray/MS chameleon/SM chamfer/DMGS chammy's chamois/DSMG chamomile/MS champagne/MS champaign/M champ/DGSZ champion/MDGS championship/MS Champlain/M chanced/M chance/GMRSD chancellery/SM chancellorship/SM chancellor/SM Chancellorsville/M chancel/SM Chance/M chancery/SM Chancey/M chanciness/S chancing/M chancre/SM chancy/RPT Chandal/M Chanda/M chandelier/SM Chandigarh/M Chandler/M chandler/MS Chandragupta/M Chandra/M Chandrasekhar/M Chandy/M Chanel/M Chane/M Chaney/M Changchun/M changeabilities changeability/UM changeableness/SM changeable/U changeably/U changed/U change/GZRSD changeless changeling/M changeover/SM changer/M changing/U Chang/M Changsha/M Chan/M Channa/M channeler/M channeling/M channelization/SM channelize/GDS channellings channel/MDRZSG Channing/M chanson/SM Chantalle/M Chantal/M chanter/M chanteuse/MS chantey/SM chanticleer/SM Chantilly/M chantry/MS chant/SJGZMRD chanty's Chanukah's Chao/M chaos/SM chaotic chaotically chaparral/MS chapbook/SM chapeau/MS chapel/MS chaperonage/MS chaperoned/U chaperone's chaperon/GMDS chaplaincy/MS chaplain/MS chaplet/SM Chaplin/M Chapman/M chap/MS Chappaquiddick/M chapped chapping chapter/SGDM Chara charabanc/MS characterful characteristically/U characteristic/SM characterizable/MS characterization/MS characterize/DRSBZG characterized/U characterizer/M characterless character/MDSG charade/SM charbroil/SDG charcoal/MGSD Chardonnay chardonnay/S chard/SM chargeableness/M chargeable/P charged/U charge/EGRSDA charger/AME chargers char/GS Charil/M charily chariness/MS Charin/M charioteer/GSDM Chariot/M chariot/SMDG Charis charisma/M charismata charismatically charismatic/S Charissa/M Charisse/M charitablenesses charitableness/UM charitable/UP charitably/U Charita/M Charity/M charity/MS charlady/M Charla/M charlatanism/MS charlatanry/SM charlatan/SM Charlean/M Charleen/M Charlemagne/M Charlena/M Charlene/M Charles/M Charleston/SM Charley/M Charlie/M Charline/M Charlot/M Charlotta/M Charlotte/M Charlottesville/M Charlottetown/M Charlton/M Charmaine/M Charmain/M Charmane/M charmer/M Charmian/M Charmine/M charming/RYT Charmin/M Charmion/M charmless charm/SGMZRD Charolais Charo/M Charon/M charred charring charted/U charter/AGDS chartered/U charterer/SM charter's chartist/SM Chartres/M chartreuse/MS chartroom/S chart/SJMRDGBZ charwoman/M charwomen Charybdis/M Charyl/M chary/PTR Chas chase/DSRGZ Chase/M chaser/M chasing/M Chasity/M chasm/SM chassis/M chastely chasteness/SM chasten/GSD chaste/UTR chastisement/SM chastiser/M chastise/ZGLDRS Chastity/M chastity/SM chastity's/U chasuble/SM Chateaubriand chteau/M chateaus chteaux chtelaine/SM chat/MS Chattahoochee/M Chattanooga/M chatted chattel/MS chatterbox/MS chatterer/M Chatterley/M chatter/SZGDRY Chatterton/M chattily chattiness/SM chatting chatty/RTP Chaucer/M chauffeur/GSMD Chaunce/M Chauncey/M Chautauqua/M chauvinism/MS chauvinistic chauvinistically chauvinist/MS Chavez/M chaw Chayefsky/M cheapen/DG cheapish cheapness/MS cheapskate/MS cheap/YRNTXSP cheater/M cheat/RDSGZ Chechen/M Chechnya/M checkable/U checkbook/MS checked/UA checkerboard/MS checker/DMG check/GZBSRDM checklist/S checkmate/MSDG checkoff/SM checkout/S checkpoint/MS checkroom/MS check's/A checks/A checksummed checksumming checksum/SM checkup/MS Cheddar/MS cheddar/S cheekbone/SM cheek/DMGS cheekily cheekiness/SM cheeky/PRT cheep/GMDS cheerer/M cheerfuller cheerfullest cheerfulness/MS cheerful/YP cheerily cheeriness/SM cheerio/S Cheerios/M cheerleader/SM cheerlessness/SM cheerless/PY cheers/S cheery/PTR cheer/YRDGZS cheeseburger/SM cheesecake/SM cheesecloth/M cheesecloths cheeseparing/S cheese/SDGM cheesiness/SM cheesy/PRT cheetah/M cheetahs Cheeto/M Cheever/M cheffed cheffing chef/SM Chekhov/M chelate/XDMNG chelation/M Chelsae/M Chelsea/M Chelsey/M Chelsie/M Chelsy/M Chelyabinsk/M chem Che/M chemic chemical/SYM chemiluminescence/M chemiluminescent chemise/SM chemistry/SM chemist/SM chemotherapeutic/S chemotherapy/SM chemurgy/SM Chengdu Cheng/M chenille/SM Chen/M Cheops/M Chere/M Cherey/M Cherianne/M Cherice/M Cherida/M Cherie/M Cherilyn/M Cherilynn/M Cheri/M Cherin/M Cherise/M cherisher/M cherish/GDRS Cherish/M Cheriton/M Cherlyn/M Cher/M Chernenko/M Chernobyl/M Cherokee/MS cheroot/MS Cherri/M Cherrita/M Cherry/M cherry/SM chert/MS cherubic cherubim/S cherub/SM chervil/MS Cherye/M Cheryl/M Chery/M Chesapeake/M Cheshire/M Cheslie/M chessboard/SM chessman/M chessmen chess/SM Chesterfield/M chesterfield/MS Chester/M Chesterton/M chestful/S chest/MRDS chestnut/SM Cheston/M chesty/TR Chet/M Chevalier/M chevalier/SM Cheviot/M cheviot/S Chev/M Chevrolet/M chevron/DMS Chevy/M chewer/M chew/GZSDR chewiness/S chewy/RTP Cheyenne/SM chg chge Chiang/M chianti/M Chianti/S chiaroscuro/SM Chiarra/M Chiba/M Chicagoan/SM Chicago/M Chicana/MS chicane/MGDS chicanery/MS Chicano/MS chichi/RTS chickadee/SM Chickasaw/SM chickenfeed chicken/GDM chickenhearted chickenpox/MS Chickie/M Chick/M chickpea/MS chickweed/MS chick/XSNM Chicky/M chicle/MS Chic/M chicness/S Chico/M chicory/MS chic/SYRPT chide/GDS chiding/Y chiefdom/MS chieftain/SM chief/YRMST chiffonier/MS chiffon/MS chigger/MS chignon/MS Chihuahua/MS chihuahua/S chilblain/MS childbearing/MS childbirth/M childbirths childcare/S childes child/GMYD childhood/MS childishness/SM childish/YP childlessness/SM childless/P childlikeness/M childlike/P childminders childproof/GSD childrearing children/M Chilean/S Chile/MS chile's chilies chili/M chiller/M chilliness/MS chilling/Y chilli's chill/MRDJGTZPS chillness/MS chilly/TPRS Chilton/M Chi/M chimaera's chimaerical Chimborazo/M chime/DSRGMZ Chimera/S chimera/SM chimeric chimerical chimer/M Chimiques chimney/SMD chimpanzee/SM chimp/MS chi/MS Chimu/M Ch'in China/M Chinaman/M Chinamen china/MS Chinatown/SM chinchilla/SM chine/MS Chinese/M Ching/M chink/DMSG chinless Chin/M chinned chinner/S chinning chino/MS Chinook/MS chin/SGDM chinstrap/S chintz/SM chintzy/TR chipboard/M Chipewyan/M Chip/M chipmunk/SM chipped Chippendale/M chipper/DGS Chippewa/MS chipping/MS chip/SM Chiquia/M Chiquita/M chiral Chirico/M chirography/SM chiropodist/SM chiropody/MS chiropractic/MS chiropractor/SM chirp/GDS chirpy/RT chirrup/DGS chiseler/M chisel/ZGSJMDR Chisholm/M Chisinau/M chitchat/SM chitchatted chitchatting chitinous chitin/SM chit/SM Chittagong/M chitterlings chivalric chivalrously/U chivalrousness/MS chivalrous/YP chivalry/SM chive/GMDS chivvy/D chivying chlamydiae chlamydia/S Chloe/M Chloette/M Chlo/M chloral/MS chlorate/M chlordane/MS chloride/MS chlorinated/C chlorinates/C chlorinate/XDSGN chlorination/M chlorine/MS Chloris chlorofluorocarbon/S chloroform/DMSG chlorophyll/SM chloroplast/MS chloroquine/M chm Ch/MGNRS chockablock chock/SGRDM chocoholic/S chocolate/MS chocolaty Choctaw/MS choiceness/M choice/RSMTYP choirboy/MS choirmaster/SM choir/SDMG chokeberry/M chokecherry/SM choke/DSRGZ choker/M chokes/M choking/Y cholera/SM choleric choler/SM cholesterol/SM choline/M cholinesterase/M chomp/DSG Chomsky/M Chongqing choose/GZRS chooser/M choosiness/S choosy/RPT chophouse/SM Chopin/M chopped chopper/SDMG choppily choppiness/MS chopping choppy/RPT chop/S chopstick/SM chorale/MS choral/SY chordal chordata chordate/MS chording/M chord/SGMD chorea/MS chore/DSGNM choreographer/M choreographic choreographically choreographs choreography/MS choreograph/ZGDR chorines chorion/M chorister/SM choroid/S chortler/M chortle/ZGDRS chorus/GDSM chosen/U chose/S Chou/M chowder/SGDM chow/DGMS Chretien/M Chris/M chrism/SM chrissake Chrisse/M Chrissie/M Chrissy/M Christabella/M Christabel/M Christalle/M Christal/M Christa/M Christan/M Christchurch/M Christean/M Christel/M Christendom/MS christened/U christening/SM Christen/M christen/SAGD Christensen/M Christenson/M Christiana/M Christiane/M Christianity/SM Christianize/GSD Christian/MS Christiano/M Christiansen/M Christians/N Christie/SM Christi/M Christina/M Christine/M Christin/M Christlike Christmas/SM Christmastide/SM Christmastime/S Christoffel/M Christoffer/M Christoforo/M Christoper/M Christophe/M Christopher/M Christoph/MR Christophorus/M Christos/M Christ/SMN Christye/M Christyna/M Christy's Chrisy/M chroma/M chromate/M chromatically chromaticism/M chromaticness/M chromatic/PS chromatics/M chromatin/MS chromatogram/MS chromatograph chromatographic chromatography/M chrome/GMSD chromic chromite/M chromium/SM chromosomal chromosome/MS chromosphere/M chronically chronicled/U chronicler/M chronicle/SRDMZG chronic/S chronograph/M chronographs chronography chronological/Y chronologist/MS chronology/MS chronometer/MS chronometric Chrotoem/M chrysalids chrysalis/SM Chrysa/M chrysanthemum/MS Chrysler/M Chrysostom/M Chrystal/M Chrystel/M Chryste/M chubbiness/SM chubby/RTP chub/MS Chucho/M chuck/GSDM chuckhole/SM chuckle/DSG chuckling/Y Chuck/M chuff/DM chugged chugging chug/MS Chukchi/M chukka/S Chumash/M chummed chummily chumminess/MS chumming chum/MS chummy/SRTP chumping/M chump/MDGS Chungking's Chung/M chunkiness/MS chunk/SGDM chunky/RPT chuntering churchgoer/SM churchgoing/SM Churchillian Churchill/M churchliness/M churchly/P churchman/M church/MDSYG churchmen Church/MS churchwarden/SM churchwoman/M churchwomen churchyard/SM churlishness/SM churlish/YP churl/SM churner/M churning/M churn/SGZRDM chute/DSGM chutney/MS chutzpah/M chutzpahs chutzpa/SM Chuvash/M ch/VT chyme/SM Ci CIA ciao/S cicada/MS cicatrice/S cicatrix's Cicely/M Cicero/M cicerone/MS ciceroni Ciceronian Cicily/M CID cider's/C cider/SM Cid/M Ciel/M cigarette/MS cigarillo/MS cigar/SM cilantro/S cilia/M ciliate/FDS ciliately cilium/M Cilka/M cinch/MSDG cinchona/SM Cincinnati/M cincture/MGSD Cinda/M Cindee/M Cindelyn/M cinder/DMGS Cinderella/MS Cindie/M Cindi/M Cindra/M Cindy/M cine/M cinema/SM cinematic cinematographer/MS cinematographic cinematography/MS Cinerama/M cinnabar/MS Cinnamon/M cinnamon/MS ciphered/C cipher/MSGD ciphers/C cir circa circadian Circe/M circler/M circle/RSDGM circlet/MS circuital circuit/GSMD circuitousness/MS circuitous/YP circuitry/SM circuity/MS circulant circularity/SM circularize/GSD circularness/M circular/PSMY circulate/ASDNG circulation/MA circulations circulative circulatory circumcise/DRSXNG circumcised/U circumciser/M circumcision/M circumference/SM circumferential/Y circumflex/MSDG circumlocution/MS circumlocutory circumnavigate/DSNGX circumnavigational circumnavigation/M circumpolar circumscribe/GSD circumscription/SM circumspection/SM circumspect/Y circumsphere circumstance/SDMG circumstantial/YS circumvention/MS circumvent/SBGD circus/SM Cirillo/M Cirilo/M Ciro/M cirque/SM cirrhoses cirrhosis/M cirrhotic/S cirri/M cirrus/M Cissiee/M Cissy/M cistern/SM citadel/SM citations/I citation/SMA cit/DSG cite/ISDAG Citibank/M citified citizenry/SM citizenship/MS citizen/SYM citrate/DM citric Citroen/M citronella/MS citron/MS citrus/SM city/DSM cityscape/MS citywide civet/SM civic/S civics/M civilian/SM civility/IMS civilizational/MS civilization/AMS civilizedness/M civilized/PU civilize/DRSZG civilizer/M civilizes/AU civil/UY civvies ck/C clack/SDG cladding/SM clads clad/U Claiborne/M Claiborn/M claimable claimant/MS claim/CDRSKAEGZ claimed/U claimer/KMACE Claire/M Clair/M Clairol/M clairvoyance/MS clairvoyant/YS clambake/MS clamberer/M clamber/SDRZG clammed clammily clamminess/MS clamming clam/MS clammy/TPR clamorer/M clamor/GDRMSZ clamorousness/UM clamorous/PUY clampdown/SM clamper/M clamp/MRDGS clamshell/MS Clancy/M clandestineness/M clandestine/YP clanger/M clangor/MDSG clangorous/Y clang/SGZRD clanking/Y clank/SGDM clan/MS clannishness/SM clannish/PY clansman/M clansmen clapboard/SDGM Clapeyron/M clapped clapper/GMDS clapping clap/S Clapton/M claptrap/SM claque/MS Clarabelle/M Clara/M Clarance/M Clare/M Claremont/M Clarence/M Clarendon/M Claresta/M Clareta/M claret/MDGS Claretta/M Clarette/M Clarey/M Claribel/M Clarice/M Clarie/M clarification/M clarifier/M clarify/NGXDRS Clari/M Clarinda/M Clarine/M clarinetist/SM clarinet/SM clarinettist's clarion/GSMD Clarissa/M Clarisse/M Clarita/M clarities clarity/UM Clarke/M Clark/M Clarridge/M Clary/M clasher/M clash/RSDG clasped/M clasper/M clasp's clasp/UGSD classer/M class/GRSDM classical/Y classicism/SM classicist/SM classic/S classics/M classifiable/U classification/AMC classificatory classified/S classifier/SM classify/CNXASDG classiness/SM classless/P classmate/MS classroom/MS classwork/M classy/PRT clatterer/M clattering/Y clatter/SGDR clattery Claudelle/M Claudell/M Claude/M Claudetta/M Claudette/M Claudia/M Claudian/M Claudianus/M Claudie/M Claudina/M Claudine/M Claudio/M Claudius/M clausal clause/MS Clausen/M Clausewitz/M Clausius/M Claus/NM claustrophobia/SM claustrophobic clave/RM clave's/F clavichord/SM clavicle/MS clavier/MS clawer/M claw/GDRMS Clayborne/M Clayborn/M Claybourne/M clayey clayier clayiest Clay/M clay/MDGS claymore/MS Clayson/M Clayton/M Clea/M cleanable cleaner/MS cleaning/SM cleanliness/UMS cleanly/PRTU cleanness/MSU cleanse cleanser/M cleans/GDRSZ cleanup/MS clean/UYRDPT clearance/MS clearcut clearer/M clearheadedness/M clearheaded/PY clearinghouse/S clearing/MS clearly clearness/MS clears clear/UTRD Clearwater/M clearway/M cleat/MDSG cleavage/MS cleaver/M cleave/RSDGZ Cleavland/M clef/SM cleft/MDGS clematis/MS clemence Clemenceau/M Clemence/M clemency/ISM Clemente/M Clementia/M Clementina/M Clementine/M Clementius/M clement/IY Clement/MS clements Clemmie/M Clemmy/M Clemons Clemson/M Clem/XM clenches clenching clench/UD Cleo/M Cleon/M Cleopatra/M Clerc/M clerestory/MS clergyman/M clergymen clergy/MS clergywoman clergywomen clericalism/SM clerical/YS cleric/SM Clerissa/M clerk/SGYDM clerkship/MS Cletis Cletus/M Cleveland/M Cleve/M cleverness/SM clever/RYPT Clevey/M Clevie/M clevis/SM clew/DMGS cl/GJ Cliburn/M clichd clich/SM clicker/M click/GZSRDM clientle/SM client/SM cliffhanger/MS cliffhanging Cliff/M Clifford/M cliff/SM Clifton/M climacteric/SM climactic climate/MS climatic climatically climatological/Y climatologist/SM climatology/MS climax/MDSG climbable/U climb/BGZSJRD climbdown climbed/U climber/M clime/SM Clim/M clinch/DRSZG clincher/M clinching/Y Cline/M clinger/MS clinging cling/U clingy/TR clinical/Y clinician/MS clinic/MS clinker/GMD clink/RDGSZ clinometer/MIS Clint/M Clinton/M Clio/M cliometrician/S cliometric/S clipboard/SM clipped/U clipper/MS clipping/SM clip/SM clique/SDGM cliquey cliquier cliquiest cliquishness/SM cliquish/YP clitoral clitorides clitoris/MS Clive/M cloacae cloaca/M cloakroom/MS cloak's cloak/USDG clobber/DGS cloche/MS clocker/M clockmaker/M clock/SGZRDMJ clockwatcher clockwise clockwork/MS clodded clodding cloddishness/M cloddish/P clodhopper/SM clod/MS Cloe/M clogged/U clogging/U clog's clog/US cloisonn cloisonnes cloister/MDGS cloistral Clo/M clomp/MDSG clonal clone/DSRGMZ clonk/SGD clopped clopping clop/S Cloris/M closed/U close/EDSRG closefisted closely closemouthed closeness/MS closeout/MS closer/EM closers closest closet/MDSG closeup/S closing/S closured closure/EMS closure's/I closuring clothbound clothesbrush clotheshorse/MS clothesline/SDGM clothesman clothesmen clothespin/MS clothe/UDSG cloth/GJMSD clothier/MS clothing/M Clotho/M cloths Clotilda/M clot/MS clotted clotting cloture/MDSG cloudburst/MS clouded/U cloudiness/SM cloudlessness/M cloudless/YP cloudscape/SM cloud/SGMD cloudy/TPR clout/GSMD cloven cloverleaf/MS clover/M clove/SRMZ Clovis/M clown/DMSG clownishness/SM clownish/PY cloy/DSG cloying/Y clubbed/M clubbing/M clubfeet clubfoot/DM clubhouse/SM club/MS clubroom/SM cluck/GSDM clueless clue/MGDS Cluj/M clump/MDGS clumpy/RT clumsily clumsiness/MS clumsy/PRT clung clunk/SGZRDM clunky/PRYT clustered/AU clusters/A cluster/SGJMD clutch/DSG cluttered/U clutter/GSD Cl/VM Clyde/M Clydesdale/M Cly/M Clytemnestra/M Clyve/M Clywd/M cm Cm/M CMOS cnidarian/MS CNN CNS CO coacher/M coachman/M coachmen coach/MSRDG coachwork/M coadjutor/MS coagulable coagulant/SM coagulate/GNXSD coagulation/M coagulator/S coaler/M coalesce/GDS coalescence/SM coalescent coalface/SM coalfield/MS coalitionist/SM coalition/MS coal/MDRGS coalminers coarseness/SM coarsen/SGD coarse/TYRP coastal coaster/M coastguard/MS coastline/SM coast/SMRDGZ coated/U Coates/M coating/M coat/MDRGZJS coattail/S coattest coauthor/MDGS coaxer/M coax/GZDSR coaxial/Y coaxing/Y Cobain/M cobalt/MS cobbed Cobbie/M cobbing cobbler/M cobble/SRDGMZ cobblestone/MSD Cobb/M Cobby/M coble/M Cob/M COBOL Cobol/M cobra/MS cob/SM cobwebbed cobwebbing cobwebby/RT cobweb/SM cocaine/MS coca/MS cocci/MS coccus/M coccyges coccyx/M Cochabamba/M cochineal/SM Cochin/M Cochise/M cochleae cochlear cochlea/SM Cochran/M cockade/SM cockamamie cockatoo/SM cockatrice/MS cockcrow/MS cockerel/MS cocker/M cockeye/DM cockeyed/PY cockfighting/M cockfight/MJSG cock/GDRMS cockily cockiness/MS cocklebur/M cockle/SDGM cockleshell/SM Cockney cockney/MS cockpit/MS cockroach/SM cockscomb/SM cockshies cocksucker/S! cocksure cocktail/GDMS cocky/RPT cocoa/SM coco/MS coconut/SM cocoon/GDMS Cocteau/M COD coda/SM codded codding coddle/GSRD coddler/M codebook/S codebreak/R coded/UA Codee/M codeine/MS codename/D codependency/S codependent/S coder/CM code's co/DES codes/A code/SCZGJRD codetermine/S codeword/SM codex/M codfish/SM codger/MS codices/M codicil/SM Codie/M codification/M codifier/M codify/NZXGRSD Codi/M coding/M codling/M Cod/M cod/MDRSZGJ codpiece/MS Cody/M coedited coediting coeditor/MS coedits coed/SM coeducational coeducation/SM coefficient/SYM coelenterate/MS coequal/SY coercer/M coerce/SRDXVGNZ coercible/I coercion/M coerciveness/M coercive/PY coeval/YS coexistence/MS coexistent coexist/GDS coextensive/Y cofactor/MS coffeecake/SM coffeecup coffeehouse/SM coffeemaker/S coffeepot/MS coffee/SM cofferdam/SM coffer/DMSG Coffey/M coffin/DMGS Coffman/M cogency/MS cogent/Y cogged cogging cogitate/DSXNGV cogitation/M cogitator/MS cog/MS Cognac/M cognac/SM cognate/SXYN cognation/M cognitional cognition/SAM cognitive/SY cognizable cognizance/MAI cognizances/A cognizant/I cognomen/SM cognoscente cognoscenti cogwheel/SM cohabitant/MS cohabitational cohabitation/SM cohabit/SDG Cohan/M coheir/MS Cohen/M cohere/GSRD coherence/SIM coherencies coherency/I coherent/IY coherer/M cohesion/MS cohesiveness/SM cohesive/PY Cohn/M cohoes coho/MS cohort/SM coiffed coiffing coiffure/MGSD coif/SM coil/UGSAD Coimbatore/M coinage's/A coinage/SM coincide/GSD coincidence/MS coincidental/Y coincident/Y coined/U coiner/M coin/GZSDRM coinsurance/SM Cointon/M cointreau coital/Y coitus/SM coke/MGDS Coke/MS COL COLA colander/SM Colan/M Colas cola/SM colatitude/MS Colbert/M Colby/M coldblooded coldish coldness/MS cold/YRPST Coleen/M Cole/M Coleman/M Colene/M Coleridge/M coleslaw/SM Colet/M Coletta/M Colette/M coleus/SM Colfax/M Colgate/M colicky colic/SM coliform Colin/M coliseum/SM colitis/MS collaborate/VGNXSD collaboration/M collaborative/SY collaborator/SM collage/MGSD collagen/M collapse/SDG collapsibility/M collapsible collarbone/MS collar/DMGS collard/SM collarless collated/U collateral/SYM collate/SDVNGX collation/M collator/MS colleague/SDGM collectedness/M collected/PY collectible/S collection/AMS collective/SY collectivism/SM collectivist/MS collectivity/MS collectivization/MS collectivize/DSG collector/MS collect/SAGD Colleen/M colleen/SM college/SM collegiality/S collegian/SM collegiate/Y Collen/M Collete/M Collette/M coll/G collide/SDG Collie/M collie/MZSRD collier/M Collier/M colliery/MS collimate/C collimated/U collimates collimating collimation/M collimator/M collinear collinearity/M Colline/M Collin/MS collisional collision/SM collocate/XSDGN collocation/M colloidal/Y colloid/MS colloq colloquialism/MS colloquial/SY colloquies colloquium/SM colloquy/M collude/SDG collusion/SM collusive collying Colly/RM Colman/M Col/MY Cologne/M cologne/MSD Colo/M Colombia/M Colombian/S Colombo/M colonelcy/MS colonel/MS colonialism/MS colonialist/MS colonial/SPY colonist/SM colonization/ACSM colonize/ACSDG colonized/U colonizer/MS colonizes/U Colon/M colonnade/MSD colon/SM colony/SM colophon/SM Coloradan/S Coloradoan/S Colorado/M colorant/SM coloration/EMS coloratura/SM colorblindness/S colorblind/P colored/USE colorer/M colorfastness/SM colorfast/P colorfulness/MS colorful/PY colorimeter/SM colorimetry coloring/M colorization/S colorize/GSD colorizing/C colorlessness/SM colorless/PY colors/EA color/SRDMGZJ colossal/Y Colosseum/M colossi colossus/M colostomy/SM colostrum/SM col/SD colter/M coltishness/M coltish/PY Colt/M colt/MRS Coltrane/M Columbia/M Columbian Columbine/M columbine/SM Columbus/M columnar columnist/MS columnize/GSD column/SDM Colver/M Co/M comae comaker/SM Comanche/MS coma/SM comatose combatant/SM combativeness/MS combative/PY combat/SVGMD combed/U comber/M combinational/A combination/ASM combinatorial/Y combinatoric/S combinator/SM combined/AU combiner/M combines/A combine/ZGBRSD combining/A combo/MS comb/SGZDRMJ Combs/M combusted combustibility/SM combustible/SI combustion/MS combustive Comdex/M Comdr/M comeback/SM comedian/SM comedic comedienne/SM comedown/MS comedy/SM come/IZSRGJ comeliness/SM comely/TPR comer/IM comes/M comestible/MS cometary cometh comet/SM comeuppance/SM comfit's comfit/SE comfortability/S comfortableness/MS comfortable/U comfortably/U comforted/U comforter/MS comfort/ESMDG comforting/YE comfy/RT comicality/MS comical/Y comic/MS Cominform/M comity/SM com/LJRTZG comm Com/M comma/MS commandant/MS commandeer/SDG commander/M commanding/Y commandment/SM commando/SM command/SZRDMGL commemorate/SDVNGX commemoration/M commemorative/YS commemorator/S commence/ALDSG commencement/AMS commencer/M commendably commendation/ASM commendatory/A commender/AM commend/GSADRB commensurable/I commensurate/IY commensurates commensuration/SM commentary/MS commentate/GSD commentator/SM commenter/M comment's comment/SUGD commerce/MGSD commercialism/MS commercialization/SM commercialize/GSD commercial/PYS Commie commie/SM commingle/GSD commiserate/VGNXSD commiseration/M commissariat/MS commissar/MS commissary/MS commission/ASCGD commissioner/SM commission's/A commitment/SM commit/SA committable committal/MA committals committed/UA committeeman/M committeemen committee/MS committeewoman/M committeewomen committing/A commode/MS commodes/IE commodiousness/MI commodious/YIP commodity/MS commodore/SM commonality/MS commonalty/MS commoner/MS commonness/MSU commonplaceness/M commonplace/SP common/RYUPT commonsense commons/M Commons/M commonweal/SHM commonwealth/M Commonwealth/M commonwealths Commonwealths commotion/MS communality/M communal/Y commune/XSDNG communicability/MS communicable/IU communicably communicant/MS communicate/VNGXSD communicational communication/M communicativeness/M communicative/PY communicator/SM communion/M Communion/SM communique/S communism/MS Communism/S communistic communist/MS Communist/S communitarian/M community/MS communize/SDG commutable/I commutate/XVGNSD commutation/M commutative/Y commutativity commutator/MS commute/BZGRSD commuter/M Comoros compaction/M compactness/MS compactor/MS compact/TZGSPRDY companionableness/M companionable/P companionably companion/GBSMD companionship/MS companionway/MS company/MSDG Compaq/M comparabilities comparability/IM comparableness/M comparable/P comparably/I comparativeness/M comparative/PYS comparator/SM compare/GRSDB comparer/M comparison/MS compartmental compartmentalization/SM compartmentalize/DSG compartment/SDMG compassionateness/M compassionate/PSDGY compassion/MS compass/MSDG compatibility/IMS compatibleness/M compatible/SI compatibly/I compatriot/SM compeer/DSGM compellable compelled compelling/YM compel/S compendious compendium/MS compensable compensated/U compensate/XVNGSD compensation/M compensator/M compensatory compete/GSD competence/ISM competency/IS competency's competent/IY competition/SM competitiveness/SM competitive/YP competitor/MS comp/GSYD compilable/U compilation/SAM compile/ASDCG compiler/CS compiler's complacence/S complacency/SM complacent/Y complainant/MS complainer/M complain/GZRDS complaining/YU complaint/MS complaisance/SM complaisant/Y complected complementariness/M complementarity complementary/SP complementation/M complementer/M complement/ZSMRDG complete/BTYVNGPRSDX completed/U completely/I completeness/ISM completer/M completion/MI complexional complexion/DMS complexity/MS complexness/M complex/TGPRSDY compliance/SM compliant/Y complicatedness/M complicated/YP complicate/SDG complication/M complicator/SM complicit complicity/MS complier/M complimentary/U complimenter/M compliment/ZSMRDG comply/ZXRSDNG component/SM comport/GLSD comportment/SM compose/CGASDE composedness/M composed/PY composer/CM composers composite/YSDXNG compositional/Y composition/CMA compositions/C compositor/MS compost/DMGS composure/ESM compote/MS compounded/U compounder/M compound/RDMBGS comprehend/DGS comprehending/U comprehensibility/SIM comprehensibleness/IM comprehensible/PI comprehensibly/I comprehension/IMS comprehensiveness/SM comprehensive/YPS compressed/Y compressibility/IM compressible/I compressional compression/CSM compressive/Y compressor/MS compress/SDUGC comprise/GSD compromiser/M compromise/SRDGMZ compromising/UY Compton/M comptroller/SM compulsion/SM compulsiveness/MS compulsive/PYS compulsivity compulsorily compulsory/S compunction/MS Compuserve/M CompuServe/M computability/M computable/UI computably computational/Y computation/SM computed/A computerese computerization/MS computerize/SDG computer/M compute/RSDZBG computes/A computing/A comradely/P comradeship/MS comrade/YMS Comte/M Conakry/M Conan/M Conant/M concatenate/XSDG concaveness/MS concave/YP conceal/BSZGRDL concealed/U concealer/M concealing/Y concealment/MS conceded/Y conceitedness/SM conceited/YP conceit/SGDM conceivable/IU conceivably/I conceive/BGRSD conceiver/M concentrate/VNGSDX concentration/M concentrator/MS concentrically Concepcin/M conceptional conception/MS concept/SVM conceptuality/M conceptualization/A conceptualizations conceptualization's conceptualize/DRSG conceptualizing/A conceptual/Y concerned/YU concern/USGD concerted/PY concert/EDSG concertina/MDGS concertize/GDS concertmaster/MS concerto/SM concert's concessionaire/SM concessional concessionary concession/R Concetta/M Concettina/M Conchita/M conch/MDG conchs concierge/SM conciliar conciliate/GNVX conciliation/ASM conciliator/MS conciliatory/A conciseness/SM concise/TYRNPX concision/M conclave/S concluder/M conclude/RSDG conclusion/SM conclusive/IPY conclusiveness/ISM concocter/M concoction/SM concoct/RDVGS concomitant/YS concordance/MS concordant/Y concordat/SM Concorde/M Concordia/M Concord/MS concourse concreteness/MS concrete/NGXRSDPYM concretion/M concubinage/SM concubine/SM concupiscence/SM concupiscent concurrence/MS concur/S concussion/MS concuss/VD condemnate/XN condemnation/M condemnatory condemner/M condemn/ZSGRDB condensate/NMXS condensation/M condenser/M condense/ZGSD condensible condescend condescending/Y condescension/MS condign condiment/SM condition/AGSJD conditionals conditional/UY conditioned/U conditioner/MS conditioning/M condition's condole condolence/MS condominium/MS condom/SM condone/GRSD condoner/M Condorcet/M condor/MS condo/SM conduce/VGSD conduciveness/M conducive/P conductance/SM conductibility/SM conductible conduction/MS conductive/Y conductivity/MS conductor/MS conductress/MS conduct/V conduit/MS coneflower/M Conestoga coney's confabbed confabbing confab/MS confabulate/XSDGN confabulation/M confectioner/M confectionery/SM confectionist confection/RDMGZS confect/S Confederacy/M confederacy/MS confederate/M Confederate/S conferee/MS conference/DSGM conferrable conferral/SM conferred conferrer/SM conferring confer/SB confessed/Y confessional/SY confession/MS confessor/SM confetti/M confidante/SM confidant/SM confidence/SM confidentiality/MS confidentialness/M confidential/PY confident/Y confider/M confide/ZGRSD confiding/PY configuration/ASM configure/AGSDB confined/U confine/L confinement/MS confiner/M confirm/AGDS confirmation/ASM confirmatory confirmedness/M confirmed/YP confiscate/DSGNX confiscation/M confiscator/MS confiscatory conflagration/MS conflate/NGSDX conflation/M conflicting/Y conflict/SVGDM confluence/MS conformable/U conformal conformance/SM conformational/Y conform/B conformer/M conformism/SM conformist/SM conformities conformity/MUI confounded/Y confound/R confrre/MS confrontational confrontation/SM confronter/M confront/Z Confucianism/SM Confucian/S Confucius/M confusedness/M confused/PY confuse/RBZ confusing/Y confutation/MS confute/GRSD confuter/M conga/MDG congeal/GSDL congealment/MS congeniality/UM congenial/U congeries/M conger/SM congestion/MS congest/VGSD conglomerate/XDSNGVM conglomeration/M Cong/M Congolese Congo/M congrats congratulate/NGXSD congratulation/M congratulatory congregate/DSXGN congregational Congregational congregationalism/MS congregationalist/MS Congregationalist/S congregation/M congressional/Y congressman/M congressmen Congress/MS congress/MSDG congresspeople congressperson/S congresswoman/M congresswomen Congreve/M congruence/IM congruences congruency/M congruential congruent/YI congruity/MSI congruousness/IM congruous/YIP conicalness/M conical/PSY conic/S conics/M conifer/MS coniferous conjectural/Y conjecture/GMDRS conjecturer/M conjoint conjugacy conjugal/Y conjugate/XVNGYSDP conjugation/M conjunct/DSV conjunctiva/MS conjunctive/YS conjunctivitis/SM conjuration/MS conjurer/M conjure/RSDZG conjuring/M conker/M conk/ZDR Conley/M Con/M conman connect/ADGES connectedly/E connectedness/ME connected/U connectible Connecticut/M connection/AME connectionless connections/E connective/SYM connectivity/MS connector/MS Connelly/M Conner/M Connery/M connexion/MS Conney/M conn/GVDR Connie/M Conni/M conniption/MS connivance/MS conniver/M connive/ZGRSD connoisseur/MS Connor/SM connotative/Y Conn/RM connubial/Y Conny/M conquerable/U conquered/AU conqueror/MS conquer/RDSBZG conquers/A conquest/ASM conquistador/MS Conrade/M Conrad/M Conrado/M Conrail/M Conroy/M Consalve/M consanguineous/Y consanguinity/SM conscienceless conscientiousness/MS conscientious/YP conscionable/U consciousness/MUS conscious/UYSP conscription/SM consecrated/AU consecrates/A consecrate/XDSNGV consecrating/A consecration/AMS consecutiveness/M consecutive/YP consensus/SM consenter/M consenting/Y consent/SZGRD consequence consequentiality/S consequential/IY consequentialness/M consequently/I consequent/PSY conservancy/SM conservationism conservationist/SM conservation/SM conservatism/SM conservativeness/M Conservative/S conservative/SYP conservator/MS conservatory/MS con/SGM considerable/I considerables considerably/I considerateness/MSI considerate/XIPNY consideration/ASMI considered/U considerer/M consider/GASD considering/S consign/ASGD consignee/SM consignment/SM consist/DSG consistence/S consistency/IMS consistent/IY consistory/MS consolable/I Consolata/M consolation/MS consolation's/E consolatory consoled/U consoler/M console/ZBG consolidated/AU consolidate/NGDSX consolidates/A consolidation/M consolidator/SM consoling/Y consomm/S consonance/IM consonances consonantal consonant/MYS consortia consortium/M conspectus/MS conspicuousness/IMS conspicuous/YIP conspiracy/MS conspiratorial/Y conspirator/SM constable Constable/M constabulary/MS constance Constance/M Constancia/M constancy/IMS Constancy/M Constanta/M Constantia/M Constantina/M Constantine/M Constantin/M Constantino/M Constantinople/M constant/IY constants constellation/SM consternate/XNGSD consternation/M constipate/XDSNG constipation/M constituency/MS constituent/SYM constituted/A constitute/NGVXDS constitutes/A constituting/A Constitution constitutionality's constitutionality/US constitutionally/U constitutional/SY constitution/AMS constitutive/Y constrain constrainedly constrained/U constraint/MS constriction/MS constrictor/MS constrict/SDGV construable construct/ASDGV constructibility constructible/A constructional/Y constructionist/MS construction/MAS constructions/C constructiveness/SM constructive/YP constructor/MS construe/GSD Consuela/M Consuelo/M consular/S consulate/MS consul/KMS consulship/MS consultancy/S consultant/MS consultation/SM consultative consulted/A consulter/M consult/RDVGS consumable/S consumed/Y consume/JZGSDB consumerism/MS consumerist/S consumer/M consuming/Y consummate/DSGVY consummated/U consumption/SM consumptive/YS cont contact/BGD contacted/A contact's/A contacts/A contagion/SM contagiousness/MS contagious/YP containerization/SM containerize/GSD container/M containment/SM contain/SLZGBRD contaminant/SM contaminated/AU contaminates/A contaminate/SDCXNG contaminating/A contamination/CM contaminative contaminator/MS contd cont'd contemn/SGD contemplate/DVNGX contemplation/M contemplativeness/M contemplative/PSY contemporaneity/MS contemporaneousness/M contemporaneous/PY contemptibleness/M contemptible/P contemptibly contempt/M contemptuousness/SM contemptuous/PY contentedly/E contentedness/SM contented/YP content/EMDLSG contention/MS contentiousness/SM contentious/PY contently contentment/ES contentment's conterminous/Y contestable/I contestant/SM contested/U contextualize/GDS contiguity/MS contiguousness/M contiguous/YP continence/ISM Continental/S continental/SY continent/IY Continent/M continents continent's contingency/SM contingent/SMY continua continuable continual/Y continuance/ESM continuant/M continuation/ESM continue/ESDG continuer/M continuity/SEM continuousness/M continuous/YE continuum/M contortionist/SM contortion/MS contort/VGD contour contraband/SM contrabass/M contraception/SM contraceptive/S contract/DG contractible contractile contractual/Y contradict/GDS contradiction/MS contradictorily contradictoriness/M contradictory/PS contradistinction/MS contraflow/S contrail/M contraindicate/SDVNGX contraindication/M contralto/SM contrapositive/S contraption/MS contrapuntal/Y contrariety/MS contrarily contrariness/MS contrariwise contrary/PS contra/S contrasting/Y contrastive/Y contrast/SRDVGZ contravene/GSRD contravener/M contravention/MS Contreras/M contretemps/M contribute/XVNZRD contribution/M contributive/Y contributorily contributor/SM contributory/S contriteness/M contrite/NXP contrition/M contrivance/SM contriver/M contrive/ZGRSD control/CS controllability/M controllable/IU controllably/U controlled/CU controller/SM controlling/C control's controversialists controversial/UY controversy/MS controvert/DGS controvertible/I contumacious/Y contumacy/MS contumelious contumely/MS contuse/NGXSD contusion/M conundrum/SM conurbation/MS convalesce/GDS convalescence/SM convalescent/S convect/DSVG convectional convection/MS convector convene/ASDG convener/MS convenience/ISM convenient/IY conventicle/SM conventionalism/M conventionalist/M conventionality/SUM conventionalize/GDS conventional/UY convention/MA conventions convergence/MS convergent conversant/Y conversationalist/SM conversational/Y conversation/SM conversazione/M converse/Y conversion/AM conversioning converted/U converter/MS convert/GADS convertibility's/I convertibility/SM convertibleness/M convertible/PS convexity/MS convex/Y conveyance/DRSGMZ conveyancer/M conveyancing/M convey/BDGS conveyor/MS conviction/MS convict/SVGD convinced/U convincer/M convince/RSDZG convincingness/M convincing/PUY conviviality/MS convivial/Y convoke/GSD convolute/XDNY convolution/M convolve/C convolved convolves convolving convoy/GMDS convulse/SDXVNG convulsion/M convulsiveness/M convulsive/YP Conway/M cony/SM coo/GSD cookbook/SM cooked/AU Cooke/M cooker/M cookery/MS cook/GZDRMJS Cookie/M cookie/SM cooking/M Cook/M cookout/SM cooks/A cookware/SM cooky's coolant/SM cooled/U cooler/M Cooley/M coolheaded Coolidge/M coolie/MS coolness/MS cool/YDRPJGZTS coon/MS! coonskin/MS cooperage/MS cooperate/VNGXSD cooperation/M cooperativeness/SM cooperative/PSY cooperator/MS cooper/GDM Cooper/M coop/MDRGZS Coop/MR coordinated/U coordinateness/M coordinate/XNGVYPDS coordination/M coordinator/MS Coors/M cootie/SM coot/MS copay/S Copeland/M Copenhagen/M coper/M Copernican Copernicus/M cope/S copied/A copier/M copies/A copilot/SM coping/M copiousness/SM copious/YP coplanar Copland/M Copley/M copolymer/MS copora copped Copperfield/M copperhead/MS copper/MSGD copperplate/MS coppersmith/M coppersmiths coppery coppice's copping Coppola/M copra/MS coprolite/M coprophagous copse/M cops/GDS cop/SJMDRG copter/SM Coptic/M copula/MS copulate/XDSNGV copulation/M copulative/S copybook/MS copycat/SM copycatted copycatting copyist/SM copy/MZBDSRG copyrighter/M copyright/MSRDGZ copywriter/MS coquetry/MS coquette/DSMG coquettish/Y Corabella/M Corabelle/M Corabel/M coracle/SM Coralie/M Coraline/M coralline Coral/M coral/SM Coralyn/M Cora/M corbel/GMDJS Corbet/M Corbett/M Corbie/M Corbin/M Corby/M cordage/MS corded/AE Cordelia/M Cordelie/M Cordell/M corder/AM Cordey/M cord/FSAEM cordiality/MS cordialness/M cordial/PYS Cordie/M cordillera/MS Cordilleras Cordi/M cording/MA cordite/MS cordless Cord/M Cordoba cordon/DMSG cordovan/SM Cordula/M corduroy/GDMS Cordy/M cored/A Coreen/M Corella/M core/MZGDRS Corenda/M Corene/M corer/M corespondent/MS Coretta/M Corette/M Corey/M Corfu/M corgi/MS coriander/SM Corie/M Corilla/M Cori/M Corina/M Corine/M coring/M Corinna/M Corinne/M Corinthian/S Corinthians/M Corinth/M Coriolanus/M Coriolis/M Corissa/M Coriss/M corked/U corker/M cork/GZDRMS Cork/M corkscrew/DMGS corks/U Corliss/M Corly/M Cormack/M corm/MS cormorant/MS Cornall/M cornball/SM cornbread/S corncob/SM corncrake/M corneal cornea/SM Corneille/M Cornela/M Cornelia/M Cornelius/M Cornelle/M Cornell/M corner/GDM cornerstone/MS cornet/SM Corney/M cornfield/SM cornflake/S cornflour/M cornflower/SM corn/GZDRMS cornice/GSDM Cornie/M cornily corniness/S Cornish/S cornmeal/S cornrow/GDS cornstalk/MS cornstarch/SM cornucopia/MS Cornwallis/M Cornwall/M Corny/M corny/RPT corolla/MS corollary/SM Coronado/M coronal/MS coronary/S corona/SM coronate/NX coronation/M coroner/MS coronet/DMS Corot/M coroutine/SM Corp corporal/SYM corpora/MS corporate/INVXS corporately corporation/MI corporatism/M corporatist corporeality/MS corporeal/IY corporealness/M corp/S corpse/M corpsman/M corpsmen corps/SM corpulence/MS corpulentness/S corpulent/YP corpuscle/SM corpuscular corpus/M corr corralled corralling corral/MS correctable/U correct/BPSDRYTGV corrected/U correctional correction/MS corrective/YPS correctly/I correctness/MSI corrector/MS Correggio/M correlated/U correlate/SDXVNG correlation/M correlative/YS Correna/M correspond/DSG correspondence/MS correspondent/SM corresponding/Y Correy/M Corrianne/M corridor/SM Corrie/M corrigenda corrigendum/M corrigible/I Corri/M Corrina/M Corrine/M Corrinne/M corroborated/U corroborate/GNVXDS corroboration/M corroborative/Y corroborator/MS corroboratory corrode/SDG corrodible corrosion/SM corrosiveness/M corrosive/YPS corrugate/NGXSD corrugation/M corrupt/DRYPTSGV corrupted/U corrupter/M corruptibility/SMI corruptible/I corruption/IM corruptions corruptive/Y corruptness/MS Corry/M corsage/MS corsair/SM corset/GMDS Corsica/M Corsican/S cortge/MS Cortes/S cortex/M Cortez's cortical/Y cortices corticosteroid/SM Cortie/M cortisone/SM Cortland/M Cort/M Cortney/M Corty/M corundum/MS coruscate/XSDGN coruscation/M Corvallis/M corvette/MS Corvus/M Cory/M Cos Cosby/M Cosetta/M Cosette/M cos/GDS cosignatory/MS cosign/SRDZG cosily Cosimo/M cosine/MS cosiness/MS Cosme/M cosmetically cosmetician/MS cosmetic/SM cosmetologist/MS cosmetology/MS cosmic cosmical/Y cosmogonist/MS cosmogony/SM cosmological/Y cosmologist/MS cosmology/SM Cosmo/M cosmonaut/MS cosmopolitanism/MS cosmopolitan/SM cosmos/SM cosponsor/DSG cossack/S Cossack/SM cosset/GDS Costa/M Costanza/M costarred costarring costar/S Costello/M costiveness/M costive/PY costless costliness/SM costly/RTP cost/MYGVJS Costner/M costumer/M costume/ZMGSRD cotangent/SM Cote/M cote/MS coterie/MS coterminous/Y cotillion/SM Cotonou/M Cotopaxi/M cot/SGMD cottager/M cottage/ZMGSRD cottar's cotted cotter/SDM cotton/GSDM Cotton/M cottonmouth/M cottonmouths cottonseed/MS cottontail/SM cottonwood/SM cottony cotyledon/MS couching/M couch/MSDG cougar/MS cougher/M cough/RDG coughs couldn't could/T could've coule/MS Coulomb/M coulomb/SM councilman/M councilmen councilor/MS councilperson/S council/SM councilwoman/M councilwomen counsel/GSDM counsellings counselor/MS countability/E countable/U countably/U countdown/SM counted/U count/EGARDS countenance/EGDS countenancer/M countenance's counteract/DSVG counteraction/SM counterargument/SM counterattack/DRMGS counterbalance/MSDG counterclaim/GSDM counterclockwise counterculture/MS countercyclical counterespionage/MS counterexample/S counterfeiter/M counterfeit/ZSGRD counterflow counterfoil/MS counterforce/M counter/GSMD counterinsurgency/MS counterintelligence/MS counterintuitive countermand/DSG counterman/M countermeasure/SM countermen counteroffensive/SM counteroffer/SM counterpane/SM counterpart/SM counterpoint/GSDM counterpoise/GMSD counterproductive counterproposal/M counterrevolutionary/MS counterrevolution/MS counter's/E counters/E countersignature/MS countersign/SDG countersink/SG counterspy/MS counterstrike countersunk countertenor/SM countervail/DSG counterweight/GMDS countess/MS countless/Y countrify/D countryman/M countrymen country/MS countryside/MS countrywide countrywoman/M countrywomen county/SM coup/ASDG coupe/MS Couperin/M couple/ACU coupled/CU coupler/C couplers coupler's couple's couples/CU couplet/SM coupling's/C coupling/SM coupon/SM coup's courage/MS courageously courageousness/MS courageous/U courages/E Courbet/M courgette/MS courier/GMDS course/EGSRDM courser's/E courser/SM course's/AF courses/FA coursework coursing/M Courtenay/M courteousness/EM courteousnesses courteous/PEY courtesan/MS courtesied courtesy/ESM courtesying court/GZMYRDS courthouse/MS courtier/SM courtliness/MS courtly/RTP Court/M Courtnay/M Courtney/M courtroom/MS courtship/SM courtyard/SM couscous/MS cousinly/U cousin/YMS Cousteau/M couture/SM couturier/SM covalent/Y covariance/SM covariant/S covariate/SN covary cove/DRSMZG covenanted/U covenanter/M covenant/SGRDM coven/SM Covent/M Coventry/MS coverable/E cover/AEGUDS coverage/MS coverall/DMS coverer/AME covering/MS coverlet/MS coversheet covers/M covertness/SM covert/YPS coveter/M coveting/Y covetousness/SM covetous/PY covet/SGRD covey/SM covington cowardice/MS cowardliness/MS cowardly/P Coward/M coward/MYS cowbell/MS cowbird/MS cowboy/MS cowcatcher/SM cowed/Y cowering/Y cower/RDGZ cowgirl/MS cowhand/S cowherd/SM cowhide/MGSD Cowley/M cowlick/MS cowling/M cowl/SGMD cowman/M cow/MDRSZG cowmen coworker/MS Cowper/M cowpoke/MS cowpony cowpox/MS cowpuncher/M cowpunch/RZ cowrie/SM cowshed/SM cowslip/MS coxcomb/MS Cox/M cox/MDSG coxswain/GSMD coy/CDSG coyer coyest coyly Coy/M coyness/MS coyote/SM coypu/SM cozenage/MS cozen/SGD cozily coziness/MS Cozmo/M Cozumel/M cozy/DSRTPG CPA cpd CPI cpl Cpl CPO CPR cps CPU/SM crabapple crabbedness/M crabbed/YP Crabbe/M crabber/MS crabbily crabbiness/S crabbing/M crabby/PRT crabgrass/S crablike crab/MS crackable/U crackdown/MS crackerjack/S cracker/M crackle/GJDS crackling/M crackly/RT crackpot/SM crackup/S crack/ZSBYRDG cradler/M cradle/SRDGM cradling/M craftily craftiness/SM Craft/M craft/MRDSG craftsman/M craftsmanship/SM craftsmen craftspeople craftspersons craftswoman craftswomen crafty/TRP Craggie/M cragginess/SM Craggy/M craggy/RTP crag/SM Craig/M Cramer/M crammed crammer/M cramming cramper/M cramp/MRDGS crampon/SM cram/S Cranach/M cranberry/SM Crandall/M crane/DSGM cranelike Crane/M Cranford/M cranial cranium/MS crankcase/MS crankily crankiness/MS crank/SGTRDM crankshaft/MS cranky/TRP Cranmer/M cranny/DSGM Cranston/M crape/SM crapped crappie/M crapping crappy/RST crapshooter/SM crap/SMDG! crasher/M crashing/Y crash/SRDGZ crassness/MS crass/TYRP crate/DSRGMZ crater/DMG Crater/M cravat/SM cravatted cravatting crave/DSRGJ cravenness/SM craven/SPYDG craver/M craving/M crawdad/S crawfish's Crawford/M crawler/M crawl/RDSGZ crawlspace/S crawlway crawly/TRS craw/SYM crayfish/GSDM Crayola/M crayon/GSDM Cray/SM craze/GMDS crazily craziness/MS crazy/SRTP creakily creakiness/SM creak/SDG creaky/PTR creamer/M creamery/MS creamily creaminess/SM cream/SMRDGZ creamy/TRP creased/CU crease/IDRSG crease's creases/C creasing/C created/U create/XKVNGADS creationism/MS creationist/MS Creation/M creation/MAK creativeness/SM creative/YP creativities creativity/K creativity's Creator/M creator/MS creatureliness/M creaturely/P creature/YMS crche/SM credence/MS credent credential/SGMD credenza/SM credibility/IMS credible/I credibly/I creditability/M creditableness/M creditable/P creditably/E credited/U credit/EGBSD creditor/MS credit's creditworthiness credo/SM credulity/ISM credulous/IY credulousness/SM creedal creed/C creeds creed's creekside creek/SM Creek/SM creel/SMDG Cree/MDS creeper/M creepily creepiness/SM creep/SGZR creepy/PRST Creigh/M Creight/M Creighton/M cremate/XDSNG cremation/M crematoria crematorium/MS crematory/S creme/S crenelate/XGNSD crenelation/M Creole/MS creole/SM Creon/M creosote/MGDS crepe/DSGM crept crescendoed crescendoing crescendo/SCM crescent/MS cress/S crestfallenness/M crestfallen/PY cresting/M crestless crest/SGMD Crestview/M cretaceous Cretaceously/M Cretaceous/Y Cretan/S Crete/M cretinism/MS cretin/MS cretinous cretonne/SM crevasse/DSMG crevice/SM crew/DMGS crewel/SM crewelwork/SM crewman/M crewmen cribbage/SM cribbed cribber/SM cribbing/M crib/SM Crichton/M cricketer/M cricket/SMZRDG crick/GDSM Crick/M cried/C crier/CM cries/C Crimea/M Crimean crime/GMDS criminality/MS criminalization/C criminalize/GC criminal/SYM criminologist/SM criminology/MS crimper/M crimp/RDGS crimson/DMSG cringer/M cringe/SRDG crinkle/DSG crinkly/TRS Crin/M crinoline/SM cripple/GMZDRS crippler/M crippling/Y Crisco/M crises crisis/M Cris/M crisper/M crispiness/SM crispness/MS crisp/PGTYRDS crispy/RPT criss crisscross/GDS Crissie/M Crissy/M Cristabel/M Cristal/M Crista/M Cristen/M Cristian/M Cristiano/M Cristie/M Cristi/M Cristina/M Cristine/M Cristin/M Cristionna/M Cristobal/M Cristy/M criteria criterion/M criticality critically/U criticalness/M critical/YP criticism/MS criticized/U criticize/GSRDZ criticizer/M criticizes/A criticizingly/S criticizing/UY critic/MS critique/MGSD critter/SM Cr/M croaker/M croak/SRDGZ croaky/RT Croatia/M Croatian/S Croat/SM Croce/M crocheter/M crochet/RDSZJG crockery/SM Crockett/M Crockpot/M crock/SGRDM crocodile/MS crocus/SM Croesus/SM crofter/M croft/MRGZS croissant/MS Croix/M Cromwellian Cromwell/M crone/SM Cronin/M Cronkite/M Cronus/M crony/SM crookedness/SM crooked/TPRY Crookes/M crookneck/MS crook/SGDM crooner/M croon/SRDGZ cropland/MS crop/MS cropped cropper/SM cropping croquet/MDSG croquette/SM Crosby/M crosier/SM crossarm crossbarred crossbarring crossbar/SM crossbeam/MS crossbones crossbowman/M crossbowmen crossbow/SM crossbred/S crossbreed/SG crosscheck/SGD crosscurrent/SM crosscut/SM crosscutting crossed/UA crosses/UA crossfire/SM crosshatch/GDS crossing/M Cross/M crossness/MS crossover/MS crosspatch/MS crosspiece/SM crosspoint crossproduct/S crossroad/GSM crossroads/M crosstalk/M crosstown crosswalk/MS crossway/M crosswind/SM crosswise crossword/MS cross/ZTYSRDMPBJG crotchetiness/M crotchet/MS crotchety/P crotchless crotch/MDS crouch/DSG croupier/M croup/SMDG croupy/TZR croton/MS crowbait crowbarred crowbarring crowbar/SM crowdedness/M crowded/P crowd/MRDSG crowfeet crowfoot/M crow/GDMS Crowley/M crowned/U crowner/M crown/RDMSJG crozier's CRT/S crucial/Y crucible/MS crucifiable crucifixion/MS Crucifixion/MS crucifix/SM cruciform/S crucify/NGDS crudded crudding cruddy/TR crudeness/MS crude/YSP crudits crudity/MS crud/STMR cruelness/MS cruelty/SM cruel/YRTSP cruet/MS cruft crufty Cruikshank/M cruise/GZSRD cruiser/M cruller/SM crumb/GSYDM crumble/DSJG crumbliness/MS crumbly/PTRS crumby/RT crumminess/S crummy/SRTP crump crumpet/SM crumple/DSG crunch/DSRGZ crunchiness/MS crunchy/TRP crupper/MS crusade/GDSRMZ crusader/M cruse/MS crushable/U crusher/M crushing/Y crushproof crush/SRDBGZ Crusoe/M crustacean/MS crustal crust/GMDS crustily crustiness/SM crusty/SRTP crutch/MDSG Crux/M crux/MS Cruz/M crybaby/MS cry/JGDRSZ cryogenic/S cryogenics/M cryostat/M cryosurgery/SM cryptanalysis/M cryptanalyst/M cryptanalytic crypt/CS cryptic cryptically cryptogram/MS cryptographer/MS cryptographic cryptographically cryptography/MS cryptologic cryptological cryptologist/M cryptology/M Cryptozoic/M crypt's crystalline/S crystallite/SM crystallization/AMS crystallized/UA crystallizes/A crystallize/SRDZG crystallizing/A crystallographer/MS crystallographic crystallography/M Crystal/M crystal/SM Crysta/M Crystie/M Cs C's cs/EA cs's CST ct CT Cthrine/M Ct/M ctn ctr Cuba/M Cuban/S cubbed cubbing cubbyhole/MS cuber/M cube/SM cubical/Y cubicle/SM cubic/YS cubism/SM cubist/MS cubit/MS cub/MDRSZG cuboid Cuchulain/M cuckold/GSDM cuckoldry/MS cuckoo/SGDM cucumber/MS cuddle/GSD cuddly/TRP cu/DG cudgel/GSJMD cud/MS cue/MS cuff/GSDM Cuisinart/M cuisine/MS Culbertson/M culinary Cullan/M cull/DRGS cullender's Cullen/M culler/M Culley/M Cullie/M Cullin/M Cull/MN Cully/M culminate/XSDGN culmination/M culotte/S culpability/MS culpable/I culpableness/M culpably culpa/SM culprit/SM cultism/SM cultist/SM cultivable cultivated/U cultivate/XBSDGN cultivation/M cultivator/SM cult/MS cultural/Y cultured/U culture/SDGM Culver/MS culvert/SM Cu/M cumber/DSG Cumberland/M cumbersomeness/MS cumbersome/YP cumbrous cumin/MS cummerbund/MS Cummings cumquat's cum/S cumulate/XVNGSD cumulation/M cumulative/Y cumuli cumulonimbi cumulonimbus/M cumulus/M Cunard/M cuneiform/S cunnilingus/SM Cunningham/M cunningness/M cunning/RYSPT cunt/SM! cupboard/SM cupcake/SM Cupertino/M cupful/SM cupidinously cupidity/MS Cupid/M cupid/S cup/MS cupola/MDGS cupped cupping/M cupric cuprous curability/MS curable/IP curableness/MI curably/I Curacao/M curacy/SM curare/MS curate/VGMSD curative/YS curatorial curator/KMS curbing/M curbside curb/SJDMG curbstone/MS Curcio/M curdle/SDG curd/SMDG cured/U cure/KBDRSGZ curer/MK curettage/SM curfew/SM curfs curiae curia/M cur/IBS Curie/M curie/SM curiosity/SM curio/SM curiousness/SM curious/TPRY Curitiba/M curium/MS curler/SM curlew/MS curlicue/MGDS curliness/SM curling/M curl/UDSG curlycue's curly/PRT curmudgeon/MYS Curran/M currant/SM curred/AFI currency's currency/SF current/FSY currently/A currentness/M Currey/M curricle/M curricula curricular curriculum/M Currie/M currier/M Currier/M curring/FAI Curr/M currycomb/DMGS Curry/MR curry/RSDMG cur's curs/ASDVG curse/A cursedness/M cursed/YRPT curse's cursive/EPYA cursiveness/EM cursives cursor/DMSG cursorily cursoriness/SM cursory/P curtailer/M curtail/LSGDR curtailment/SM curtain/GSMD Curtice/M Curtis/M Curt/M curtness/MS curtsey's curtsy/SDMG curt/TYRP curvaceousness/S curvaceous/YP curvature/MS curved/A curved's curve/DSGM curvilinearity/M curvilinear/Y curving/M curvy/RT cushion/SMDG Cushman/M cushy/TR cuspid/MS cuspidor/MS cusp/MS cussedness/M cussed/YP cuss/EGDSR cusses/F cussing/F cuss's custard/MS Custer/M custodial custodianship/MS custodian/SM custody/MS customarily customariness/M customary/PS customer/M customhouse/S customization/SM customize/ZGBSRD custom/SMRZ cutaneous/Y cutaway/SM cutback/SM cuteness/MS cute/SPY cutesy/RT cuticle/SM cutlass/MS cutler/SM cutlery/MS cutlet/SM cut/MRST cutoff/MS cutout/SM cutter/SM cutthroat/SM cutting/MYS cuttlebone/SM cuttlefish/MS cuttle/M cutup/MS cutworm/MS Cuvier/M Cuzco/M CV cw cwt Cyanamid/M cyanate/M cyanic cyanide/GMSD cyan/MS cyanogen/M Cybele/M cybernetic/S cybernetics/M cyberpunk/S cyberspace/S Cybill/M Cybil/M Cyb/M cyborg/S Cyclades cyclamen/MS cycle/ASDG cycler cycle's cycleway/S cyclic cyclical/SY cycling/M cyclist/MS cyclohexanol cycloidal cycloid/SM cyclometer/MS cyclone/SM cyclonic cyclopean cyclopedia/MS cyclopes Cyclopes cyclops Cyclops/M cyclotron/MS cyder/SM cygnet/MS Cygnus/M cylinder/GMDS cylindric cylindrical/Y Cy/M cymbalist/MS cymbal/SM Cymbre/M Cynde/M Cyndia/M Cyndie/M Cyndi/M Cyndy/M cynical/UY cynicism/MS cynic/MS cynosure/SM Cynthea/M Cynthia/M Cynthie/M Cynthy/M cypher/MGSD cypreses cypress/SM Cyprian Cypriot/SM Cyprus/M Cyrano/M Cyrille/M Cyrillic Cyrill/M Cyrillus/M Cyril/M Cyrus/M cystic cyst/MS cytochemistry/M cytochrome/M cytologist/MS cytology/MS cytolysis/M cytoplasmic cytoplasm/SM cytosine/MS cytotoxic CZ czarevitch/M czarina/SM czarism/M czarist/S czarship czar/SM Czech Czechoslovakia/M Czechoslovakian/S Czechoslovak/S Czechs Czerniak/M Czerny/M D DA dabbed dabber/MS dabbing dabbler/M dabble/RSDZG dab/S Dacca's dace/MS Dacey/M dacha/SM Dachau/M dachshund/SM Dacia/M Dacie/M Dacron/MS dactylic/S dactyl/MS Dacy/M Dadaism/M dadaism/S Dadaist/M dadaist/S Dada/M daddy/SM Dade/M dado/DMG dadoes dad/SM Daedalus/M Dael/M daemonic daemon/SM Daffie/M Daffi/M daffiness/S daffodil/MS Daffy/M daffy/PTR daftness/MS daft/TYRP DAG dagger/DMSG Dag/M Dagmar/M Dagny/M Daguerre/M daguerreotype/MGDS Dagwood/M Dahlia/M dahlia/MS Dahl/M Dahomey/M Daile/M dailiness/MS daily/PS Daimler/M daintily daintiness/MS dainty/TPRS daiquiri/SM dairying/M dairyland dairymaid/SM dairyman/M dairymen dairy/MJGS dairywoman/M dairywomen Daisey/M Daisie/M Daisi/M dais/SM Daisy/M daisy/SM Dakar/M Dakotan Dakota/SM Dale/M Dalenna/M dale/SMH daleth/M Daley/M Dalhousie/M Dalia/M Dalian/M Dalila/M Dali/SM Dallas/M dalliance/SM dallier/M Dalli/MS Dall/M Dallon/M dally/ZRSDG Dal/M Dalmatia/M dalmatian/S Dalmatian/SM Daloris/M Dalston/M Dalt/M Dalton/M Daly/M damageable damaged/U damage/MZGRSD damager/M damaging/Y Damara/M Damaris/M Damascus/M damask/DMGS dame/SM Dame/SMN Damian/M Damiano/M Damien/M Damion/M Damita/M dam/MDS dammed damming dammit/S damnably damnation/MS damnedest/MS damned/TR damn/GSBRD damning/Y Damocles/M Damon/M damped/U dampener/M dampen/RDZG damper/M dampness/MS damp/SGZTXYRDNP damselfly/MS damsel/MS damson/MS Dana Dana/M Danbury/M dancelike dancer/M dance/SRDJGZ dandelion/MS dander/DMGS dandify/SDG dandily dandle/GSD dandruff/MS dandy/TRSM Danelaw/M Danella/M Danell/M Dane/SM Danette/M danger/DMG Dangerfield/M dangerousness/M dangerous/YP dangler/M dangle/ZGRSD dangling/Y dang/SGZRD Danial/M Dania/M Danica/M Danice/M Daniela/M Daniele/M Daniella/M Danielle/M Daniel/SM Danielson/M Danie/M Danika/M Danila/M Dani/M Danish danish/S Danita/M Danit/M dankness/MS dank/TPYR Danna/M Dannel/M Dannie/M Danni/M Dannye/M Danny/M danseuse/SM Dan/SM Dante/M Danton/M Danube/M Danubian Danville/M Danya/M Danyelle/M Danyette/M Danzig/M Daphene/M Daphna/M Daphne/M dapperness/M dapper/PSTRY dapple/SDG Dara/M Darbee/M Darbie/M Darb/M Darby/M Darcee/M Darcey/M Darcie/M Darci/M D'Arcy Darcy/M Darda/M Dardanelles daredevil/MS daredevilry/S Dareen/M Darelle/M Darell/M Dare/M Daren/M darer/M daresay dare/ZGDRSJ d'Arezzo Daria/M Darice/M Darill/M Dari/M daringness/M daring/PY Darin/M Dario/M Darius/M Darjeeling/M darkener/M darken/RDZG dark/GTXYRDNSP darkish darkly/TR darkness/MS darkroom/SM Darla/M Darleen/M Darlene/M Darline/M Darling/M darlingness/M Darlington/M darling/YMSP Darlleen/M Dar/MNH Darnall/M darned/TR Darnell/M darner/M darn/GRDZS darning/M Darn/M Daron/M DARPA/M Darrelle/M Darrell/M Darrel/M Darren/M Darrick/M Darrin/M Darrow/M Darryl/M Darsey/M Darsie/M d'art dartboard/SM darter/M Darth/M Dartmouth/M dart/MRDGZS Darvon/M Darwinian/S Darwinism/MS Darwinist/MS Darwin/M Darya/M Daryle/M Daryl/M Daryn/M Dasha/M dashboard/SM dasher/M dash/GZSRD dashiki/SM dashing/Y Dasie/M Dasi/M dastardliness/SM dastardly/P dastard/MYS Dasya/M DAT database/DSMG datafile datagram/MS data/M Datamation/M Datamedia/M dataset/S datedly datedness date/DRSMZGV dated/U dateless dateline/DSMG dater/M Datha/M dative/S Datsun/M datum/MS dauber/M daub/RDSGZ Daugherty/M daughter/MYS Daumier/M Daune/M daunt/DSG daunted/U daunting/Y dauntlessness/SM dauntless/PY dauphin/SM Davao/M Daveen/M Dave/M Daven/M Davenport/M davenport/MS Daveta/M Davey/M Davida/M Davidde/M Davide/M David/SM Davidson/M Davie/M Davina/M Davine/M Davinich/M Davin/M Davis/M Davita/M davit/SM Dav/MN Davon/M Davy/SM dawdler/M dawdle/ZGRSD Dawes/M Dawna/M dawn/GSDM Dawn/M Dawson/M daybed/S daybreak/SM daycare/S daydreamer/M daydream/RDMSZG Dayle/M daylight/GSDM Day/M Dayna/M daysack day/SM daytime/SM Dayton/M dazed/PY daze/DSG dazzler/M dazzle/ZGJRSD dazzling/Y db DB dbl dB/M DBMS DC DD Ddene/M DDS DDT DE deacon/DSMG deaconess/MS deadbeat/SM deadbolt/S deadener/M deadening/MY deaden/RDG deadhead/MS deadline/MGDS deadliness/SM deadlock/MGDS deadly/RPT deadness/M deadpanned deadpanner deadpanning deadpan/S dead/PTXYRN deadwood/SM deafening/MY deafen/JGD deafness/MS deaf/TXPYRN dealer/M dealership/MS dealing/M deallocator deal/RSGZJ dealt Deana/M dean/DMG Deandre/M Deane/M deanery/MS Dean/M Deanna/M Deanne/M Deann/M deanship/SM Dearborn/M dearness/MS dearth/M dearths dear/TYRHPS deary/MS deassign deathbed/MS deathblow/SM deathless/Y deathlike deathly/TR death/MY deaths deathtrap/SM deathward deathwatch/MS debacle/SM debarkation/SM debark/G debar/L debarment/SM debarring debaser/M debatable/U debate/BMZ debater/M debauchedness/M debauched/PY debauchee/SM debaucher/M debauchery/SM debauch/GDRS Debbie/M Debbi/M Debby/M Debee/M debenture/MS Debera/M debilitate/NGXSD debilitation/M debility/MS Debi/M debit/DG deb/MS Deb/MS debonairness/SM debonair/PY Deborah/M Debora/M Debor/M debouch/DSG Debra/M debrief/GJ debris/M debtor/SM debt/SM Debussy/M dbutante/SM debut/MDG decade/MS decadency/S decadent/YS decaffeinate/DSG decaf/S decagon/MS Decalogue/M decal/SM decamp/L decampment/MS decapitate/GSD decapitator/SM decathlon/SM Decatur/M decay/GRD Decca/M Deccan/M decease/M decedent/MS deceitfulness/SM deceitful/PY deceit/SM deceived/U deceiver/M deceives/U deceive/ZGRSD deceivingly deceiving/U decelerate/XNGSD deceleration/M decelerator/SM December/SM decency/ISM decennial/SY decent/TIYR deception/SM deceptiveness/SM deceptive/YP decertify/N dechlorinate/N decibel/MS decidability/U decidable/U decidedness/M decided/PY decide/GRSDB deciduousness/M deciduous/YP decile/SM deciliter/SM decimal/SYM decimate/XNGDS decimation/M decimeter/MS decipherable/IU decipher/BRZG decipherer/M decisional decisioned decisioning decision/ISM decisive/IPY decisiveness/MSI deckchair decker/M Decker/M deck/GRDMSJ deckhand/S decking/M Deck/RM declamation/SM declamatory declarable declaration/MS declaration's/A declarative/SY declarator/MS declaratory declare/AGSD declared/U declarer/MS declension/SM declination/MS decliner/M decline/ZGRSD declivity/SM Dec/M DEC/M DECNET DECnet/M deco dcolletage/S dcollet decolletes decolorising decomposability/M decomposable/IU decompose/B decompress/R decongestant/S deconstruction deconvolution decorated/AU decorate/NGVDSX decorates/A decorating/A decoration/ASM decorativeness/M decorative/YP decorator/SM decorousness/MS decorousness's/I decorous/PIY decor/S decorticate/GNDS decortication/M decorum/MS decoupage/MGSD decouple/G decoy/M decrease decreasing/Y decreeing decree/RSM decremental decrement/DMGS decrepit decrepitude/SM decriminalization/S decriminalize/DS decry/G decrypt/GD decryption DECstation/M DECsystem/M DECtape/M decustomised Dedekind/M Dede/M dedicate/AGDS dedicated/Y dedication/MS dedicative dedicator/MS dedicatory Dedie/M Dedra/M deduce/RSDG deducible deductibility/M deductible/S deduction/SM deductive/Y deduct/VG Deeanne/M Deeann/M deeded Deedee/M deeding deed/IS deed's deejay/MDSG Dee/M deem/ADGS deemphasis Deena/M deepen/DG deepish deepness/MS deep/PTXSYRN Deerdre/M Deere/M deerskin/MS deer/SM deerstalker/SM deerstalking/M Deeyn/M deface/LZ defacement/SM defaecate defalcate/NGXSD defalcation/M defamation/SM defamatory defamer/M defame/ZR defaulter/M default/ZR defeated/U defeater/M defeatism/SM defeatist/SM defeat/ZGD defecate/DSNGX defecation/M defection/SM defectiveness/MS defective/PYS defect/MDSVG defector/MS defendant/SM defended/U defenestrate/GSD defenselessness/MS defenseless/PY defenses/U defense/VGSDM defensibility/M defensible/I defensibly/I defensiveness/MS defensive/PSY deference/MS deferential/Y deferent/S deferrable deferral/SM deferred deferrer/MS deferring deffer defiance/MS defiant/Y defibrillator/M deficiency/MS deficient/SY deficit/MS defier/M defile/L defilement/MS definable/UI definably/I define/AGDRS defined/U definer/SM definite/IPY definiteness/IMS definitional definition/ASM definitiveness/M definitive/SYP defis deflate/XNGRSDB deflationary deflation/M deflect/DSGV deflected/U deflection/MS deflector/MS defocus defocussing Defoe/M defog defogger/S defoliant/SM defoliator/SM deformational deform/B deformed/U deformity/SM defrauder/M defraud/ZGDR defrayal/SM defroster/M defrost/RZ deftness/MS deft/TYRP defunct/S defying/Y defy/RDG def/Z deg Degas/M degassing degauss/GD degeneracy/MS degenerateness/M degenerate/PY degrade/B degradedness/M degraded/YP degrading/Y degrease degree/SM degum Dehlia/M dehumanize dehydrator/MS deicer/M deice/ZR deictic Deidre/M deification/M deify/SDXGN deign/DGS Deimos/M Deina/M Deirdre/MS deistic deist/SM Deity/M deity/SM deja deject/DSG dejectedness/M dejected/PY dejection/SM Dejesus/M DeKalb/M DeKastere/M Delacroix/M Delacruz/M Delainey/M Dela/M Delaney/M Delano/M Delawarean/SM Delaware/MS delay/D delayer/G Delbert/M Delcina/M Delcine/M delectableness/M delectable/SP delectably delectation/MS delegable Deleon/M deleted/U deleteriousness/M deleterious/PY delete/XBRSDNG deletion/M delfs Delft/M delft/MS delftware/S Delgado/M Delhi/M Delia/M deliberateness/SM deliberate/PVY deliberativeness/M deliberative/PY Delibes/M delicacy/IMS delicate/IYP delicatenesses delicateness/IM delicates delicatessen/MS deliciousness/MS delicious/YSP delicti delightedness/M delighted/YP delightfulness/M delightful/YP Delilah/M Delilahs Delila/M Delinda/M delineate/SDXVNG delineation/M delinquency/MS delinquent/SYM deliquesce/GSD deliquescent deliriousness/MS delirious/PY delirium/SM deli/SM Delius/M deliverables deliverable/U deliver/AGSD deliverance/SM delivered/U deliverer/SM delivery/AM deliverymen/M Della/M Dell/M dell/SM Dellwood/M Delly/M Delmar/M Delmarva/M Delmer/M Delmonico Delmore/M Delmor/M Del/MY Delora/M Delores/M Deloria/M Deloris/M Delphic Delphi/M Delphine/M Delphinia/M delphinium/SM Delphinus/M Delta/M delta/MS deltoid/SM deluder/M delude/RSDG deluding/Y deluge/SDG delusional delusion/SM delusiveness/M delusive/PY deluxe delve/GZSRD delver/M demagnify/N demagogic demagogue/GSDM demagoguery/SM demagogy/MS demander/M demand/GSRD demandingly demanding/U demarcate/SDNGX demarcation/M Demavend/M demean/GDS demeanor/SM dementedness/M demented/YP dementia/MS Demerol/M demesne/SM Demeter/M Demetra/M Demetre/M Demetria/M Demetri/MS Demetrius/M demigod/MS demijohn/MS demimondaine/SM demimonde/SM demineralization/SM Deming/M demise/DMG demit demitasse/MS demitted demitting Dem/MG democracy/MS Democratic democratically/U democratic/U democratization/MS democratize/DRSG democratizes/U Democrat/MS democrat/SM Democritus/M dmod demo/DMPG demographer/MS demographical/Y demographic/S demography/MS demolisher/M demolish/GSRD demolition/MS demonetization/S demoniacal/Y demoniac/S demonic demonology/M demon/SM demonstrable/I demonstrableness/M demonstrably/I demonstrate/XDSNGV demonstration/M demonstrativenesses demonstrativeness/UM demonstratives demonstrative/YUP demonstrator/MS demoralization/M demoralizer/M demoralizing/Y DeMorgan/M Demosthenes/M demote/DGX demotic/S Demott/M demount/B Dempsey/M demulcent/S demultiplex demureness/SM demure/YP demurral/MS demurred demurrer/MS demurring demur/RTS demythologization/M demythologize/R den Dena/M dendrite/MS Deneb/M Denebola/M Deneen/M Dene/M Deng/M dengue/MS deniable/U denial/SM Denice/M denier/M denigrate/VNGXSD denigration/M denim/SM Denise/M Deni/SM denizen/SMDG Den/M De/NM Denmark/M Denna/M denned Dennet/M Denney/M Dennie/M Denni/MS denning Dennison/M Denny/M denominate/V denominational/Y denote/B denouement/MS denounce/LZRSDG denouncement/SM denouncer/M dense/FR densely denseness/SM densitometer/MS densitometric densitometry/M density/MS dens/RT dental/YS dentifrice/SM dentine's dentin/SM dent/ISGD dentistry/MS dentist/SM dentition/MS dent's denture/IMS denuclearize/GSD denudation/SM denude/DG denuder/M denunciate/VNGSDX denunciation/M Denver/M denying/Y Deny/M Denys Denyse/M deny/SRDZG deodorant/SM deodorization/SM deodorize/GZSRD deodorizer/M Deon/M Deonne/M deoxyribonucleic depart/L departmentalization/SM departmentalize/DSG departmental/Y department/MS departure/MS dependability/MS dependableness/M dependable/P dependably Dependant/MS depend/B dependence/ISM dependency/MS dependent/IYS dependent's depicted/U depicter/M depiction/SM depict/RDSG depilatory/S deplete/VGNSDX depletion/M deplorableness/M deplorable/P deplorably deplorer/M deplore/SRDBG deploring/Y deployable deploy/AGDLS deployment/SAM depolarize deponent/S deportation/MS deportee/SM deport/LG deportment/MS depose deposit/ADGS depositary/M deposition/A depositor/SAM depository/MS depravedness/M depraved/PY deprave/GSRD depraver/M depravity/SM deprecate/XSDNG deprecating/Y deprecation/M deprecatory depreciable depreciate/XDSNGV depreciating/Y depreciation/M depreciative/Y depressant/S depressible depression/MS depressive/YS depressor/MS depress/V deprive/GSD depth/M depths Dept/M deputation/SM depute/SDG deputize/DSG deputy/MS dequeue derail/L drailleur/MS derailment/MS derange/L derangement/MS Derbyshire/M derby/SM Derby/SM dereference/Z Derek/M dereliction/SM derelict/S Derick/M deride/D deriding/Y derision/SM derisiveness/MS derisive/PY derisory derivable/U derivate/XNV derivation/M derivativeness/M derivative/SPYM derive/B derived/U Derk/M Der/M dermal dermatitides dermatitis/MS dermatological dermatologist/MS dermatology/MS dermis/SM Dermot/M derogate/XDSNGV derogation/M derogatorily derogatory Derrek/M Derrick/M derrick/SMDG Derrida/M derrire/S Derrik/M Derril/M derringer/SM Derron/M Derry/M dervish/SM Derward/M Derwin/M Des desalinate/NGSDX desalination/M desalinization/MS desalinize/GSD desalt/G descant/M Descartes/M descendant/SM descended/FU descendent's descender/M descending/F descends/F descend/ZGSDR descent describable/I describe/ZB description/MS descriptiveness/MS descriptive/SYP descriptor/SM descry/SDG Desdemona/M desecrater/M desecrate/SRDGNX desecration/M deserter/M desertification desertion/MS desert/ZGMRDS deservedness/M deserved/YU deserve/J deserving/Y dshabill's desiccant/S desiccate/XNGSD desiccation/M desiccator/SM desiderata desideratum/M designable design/ADGS designate/VNGSDX designational designation/M designator/SM designed/Y designer/M designing/U Desi/M desirabilia desirability's desirability/US desirableness/SM desirableness's/U desirable/UPS desirably/U Desirae/M desire/BR desired/U Desiree/M desirer/M Desiri/M desirousness/M desirous/PY desist/DSG desk/SM desktop/S Desmond/M Desmund/M desolateness/SM desolate/PXDRSYNG desolater/M desolating/Y desolation/M desorption/M despairer/M despairing/Y despair/SGDR desperadoes desperado/M desperateness/SM desperate/YNXP desperation/M despicable despicably despiser/M despise/SRDG despoil/L despoilment/MS despond despondence/S despondency/MS despondent/Y despotic despotically despotism/SM dessert/SM dessicate/DN d'Estaing destinate/NX destination/M destine/GSD destiny/MS destituteness/M destitute/NXP destitution/M destroy/BZGDRS destroyer/M destructibility/SMI destructible/I destruction/SM destructiveness/MS destructive/YP destructor/M destruct/VGSD desuetude/MS desultorily desultoriness/M desultory/P detachedness/M detached/YP detacher/M detach/LSRDBG detachment/SM detailedness/M detailed/YP detainee/S detainer/M detain/LGRDS detainment/MS d'etat detectability/U detectable/U detectably/U detect/DBSVG detected/U detection/SM detective/MS detector/MS dtente detentes detention/SM detergency/M detergent/SM deteriorate/XDSNGV deterioration/M determent/SM determinability/M determinable/IP determinableness/IM determinacy/I determinant/MS determinateness/IM determinate/PYIN determination/IM determinativeness/M determinative/P determinedly determinedness/M determined/U determine/GASD determiner/SM determinism/MS determinism's/I deterministically deterministic/I deterred/U deterrence/SM deterrent/SMY deterring detersive/S deter/SL deters/V detestableness/M detestable/P detestably detestation/SM dethrone/L dethronement/SM detonable detonated/U detonate/XDSNGV detonation/M detonator/MS detour/G detoxification/M detoxify/NXGSD detox/SDG detract/GVD detractive/Y d'etre detribalize/GSD detrimental/SY detriment/SM detritus/M Detroit/M deuced/Y deuce/SDGM deus deuterium/MS deuteron/M Deuteronomy/M Deutsch/M Deva/M Devanagari/M Devan/M devastate/XVNGSD devastating/Y devastation/M devastator/SM develop/ALZSGDR developed/U developer/MA developmental/Y development/ASM deviance/MS deviancy/S deviant/YMS deviated/U deviate/XSDGN deviating/U deviation/M devilishness/MS devilish/PY devilment/SM devilry/MS devil/SLMDG deviltry/MS Devi/M Devina/M Devin/M Devinne/M deviousness/SM devious/YP devise/JR deviser/M Devland/M Devlen/M Devlin/M Dev/M devoice devolution/MS devolve/GSD Devondra/M Devonian Devon/M Devonna/M Devonne/M Devonshire/M Devora/M devoted/Y devotee/MS devote/XN devotional/YS devotion/M devourer/M devour/SRDZG devoutness/MS devout/PRYT Devy/M Dewain/M dewar Dewar/M Dewayne/M dewberry/MS dewclaw/SM dewdrop/MS Dewey/M Dewie/M dewiness/MS Dewitt/M dewlap/MS Dew/M dew/MDGS dewy/TPR Dexedrine/M dexes/I Dex/M dexter dexterity/MS Dexter/M dexterousness/MS dexterous/PY dextrose/SM DH Dhaka Dhaulagiri/M dhoti/SM dhow/MS DI diabase/M diabetes/M diabetic/S diabolic diabolicalness/M diabolical/YP diabolism/M diachronic/P diacritical/YS diacritic/MS diadem/GMDS diaereses diaeresis/M Diaghilev/M diagnometer/SM diagnosable/U diagnose/BGDS diagnosed/U diagnosis/M diagnostically diagnostician/SM diagnostic/MS diagnostics/M diagonalize/GDSB diagonal/YS diagrammable diagrammatic diagrammaticality diagrammatically diagrammed diagrammer/SM diagramming diagram/MS Diahann/M dialectal/Y dialectical/Y dialectic/MS dialect/MS dialed/A dialer/M dialing/M dial/MRDSGZJ dialogged dialogging dialog/MS dials/A dialysis/M dialyzed/U dialyzes diam diamagnetic diameter/MS diametric diametrical/Y diamondback/SM diamond/GSMD Diana/M Diandra/M Diane/M Dianemarie/M Dian/M Dianna/M Dianne/M Diann/M Diannne/M diapason/MS diaper/SGDM diaphanousness/M diaphanous/YP diaphragmatic diaphragm/SM diarist/SM Diarmid/M diarrheal diarrhea/MS diary/MS diaspora Diaspora/SM diastase/SM diastole/MS diastolic diathermy/SM diathesis/M diatomic diatom/SM diatonic diatribe/MS Diaz's dibble/SDMG dibs DiCaprio/M dice/GDRS dicer/M dicey dichloride/M dichotomization/M dichotomize/DSG dichotomous/PY dichotomy/SM dicier diciest dicing/M Dickensian/S dickens/M Dickens/M dicker/DG Dickerson/M dickey/SM dick/GZXRDMS! Dickie/M dickier dickiest Dickinson/M Dickson/M Dick/XM Dicky/M dicky's dicotyledonous dicotyledon/SM dicta/M Dictaphone/SM dictate/SDNGX dictation/M dictatorialness/M dictatorial/YP dictator/MS dictatorship/SM dictionary/SM diction/MS dictum/M didactically didactic/S didactics/M did/AU diddler/M diddle/ZGRSD Diderot/M Didi/M didn't didoes dido/M Dido/M didst die/DS Diefenbaker/M Diego/M dieing dielectric/MS diem Diem/M Diena/M Dierdre/M diereses dieresis/M diesel/GMDS Diesel's dies's dies/U dietary/S dieter/M Dieter/M dietetic/S dietetics/M diethylaminoethyl diethylstilbestrol/M dietitian/MS diet/RDGZSM Dietrich/M Dietz/M difference/DSGM difference's/I differences/I differentiability differentiable differential/SMY differentiated/U differentiate/XSDNG differentiation/M differentiator/SM differentness different/YI differ/SZGRD difficile difficult/Y difficulty/SM diffidence/MS diffident/Y diffract/GSD diffraction/SM diffractometer/SM diffuseness/MS diffuse/PRSDZYVXNG diffuser/M diffusible diffusional diffusion/M diffusiveness/M diffusive/YP diffusivity/M digerati digested/IU digester/M digestibility/MS digestible/I digestifs digestion/ISM digestive/YSP digest/RDVGS digger/MS digging/S digitalis/M digitalization/MS digitalized digitalizes digitalizing digital/SY digitization/M digitizer/M digitize/ZGDRS digit/SM dignified/U dignify/DSG dignitary/SM dignity/ISM digram digraph/M digraphs digress/GVDS digression/SM digressiveness/M digressive/PY dig/TS dihedral Dijkstra/M Dijon/M dike/DRSMG diker/M diktat/SM Dilan/M dilapidate/XGNSD dilapidation/M dilatation/SM dilated/YP dilate/XVNGSD dilation/M dilatoriness/M dilator/SM dilatory/P Dilbert/M dilemma/MS dilettante/MS dilettantish dilettantism/MS diligence/SM diligentness/M diligent/YP dilithium Dillard/M Dillie/M Dillinger/M dilling/R dillis Dill/M Dillon/M dill/SGMD dillydally/GSD Dilly/M dilly/SM dilogarithm diluent diluted/U diluteness/M dilute/RSDPXYVNG dilution/M Di/M DiMaggio/M dimensionality/M dimensional/Y dimensionless dimension/MDGS dimer/M dime/SM dimethylglyoxime dimethyl/M diminished/U diminish/SDGBJ diminuendo/SM diminution/SM diminutiveness/M diminutive/SYP Dimitri/M Dimitry/M dimity/MS dimmed/U dimmer/MS dimmest dimming dimness/SM dimorphism/M dimple/MGSD dimply/RT dim/RYPZS dimwit/MS dimwitted Dinah/M Dina/M dinar/SM diner/M dine/S dinette/MS dingbat/MS ding/GD dinghy/SM dingily dinginess/SM dingle/MS dingoes dingo/MS dingus/SM dingy/PRST dinky/RST din/MDRZGS dinned dinner/SM dinnertime/S dinnerware/MS Dinnie/M dinning Dinny/M Dino/M dinosaur/MS dint/SGMD diocesan/S diocese/SM Diocletian/M diode/SM Diogenes/M Dione/M Dionisio/M Dionis/M Dion/M Dionne/M Dionysian Dionysus/M Diophantine/M diopter/MS diorama/SM Dior/M dioxalate dioxide/MS dioxin/S diphtheria/SM diphthong/SM diplexers diploid/S diplomacy/SM diploma/SMDG diplomata diplomatically diplomatic/S diplomatics/M diplomatist/SM diplomat/MS dipodic dipody/M dipole/MS dipped Dipper/M dipper/SM dipping/S dippy/TR dip/S dipsomaniac/MS dipsomania/SM dipstick/MS dipterous diptych/M diptychs Dir Dirac/M directed/IUA directionality directional/SY direction/MIS directions/A directive/SM directivity/M directly/I directness/ISM director/AMS directorate/SM directorial directorship/SM directory/SM direct/RDYPTSVG directrix/MS directs/IA direful/Y direness/M dire/YTRP dirge/GSDM Dirichlet/M dirigible/S dirk/GDMS Dirk/M dirndl/MS dirtily dirtiness/SM dirt/MS dirty/GPRSDT Dis disable/LZGD disablement/MS disabler/M disabuse disadvantaged/P disagreeable/S disallow/D disambiguate/DSGNX disappointed/Y disappointing/Y disarming/Y disarrange/L disastrous/Y disband/L disbandment/SM disbar/L disbarment/MS disbarring disbelieving/Y disbursal/S disburse/GDRSL disbursement/MS disburser/M discerner/M discernibility discernible/I discernibly discerning/Y discernment/MS discern/SDRGL disc/GDM discharged/U disciple/DSMG discipleship/SM disciplinarian/SM disciplinary disciplined/U discipline/IDM discipliner/M disciplines disciplining disclosed/U discography/MS discolored/MP discoloreds/U discolor/G discombobulate/SDGNX discomfit/DG discomfiture/MS disco/MG discommode/DG disconcerting/Y disconnectedness/S disconnected/P disconnecter/M disconnect/R disconsolate/YN discordance/SM discordant/Y discord/G discorporate/D discotheque/MS discount/B discourage/LGDR discouragement/MS discouraging/Y discoverable/I discover/ADGS discovered/U discoverer/S discovery/SAM discreetly/I discreetness's/I discreetness/SM discreet/TRYP discrepancy/SM discrepant/Y discreteness/SM discrete/YPNX discretionary discretion/IMS discretization discretized discriminable discriminant/MS discriminated/U discriminate/SDVNGX discriminating/YI discrimination/MI discriminator/MS discriminatory discursiveness/S discussant/MS discussed/UA discusser/M discussion/SM discus/SM disdainfulness/M disdainful/YP disdain/MGSD disease/G disembowelment/SM disembowel/SLGD disengage/L disfigure/L disfigurement/MS disfranchise/L disfranchisement/MS disgorge disgrace/R disgracer/M disgruntle/DSLG disgruntlement/MS disguised/UY disguise/R disguiser/M disgust disgusted/Y disgustful/Y disgusting/Y dishabille/SM disharmonious dishcloth/M dishcloths dishevel/LDGS dishevelment/MS dish/GD dishonest dishonored/U dishpan/MS dishrag/SM dishtowel/SM dishwasher/MS dishwater/SM disillusion/LGD disillusionment/SM disinfectant/MS disinherit disinterestedness/SM disinterested/P disinvest/L disjoin disjointedness/S disjunctive/YS disjunct/VS disk/D diskette/S dislike/G dislodge/LG dislodgement/M dismalness/M dismal/PSTRY dismantle/L dismantlement/SM dismay/D dismayed/U dismaying/Y dis/MB dismember/LG dismemberment/MS dismissive/Y dismiss/RZ Disneyland/M Disney/M disoblige/G disorderedness/M disordered/YP disorderliness/M disorderly/P disorder/Y disorganize disorganized/U disparagement/MS disparager/M disparage/RSDLG disparaging/Y disparateness/M disparate/PSY dispatch/Z dispelled dispelling dispel/S dispensable/I dispensary/MS dispensate/NX dispensation/M dispenser/M dispense/ZGDRSB dispersal/MS dispersant/M dispersed/Y disperser/M disperse/XDRSZLNGV dispersible dispersion/M dispersiveness/M dispersive/PY dispirit/DSG displace/L display/AGDS displayed/U displeased/Y displease/G displeasure disport disposable/S disposal/SM dispose/IGSD dispositional disposition/ISM disproportional disproportionate/N disproportionation/M disprove/B disputable/I disputably/I disputant/SM disputation/SM disputatious/Y disputed/U disputer/M dispute/ZBGSRD disquieting/Y disquiet/M disquisition/SM Disraeli/M disregardful disrepair/M disreputableness/M disreputable/P disrepute/M disrespect disrupted/U disrupter/M disrupt/GVDRS disruption/MS disruptive/YP disruptor/M dissatisfy dissect/DG dissed dissembler/M dissemble/ZGRSD disseminate/XGNSD dissemination/M dissension/SM dissenter/M dissent/ZGSDR dissertation/SM disservice disses dissever dissidence/SM dissident/MS dissimilar/S dissing dissipatedly dissipatedness/M dissipated/U dissipater/M dissipate/XRSDVNG dissipation/M dissociable/I dissociate/DSXNGV dissociated/U dissociation/M dissociative/Y dissoluble/I dissoluteness/SM dissolute/PY dissolve/ASDG dissolved/U dissonance/SM dissonant/Y dissuade/GDRS dissuader/M dissuasive dist distaff/SM distal/Y distance/DSMG distantness/M distant/YP distaste distemper distend distension distention/SM distillate/XNMS distillation/M distillery/MS distincter distinctest distinction/MS distinctiveness/MS distinctive/YP distinct/IYVP distinctness/MSI distinguishable/I distinguishably/I distinguish/BDRSG distinguished/U distinguisher/M distort/BGDR distorted/U distorter/M distortion/MS distract/DG distractedness/M distracted/YP distracting/Y distrait distraught/Y distress distressful distressing/Y distribute/ADXSVNGB distributed/U distributer distributional distribution/AM distributiveness/M distributive/SPY distributivity distributorship/M distributor/SM district/GSAD district's distrust/G disturbance/SM disturbed/U disturber/M disturbing/Y disturb/ZGDRS disulfide/M disuse/M disyllable/M Dita/M ditcher/M ditch/MRSDG dither/RDZSG ditsy/TR ditto/DMGS ditty/SDGM Ditzel/M ditz/S diuresis/M diuretic/S diurnal/SY divalent/S diva/MS divan/SM dived/M divergence/SM divergent/Y diverge/SDG diver/M diverseness/MS diverse/XYNP diversification/M diversifier/M diversify/GSRDNX diversionary diversion/M diversity/SM divert/GSD diverticulitis/SM divertimento/M dive/S divestiture/MS divest/LDGS divestment/S dividable divide/AGDS divided/U dividend/MS divider/MS divination/SM diviner/M divine/RSDTZYG divinity/MS divisibility/IMS divisible/I divisional division/SM divisiveness/MS divisive/PY divisor/SM divorce/MS divorce/GSDLM divorcement/MS divot/MS div/TZGJDRS divulge/GSD divvy/GSDM Dixiecrat/MS dixieland Dixieland/MS Dixie/M Dix/M Dixon/M dizzily dizziness/SM dizzying/Y dizzy/PGRSDT DJ Djakarta's djellabah's djellaba/S d/JGVX Djibouti/M DMD Dmitri/M DMZ DNA Dnepropetrovsk/M Dnepr's Dnieper's Dniester/M Dniren/M DOA doable DOB Dobbin/M dobbin/MS Doberman Dobro/M docent/SM docile/Y docility/MS docker/M docket/GSMD dock/GZSRDM dockland/MS dockside/M dockworker/S dockyard/SM doc/MS Doctor doctoral doctorate/SM doctor/GSDM Doctorow/M doctrinaire/S doctrinal/Y doctrine/SM docudrama/S documentary/MS documentation/MS documented/U document/RDMZGS DOD dodder/DGS dodecahedra dodecahedral dodecahedron/M Dode/M dodge/GZSRD Dodge/M dodgem/S dodger/M Dodgson/M Dodie/M Dodi/M Dodington/M Dodoma/M dodo/SM Dodson/M Dody/M DOE Doe/M doe/MS doer/MU does/AU doeskin/MS doesn't d'oeuvre doff/SGD dogcart/SM dogcatcher/MS dogeared Doge/M doge/SM dogfight/GMS dogfish/SM dogfought doggedness/SM dogged/PY doggerel/SM dogging doggone/RSDTG doggy/SRMT doghouse/SM dogie/SM doglegged doglegging dogleg/SM dogma/MS dogmatically/U dogmatic/S dogmatics/M dogmatism/SM dogmatist/SM dogsbody/M dog/SM dogtooth/M Dogtown/M dogtrot/MS dogtrotted dogtrotting dogwood/SM dogy's Doha/M doh's doily/SM doing/MU Dolby/SM doldrum/S doldrums/M doled/F dolefuller dolefullest dolefulness/MS doleful/PY Dole/M dole/MGDS doles/F Dolf/M doling/F dollar/SM Dolley/M Dollie/M Dolli/M Doll/M doll/MDGS dollop/GSMD Dolly/M dolly/SDMG dolmen/MS dolomite/SM dolomitic Dolores/M Dolorita/SM dolorous/Y dolor/SM dolphin/SM Dolph/M doltishness/SM doltish/YP dolt/MS domain/MS dome/DSMG Domenic/M Domenico/M Domeniga/M Domesday/M domestically domesticate/DSXGN domesticated/U domestication/M domesticity/MS domestic/S domicile/SDMG domiciliary dominance/MS dominant/YS dominate/VNGXSD domination/M dominator/M dominatrices dominatrix domineer/DSG domineeringness/M domineering/YP Dominga/M Domingo/M Dominguez/M Dominica/M Dominican/MS Dominick/M Dominic/M Dominik/M Domini/M dominion/MS Dominique/M dominoes domino/M Domitian/M Dom/M Donahue/M Donald/M Donaldson/M Donall/M Donal/M Donalt/M Dona/M dona/MS Donatello/M donate/XVGNSD donation/M donative/M Donaugh/M Donavon/M done/AUF Donella/M Donelle/M Donetsk/M Donetta/M dong/GDMS dongle/S Donia/M Donica/M Donielle/M Donizetti/M donkey/MS Donna/M Donnamarie/M donned Donnell/M Donnelly/M Donne/M Donner/M Donnie/M Donni/M donning donnishness/M donnish/YP Donn/RM donnybrook/MS Donny/M donor/MS Donovan/M don/S Don/SM don't donut/MS donutted donutting doodad/MS doodlebug/MS doodler/M doodle/SRDZG doohickey/MS Dooley/M Doolittle/M doom/MDGS doomsday/SM Doonesbury/M doorbell/SM door/GDMS doorhandles doorkeeper/M doorkeep/RZ doorknob/SM doorman/M doormat/SM doormen doornail/M doorplate/SM doors/I doorstep/MS doorstepped doorstepping doorstop/MS doorway/MS dooryard/SM dopamine dopant/M dopa/SM dope/DRSMZG doper/M dopey dopier dopiest dopiness/S Doppler/M Dorado/M Doralia/M Doralin/M Doralyn/M Doralynne/M Doralynn/M Dora/M Dorcas Dorchester/M Doreen/M Dorelia/M Dorella/M Dorelle/M Dor/M Dorena/M Dorene/M Doretta/M Dorette/M Dorey/M Doria/M Dorian/M Doric Dorice/M Dorie/M Dori/MS Dorine/M Dorisa/M Dorise/M Dorita/M dork/S dorky/RT dormancy/MS dormant/S dormer/M dormice dormitory/SM dorm/MRZS dormouse/M Dorolice/M Dorolisa/M Doro/M Dorotea/M Doroteya/M Dorothea/M Dorothee/M Dorothy/M Dorree/M Dorrie/M Dorri/SM Dorry/M dorsal/YS Dorsey/M Dorthea/M Dorthy/M Dortmund/M Dory/M dory/SM DOS dosage/SM dose/M dos/GDS Dosi/M dosimeter/MS dosimetry/M dossier/MS dost Dostoevsky/M DOT dotage/SM dotard/MS doter/M dote/S Doti/M doting/Y Dot/M dot/MDRSJZG Dotson/M dotted Dottie/M Dotti/M dottiness/M dotting Dotty/M dotty/PRT do/TZRHGJ Douala/M Douay/M Doubleday/M doubled/UA double/GPSRDZ doubleheader/MS doubleness/M doubler/M doubles/M doublespeak/S doublethink/M doublet/MS doubleton/M doubling/A doubloon/MS doubly doubt/AGSDMB doubted/U doubter/SM doubtfulness/SM doubtful/YP doubting/Y doubtlessness/M doubtless/YP douche/GSDM Dougherty/M dough/M doughs doughty/RT doughy/RT Dougie/M Douglas/M Douglass Doug/M Dougy/M dourness/MS Douro/M dour/TYRP douser/M douse/SRDG dovecote/MS Dover/M dove/RSM dovetail/GSDM dovish Dov/MR dowager/SM dowdily dowdiness/MS dowdy/TPSR dowel/GMDS dower/GDMS Dow/M downbeat/SM downcast/S downdraft/M downer/M Downey/M downfall/NMS downgrade/GSD down/GZSRD downheartedness/MS downhearted/PY downhill/RS downland download/DGS downpipes downplay/GDS downpour/MS downrange downrightness/M downright/YP downriver Downs downscale/GSD downside/S downsize/DSG downslope downspout/SM downstage/S downstairs downstate/SR downstream downswing/MS downtime/SM downtowner/M downtown/MRS downtrend/M downtrodden downturn/MS downwardness/M downward/YPS downwind downy/RT dowry/SM dowse/GZSRD dowser/M doxology/MS doyenne/SM doyen/SM Doyle/M Doy/M doze dozen/GHD dozenths dozer/M doz/XGNDRS dozy DP DPs dpt DPT drabbed drabber drabbest drabbing drabness/MS drab/YSP drachma/MS Draco/M draconian Draconian Dracula/M draft/AMDGS draftee/SM drafter/MS draftily draftiness/SM drafting/S draftsman/M draftsmanship/SM draftsmen draftsperson draftswoman draftswomen drafty/PTR dragged dragger/M dragging/Y draggy/RT drag/MS dragnet/MS dragonfly/SM dragonhead/M dragon/SM dragoon/DMGS drainage/MS drainboard/SM drained/U drainer/M drainpipe/MS drain/SZGRDM Drake/M drake/SM Dramamine/MS drama/SM dramatically/U dramatical/Y dramatic/S dramatics/M dramatist/MS dramatization/MS dramatized/U dramatizer/M dramatize/SRDZG dramaturgy/M Drambuie/M drammed dramming dram/MS drank Drano/M draper/M drapery/MS drape/SRDGZ drastic drastically drat/S dratted dratting Dravidian/M drawable draw/ASG drawback/MS drawbridge/SM drawer/SM drawing/SM drawler/M drawling/Y drawl/RDSG drawly drawn/AI drawnly drawnness drawstring/MS dray/SMDG dreadfulness/SM dreadful/YPS dreadlocks dreadnought/SM dread/SRDG dreamboat/SM dreamed/U dreamer/M dreamily dreaminess/SM dreaming/Y dreamland/SM dreamlessness/M dreamless/PY dreamlike dream/SMRDZG dreamworld/S dreamy/PTR drearily dreariness/SM drear/S dreary/TRSP Dreddy/M dredge/MZGSRD dredger/M Dredi/M dreg/MS Dreiser/M Dre/M drencher/M drench/GDRS Dresden/M dress/ADRSG dressage/MS dressed/U dresser/MS dresser's/A dresses/U dressiness/SM dressing/MS dressmaker/MS dressmaking/SM dressy/PTR drew/A Drew/M Drexel/M Dreyfus/M Dreyfuss dribble/DRSGZ dribbler/M driblet/SM drib/SM dried/U drier/M drifter/M drifting/Y drift/RDZSG driftwood/SM driller/M drilling/M drillmaster/SM drill/MRDZGS drinkable/S drink/BRSZG drinker/M dripped dripping/MS drippy/RT drip/SM driveler/M drivel/GZDRS driven/P driver/M drive/SRBGZJ driveway/MS drizzle/DSGM drizzling/Y drizzly/TR Dr/M drogue/MS drollery/SM drollness/MS droll/RDSPTG drolly dromedary/MS Drona/M drone/SRDGM droning/Y drool/GSRD droopiness/MS drooping/Y droop/SGD droopy/PRT drophead dropkick/S droplet/SM dropout/MS dropped dropper/SM dropping/MS dropsical drop/SM dropsy/MS drosophila/M dross/SM drought/SM drover/M drove/SRDGZ drowner/M drown/RDSJG drowse/SDG drowsily drowsiness/SM drowsy/PTR drubbed drubber/MS drubbing/SM drub/S Drucie/M Drucill/M Druci/M Drucy/M drudge/MGSRD drudger/M drudgery/SM drudging/Y Drud/M drugged druggie/SRT drugging druggist/SM Drugi/M drugless drug/SM drugstore/SM druidism/MS druid/MS Druid's Dru/M drumbeat/SGM drumhead/M drumlin/MS drummed drummer/SM drumming Drummond/M drum/SM drumstick/SM drunkard/SM drunkenness/SM drunken/YP drunk/SRNYMT drupe/SM Drury/M Drusie/M Drusilla/M Drusi/M Drusy/M druthers dryad/MS Dryden/M dryer/MS dry/GYDRSTZ dryish dryness/SM drys drystone drywall/GSD D's d's/A Dshubba/M DST DTP dualism/MS dualistic dualist/M duality/MS dual/YS Duane/M Dubai/M dubbed dubber/S dubbing/M dubbin/MS Dubcek/M Dubhe/M dubiety/MS dubiousness/SM dubious/YP Dublin/M Dubrovnik/M dub/S Dubuque/M ducal ducat/SM duce/CAIKF duce's Duchamp/M duchess/MS duchy/SM duckbill/SM ducker/M duck/GSRDM duckling/SM duckpins duckpond duckweed/MS ducky/RSMT ducted/CFI ductile/I ductility/SM ducting/F duct/KMSF ductless duct's/A ducts/CI ductwork/M dudder dude/MS dudgeon/SM dud/GMDS Dudley/M Dud/M duelist/MS duel/MRDGZSJ dueness/M duenna/MS due/PMS duet/MS duetted duetting duffel/M duffer/M duff/GZSRDM Duffie/M Duff/M Duffy/M Dugald/M dugout/SM dug/S duh DUI Duisburg/M dukedom/SM duke/DSMG Duke/M Dukey/M Dukie/M Duky/M Dulcea/M Dulce/M dulcet/SY Dulcia/M Dulciana/M Dulcie/M dulcify Dulci/M dulcimer/MS Dulcinea/M Dulcine/M Dulcy/M dullard/MS Dulles/M dullness/MS dull/SRDPGT dully dulness's Dulsea/M Duluth/M duly/U Du/M Dumas dumbbell/MS dumbfound/GSDR dumbness/MS Dumbo/M dumb/PSGTYRD dumbstruck dumbwaiter/SM dumdum/MS dummy/SDMG Dumont/M dumper/UM dumpiness/MS dumpling/MS dump/SGZRD dumpster/S Dumpster/S Dumpty/M dumpy/PRST Dunant/M Dunbar/M Duncan/M dunce/MS Dunc/M Dundee/M dunderhead/MS Dunedin/M dune/SM dungaree/SM dungeon/GSMD dunghill/MS dung/SGDM Dunham/M dunker/M dunk/GSRD Dunkirk/M Dunlap/M Dun/M dunned Dunne/M dunner dunnest dunning Dunn/M dunno/M dun/S Dunstan/M duodecimal/S duodena duodenal duodenum/M duologue/M duo/MS duopolist duopoly/M dupe/NGDRSMZ duper/M dupion/M duple duplexer/M duplex/MSRDG duplicability/M duplicable duplicate/ADSGNX duplication/AM duplicative duplicator/MS duplicitous duplicity/SM Dupont/MS DuPont/MS durability/MS durableness/M durable/PS durably Duracell/M durance/SM Durand/M Duran/M Durante/M Durant/M durational duration/MS Durban/M Drer/M duress/SM Durex/M Durham/MS during Durkee/M Durkheim/M Dur/M Durocher/M durst durum/MS Durward/M Duse/M Dusenberg/M Dusenbury/M Dushanbe/M dusk/GDMS duskiness/MS dusky/RPT Dsseldorf dustbin/MS dustcart/M dustcover duster/M dustily dustiness/MS dusting/M Dustin/M dustless dustman/M dustmen dust/MRDGZS dustpan/SM Dusty/M dusty/RPT Dutch/M Dutchman/M Dutchmen dutch/MS Dutchwoman Dutchwomen duteous/Y dutiable dutifulness/S dutiful/UPY duty/SM Duvalier/M duvet/SM duxes Dvina/M Dvork/M Dwain/M dwarfish dwarfism/MS dwarf/MTGSPRD Dwayne/M dweeb/S dweller/SM dwell/IGS dwelling/MS dwelt/I DWI Dwight/M dwindle/GSD dyadic dyad/MS Dyana/M Dyane/M Dyan/M Dyanna/M Dyanne/M Dyann/M dybbukim dybbuk/SM dyed/A dyeing/M dye/JDRSMZG dyer/M Dyer/M dyes/A dyestuff/SM dying/UA Dyke/M dyke's Dylan/M Dy/M Dynah/M Dyna/M dynamical/Y dynamic/S dynamics/M dynamism/SM dynamiter/M dynamite/RSDZMG dynamized dynamo/MS dynastic dynasty/MS dyne/M dysentery/SM dysfunctional dysfunction/MS dyslectic/S dyslexia/MS dyslexically dyslexic/S dyspepsia/MS dyspeptic/S dysprosium/MS dystopia/M dystrophy/M dz Dzerzhinsky/M E ea each Eachelle/M Eada/M Eadie/M Eadith/M Eadmund/M eagerness/MS eager/TSPRYM eagle/SDGM eaglet/SM Eakins/M Ealasaid/M Eal/M Eamon/M earache/SM eardrum/SM earful/MS ear/GSMDYH Earhart/M earing/M earldom/MS Earle/M Earlene/M Earlie/M Earline/M earliness/SM Earl/M earl/MS earlobe/S Early/M early/PRST earmark/DGSJ earmuff/SM earned/U earner/M Earnestine/M Earnest/M earnestness/MS earnest/PYS earn/GRDZTSJ earning/M earphone/MS earpieces earplug/MS Earp/M earring/MS earshot/MS earsplitting Eartha/M earthbound earthed/U earthenware/MS earthiness/SM earthliness/M earthling/MS earthly/TPR earth/MDNYG earthmen earthmover/M earthmoving earthquake/SDGM earthshaking earths/U earthward/S earthwork/MS earthworm/MS earthy/PTR Earvin/M earwax/MS earwigged earwigging earwig/MS eased/E ease/LDRSMG easel/MS easement/MS easer/M ease's/EU eases/UE easies easily/U easiness/MSU easing/M eastbound easterly/S Easter/M easterner/M Easterner/M easternmost Eastern/RZ eastern/ZR easter/Y east/GSMR Easthampton/M easting/M Eastland/M Eastman/M eastward/S Eastwick/M Eastwood/M East/ZSMR easygoingness/M easygoing/P easy/PUTR eatables eatable/U eaten/U eater/M eatery/MS eating/M Eaton/M eat/SJZGNRB eavesdropped eavesdropper/MS eavesdropping eavesdrop/S eave/SM Eba/M Ebba/M ebb/DSG EBCDIC Ebeneezer/M Ebeneser/M Ebenezer/M Eben/M Eberhard/M Eberto/M Eb/MN Ebola Ebonee/M Ebonics Ebony/M ebony/SM Ebro/M ebullience/SM ebullient/Y ebullition/SM EC eccentrically eccentricity/SM eccentric/MS eccl Eccles Ecclesiastes/M ecclesiastical/Y ecclesiastic/MS ECG echelon/SGDM echinoderm/SM echo/DMG echoed/A echoes/A echoic echolocation/SM clair/MS clat/MS eclectically eclecticism/MS eclectic/S eclipse/MGSD ecliptic/MS eclogue/MS ecocide/SM ecol Ecole/M ecologic ecological/Y ecologist/MS ecology/MS Eco/M econ Econometrica/M econometricians econometric/S econometrics/M economical/YU economic/S economics/M economist/MS economization economize/GZSRD economizer/M economizing/U economy/MS ecosystem/MS ecru/SM ecstasy/MS Ecstasy/S ecstatically ecstatic/S ectoplasm/M Ecuadoran/S Ecuadorean/S Ecuadorian/S Ecuador/M ecumenical/Y ecumenicism/SM ecumenicist/MS ecumenic/MS ecumenics/M ecumenism/SM ecumenist/MS eczema/MS Eda/M Edam/SM Edan/M ed/ASC Edda/M Eddie/M Eddi/M Edd/M Eddy/M eddy/SDMG Edee/M Edeline/M edelweiss/MS Ede/M edema/SM edematous eden Eden/M Edgard/M Edgardo/M Edgar/M edge/DRSMZGJ edgeless edger/M Edgerton/M Edgewater/M edgewise Edgewood/M edgily edginess/MS edging/M edgy/TRP edibility/MS edibleness/SM edible/SP edict/SM Edie/M edification/M edifice/SM edifier/M edifying/U edify/ZNXGRSD Edik/M Edi/MH Edinburgh/M Edin/M Edison/M editable Edita/M edited/IU Editha/M Edithe/M Edith/M edition/SM editorialist/M editorialize/DRSG editorializer/M editorial/YS editor/MS editorship/MS edit/SADG Ediva/M Edlin/M Edmond/M Edmon/M Edmonton/M Edmund/M Edna/M Edouard/M EDP eds Edsel/M Edsger/M EDT Eduard/M Eduardo/M educability/SM educable/S educated/YP educate/XASDGN educationalists educational/Y education/AM educationists educative educator/MS educ/DBG educe/S eduction/M Eduino/M edutainment/S Edvard/M Edwardian Edwardo/M Edward/SM Edwina/M Edwin/M Ed/XMN Edy/M Edythe/M Edyth/M EEC EEG eek/S eelgrass/M eel/MS e'en EEO EEOC e'er eerie/RT eerily eeriness/MS Eeyore/M effaceable/I effacement/MS effacer/M efface/SRDLG effectiveness/ISM effectives effective/YIP effector/MS effect/SMDGV effectual/IYP effectualness/MI effectuate/SDGN effectuation/M effeminacy/MS effeminate/SY effendi/MS efferent/SY effervesce/GSD effervescence/SM effervescent/Y effeteness/SM effete/YP efficacious/IPY efficaciousness/MI efficacy/IMS efficiency/MIS efficient/ISY Effie/M effigy/SM effloresce efflorescence/SM efflorescent effluence/SM effluent/MS effluvia effluvium/M effluxion efflux/M effortlessness/SM effortless/PY effort/MS effrontery/MS effulgence/SM effulgent effuse/XSDVGN effusion/M effusiveness/MS effusive/YP EFL e/FMDS Efrain/M Efrem/M Efren/M EFT egad egalitarian/I egalitarianism/MS egalitarians EGA/M Egan/M Egbert/M Egerton/M eggbeater/SM eggcup/MS egger/M egg/GMDRS eggheaded/P egghead/SDM eggnog/SM eggplant/MS eggshell/SM egis's eglantine/MS egocentrically egocentricity/SM egocentric/S egoism/SM egoistic egoistical/Y egoist/SM egomaniac/MS egomania/MS Egon/M Egor/M ego/SM egotism/SM egotistic egotistical/Y egotist/MS egregiousness/MS egregious/PY egress/SDMG egret/SM Egyptian/S Egypt/M Egyptology/M eh Ehrlich/M Eichmann/M eiderdown/SM eider/SM eidetic Eiffel/M eigenfunction/MS eigenstate/S eigenvalue/SM eigenvector/MS eighteen/MHS eighteenths eightfold eighth/MS eighths eightieths eightpence eight/SM eighty/SHM Eileen/M Eilis/M Eimile/M Einsteinian einsteinium/MS Einstein/SM Eire/M Eirena/M Eisenhower/M Eisenstein/M Eisner/M eisteddfod/M either ejaculate/SDXNG ejaculation/M ejaculatory ejecta ejection/SM ejector/SM eject/VGSD Ekaterina/M Ekberg/M eked/A eke/DSG EKG Ekstrom/M Ektachrome/M elaborateness/SM elaborate/SDYPVNGX elaboration/M elaborators Elaina/M Elaine/M Elana/M eland/SM Elane/M lan/M Elanor/M elans elapse/SDG el/AS elastically/I elasticated elasticity/SM elasticize/GDS elastic/S elastodynamics elastomer/M elatedness/M elated/PY elater/M elate/SRDXGN elation/M Elayne/M Elba/MS Elbe/M Elberta/M Elbertina/M Elbertine/M Elbert/M elbow/GDMS elbowroom/SM Elbrus/M Elden/M elderberry/MS elderflower elderliness/M elderly/PS elder/SY eldest Eldin/M Eldon/M Eldorado's Eldredge/M Eldridge/M Eleanora/M Eleanore/M Eleanor/M Eleazar/M electable/U elect/ASGD elected/U electioneer/GSD election/SAM electiveness/M elective/SPY electoral/Y electorate/SM elector/SM Electra/M electress/M electricalness/M electrical/PY electrician/SM electricity/SM electric/S electrification/M electrifier/M electrify/ZXGNDRS electrocardiogram/MS electrocardiograph/M electrocardiographs electrocardiography/MS electrochemical/Y electrocute/GNXSD electrocution/M electrode/SM electrodynamics/M electrodynamic/YS electroencephalogram/SM electroencephalographic electroencephalograph/M electroencephalographs electroencephalography/MS electrologist/MS electroluminescent electrolysis/M electrolyte/SM electrolytic electrolytically electrolyze/SDG electro/M electromagnetic electromagnetically electromagnetism/SM electromagnet/SM electromechanical electromechanics electromotive electromyograph electromyographic electromyographically electromyography/M electronegative electronically electronic/S electronics/M electron/MS electrophoresis/M electrophorus/M electroplate/DSG electroscope/MS electroscopic electroshock/GDMS electrostatic/S electrostatics/M electrotherapist/M electrotype/GSDZM electroweak eleemosynary Eleen/M elegance/ISM elegant/YI elegiacal elegiac/S elegy/SM elem elemental/YS elementarily elementariness/M elementary/P element/MS Elena/M Elene/M Eleni/M Elenore/M Eleonora/M Eleonore/M elephantiases elephantiasis/M elephantine elephant/SM elevated/S elevate/XDSNG elevation/M elevator/SM eleven/HM elevens/S elevenths elev/NX Elfie/M elfin/S elfish elf/M Elfreda/M Elfrida/M Elfrieda/M Elga/M Elgar/M Elianora/M Elianore/M Elia/SM Elicia/M elicitation/MS elicit/GSD elide/GSD Elie/M eligibility/ISM eligible/SI Elihu/M Elijah/M Eli/M eliminate/XSDYVGN elimination/M eliminator/SM Elinore/M Elinor/M Eliot/M Elisabeth/M Elisabet/M Elisabetta/M Elisa/M Elise/M Eliseo/M Elisha/M elision/SM Elissa/M Elita/M elite/MPS elitism/SM elitist/SM elixir/MS Elizabethan/S Elizabeth/M Elizabet/M Eliza/M Elka/M Elke/M Elkhart/M elk/MS Elladine/M Ella/M Ellary/M Elle/M Ellene/M Ellen/M Ellerey/M Ellery/M Ellesmere/M Ellette/M Ellie/M Ellington/M Elliot/M Elliott/M ellipse/MS ellipsis/M ellipsoidal ellipsoid/MS ellipsometer/MS ellipsometry elliptic elliptical/YS ellipticity/M Elli/SM Ellison/M Ellissa/M ell/MS Ellswerth/M Ellsworth/M Ellwood/M Elly/M Ellyn/M Ellynn/M Elma/M Elmer/M Elmhurst/M Elmira/M elm/MRS Elmo/M Elmore/M Elmsford/M El/MY Elna/MH Elnar/M Elnath/M Elnora/M Elnore/M elocutionary elocutionist/MS elocution/SM elodea/S Elohim/M Eloisa/M Eloise/M elongate/NGXSD elongation/M Elonore/M elopement/MS eloper/M elope/SRDLG eloquence/SM eloquent/IY Elora/M Eloy/M Elroy/M els Elsa/M Elsbeth/M else/M Else/M Elset/M elsewhere Elsey/M Elsie/M Elsi/M Elsinore/M Elspeth/M Elston/M Elsworth/M Elsy/M Eltanin/M Elton/M eluate/SM elucidate/SDVNGX elucidation/M elude/GSD elusiveness/SM elusive/YP elute/DGN elution/M Elva/M elven Elvera/M elver/SM elves/M Elvia/M Elvina/M Elvin/M Elvira/M elvish Elvis/M Elvyn/M Elwin/M Elwira/M Elwood/M Elwyn/M Ely/M Elyn/M Elyse/M Elysees Elyse/M Elysha/M Elysia/M elysian Elysian Elysium/SM Elyssa/M EM emaciate/NGXDS emaciation/M emacs/M Emacs/M email/SMDG Emalee/M Emalia/M Ema/M emanate/XSDVNG emanation/M emancipate/DSXGN emancipation/M emancipator/MS Emanuele/M Emanuel/M emasculate/GNDSX emasculation/M embalmer/M embalm/ZGRDS embank/GLDS embankment/MS embarcadero embargoes embargo/GMD embark/ADESG embarkation/EMS embarrassedly embarrassed/U embarrassing/Y embarrassment/MS embarrass/SDLG embassy/MS embattle/DSG embeddable embedded embedder embedding/MS embed/S embellished/U embellisher/M embellish/LGRSD embellishment/MS ember/MS embezzle/LZGDRS embezzlement/MS embezzler/M embitter/LGDS embitterment/SM emblazon/DLGS emblazonment/SM emblematic emblem/GSMD embodier/M embodiment/ESM embody/ESDGA embolden/DSG embolism/SM embosom embosser/M emboss/ZGRSD embouchure/SM embower/GSD embraceable embracer/M embrace/RSDVG embracing/Y embrasure/MS embrittle embrocation/SM embroiderer/M embroider/SGZDR embroidery/MS embroilment/MS embroil/SLDG embryologist/SM embryology/MS embryonic embryo/SM emceeing emcee/SDM Emelda/M Emelen/M Emelia/M Emelina/M Emeline/M Emelita/M Emelyne/M emendation/MS emend/SRDGB emerald/SM Emera/M emerge/ADSG emergence/MAS emergency/SM emergent/S emerita emeritae emeriti emeritus Emerson/M Emery/M emery/MGSD emetic/S emf/S emigrant/MS emigrate/SDXNG emigration/M migr/S Emilee/M Emile/M Emilia/M Emilie/M Emili/M Emiline/M Emilio/M Emil/M Emily/M eminence/MS Eminence/MS eminent/Y emirate/SM emir/SM emissary/SM emission/AMS emissivity/MS emit/S emittance/M emitted emitter/SM emitting Emlen/M Emlyn/M Emlynne/M Emlynn/M em/M Em/M Emmalee/M Emmaline/M Emmalyn/M Emmalynne/M Emmalynn/M Emma/M Emmanuel/M Emmeline/M Emmerich/M Emmery/M Emmet/M Emmett/M Emmey/M Emmie/M Emmi/M Emmit/M Emmott/M Emmye/M Emmy/SM Emogene/M emollient/S emolument/SM Emory/M emote/SDVGNX emotionalism/MS emotionality/M emotionalize/GDS emotional/UY emotionless emotion/M emotive/Y empaneled empaneling empath empathetic empathetical/Y empathic empathize/SDG empathy/MS emperor/MS emphases emphasis/M emphasize/ZGCRSDA emphatically/U emphatic/U emphysema/SM emphysematous empire/MS empirical/Y empiricism/SM empiricist/SM empiric/SM emplace/L emplacement/MS employability/UM employable/US employed/U employee/SM employer/SM employ/LAGDS employment/UMAS emporium/MS empower/GLSD empowerment/MS empress/MS emptier/M emptily emptiness/SM empty/GRSDPT empyrean/SM ems/C EMT emulate/SDVGNX emulation/M emulative/Y emulator/MS emulsification/M emulsifier/M emulsify/NZSRDXG emulsion/SM emu/SM Emylee/M Emyle/M enabler/M enable/SRDZG enactment/ASM enact/SGALD enameler/M enamelware/SM enamel/ZGJMDRS enamor/DSG en/BM enc encamp/LSDG encampment/MS encapsulate/SDGNX encapsulation/M encase/GSDL encasement/SM encephalitic encephalitides encephalitis/M encephalographic encephalopathy/M enchain/SGD enchanter/MS enchant/ESLDG enchanting/Y enchantment/MSE enchantress/MS enchilada/SM encipherer/M encipher/SRDG encircle/GLDS encirclement/SM encl enclave/MGDS enclosed/U enclose/GDS enclosure/SM encoder/M encode/ZJGSRD encomium/SM encompass/GDS encore/GSD encounter/GSD encouragement/SM encourager/M encourage/SRDGL encouraging/Y encroacher/M encroach/LGRSD encroachment/MS encrustation/MS encrust/DSG encrypt/DGS encrypted/U encryption/SM encumbered/U encumber/SEDG encumbrancer/M encumbrance/SRM ency encyclical/SM encyclopaedia's encyclopedia/SM encyclopedic encyst/GSLD encystment/MS endanger/DGSL endangerment/SM endear/GSLD endearing/Y endearment/MS endeavored/U endeavorer/M endeavor/GZSMRD endemically endemicity endemic/S ender/M endgame/M Endicott/M ending/M endive/SM endlessness/MS endless/PY endmost endnote/MS endocrine/S endocrinologist/SM endocrinology/SM endogamous endogamy/M endogenous/Y endomorphism/SM endorse/DRSZGL endorsement/MS endorser/M endoscope/MS endoscopic endoscopy/SM endosperm/M endothelial endothermic endow/GSDL endowment/SM endpoint/MS endue/SDG endungeoned endurable/U endurably/U endurance/SM endure/BSDG enduringness/M enduring/YP endways Endymion/M end/ZGVMDRSJ ENE enema/SM enemy/SM energetically energetic/S energetics/M energized/U energizer/M energize/ZGDRS energy/MS enervate/XNGVDS enervation/M enfeeble/GLDS enfeeblement/SM enfilade/MGDS enfold/SGD enforceability/M enforceable/U enforced/Y enforce/LDRSZG enforcement/SM enforcer/M enforcible/U enfranchise/ELDRSG enfranchisement/EMS enfranchiser/M engage/ADSGE engagement/SEM engaging/Y Engelbert/M Engel/MS engender/DGS engineer/GSMDJ engineering/MY engine/MGSD England/M england/ZR Englebert/M Englewood/M English/GDRSM Englishman/M Englishmen Englishwoman/M Englishwomen Eng/M engorge/LGDS engorgement/MS Engracia/M engram/MS engraver/M engrave/ZGDRSJ engraving/M engrossed/Y engrosser/M engross/GLDRS engrossing/Y engrossment/SM engulf/GDSL engulfment/SM enhanceable enhance/LZGDRS enhancement/MS enhancer/M enharmonic Enid/M Enif/M enigma/MS enigmatic enigmatically Eniwetok/M enjambement's enjambment/MS enjoinder enjoin/GSD enjoyability enjoyableness/M enjoyable/P enjoyably enjoy/GBDSL enjoyment/SM Enkidu/M enlargeable enlarge/LDRSZG enlargement/MS enlarger/M enlightened/U enlighten/GDSL enlightening/U enlightenment/SM enlistee/MS enlister/M enlistment/SAM enlist/SAGDL enliven/LDGS enlivenment/SM enmesh/DSLG enmeshment/SM enmity/MS Ennis/M ennoble/LDRSG ennoblement/SM ennobler/M ennui/SM Enoch/M enormity/SM enormousness/MS enormous/YP Enos enough enoughs enplane/DSG enqueue/DS enquirer/S enquiringly enrage/SDG enrapture/GSD Enrica/M enricher/M Enrichetta/M enrich/LDSRG enrichment/SM Enrico/M Enrika/M Enrique/M Enriqueta/M enrobed enrollee/SM enroll/LGSD enrollment/SM ens ensconce/DSG ensemble/MS enshrine/DSLG enshrinement/SM enshroud/DGS ensign/SM ensilage/DSMG enslavement/MS enslaver/M enslave/ZGLDSR ensnare/GLDS ensnarement/SM Ensolite/M ensue/SDG ensurer/M ensure/SRDZG entailer/M entailment/MS entail/SDRLG entangle/EGDRSL entanglement/ESM entangler/EM entente/MS enter/ASDG entered/U enterer/M enteritides enteritis/SM enterprise/GMSR Enterprise/M enterpriser/M enterprising/Y entertainer/M entertaining/Y entertainment/SM entertain/SGZRDL enthalpy/SM enthrall/GDSL enthrallment/SM enthrone/GDSL enthronement/MS enthuse/DSG enthusiasm/SM enthusiastically/U enthusiastic/U enthusiast/MS enticement/SM entice/SRDJLZG enticing/Y entire/SY entirety/SM entitle/GLDS entitlement/MS entity/SM entomb/GDSL entombment/MS entomological entomologist/S entomology/MS entourage/SM entr'acte/S entrails entrainer/M entrain/GSLDR entrancement/MS entrance/MGDSL entranceway/M entrancing/Y entrant/MS entrapment/SM entrapped entrapping entrap/SL entreating/Y entreat/SGD entreaty/SM entre/S entrench/LSDG entrenchment/MS entrepreneurial entrepreneur/MS entrepreneurship/M entropic entropy/MS entrust/DSG entry/ASM entryway/SM entwine/DSG enumerable enumerate/AN enumerated/U enumerates enumerating enumeration's/A enumeration/SM enumerative enumerator/SM enunciable enunciated/U enunciate/XGNSD enunciation/M enureses enuresis/M envelope/MS enveloper/M envelopment/MS envelop/ZGLSDR envenom/SDG enviableness/M enviable/U enviably envied/U envier/M enviousness/SM envious/PY environ/LGSD environmentalism/SM environmentalist/SM environmental/Y environment/MS envisage/DSG envision/GSD envoy/SM envying/Y envy/SRDMG enzymatic enzymatically enzyme/SM enzymology/M Eocene EOE eohippus/M Eolanda/M Eolande/M eolian eon/SM EPA epaulet/SM pe/S ephedrine/MS ephemeral/SY ephemera/MS ephemerids ephemeris/M Ephesian/S Ephesians/M Ephesus/M Ephraim/M Ephrayim/M Ephrem/M epically epicenter/SM epic/SM Epictetus/M Epicurean epicurean/S epicure/SM Epicurus/M epicycle/MS epicyclic epicyclical/Y epicycloid/M epidemically epidemic/MS epidemiological/Y epidemiologist/MS epidemiology/MS epidermal epidermic epidermis/MS epidural epigenetic epiglottis/SM epigrammatic epigram/MS epigrapher/M epigraph/RM epigraphs epigraphy/MS epilepsy/SM epileptic/S epilogue/SDMG Epimethius/M epinephrine/SM epiphany/SM Epiphany/SM epiphenomena episcopacy/MS episcopalian Episcopalian/S Episcopal/S episcopal/Y episcopate/MS episode/SM episodic episodically epistemic epistemological/Y epistemology/M epistle/MRS Epistle/SM epistolary/S epistolatory epitaph/GMD epitaphs epitaxial/Y epitaxy/M epithelial epithelium/MS epithet/MS epitome/MS epitomized/U epitomizer/M epitomize/SRDZG epochal/Y epoch/M epochs eponymous epoxy/GSD epsilon/SM Epsom/M Epstein/M equability/MS equableness/M equable/P equably equaling equality/ISM equalization/MS equalize/DRSGJZ equalized/U equalizer/M equalizes/U equal/USDY equanimity/MS equate/NGXBSD equation/M equatorial/S equator/SM equerry/MS equestrianism/SM equestrian/S equestrienne/SM equiangular equidistant/Y equilateral/S equilibrate/GNSD equilibration/M equilibrium/MSE equine/S equinoctial/S equinox/MS equipage/SM equipartition/M equip/AS equipment/SM equipoise/GMSD equipotent equipped/AU equipping/A equiproportional equiproportionality equiproportionate equitable/I equitableness/M equitably/I equitation/SM equity/IMS equiv equivalence/DSMG equivalent/SY equivocalness/MS equivocal/UY equivocate/NGSDX equivocation/M equivocator/SM Equuleus/M ER ERA eradicable/I eradicate/SDXVGN eradication/M eradicator/SM era/MS Eran/M erase/N eraser/M erasion/M Erasmus/M eras/SRDBGZ Erastus/M erasure/MS Erato/M Eratosthenes/M erbium/SM Erda/M ere Erebus/M erect/GPSRDY erectile erection/SM erectness/MS erector/SM Erek/M erelong eremite/MS Erena/M ergo ergodic ergodicity/M ergonomically ergonomics/M ergonomic/U ergophobia ergosterol/SM ergot/SM erg/SM Erhard/M Erhart/M Erica/M Ericha/M Erich/M Ericka/M Erick/M Erickson/M Eric/M Ericson's Ericsson's Eridanus/M Erie/SM Erika/M Erik/M Erikson/M Erina/M Erin/M Erinna/M Erinn/M eris Eris Eritrea/M Erlang/M Erlenmeyer/M Erl/M Er/M Erma/M Ermanno/M Ermengarde/M Ermentrude/M Ermina/M ermine/MSD Erminia/M Erminie/M Ermin/M Ernaline/M Erna/M Ernesta/M Ernestine/M Ernest/M Ernesto/M Ernestus/M Ernie/M Ernst/M Erny/M erode/SDG erodible erogenous erosible erosional erosion/SM erosiveness/M erosive/P Eros/SM erotically erotica/M eroticism/MS erotic/S errancy/MS errand/MS errantry/M errant/YS errata/SM erratically erratic/S erratum/MS err/DGS Errick/M erring/UY Erroll/M Errol/M erroneousness/M erroneous/YP error/SM ersatz/S Erse/M Erskine/M erst erstwhile Ertha/M eructation/MS eruct/DGS erudite/NYX erudition/M erupt/DSVG eruption/SM eruptive/SY Ervin/M ErvIn/M Erv/M Erwin/M Eryn/M erysipelas/SM erythrocyte/SM es e's Es E's Esau/M escadrille/M escalate/CDSXGN escalation/MC escalator/SM escallop/SGDM escapable/I escapade/SM escapee/MS escape/LGSRDB escapement/MS escaper/M escapism/SM escapist/S escapology escarole/MS escarpment/MS eschatology/M Escherichia/M Escher/M eschew/SGD Escondido/M escort/SGMD escritoire/SM escrow/DMGS escudo/MS escutcheon/SM Esdras/M ESE Eskimo/SM ESL Esma/M Esmaria/M Esmark/M Esme/M Esmeralda/M esophageal esophagi esophagus/M esoteric esoterica esoterically esp ESP espadrille/MS Espagnol/M espalier/SMDG especial/Y Esperanto/M Esperanza/M Espinoza/M espionage/SM esplanade/SM Esp/M Esposito/M espousal/MS espouser/M espouse/SRDG espresso/SM esprit/SM espy/GSD Esq/M esquire/GMSD Esquire/S Esra/M Essa/M essayer/M essayist/SM essay/SZMGRD essence/MS Essene/SM Essen/M essentialist/M essentially essentialness/M essential/USI Essequibo/M Essex/M Essie/M Essy/M EST established/U establisher/M establish/LAEGSD establishment/EMAS Establishment/MS Esta/M estate/GSDM Esteban/M esteem/EGDS Estela/M Estele/M Estella/M Estelle/M Estell/M Estel/M Esterhzy/M ester/M Ester/M Estes Estevan/M Esther/M esthete's esthetically esthetic's esthetics's estimable/I estimableness/M estimate/XDSNGV estimating/A estimation/M estimator/SM Estonia/M Estonian/S estoppal Estrada/M estrange/DRSLG estrangement/SM estranger/M Estrella/M Estrellita/M estrogen/SM estrous estrus/SM est/RZ estuarine estuary/SM et ET ETA Etan/M eta/SM etc etcetera/SM etcher/M etch/GZJSRD etching/M ETD eternalness/SM eternal/PSY eternity/SM ethane/SM Ethan/M ethanol/MS Ethelbert/M Ethelda/M Ethelind/M Etheline/M Ethelin/M Ethel/M Ethelred/M Ethelyn/M Ethe/M etherealness/M ethereal/PY etherized Ethernet/MS ether/SM ethically/U ethicalness/M ethical/PYS ethicist/S ethic/MS Ethiopia/M Ethiopian/S ethnically ethnicity/MS ethnic/S ethnocentric ethnocentrism/MS ethnographers ethnographic ethnography/M ethnological ethnologist/SM ethnology/SM ethnomethodology ethological ethologist/MS ethology/SM ethos/SM ethylene/MS Ethyl/M ethyl/SM Etienne/M etiologic etiological etiology/SM etiquette/SM Etna/M Etruria/M Etruscan/MS Etta/M Ettie/M Etti/M Ettore/M Etty/M tude/MS etymological/Y etymologist/SM etymology/MS EU eucalypti eucalyptus/SM Eucharistic Eucharist/SM euchre/MGSD euclidean Euclid/M Eudora/M Euell/M Eugene/M Eugenia/M eugenically eugenicist/SM eugenic/S eugenics/M Eugenie/M Eugenio/M Eugenius/M Eugen/M Eugine/M Eulalie/M Eula/M Eulerian/M Euler/M eulogistic eulogist/MS eulogized/U eulogize/GRSDZ eulogizer/M eulogy/MS Eu/M Eumenides Eunice/M eunuch/M eunuchs Euphemia/M euphemism/MS euphemistic euphemistically euphemist/M euphonious/Y euphonium/M euphony/SM euphoria/SM euphoric euphorically Euphrates/M Eurasia/M Eurasian/S eureka/S Euripides/M Eur/M Eurodollar/SM Europa/M Europeanization/SM Europeanized European/MS Europe/M europium/MS Eurydice/M Eustace/M Eustachian/M Eustacia/M eutectic Euterpe/M euthanasia/SM euthenics/M evacuate/DSXNGV evacuation/M evacuee/MS evader/M evade/SRDBGZ Evaleen/M evaluable evaluate/ADSGNX evaluated/U evaluational evaluation/MA evaluative evaluator/MS Eva/M evanescence/MS evanescent Evangelia/M evangelic evangelicalism/SM Evangelical/S evangelical/YS Evangelina/M Evangeline/M Evangelin/M evangelism/SM evangelistic evangelist/MS Evangelist/MS evangelize/GDS Evania/M Evan/MS Evanne/M Evanston/M Evansville/M evaporate/VNGSDX evaporation/M evaporative/Y evaporator/MS evasion/SM evasiveness/SM evasive/PY Eveleen/M Evelina/M Eveline/M Evelin/M Evelyn/M Eve/M evened evener/M evenhanded/YP evening/SM Evenki/M Even/M evenness/MSU even/PUYRT evens evensong/MS eventfulness/SM eventful/YU eventide/SM event/SGM eventuality/MS eventual/Y eventuate/GSD Everard/M Eveready/M Evered/M Everest/M Everette/M Everett/M everglade/MS Everglades evergreen/S Everhart/M everlastingness/M everlasting/PYS everliving evermore EverReady/M eve/RSM ever/T every everybody/M everydayness/M everyday/P everyman everyone/MS everyplace everything everywhere eve's/A eves/A Evey/M evict/DGS eviction/SM evidence/MGSD evidential/Y evident/YS Evie/M evildoer/SM evildoing/MS evilness/MS evil/YRPTS evince/SDG Evin/M eviscerate/GNXDS evisceration/M Evita/M Ev/MN evocable evocate/NVX evocation/M evocativeness/M evocative/YP evoke/SDG evolute/NMXS evolutionarily evolutionary evolutionist/MS evolution/M evolve/SDG Evonne/M Evvie/M Evvy/M Evy/M Evyn/M Ewan/M Eward/M Ewart/M Ewell/M ewe/MZRS Ewen/M ewer/M Ewing/M exacerbate/NGXDS exacerbation/M exacter/M exactingness/M exacting/YP exaction/SM exactitude/ISM exactly/I exactness/MSI exact/TGSPRDY exaggerate/DSXNGV exaggerated/YP exaggeration/M exaggerative/Y exaggerator/MS exaltation/SM exalted/Y exalter/M exalt/ZRDGS examen/M examination/AS examination's examine/BGZDRS examined/AU examinees examiner/M examines/A examining/A exam/MNS example/DSGM exampled/U exasperate/DSXGN exasperated/Y exasperating/Y exasperation/M Excalibur/M excavate/NGDSX excavation/M excavator/SM Excedrin/M exceeder/M exceeding/Y exceed/SGDR excelled excellence/SM excellency/MS Excellency/MS excellent/Y excelling excel/S excelsior/S except/DSGV exceptionable/U exceptionalness/M exceptional/YU exception/BMS excerpter/M excerpt/GMDRS excess/GVDSM excessiveness/M excessive/PY exchangeable exchange/GDRSZ exchanger/M exchequer/SM Exchequer/SM excise/XMSDNGB excision/M excitability/MS excitableness/M excitable/P excitably excitation/SM excitatory excited/Y excitement/MS exciter/M excite/RSDLBZG excitingly exciting/U exciton/M exclaimer/M exclaim/SZDRG exclamation/MS exclamatory exclude/DRSG excluder/M exclusionary exclusioner/M exclusion/SZMR exclusiveness/SM exclusive/SPY exclusivity/MS excommunicate/XVNGSD excommunication/M excoriate/GNXSD excoriation/M excremental excrement/SM excrescence/MS excrescent excreta excrete/NGDRSX excreter/M excretion/M excretory/S excruciate/NGDS excruciating/Y excruciation/M exculpate/XSDGN exculpation/M exculpatory excursionist/SM excursion/MS excursiveness/SM excursive/PY excursus/MS excusable/IP excusableness/IM excusably/I excuse/BGRSD excused/U excuser/M exec/MS execrableness/M execrable/P execrably execrate/DSXNGV execration/M executable/MS execute/NGVZBXDRS executer/M executional executioner/M execution/ZMR executive/SM executor/SM executrices executrix/M exegeses exegesis/M exegete/M exegetical exegetic/S exemplariness/M exemplar/MS exemplary/P exemplification/M exemplifier/M exemplify/ZXNSRDG exemption/MS exempt/SDG exerciser/M exercise/ZDRSGB exertion/MS exert/SGD Exeter/M exeunt exhalation/SM exhale/GSD exhausted/Y exhauster/M exhaustible/I exhausting/Y exhaustion/SM exhaustiveness/MS exhaustive/YP exhaust/VGRDS exhibitioner/M exhibitionism/MS exhibitionist/MS exhibition/ZMRS exhibitor/SM exhibit/VGSD exhilarate/XSDVNG exhilarating/Y exhilaration/M exhortation/SM exhort/DRSG exhorter/M exhumation/SM exhume/GRSD exhumer/M exigence/S exigency/SM exigent/SY exiguity/SM exiguous exile/SDGM existence/MS existent/I existentialism/MS existentialistic existentialist/MS existential/Y existents exist/SDG exit/MDSG exobiology/MS exocrine Exodus/M exodus/SM exogamous exogamy/M exogenous/Y exonerate/SDVGNX exoneration/M exorbitance/MS exorbitant/Y exorcise/SDG exorcism/SM exorcist/SM exorcizer/M exoskeleton/MS exosphere/SM exothermic exothermically exotica exotically exoticism/SM exoticness/M exotic/PS exp expandability/M expand/DRSGZB expanded/U expander/M expanse/DSXGNVM expansible expansionary expansionism/MS expansionist/MS expansion/M expansiveness/S expansive/YP expatiate/XSDNG expatiation/M expatriate/SDNGX expatriation/M expectancy/MS expectant/YS expectational expectation/MS expected/UPY expecting/Y expectorant/S expectorate/NGXDS expectoration/M expect/SBGD expedience/IS expediency/IMS expedients expedient/YI expediter/M expedite/ZDRSNGX expeditionary expedition/M expeditiousness/MS expeditious/YP expeditor's expellable expelled expelling expel/S expendable/S expended/U expender/M expenditure/SM expend/SDRGB expense/DSGVM expensive/IYP expensiveness/SMI experienced/U experience/ISDM experiencing experiential/Y experimentalism/M experimentalist/SM experimental/Y experimentation/SM experimenter/M experiment/GSMDRZ experted experting expertise/SM expertize/GD expertnesses expertness/IM expert/PISY expert's expiable/I expiate/XGNDS expiation/M expiatory expiration/MS expired/U expire/SDG expiry/MS explainable/UI explain/ADSG explained/U explainer/SM explanation/MS explanatory expletive/SM explicable/I explicate/VGNSDX explication/M explicative/Y explicitness/SM explicit/PSY explode/DSRGZ exploded/U exploder/M exploitation/MS exploitative exploited/U exploiter/M exploit/ZGVSMDRB exploration/MS exploratory explore/DSRBGZ explored/U explorer/M explosion/MS explosiveness/SM explosive/YPS expo/MS exponential/SY exponentiate/XSDNG exponentiation/M exponent/MS exportability exportable export/AGSD exportation/SM exporter/MS export's expose exposed/U exposer/M exposit/D exposition/SM expositor/MS expository expos/RSDZG expostulate/DSXNG expostulation/M exposure/SM expounder/M expound/ZGSDR expressed/U expresser/M express/GVDRSY expressibility/I expressible/I expressibly/I expressionism/SM expressionistic expressionist/S expressionless/YP expression/MS expressive/IYP expressiveness/MS expressiveness's/I expressway/SM expropriate/XDSGN expropriation/M expropriator/SM expulsion/MS expunge/GDSR expunger/M expurgated/U expurgate/SDGNX expurgation/M exquisiteness/SM exquisite/YPS ex/S ext extant extemporaneousness/MS extemporaneous/YP extempore/S extemporization/SM extemporizer/M extemporize/ZGSRD extendability/M extendedly extendedness/M extended/U extender/M extendibility/M extendibles extend/SGZDR extensibility/M extensible/I extensional/Y extension/SM extensiveness/SM extensive/PY extensor/MS extent/SM extenuate/XSDGN extenuation/M exterior/MYS exterminate/XNGDS extermination/M exterminator/SM externalities externalization/SM externalize/GDS external/YS extern/M extinct/DGVS extinction/MS extinguishable/I extinguish/BZGDRS extinguisher/M extirpate/XSDVNG extirpation/M extolled extoller/M extolling extol/S extort/DRSGV extorter/M extortionate/Y extortioner/M extortionist/SM extortion/ZSRM extracellular/Y extract/GVSBD extraction/SM extractive/Y extractor/SM extracurricular/S extradite/XNGSDB extradition/M extragalactic extralegal/Y extramarital extramural extraneousness/M extraneous/YP extraordinarily extraordinariness/M extraordinary/PS extrapolate/XVGNSD extrapolation/M extra/S extrasensory extraterrestrial/S extraterritorial extraterritoriality/MS extravagance/MS extravagant/Y extravaganza/SM extravehicular extravert's extrema extremal extreme/DSRYTP extremeness/MS extremism/SM extremist/MS extremity/SM extricable/I extricate/XSDNG extrication/M extrinsic extrinsically extroversion/SM extrovert/GMDS extrude/GDSR extruder/M extrusion/MS extrusive exuberance/MS exuberant/Y exudate/XNM exudation/M exude/GSD exultant/Y exultation/SM exult/DGS exulting/Y exurban exurbanite/SM exurbia/MS exurb/MS Exxon/M Eyck/M Eyde/M Eydie/M eyeball/GSMD eyebrow/MS eyed/P eyedropper/MS eyeful/MS eye/GDRSMZ eyeglass/MS eyelash/MS eyeless eyelet/GSMD eyelid/SM eyeliner/MS eyeopener/MS eyeopening eyepiece/SM eyer/M eyeshadow eyesight/MS eyesore/SM eyestrain/MS eyeteeth eyetooth/M eyewash/MS eyewitness/SM Eyre/M eyrie's Eysenck/M Ezechiel/M Ezekiel/M Ezequiel/M Eziechiele/M Ezmeralda/M Ezra/M Ezri/M F FAA Fabe/MR Faberg/M Faber/M Fabiano/M Fabian/S Fabien/M Fabio/M fable/GMSRD fabler/M fabricate/SDXNG fabrication/M fabricator/MS fabric/MS fabulists fabulousness/M fabulous/YP facade/GMSD face/AGCSD facecloth facecloths faceless/P faceplate/M facer/CM face's facetiousness/MS facetious/YP facet/SGMD facial/YS facileness/M facile/YP facilitate/VNGXSD facilitation/M facilitator/SM facilitatory facility/MS facing/MS facsimileing facsimile/MSD factional factionalism/SM faction/SM factiousness/M factious/PY factitious fact/MS facto factoid/S factorial/MS factoring/A factoring's factorisable factorization/SM factorize/GSD factor/SDMJG factory/MS factotum/MS factuality/M factualness/M factual/PY faculty/MS faddish faddist/SM fadedly faded/U fadeout fader/M fade/S fading's fading/U fad/ZGSMDR Fae/M faerie/MS Faeroe/M faery's Fafnir/M fagged fagging faggoting's Fagin/M fag/MS fagoting/M fagot/MDSJG Fahd/M Fahrenheit/S faence/S failing's failing/UY fail/JSGD faille/MS failsafe failure/SM Faina/M fain/GTSRD fainter/M fainthearted faintness/MS faint/YRDSGPT Fairbanks Fairchild/M faired Fairfax/M Fairfield/M fairgoer/S fairground/MS fairing/MS fairish Fairleigh/M fairless Fairlie/M Fair/M Fairmont/M fairness's fairness/US Fairport/M fairs fair/TURYP Fairview/M fairway/MS fairyland/MS fairy/MS fairytale Faisalabad Faisal/M faithed faithfulness/MSU faithfuls faithful/UYP faithing faithlessness/SM faithless/YP Faith/M faiths faith's faith/U fajitas faker/M fake/ZGDRS fakir/SM falafel falconer/M falconry/MS falcon/ZSRM Falito/M Falkland/MS Falk/M Falkner/M fallaciousness/M fallacious/PY fallacy/MS faller/M fallibility/MSI fallible/I fallibleness/MS fallibly/I falloff/S Fallon/M fallopian Fallopian/M fallout/MS fallowness/M fallow/PSGD fall/SGZMRN falsehood/SM falseness/SM false/PTYR falsetto/SM falsie/MS falsifiability/M falsifiable/U falsification/M falsifier/M falsify/ZRSDNXG falsity/MS Falstaff/M falterer/M faltering/UY falter/RDSGJ Falwell/M fa/M famed/C fame/DSMG fames/C familial familiarity/MUS familiarization/MS familiarized/U familiarizer/M familiarize/ZGRSD familiarizing/Y familiarly/U familiarness/M familiar/YPS family/MS famine/SM faming/C famish/GSD famously/I famousness/M famous/PY fanaticalness/M fanatical/YP fanaticism/MS fanatic/SM Fanchette/M Fanchon/M fancied Fancie/M fancier/SM fanciest fancifulness/MS fanciful/YP fancily fanciness/SM fancying fancy/IS Fancy/M fancywork/SM fandango/SM Fanechka/M fanfare/SM fanfold/M fang/DMS fangled Fania/M fanlight/SM Fan/M fanned Fannie/M Fanni/M fanning fanny/SM Fanny/SM fanout fan/SM fantail/SM fantasia/SM fantasist/M fantasize/SRDG fantastical/Y fantastic/S fantasy/GMSD Fanya/M fanzine/S FAQ/SM Faraday/M farad/SM Farah/M Fara/M Farand/M faraway Farber/M farce/SDGM farcical/Y fare/MS farer/M farewell/DGMS farfetchedness/M far/GDR Fargo/M Farica/M farinaceous farina/MS Farkas/M Farlay/M Farlee/M Farleigh/M Farley/M Farlie/M Farly/M farmer/M Farmer/M farmhand/S farmhouse/SM farming/M Farmington/M farmland/SM farm/MRDGZSJ farmstead/SM farmworker/S Far/MY farmyard/MS faro/MS farragoes farrago/M Farragut/M Farrah/M Farrakhan/M Farra/M Farrand/M Farrell/M Farrel/M farrier/SM Farris/M Farr/M farrow/DMGS farseeing farsightedness/SM farsighted/YP farther farthermost farthest farthing/SM fart/MDGS! fas fascia/SM fascicle/DSM fasciculate/DNX fasciculation/M fascinate/SDNGX fascinating/Y fascination/M fascism/MS Fascism's fascistic Fascist's fascist/SM fashionableness/M fashionable/PS fashionably/U fashion/ADSG fashioner/SM fashion's Fassbinder/M fastback/MS fastball/S fasten/AGUDS fastener/MS fastening/SM fast/GTXSPRND fastidiousness/MS fastidious/PY fastness/MS fatalism/MS fatalistic fatalistically fatalist/MS fatality/MS fatal/SY fatback/SM fatefulness/MS fateful/YP fate/MS Fates fatheaded/P fathead/SMD father/DYMGS fathered/U fatherhood/MS fatherland/SM fatherless fatherliness/M fatherly/P Father/SM fathomable/U fathomless fathom/MDSBG fatigued/U fatigue/MGSD fatiguing/Y Fatima/M fatness/SM fat/PSGMDY fatso/M fatted fattener/M fatten/JZGSRD fatter fattest/M fattiness/SM fatting fatty/RSPT fatuity/MS fatuousness/SM fatuous/YP fatwa/SM faucet/SM Faulknerian Faulkner/M fault/CGSMD faultfinder/MS faultfinding/MS faultily faultiness/MS faultlessness/SM faultless/PY faulty/RTP fauna/MS Faunie/M Faun/M faun/MS Fauntleroy/M Faustian Faustina/M Faustine/M Faustino/M Faust/M Faustus/M fauvism/S favorableness/MU favorable/UMPS favorably/U favoredness/M favored's/U favored/YPSM favorer/EM favor/ESMRDGZ favoring/MYS favorings/U favorite/SMU favoritism/MS favors/A Fawkes/M Fawne/M fawner/M fawn/GZRDMS Fawnia/M fawning/Y Fawn/M fax/GMDS Fax/M Faydra/M Faye/M Fayette/M Fayetteville/M Fayina/M Fay/M fay/MDRGS Fayre/M Faythe/M Fayth/M faze/DSG FBI FCC FD FDA FDIC FDR/M fealty/MS fearfuller fearfullest fearfulness/MS fearful/YP fearlessness/MS fearless/PY fear/RDMSG fearsomeness/M fearsome/PY feasibility/SM feasibleness/M feasible/UI feasibly/U feaster/M feast/GSMRD feater/C featherbed featherbedding/SM featherbrain/MD feathered/U feathering/M featherless featherlight Featherman/M feathertop featherweight/SM feathery/TR feather/ZMDRGS feat/MYRGTS feats/C featureless feature/MGSD Feb/M febrile February/MS fecal feces fecklessness/M feckless/PY fecundability fecundate/XSDGN fecundation/M fecund/I fecundity/SM federalism/SM Federalist federalist/MS federalization/MS federalize/GSD Federal/S federal/YS federated/U federate/FSDXVNG federation/FM federative/Y Federica/M Federico/M FedEx/M Fedora/M fedora/SM feds Fed/SM fed/U feebleness/SM feeble/TPR feebly feedback/SM feedbag/MS feeder/M feed/GRZJS feeding/M feedlot/SM feedstock feedstuffs feeing feeler/M feel/GZJRS feelingly/U feeling/MYP feelingness/M Fee/M fee/MDS feet/M feigned/U feigner/M feign/RDGS feint/MDSG feisty/RT Felder/M Feldman/M feldspar/MS Felecia/M Felicdad/M Felice/M Felicia/M Felicio/M felicitate/XGNSD felicitation/M felicitous/IY felicitousness/M felicity/IMS Felicity/M Felicle/M Felic/M Felike/M Feliks/M feline/SY Felipa/M Felipe/M Felisha/M Felita/M Felix/M Feliza/M Felizio/M fella/S fellatio/SM felled/A feller/M felling/A Fellini/M fellness/M fellowman fellowmen fellow/SGDYM fellowshipped fellowshipping fellowship/SM fell/PSGZTRD feloniousness/M felonious/PY felon/MS felony/MS felt/GSD felting/M Fe/M female/MPS femaleness/SM feminineness/M feminine/PYS femininity/MS feminism/MS feminist/MS femme/MS femoral fem/S femur/MS fenced/U fencepost/M fencer/M fence/SRDJGMZ fencing/M fender/CM fend/RDSCZG Fenelia/M fenestration/CSM Fenian/M fenland/M fen/MS fennel/SM Fenwick/M Feodora/M Feodor/M feral Ferber/M Ferdie/M Ferdinanda/M Ferdinande/M Ferdinand/M Ferdinando/M Ferd/M Ferdy/M fer/FLC Fergus/M Ferguson/M Ferlinghetti/M Fermat/M fermentation/MS fermented fermenter ferment/FSCM fermenting Fermi/M fermion/MS fermium/MS Fernanda/M Fernande/M Fernandez/M Fernandina/M Fernando/M Ferne/M fernery/M Fern/M fern/MS ferny/TR ferociousness/MS ferocious/YP ferocity/MS Ferrari/M Ferraro/M Ferreira/M Ferrell/M Ferrel/M Ferrer/M ferreter/M ferret/SMRDG ferric ferris Ferris ferrite/M ferro ferroelectric ferromagnetic ferromagnet/M ferrous ferrule/MGSD ferryboat/MS ferryman/M ferrymen ferry/SDMG fertileness/M fertile/YP fertility/IMS fertilization/ASM fertilized/U fertilizer/M fertilizes/A fertilize/SRDZG ferule/SDGM fervency/MS fervent/Y fervidness/M fervid/YP fervor/MS fess/KGFSD Fess/M fess's festal/S fester/GD festival/SM festiveness/SM festive/PY festivity/SM festoon/SMDG fest/RVZ fetal feta/MS fetcher/M fetching/Y fetch/RSDGZ feted fte/MS fetich's fetidness/SM fetid/YP feting fetishism/SM fetishistic fetishist/SM fetish/MS fetlock/MS fetter's fetter/UGSD fettle/GSD fettling/M fettuccine/S fetus/SM feudalism/MS feudalistic feudal/Y feudatory/M feud/MDSG feverishness/SM feverish/PY fever/SDMG fewness/MS few/PTRS Fey/M Feynman/M fey/RT fez/M Fez/M fezzes ff FHA fiance/S fianc/MS Fianna/M Fiann/M fiascoes fiasco/M Fiat/M fiat/MS fibbed fibber/MS fibbing fiberboard/MS fiber/DM fiberfill/S Fiberglas/M fiberglass/DSMG Fibonacci/M fibrillate/XGNDS fibrillation/M fibril/MS fibrin/MS fibroblast/MS fibroid/S fibroses fibrosis/M fibrousness/M fibrous/YP fib/SZMR fibulae fibula/M fibular FICA fices fiche/SM Fichte/M fichu/SM fickleness/MS fickle/RTP ficos fictionalization/MS fictionalize/DSG fictional/Y fiction/SM fictitiousness/M fictitious/PY fictive/Y ficus fiddle/GMZJRSD fiddler/M fiddlestick/SM fiddly fide/F Fidela/M Fidelia/M Fidelio/M fidelity/IMS Fidelity/M Fidel/M fidget/DSG fidgety Fidole/M Fido/M fiducial/Y fiduciary/MS fiefdom/S fief/MS fielded fielder/IM fielding Fielding/M Field/MGS fieldstone/M fieldworker/M fieldwork/ZMRS field/ZISMR fiendishness/M fiendish/YP fiend/MS fierceness/SM fierce/RPTY fierily fieriness/MS fiery/PTR fie/S fies/C fiesta/MS fife/DRSMZG fifer/M Fifi/M Fifine/M FIFO fifteen/HRMS fifteenths fifths fifth/Y fiftieths fifty/HSM Figaro/M figged figging fightback fighter/MIS fighting/IS fight/ZSJRG figment/MS fig/MLS Figueroa/M figural figuration/FSM figurativeness/M figurative/YP figure/GFESD figurehead/SM figurer/SM figure's figurine/SM figuring/S Fijian/SM Fiji/M filamentary filament/MS filamentous Filberte/M Filbert/M filbert/MS Filberto/M filch/SDG filed/AC file/KDRSGMZ filename/SM filer/KMCS files/AC filet's filial/UY Filia/M filibusterer/M filibuster/MDRSZG Filide/M filigreeing filigree/MSD filing/AC filings Filipino/SM Filip/M Filippa/M Filippo/M fill/BAJGSD filled/U filler/MS filleting/M fillet/MDSG filling/M fillip/MDGS Fillmore/M filly/SM filmdom/M Filmer/M filminess/SM filming/M filmmaker/S Filmore/M film/SGMD filmstrip/SM filmy/RTP Filofax/S filtered/U filterer/M filter/RDMSZGB filthily filthiness/SM filth/M filths filthy/TRSDGP filtrated/I filtrate/SDXMNG filtrates/I filtrating/I filtration/IMS finagler/M finagle/RSDZG finale/MS finalist/MS finality/MS finalization/SM finalize/GSD final/SY Fina/M financed/A finance/MGSDJ finances/A financial/Y financier/DMGS financing/A Finch/M finch/MS findable/U find/BRJSGZ finder/M finding/M Findlay/M Findley/M fine/FGSCRDA finely fineness/MS finery/MAS fine's finespun finesse/SDMG fingerboard/SM fingerer/M fingering/M fingerless fingerling/M fingernail/MS fingerprint/SGDM finger/SGRDMJ fingertip/MS finial/SM finical finickiness/S finicky/RPT fining/M finished/UA finisher/M finishes/A finish/JZGRSD finis/SM finite/ISPY finitely/C finiteness/MIC fink/GDMS Finland/M Finlay/M Finley/M Fin/M Finnbogadottir/M finned Finnegan/M finner finning Finnish Finn/MS finny/RT fin/TGMDRS Fiona/M Fionna/M Fionnula/M fiord's Fiorello/M Fiorenze/M Fiori/M f/IRAC firearm/SM fireball/SM fireboat/M firebomb/MDSG firebox/MS firebrand/MS firebreak/SM firebrick/SM firebug/SM firecracker/SM firedamp/SM fired/U firefight/JRGZS firefly/MS Firefox/M fireguard/M firehouse/MS firelight/GZSM fireman/M firemen fire/MS fireplace/MS fireplug/MS firepower/SM fireproof/SGD firer/M firesafe fireside/SM Firestone/M firestorm/SM firetrap/SM firetruck/S firewall/S firewater/SM firewood/MS firework/MS firing/M firkin/M firmament/MS firmer firmest firm/ISFDG firmly/I firmness/MS firm's firmware/MS firring firstborn/S firsthand first/SY firth/M firths fir/ZGJMDRHS fiscal/YS Fischbein/M Fischer/M fishbowl/MS fishcake/S fisher/M Fisher/M fisherman/M fishermen/M fishery/MS fishhook/MS fishily fishiness/MS fishing/M fish/JGZMSRD Fishkill/M fishmeal fishmonger/MS fishnet/SM fishpond/SM fishtail/DMGS fishtanks fishwife/M fishwives fishy/TPR Fiske/M Fisk/M fissile fissionable/S fission/BSDMG fissure/MGSD fistfight/SM fistful/MS fisticuff/SM fist/MDGS fistula/SM fistulous Fitchburg/M Fitch/M fitfulness/SM fitful/PY fitments fitness/USM fits/AK fit's/K fitted/UA fitter/SM fittest fitting/AU fittingly fittingness/M fittings fit/UYPS Fitzgerald/M Fitz/M Fitzpatrick/M Fitzroy/M fivefold five/MRS fiver/M fixable fixate/VNGXSD fixatifs fixation/M fixative/S fixedness/M fixed/YP fixer/SM fixes/I fixing/SM fixity/MS fixture/SM fix/USDG Fizeau/M fizzer/M fizzle/GSD fizz/SRDG fizzy/RT fjord/SM FL flabbergast/GSD flabbergasting/Y flabbily flabbiness/SM flabby/TPR flab/MS flaccidity/MS flaccid/Y flack/SGDM flagella/M flagellate/DSNGX flagellation/M flagellum/M flagged flaggingly/U flagging/SMY flagman/M flagmen flag/MS flagon/SM flagpole/SM flagrance/MS flagrancy/SM flagrant/Y flagship/MS flagstaff/MS flagstone/SM flail/SGMD flair/SM flaker/M flake/SM flakiness/MS flak/RDMGS flaky/PRT Fla/M flamb/D flambeing flambes flamboyance/MS flamboyancy/MS flamboyant/YS flamenco/SM flamen/M flameproof/DGS flamer/IM flame's flame/SIGDR flamethrower/SM flamingo/SM flaming/Y flammability/ISM flammable/SI flam/MRNDJGZ Flanagan/M Flanders/M flange/GMSD flanker/M flank/SGZRDM flan/MS flannel/DMGS flannelet/MS flannelette's flapjack/SM flap/MS flapped flapper/SM flapping flaps/M flare/SDG flareup/S flaring/Y flashback/SM flashbulb/SM flashcard/S flashcube/MS flasher/M flashgun/S flashily flashiness/SM flashing/M flash/JMRSDGZ flashlight/MS flashy/TPR flask/SM flatbed/S flatboat/MS flatcar/MS flatfeet flatfish/SM flatfoot/SGDM flathead/M flatiron/SM flatland/RS flatmate/M flat/MYPS flatness/MS flatted flattener/M flatten/SDRG flatter/DRSZG flatterer/M flattering/YU flattery/SM flattest/M flatting flattish Flatt/M flattop/MS flatulence/SM flatulent/Y flatus/SM flatware/MS flatworm/SM Flaubert/M flaunting/Y flaunt/SDG flautist/SM flavored/U flavorer/M flavorful flavoring/M flavorless flavor/SJDRMZG flavorsome flaw/GDMS flawlessness/MS flawless/PY flax/MSN flaxseed/M flayer/M flay/RDGZS fleabag/MS fleabites flea/SM fleawort/M fleck/GRDMS Fledermaus/M fledged/U fledge/GSD fledgling/SM fleecer/M fleece/RSDGMZ fleeciness/SM fleecy/RTP fleeing flee/RS fleetingly/M fleetingness/SM fleeting/YP fleet/MYRDGTPS fleetness/MS Fleischer/M Fleischman/M Fleisher/M Fleming/M Flemished/M Flemish/GDSM Flemishing/M Flem/JGM Flemming/M flesher/M fleshiness/M flesh/JMYRSDG fleshless fleshly/TR fleshpot/SM fleshy/TPR fletch/DRSGJ fletcher/M Fletcher/M fletching/M Fletch/MR Fleurette/M Fleur/M flew/S flews/M flexed/I flexibility/MSI flexible/I flexibly/I flexitime's flex/MSDAG flextime/S flexural flexure/M fl/GJD flibbertigibbet/MS flicker/GD flickering/Y flickery flick/GZSRD flier/M flight/GMDS flightiness/SM flightless flightpath flighty/RTP flimflammed flimflamming flimflam/MS flimsily flimsiness/MS flimsy/PTRS flincher/M flinch/GDRS flinching/U flinger/M fling/RMG Flin/M Flinn/M flintiness/M flintless flintlock/MS Flint/M flint/MDSG Flintstones flinty/TRP flipflop flippable flippancy/MS flippant/Y flipped flipper/SM flippest flipping flip/S flirtation/SM flirtatiousness/MS flirtatious/PY flirt/GRDS flit/S flitted flitting floater/M float/SRDGJZ floaty flocculate/GNDS flocculation/M flock/SJDMG floe/MS flogged flogger/SM flogging/SM flog/S Flo/M floodgate/MS floodlight/DGMS floodlit floodplain/S flood/SMRDG floodwater/SM floorboard/MS floorer/M flooring/M floor/SJRDMG floorspace floorwalker/SM floozy/SM flophouse/SM flop/MS flopped flopper/M floppily floppiness/SM flopping floppy/TMRSP floral/SY Flora/M Florance/M flora/SM Florella/M Florence/M Florencia/M Florentia/M Florentine/S Florenza/M florescence/MIS florescent/I Flore/SM floret/MS Florette/M Floria/M Florian/M Florida/M Floridan/S Floridian/S floridness/SM florid/YP Florie/M Florina/M Florinda/M Florine/M florin/MS Flori/SM florist/MS Flor/M Florrie/M Florri/M Florry/M Flory/M floss/GSDM Flossie/M Flossi/M Flossy/M flossy/RST flotation/SM flotilla/SM flotsam/SM flounce/GDS flouncing/M flouncy/RT flounder/SDG flourisher/M flourish/GSRD flourishing/Y flour/SGDM floury/TR flouter/M flout/GZSRD flowchart/SG flowed flowerbed/SM flower/CSGD flowerer/M floweriness/SM flowerless flowerpot/MS flower's Flowers flowery/TRP flowing/Y flow/ISG flown flowstone Floyd/M Flss/M flt flubbed flubbing flub/S fluctuate/XSDNG fluctuation/M fluency/MS fluently fluent/SF flue/SM fluffiness/SM fluff/SGDM fluffy/PRT fluidity/SM fluidized fluid/MYSP fluidness/M fluke/SDGM fluky/RT flume/SDGM flummox/DSG flu/MS flung flunkey's flunk/SRDG flunky/MS fluoresce/GSRD fluorescence/MS fluorescent/S fluoridate/XDSGN fluoridation/M fluoride/SM fluorimetric fluorinated fluorine/SM fluorite/MS fluorocarbon/MS fluoroscope/MGDS fluoroscopic flurry/GMDS flushness/M flush/TRSDPBG fluster/DSG fluter/M flute/SRDGMJ fluting/M flutist/MS flutter/DRSG flutterer/M fluttery fluxed/A fluxes/A flux/IMS fluxing flyaway flyblown flyby/M flybys flycatcher/MS flyer's fly/JGBDRSTZ flyleaf/M flyleaves Flynn/M flyover/MS flypaper/MS flysheet/S flyspeck/MDGS flyswatter/S flyway/MS flyweight/MS flywheel/MS FM Fm/M FNMA/M foal/MDSG foaminess/MS foam/MRDSG foamy/RPT fobbed fobbing fob/SM focal/F focally Foch/M foci's focused/AU focuser/M focuses/A focus/SRDMBG fodder/GDMS foe/SM foetid FOFL fogbound fogged/C foggily fogginess/MS fogging/C foggy/RPT foghorn/SM fogs/C fog/SM fogyish fogy/SM foible/MS foil/GSD foist/GDS Fokker/M foldaway/S folded/AU folder/M foldout/MS fold/RDJSGZ folds/UA Foley/M foliage/MSD foliate/CSDXGN foliation/CM folio/SDMG folklike folklore/MS folkloric folklorist/SM folk/MS folksiness/MS folksinger/S folksinging/S folksong/S folksy/TPR folktale/S folkway/S foll follicle/SM follicular follower/M follow/JSZBGRD followup's folly/SM Folsom fol/Y Fomalhaut/M fomentation/SM fomenter/M foment/RDSG Fonda/M fondant/SM fondle/GSRD fondler/M fondness/MS fond/PMYRDGTS fondue/MS Fons Fonsie/M Fontainebleau/M Fontaine/M Fontana/M fontanelle's fontanel/MS font/MS Fonzie/M Fonz/M foodie/S food/MS foodstuff/MS foolery/MS foolhardily foolhardiness/SM foolhardy/PTR foolishness/SM foolish/PRYT fool/MDGS foolproof foolscap/MS footage/SM football/SRDMGZ footbridge/SM Foote/M footer/M footfall/SM foothill/SM foothold/MS footing/M footless footlights footling footlocker/SM footloose footman/M footmarks footmen footnote/MSDG footpad/SM footpath/M footpaths footplate/M footprint/MS footrace/S footrest/MS footsie/SM foot/SMRDGZJ footsore footstep/SM footstool/SM footwear/M footwork/SM fop/MS fopped foppery/MS fopping foppishness/SM foppish/YP forage/GSRDMZ forager/M forayer/M foray/SGMRD forbade forbearance/SM forbearer/M forbear/MRSG Forbes/M forbidden forbiddingness/M forbidding/YPS forbid/S forbore forborne forced/Y forcefield/MS forcefulness/MS forceful/PY forceps/M forcer/M force/SRDGM forcibleness/M forcible/P forcibly fordable/U Fordham/M Ford/M ford/SMDBG forearm/GSDM forebear/MS forebode/GJDS forebodingness/M foreboding/PYM forecaster/M forecastle/MS forecast/SZGR foreclose/GSD foreclosure/MS forecourt/SM foredoom/SDG forefather/SM forefeet forefinger/MS forefoot/M forefront/SM foregoer/M foregoing/S foregone foregos foreground/MGDS forehand/S forehead/MS foreigner/M foreignness/SM foreign/PRYZS foreknew foreknow/GS foreknowledge/MS foreknown foreleg/MS forelimb/MS forelock/MDSG foreman/M Foreman/M foremast/SM foremen foremost forename/DSM forenoon/SM forensically forensic/S forensics/M foreordain/DSG forepart/MS forepaws forepeople foreperson/S foreplay/MS forequarter/SM forerunner/MS fore/S foresail/SM foresaw foreseeable/U foreseeing foreseen/U foreseer/M foresee/ZSRB foreshadow/SGD foreshore/M foreshorten/DSG foresightedness/SM foresighted/PY foresight/SMD foreskin/SM forestaller/M forestall/LGSRD forestallment/M forestation/MCS forestations/A forest/CSAGD Forester/M forester/SM forestland/S Forest/MR forestry/MS forest's foretaste/MGSD foreteller/M foretell/RGS forethought/MS foretold forevermore forever/PS forewarner/M forewarn/GSJRD forewent forewoman/M forewomen foreword/SM forfeiter/M forfeiture/MS forfeit/ZGDRMS forfend/GSD forgather/GSD forgave forged/A forge/JVGMZSRD forger/M forgery/MS forges/A forgetfulness/SM forgetful/PY forget/SV forgettable/U forgettably/U forgetting forging/M forgivable/U forgivably/U forgiven forgiveness/SM forgiver/M forgive/SRPBZG forgivingly forgivingness/M forgiving/UP forgoer/M forgoes forgone forgo/RSGZ forgot forgotten/U for/HT forkful/S fork/GSRDM forklift/DMSG forlornness/M forlorn/PTRY formability/AM formaldehyde/SM formalin/M formalism/SM formalistic formalist/SM formality/SMI formal/IY formalization/SM formalized/U formalizer/M formalizes/I formalize/ZGSRD formalness/M formals formant/MIS format/AVS formate/MXGNSD formation/AFSCIM formatively/I formativeness/IM formative/SYP format's formatted/UA formatter/A formatters formatter's formatting/A form/CGSAFDI formed/U former/FSAI formerly formfitting formic Formica/MS formidableness/M formidable/P formidably formlessness/MS formless/PY Formosa/M Formosan form's formulaic formula/SM formulate/AGNSDX formulated/U formulation/AM formulator/SM fornicate/GNXSD fornication/M fornicator/SM Forrester/M Forrest/RM forsaken forsake/SG forsook forsooth Forster/M forswear/SG forswore forsworn forsythia/MS Fortaleza/M forte/MS forthcome/JG forthcoming/U FORTH/M forthrightness/SM forthright/PYS forthwith fortieths fortification/MS fortified/U fortifier/SM fortify/ADSG fortiori fortissimo/S fortitude/SM fortnightly/S fortnight/MYS FORTRAN Fortran/M fortress/GMSD fort/SM fortuitousness/SM fortuitous/YP fortuity/MS fortunateness/M fortunate/YUS fortune/MGSD fortuneteller/SM fortunetelling/SM forty/SRMH forum/MS forwarder/M forwarding/M forwardness/MS forward/PTZSGDRY forwent fossiliferous fossilization/MS fossilized/U fossilize/GSD fossil/MS Foss/M fosterer/M Foster/M foster/SRDG Foucault/M fought foulard/SM foulmouth/D foulness/MS fouls/M foul/SYRDGTP foundational foundation/SM founded/UF founder/MDG founder's/F founding/F foundling/MS found/RDGZS foundry/MS founds/KF fountainhead/SM fountain/SMDG fount/MS fourfold Fourier/M fourpence/M fourpenny fourposter/SM fourscore/S four/SHM foursome/SM foursquare fourteener/M fourteen/SMRH fourteenths Fourth fourths Fourths fourth/Y fovea/M fowler/M Fowler/M fowling/M fowl/SGMRD foxfire/SM foxglove/SM Foxhall/M foxhole/SM foxhound/SM foxily foxiness/MS foxing/M fox/MDSG Fox/MS foxtail/M foxtrot/MS foxtrotted foxtrotting foxy/TRP foyer/SM FPO fps fr fracas/SM fractal/SM fractional/Y fractionate/DNG fractionation/M fractioned fractioning fraction/ISMA fractiousness/SM fractious/PY fracture/MGDS fragile/Y fragility/MS fragmentarily fragmentariness/M fragmentary/P fragmentation/MS fragment/SDMG Fragonard/M fragrance/SM fragrant/Y frailness/MS frail/STPYR frailty/MS framed/U framer/M frame/SRDJGMZ framework/SM framing/M Francaise/M France/MS Francene/M Francesca/M Francesco/M franchisee/S franchise/ESDG franchiser/SM franchise's Franchot/M Francie/M Francine/M Francis Francisca/M Franciscan/MS Francisco/M Franciska/M Franciskus/M francium/MS Francklin/M Francklyn/M Franck/M Francoise/M Francois/M Franco/M francophone/M franc/SM Francyne/M frangibility/SM frangible Frankel/M Frankenstein/MS franker/M Frankford/M Frankfort/M Frankfurter/M frankfurter/MS Frankfurt/RM Frankie/M frankincense/MS Frankish/M franklin/M Franklin/M Franklyn/M frankness/MS frank/SGTYRDP Frank/SM Franky/M Fran/MS Frannie/M Franni/M Franny/M Fransisco/M frantically franticness/M frantic/PY Frants/M Franzen/M Franz/NM frapp frappeed frappeing frappes Frasco/M Fraser/M Frasier/M Frasquito/M fraternal/Y fraternity/MSF fraternization/SM fraternize/GZRSD fraternizer/M fraternizing/U frat/MS fratricidal fratricide/MS fraud/CS fraud's fraudsters fraudulence/S fraudulent/YP fraught/SGD Fraulein/S Frau/MN fray/CSDG Frayda/M Frayne/M fray's Fraze/MR Frazer/M Frazier/M frazzle/GDS freakishness/SM freakish/YP freak/SGDM freaky/RT freckle/GMDS freckly/RT Freda/M Freddie/M Freddi/M Freddy/M Fredek/M Fredelia/M Frederica/M Frederich/M Fredericka/M Frederick/MS Frederic/M Frederico/M Fredericton/M Frederigo/M Frederik/M Frederique/M Fredholm/M Fredia/M Fredi/M Fred/M Fredra/M Fredrick/M Fredrickson/M Fredric/M Fredrika/M freebase/GDS freebie/MS freebooter/M freeboot/ZR freeborn freedman/M Freedman/M freedmen freedom/MS freehand/D freehanded/Y freeholder/M freehold/ZSRM freeing/S freelance/SRDGZM Freeland/M freeloader/M freeload/SRDGZ Free/M freeman/M Freeman/M freemasonry/M Freemasonry/MS Freemason/SM freemen Freemon/M freeness/M Freeport/M freestanding freestone/SM freestyle/SM freethinker/MS freethinking/S Freetown/M freeway/MS freewheeler/M freewheeling/P freewheel/SRDMGZ freewill free/YTDRSP freezable freezer/SM freeze/UGSA freezing/S Freida/M freighter/M freight/ZGMDRS Fremont/M Frenchman/M French/MDSG Frenchmen Frenchwoman/M Frenchwomen frenetically frenetic/S frenzied/Y frenzy/MDSG freon/S Freon/SM freq frequency/ISM frequented/U frequenter/MS frequentest frequenting frequent/IY frequentness/M frequents fresco/DMG frescoes fresh/AZSRNDG freshener/M freshen/SZGDR fresher/MA freshest freshet/SM freshly freshman/M freshmen freshness/MS freshwater/SM Fresnel/M Fresno/M fretboard fretfulness/MS fretful/PY fret/S fretsaw/S fretted fretting fretwork/MS Freudian/S Freud/M Freya/M Frey/M friableness/M friable/P friary/MS friar/YMS fricasseeing fricassee/MSD frication/M fricative/MS Frick/M frictional/Y frictionless/Y friction/MS Friday/SM fridge/SM fried/A Frieda/M Friedan/M friedcake/SM Friederike/M Friedman/M Friedrich/M Friedrick/M friendlessness/M friendless/P friendlies friendlily friendliness/USM friendly/PUTR friend/SGMYD friendship/MS frier's fries/M frieze/SDGM frigate/SM Frigga/M frigged frigging/S frighten/DG frightening/Y frightfulness/MS frightful/PY fright/GXMDNS Frigidaire/M frigidity/MS frigidness/SM frigid/YP frig/S frill/MDGS frilly/RST Fri/M fringe/IGSD fringe's frippery/SM Frisbee/MS Frisco/M Frisian/SM frisker/M friskily friskiness/SM frisk/RDGS frisky/RTP frisson/M Frito/M fritterer/M fritter/RDSG Fritz/M fritz/SM frivolity/MS frivolousness/SM frivolous/PY frizz/GYSD frizzle/DSG frizzly/RT frizzy/RT Fr/MD Frobisher/M frocking/M frock's frock/SUDGC frogged frogging frogman/M frogmarched frogmen frog/MS fro/HS Froissart/M frolicked frolicker/SM frolicking frolic/SM frolicsome from Fromm/M frond/SM frontage/MS frontal/SY Frontenac/M front/GSFRD frontier/SM frontiersman/M frontiersmen frontispiece/SM frontrunner's front's frontward/S frosh/M Frostbelt/M frostbite/MS frostbit/G frostbiting/M frostbitten frost/CDSG frosteds frosted/U frostily frostiness/SM frosting/MS Frost/M frost's frosty/PTR froth/GMD frothiness/SM froths frothy/TRP froufrou/MS frowardness/MS froward/P frowner/M frowning/Y frown/RDSG frowzily frowziness/SM frowzy/RPT frozenness/M frozen/YP froze/UA fructify/GSD fructose/MS Fruehauf/M frugality/SM frugal/Y fruitcake/SM fruiterer/M fruiter/RM fruitfuller fruitfullest fruitfulness/MS fruitful/UYP fruit/GMRDS fruitiness/MS fruition/SM fruitlessness/MS fruitless/YP fruity/RPT frumpish frump/MS frumpy/TR Frunze/M frustrater/M frustrate/RSDXNG frustrating/Y frustration/M frustum/SM Frye/M fryer/MS Fry/M fry/NGDS F's f's/KA FSLIC ft/C FTC FTP fuchsia/MS Fuchs/M fucker/M! fuck/GZJRDMS! FUD fuddle/GSD fudge/GMSD fuel/ASDG fueler/SM fuel's Fuentes/M fugal Fugger/M fugitiveness/M fugitive/SYMP fugue/GMSD fuhrer/S Fuji/M Fujitsu/M Fujiyama Fukuoka/M Fulani/M Fulbright/M fulcrum/SM fulfilled/U fulfiller/M fulfill/GLSRD fulfillment/MS fullback/SMG fuller/DMG Fuller/M Fullerton/M fullish fullness/MS full/RDPSGZT fullstops fullword/SM fully fulminate/XSDGN fulmination/M fulness's fulsomeness/SM fulsome/PY Fulton/M Fulvia/M fumble/GZRSD fumbler/M fumbling/Y fume/DSG fumigant/MS fumigate/NGSDX fumigation/M fumigator/SM fuming/Y fumy/TR Funafuti functionalism/M functionalist/SM functionality/S functional/YS functionary/MS function/GSMD functor/SM fundamentalism/SM fundamentalist/SM fundamental/SY fund/ASMRDZG funded/U fundholders fundholding funding/S Fundy/M funeral/MS funerary funereal/Y funfair/M fungal/S fungible/M fungicidal fungicide/SM fungi/M fungoid/S fungous fungus/M funicular/SM funk/GSDM funkiness/S funky/RTP fun/MS funned funnel/SGMD funner funnest funnily/U funniness/SM funning funny/RSPT furbelow/MDSG furbisher/M furbish/GDRSA furiousness/M furious/RYP furlong/MS furlough/DGM furloughs furl/UDGS furn furnace/GMSD furnished/U furnisher/MS furnish/GASD furnishing/SM furniture/SM furore/MS furor/MS fur/PMS furred furrier/M furriness/SM furring/SM furrow/DMGS furry/RTZP furtherance/MS furtherer/M furthermore furthermost further/TGDRS furthest furtiveness/SM furtive/PY fury/SM furze/SM fusebox/S fusee/SM fuse/FSDAGCI fuselage/SM fuse's/A Fushun/M fusibility/SM fusible/I fusiform fusilier/MS fusillade/SDMG fusion/KMFSI fussbudget/MS fusser/M fussily fussiness/MS fusspot/SM fuss/SRDMG fussy/PTR fustian/MS fustiness/MS fusty/RPT fut futileness/M futile/PY futility/MS futon/S future/SM futurism/SM futuristic/S futurist/S futurity/MS futurologist/S futurology/MS futz/GSD fuze's Fuzhou/M Fuzzbuster/M fuzzily fuzziness/SM fuzz/SDMG fuzzy/PRT fwd FWD fwy FY FYI GA gabardine/SM gabbed Gabbey/M Gabbie/M Gabbi/M gabbiness/S gabbing gabble/SDG Gabby/M gabby/TRP Gabe/M gaberdine's Gabey/M gabfest/MS Gabie/M Gabi/M gable/GMSRD Gable/M Gabonese Gabon/M Gaborone/M Gabriela/M Gabriele/M Gabriella/M Gabrielle/M Gabriellia/M Gabriell/M Gabriello/M Gabriel/M Gabrila/M gab/S Gaby/M Gacrux/M gadabout/MS gadded gadder/MS gadding gadfly/MS gadgetry/MS gadget/SM gadolinium/MS gad/S Gadsden/M Gaea/M Gaelan/M Gaelic/M Gael/SM Gae/M gaffe/MS gaffer/M gaff/SGZRDM gaga Gagarin/M gag/DRSG Gage/M gager/M gage/SM gagged gagging gaggle/SDG gagwriter/S gaiety/MS Gaile/M Gail/M gaily gain/ADGS gainer/SM Gaines/M Gainesville/M gainfulness/M gainful/YP gaining/S gainly/U gainsaid gainsayer/M gainsay/RSZG Gainsborough/M gaiter/M gait/GSZMRD Gaithersburg/M galactic Galahad/MS Galapagos/M gal/AS gala/SM Galatea/M Galatia/M Galatians/M Galaxy/M galaxy/MS Galbraith/M Galbreath/M gale/AS Gale/M galen galena/MS galenite/M Galen/M gale's Galibi/M Galilean/MS Galilee/M Galileo/M Galina/M Gallagher/M gallanted gallanting gallantry/MS gallants gallant/UY Gallard/M gallbladder/MS Gallegos/M galleon/SM galleria/S gallery/MSDG galley/MS Gallic Gallicism/SM gallimaufry/MS galling/Y gallium/SM gallivant/GDS Gall/M gallonage/M gallon/SM galloper/M gallop/GSRDZ Galloway/M gallows/M gall/SGMD gallstone/MS Gallup/M Gal/MN Galois/M galoot/MS galore/S galosh/GMSD gal's Galsworthy/M galumph/GD galumphs galvanic Galvani/M galvanism/MS galvanization/SM galvanize/SDG Galvan/M galvanometer/SM galvanometric Galven/M Galveston/M Galvin/M Ga/M Gamaliel/M Gama/M Gambia/M Gambian/S gambit/MS gamble/GZRSD Gamble/M gambler/M gambol/SGD gamecock/SM gamekeeper/MS gameness/MS game/PJDRSMYTZG gamesmanship/SM gamesmen gamester/M gamest/RZ gamete/MS gametic gamine/SM gaminess/MS gaming/M gamin/MS gamma/MS gammon/DMSG Gamow/M gamut/MS gamy/TRP gander/DMGS Gandhian Gandhi/M gangbusters ganger/M Ganges/M gang/GRDMS gangland/SM ganglia/M gangling ganglionic ganglion/M gangplank/SM gangrene/SDMG gangrenous gangster/SM Gangtok/M gangway/MS Gan/M gannet/SM Gannie/M Gannon/M Ganny/M gantlet/GMDS Gantry/M gantry/MS Ganymede/M GAO gaoler/M gaol/MRDGZS gaper/M gape/S gaping/Y gapped gapping gap/SJMDRG garage/GMSD Garald/M garbageman/M garbage/SDMG garbanzo/MS garb/DMGS garbler/M garble/RSDG Garbo/M Garcia/M garon/SM gardener/M Gardener/M gardenia/SM gardening/M garden/ZGRDMS Gardie/M Gardiner/M Gard/M Gardner/M Gardy/M Garek/M Gare/MH Gareth/M Garey/M Garfield/M garfish/MS Garfunkel/M Gargantua/M gargantuan gargle/SDG gargoyle/DSM Garibaldi/M Garik/M garishness/MS garish/YP Garland/M garland/SMDG garlicked garlicking garlicky garlic/SM garment/MDGS Gar/MH Garner/M garner/SGD Garnet/M garnet/SM Garnette/M Garnett/M garnish/DSLG garnisheeing garnishee/SDM garnishment/MS Garold/M garote's garotte's Garrard/M garred Garrek/M Garreth/M Garret/M garret/SM Garrett/M Garrick/M Garrik/M garring Garrison/M garrison/SGMD garroter/M garrote/SRDMZG Garrot/M garrotte's Garrott/M garrulity/SM garrulousness/MS garrulous/PY Garry/M gar/SLM garter/SGDM Garth/M Garvey/M Garvin/M Garv/M Garvy/M Garwin/M Garwood/M Gary/M Garza/M gasbag/MS Gascony/M gaseousness/M gaseous/YP gases/C gas/FC gash/GTMSRD gasification/M gasifier/M gasify/SRDGXZN gasket/SM gaslight/DMS gasohol/S gasoline/MS gasometer/M Gaspard/M Gaspar/M Gasparo/M gasper/M Gasper/M gasp/GZSRD gasping/Y gas's gassed/C Gasser/M gasser/MS Gasset/M gassiness/M gassing/SM gassy/PTR Gaston/M gastric gastritides gastritis/MS gastroenteritides gastroenteritis/M gastrointestinal gastronome/SM gastronomic gastronomical/Y gastronomy/MS gastropod/SM gasworks/M gateau/MS gateaux gatecrash/GZSRD gatehouse/MS gatekeeper/SM gate/MGDS gatepost/SM Gates gateway/MS gathered/IA gatherer/M gathering/M gather/JRDZGS gathers/A Gatlinburg/M Gatling/M Gatorade/M gator/MS Gatsby/M Gatun/M gaucheness/SM gaucherie/SM gauche/TYPR gaucho/SM gaudily gaudiness/MS gaudy/PRST gaugeable gauger/M Gauguin/M Gaulish/M Gaulle/M Gaul/MS Gaultiero/M gauntlet/GSDM Gauntley/M gauntness/MS gaunt/PYRDSGT gauss/C gausses Gaussian Gauss/M gauss's Gautama/M Gauthier/M Gautier/M gauze/SDGM gauziness/MS gauzy/TRP Gavan/M gave gavel/GMDS Gaven/M Gavin/M Gav/MN gavotte/MSDG Gavra/M Gavrielle/M Gawain/M Gawen/M gawkily gawkiness/MS gawk/SGRDM gawky/RSPT Gayel/M Gayelord/M Gaye/M gayety's Gayla/M Gayleen/M Gaylene/M Gayler/M Gayle/RM Gaylord/M Gaylor/M Gay/M gayness/SM Gaynor/M gay/RTPS Gaza/M gazebo/SM gaze/DRSZG gazelle/MS gazer/M gazetteer/SGDM gazette/MGSD Gaziantep/M gazillion/S gazpacho/MS GB G/B Gdansk/M Gd/M GDP Gearalt/M Gearard/M gearbox/SM gear/DMJSG gearing/M gearshift/MS gearstick gearwheel/SM Geary/M gecko/MS GED geegaw's geeing geek/SM geeky/RT geese/M geest/M gee/TDS geezer/MS Gehenna/M Gehrig/M Geiger/M Geigy/M geisha/M gelatinousness/M gelatinous/PY gelatin/SM gelcap gelding/M geld/JSGD gelid gelignite/MS gelled gelling gel/MBS Gelya/M Ge/M GE/M Gemini/SM gemlike Gemma/M gemmed gemming gem/MS gemological gemologist/MS gemology/MS gemstone/SM gen Gena/M Genaro/M gendarme/MS gender/DMGS genderless genealogical/Y genealogist/SM genealogy/MS Gene/M gene/MS generalissimo/SM generalist/MS generality/MS generalizable/SM generalization/MS generalized/U generalize/GZBSRD generalizer/M general/MSPY generalness/M generalship/SM genera/M generate/CXAVNGSD generational generation/MCA generative/AY generators/A generator/SM generically generic/PS generosity/MS generously/U generousness/SM generous/PY Genesco/M genesis/M Genesis/M genes/S genetically geneticist/MS genetic/S genetics/M Genet/M Geneva/M Genevieve/M Genevra/M Genghis/M geniality/FMS genially/F genialness/M genial/PY Genia/M genies/K genie/SM genii/M genitalia genitals genital/YF genitive/SM genitourinary genius/SM Gen/M Genna/M Gennie/M Gennifer/M Genni/M Genny/M Genoa/SM genocidal genocide/SM Geno/M genome/SM genotype/MS Genovera/M genre/MS gent/AMS genteelness/MS genteel/PRYT gentian/SM gentile/S Gentile's gentility/MS gentlefolk/S gentlemanliness/M gentlemanly/U gentleman/YM gentlemen gentleness/SM gentle/PRSDGT gentlewoman/M gentlewomen/M gently gentrification/M gentrify/NSDGX Gentry/M gentry/MS genuflect/GDS genuflection/MS genuineness/SM genuine/PY genus Genvieve/M geocentric geocentrically geocentricism geochemical/Y geochemistry/MS geochronology/M geodesic/S geode/SM geodesy/MS geodetic/S Geoff/M Geoffrey/M Geoffry/M geog geographer/MS geographic geographical/Y geography/MS geologic geological/Y geologist/MS geology/MS geom Geo/M geomagnetic geomagnetically geomagnetism/SM geometer/MS geometrical/Y geometrician/M geometric/S geometry/MS geomorphological geomorphology/M geophysical/Y geophysicist/MS geophysics/M geopolitical/Y geopolitic/S geopolitics/M Georas/M Geordie/M Georgeanna/M Georgeanne/M Georgena/M George/SM Georgeta/M Georgetown/M Georgetta/M Georgette/M Georgia/M Georgiana/M Georgianna/M Georgianne/M Georgian/S Georgie/M Georgi/M Georgina/M Georgine/M Georg/M Georgy/M geostationary geosynchronous geosyncline/SM geothermal geothermic Geralda/M Geraldine/M Gerald/M geranium/SM Gerard/M Gerardo/M Gerber/M gerbil/MS Gerda/M Gerek/M Gerhardine/M Gerhard/M Gerhardt/M Gerianna/M Gerianne/M geriatric/S geriatrics/M Gerick/M Gerik/M Geri/M Geritol/M Gerladina/M Ger/M Germaine/M Germain/M Germana/M germane Germania/M Germanic/M germanium/SM germanized German/SM Germantown/M Germany/M Germayne/M germen/M germicidal germicide/MS germinal/Y germinated/U germinate/XVGNSD germination/M germinative/Y germ/MNS Gerome/M Geronimo/M gerontocracy/M gerontological gerontologist/SM gerontology/SM Gerrard/M Gerrie/M Gerrilee/M Gerri/M Gerry/M gerrymander/SGD Gershwin/MS Gerta/M Gertie/M Gerti/M Gert/M Gertruda/M Gertrude/M Gertrudis/M Gertrud/M Gerty/M gerundive/M gerund/SVM Gery/M gestalt/M gestapo/S Gestapo/SM gestate/SDGNX gestational gestation/M gesticulate/XSDVGN gesticulation/M gesticulative/Y gestural gesture/SDMG gesundheit getaway/SM Gethsemane/M get/S getter/SDM getting Getty/M Gettysburg/M getup/MS gewgaw/MS Gewrztraminer geyser/GDMS Ghanaian/MS Ghana/M Ghanian's ghastliness/MS ghastly/TPR ghat/MS Ghats/M Ghent/M Gherardo/M gherkin/SM ghetto/DGMS ghettoize/SDG Ghibelline/M ghostlike ghostliness/MS ghostly/TRP ghost/SMYDG ghostwrite/RSGZ ghostwritten ghostwrote ghoulishness/SM ghoulish/PY ghoul/SM GHQ GI Giacinta/M Giacobo/M Giacometti/M Giacomo/M Giacopo/M Giana/M Gianina/M Gian/M Gianna/M Gianni/M Giannini/M giantess/MS giantkiller giant/SM Giauque/M Giavani/M gibber/DGS gibberish/MS gibbet/MDSG Gibbie/M Gibb/MS Gibbon/M gibbon/MS gibbousness/M gibbous/YP Gibby/M gibe/GDRS giber/M giblet/MS Gib/M Gibraltar/MS Gibson/M giddap giddily giddiness/SM Giddings/M giddy/GPRSDT Gide/M Gideon/MS Gielgud/M Gienah/M Giffard/M Giffer/M Giffie/M Gifford/M Giff/RM Giffy/M giftedness/M gifted/PY gift/SGMD gigabyte/S gigacycle/MS gigahertz/M gigantically giganticness/M gigantic/P gigavolt gigawatt/M gigged gigging giggler/M giggle/RSDGZ giggling/Y giggly/TR Gigi/M gig/MS GIGO gigolo/MS gila Gila/M Gilberta/M Gilberte/M Gilbertina/M Gilbertine/M gilbert/M Gilbert/M Gilberto/M Gilbertson/M Gilburt/M Gilchrist/M Gilda/M gilder/M gilding/M gild/JSGZRD Gilead/M Gilemette/M Giles Gilgamesh/M Gilkson/M Gillan/M Gilles Gillespie/M Gillette/M Gilliam/M Gillian/M Gillie/M Gilligan/M Gilli/M Gill/M gill/SGMRD Gilly/M Gilmore/M Gil/MY gilt/S gimbaled gimbals Gimbel/M gimcrackery/SM gimcrack/S gimlet/MDSG gimme/S gimmick/GDMS gimmickry/MS gimmicky gimp/GSMD gimpy/RT Gina/M Ginelle/M Ginevra/M gingerbread/SM gingerliness/M gingerly/P Ginger/M ginger/SGDYM gingersnap/SM gingery gingham/SM gingivitis/SM Gingrich/M ginkgoes ginkgo/M ginmill gin/MS ginned Ginnie/M Ginnifer/M Ginni/M ginning Ginny/M Gino/M Ginsberg/M Ginsburg/M ginseng/SM Gioconda/M Giordano/M Giorgia/M Giorgi/M Giorgio/M Giorgione/M Giotto/M Giovanna/M Giovanni/M Gipsy's giraffe/MS Giralda/M Giraldo/M Giraud/M Giraudoux/M girded/U girder/M girdle/GMRSD girdler/M gird/RDSGZ girlfriend/MS girlhood/SM girlie/M girlishness/SM girlish/YP girl/MS giro/M girt/GDS girth/MDG girths Gisela/M Giselbert/M Gisele/M Gisella/M Giselle/M Gish/M gist/MS git/M Giuditta/M Giulia/M Giuliano/M Giulietta/M Giulio/M Giuseppe/M Giustina/M Giustino/M Giusto/M giveaway/SM giveback/S give/HZGRS given/SP giver/M giving/Y Giza/M Gizela/M gizmo's gizzard/SM Gk/M glac/DGS glacial/Y glaciate/XNGDS glaciation/M glacier/SM glaciological glaciologist/M glaciology/M gladded gladden/GDS gladder gladdest gladding gladdy glade/SM gladiatorial gladiator/SM Gladi/M gladiola/MS gladioli gladiolus/M gladly/RT Glad/M gladness/MS gladsome/RT Gladstone/MS Gladys glad/YSP glamor/DMGS glamorization/MS glamorizer/M glamorize/SRDZG glamorousness/M glamorous/PY glance/GJSD glancing/Y glanders/M glandes glandular/Y gland/ZSM glans/M glare/SDG glaringness/M glaring/YP Glaser/M Glasgow/M glasnost/S glassblower/S glassblowing/MS glassful/MS glass/GSDM glasshouse/SM glassily glassiness/SM glassless Glass/M glassware/SM glasswort/M glassy/PRST Glastonbury/M Glaswegian/S glaucoma/SM glaucous glazed/U glazer/M glaze/SRDGZJ glazier/SM glazing/M gleam/MDGS gleaner/M gleaning/M glean/RDGZJS Gleason/M Gleda/M gleed/M glee/DSM gleefulness/MS gleeful/YP gleeing Glendale/M Glenda/M Glenden/M Glendon/M Glenine/M Glen/M Glenna/M Glennie/M Glennis/M Glenn/M glen/SM glibber glibbest glibness/MS glib/YP glide/JGZSRD glider/M glim/M glimmer/DSJG glimmering/M glimpse/DRSZMG glimpser/M glint/DSG glissandi glissando/M glisten/DSG glister/DGS glitch/MS glitter/GDSJ glittering/Y glittery glitz/GSD glitzy/TR gloaming/MS gloater/M gloating/Y gloat/SRDG globalism/S globalist/S global/SY globe/SM globetrotter/MS glob/GDMS globularity/M globularness/M globular/PY globule/MS globulin/MS glockenspiel/SM glommed gloom/GSMD gloomily gloominess/MS gloomy/RTP glop/MS glopped glopping gloppy/TR Gloria/M Gloriana/M Gloriane/M glorification/M glorifier/M glorify/XZRSDNG Glori/M glorious/IYP gloriousness/IM Glory/M glory/SDMG glossary/MS gloss/GSDM glossily glossiness/SM glossolalia/SM glossy/RSPT glottal glottalization/M glottis/MS Gloucester/M gloveless glover/M Glover/M glove/SRDGMZ glower/GD glow/GZRDMS glowing/Y glowworm/SM glucose/SM glue/DRSMZG glued/U gluer/M gluey gluier gluiest glummer glummest glumness/MS glum/SYP gluon/M glutamate/M gluten/M glutenous glutinousness/M glutinous/PY glut/SMNX glutted glutting glutton/MS gluttonous/Y gluttony/SM glyceride/M glycerinate/MD glycerine's glycerin/SM glycerolized/C glycerol/SM glycine/M glycogen/SM glycol/MS Glynda/M Glynis/M Glyn/M Glynnis/M Glynn/M glyph/M glyphs gm GM GMT gnarl/SMDG gnash/SDG gnat/MS gnawer/M gnaw/GRDSJ gnawing/M gneiss/SM Gnni/M gnomelike GNOME/M gnome/SM gnomic gnomish gnomonic gnosticism Gnosticism/M gnostic/K Gnostic/M GNP gnu/MS goad/MDSG goalie/SM goalkeeper/MS goalkeeping/M goalless goal/MDSG goalmouth/M goalpost/S goalscorer goalscoring goaltender/SM Goa/M goatee/SM goatherd/MS goat/MS goatskin/SM gobbed gobbet/MS gobbing gobbledegook's gobbledygook/S gobbler/M gobble/SRDGZ Gobi/M goblet/MS goblin/SM gob/SM Godard/M Godart/M godchild/M godchildren goddammit goddamn/GS Goddard/M Goddart/M goddaughter/SM godded goddess/MS godding Gdel/M godfather/GSDM godforsaken Godfree/M Godfrey/M Godfry/M godhead/S godhood/SM Godiva/M godlessness/MS godless/P godlikeness/M godlike/P godliness/UMS godly/UTPR God/M godmother/MS Godot/M godparent/SM godsend/MS god/SMY godson/MS Godspeed/S Godthaab/M Godunov/M Godwin/M Godzilla/M Goebbels/M Goering/M goer/MG goes Goethals/M Goethe/M gofer/SM Goff/M goggler/M goggle/SRDGZ Gogh/M Gog/M Gogol/M Goiania/M going/M goiter/SM Golan/M Golconda/M Golda/M Goldarina/M Goldberg/M goldbricker/M goldbrick/GZRDMS Golden/M goldenness/M goldenrod/SM goldenseal/M golden/TRYP goldfinch/MS goldfish/SM Goldia/M Goldie/M Goldilocks/M Goldi/M Goldina/M Golding/M Goldman/M goldmine/S gold/MRNGTS goldsmith/M Goldsmith/M goldsmiths Goldstein/M Goldwater/M Goldwyn/M Goldy/M Goleta/M golfer/M golf/RDMGZS Golgotha/M Goliath/M Goliaths golly/S Gomez/M Gomorrah/M Gompers/M go/MRHZGJ gonadal gonad/SM gondola/SM gondolier/MS Gondwanaland/M goner/M gone/RZN gong/SGDM gonion/M gonna gonorrheal gonorrhea/MS Gonzales/M Gonzalez/M Gonzalo/M Goober/M goober/MS goodbye/MS goodhearted goodie's goodish goodly/TR Good/M Goodman/M goodness/MS goodnight Goodrich/M good/SYP goodwill/MS Goodwin/M Goodyear/M goody/SM gooey goofiness/MS goof/SDMG goofy/RPT Google/M gooier gooiest gook/SM goo/MS goon/SM goop/SM gooseberry/MS goosebumps goose/M goos/SDG GOP Gopher gopher/SM Goran/M Goraud/M Gorbachev Gordan/M Gorden/M Gordian/M Gordie/M Gordimer/M Gordon/M Gordy/M gore/DSMG Gore/M Goren/M Gorey/M Gorgas gorged/E gorge/GMSRD gorgeousness/SM gorgeous/YP gorger/EM gorges/E gorging/E Gorgon/M gorgon/S Gorgonzola/M Gorham/M gorilla/MS gorily goriness/MS goring/M Gorky/M gormandizer/M gormandize/SRDGZ gormless gorp/S gorse/SM gory/PRT gos goshawk/MS gosh/S gosling/M gospeler/M gospel/MRSZ Gospel/SM gossamer/SM gossipy gossip/ZGMRDS gotcha/SM Gteborg/M Gotham/M Gothart/M Gothicism/M Gothic/S Goth/M Goths got/IU goto GOTO/MS gotta gotten/U Gottfried/M Goucher/M Gouda/SM gouge/GZSRD gouger/M goulash/SM Gould/M Gounod/M gourde/SM gourd/MS gourmand/MS gourmet/MS gout/SM gouty/RT governable/U governance/SM governed/U governess/SM govern/LBGSD governmental/Y government/MS Governor governor/MS governorship/SM gov/S govt gown/GSDM Goya/M GP GPA GPO GPSS gr grabbed grabber/SM grabbing/S grab/S Gracchus/M grace/ESDMG graceful/EYPU gracefuller gracefullest gracefulness/ESM Graceland/M gracelessness/MS graceless/PY Grace/M Gracia/M Graciela/M Gracie/M graciousness/SM gracious/UY grackle/SM gradate/DSNGX gradation/MCS grade/ACSDG graded/U Gradeigh/M gradely grader/MC grade's Gradey/M gradient/RMS grad/MRDGZJS gradualism/MS gradualist/MS gradualness/MS gradual/SYP graduand/SM graduate/MNGDSX graduation/M Grady/M Graehme/M Graeme/M Graffias/M graffiti graffito/M Graff/M grafter/M grafting/M graft/MRDSGZ Grafton/M Grahame/M Graham/M graham/SM Graig/M grail/S Grail/SM grainer/M grain/IGSD graininess/MS graining/M grain's grainy/RTP gram/KSM Gram/M grammarian/SM grammar/MS grammaticality/M grammaticalness/M grammatical/UY grammatic/K gramme/SM Grammy/S gramophone/SM Grampians grampus/SM Granada/M granary/MS grandam/SM grandaunt/MS grandchild/M grandchildren granddaddy/MS granddad/SM granddaughter/MS grandee/SM grandeur/MS grandfather/MYDSG grandiloquence/SM grandiloquent/Y grandiose/YP grandiosity/MS grandkid/SM grandma/MS grandmaster/MS grandmother/MYS grandnephew/MS grandness/MS grandniece/SM grandpa/MS grandparent/MS grandson/MS grandstander/M grandstand/SRDMG grand/TPSYR granduncle/MS Grange/MR grange/MSR Granger/M granite/MS granitic Gran/M Grannie/M Granny/M granny/MS granola/S grantee/MS granter/M Grantham/M Granthem/M Grantley/M Grant/M grantor's grant/SGZMRD grantsmanship/S granularity/SM granular/Y granulate/SDXVGN granulation/M granule/SM granulocytic Granville/M grapefruit/SM grape/SDGM grapeshot/M grapevine/MS grapheme/M graph/GMD graphical/Y graphicness/M graphic/PS graphics/M graphite/SM graphologist/SM graphology/MS graphs grapnel/SM grapple/DRSG grappler/M grappling/M grasper/M graspingness/M grasping/PY grasp/SRDBG grass/GZSDM grasshopper/SM grassland/MS Grass/M grassroots grassy/RT Grata/M gratefuller gratefullest gratefulness/USM grateful/YPU grater/M grates/I grate/SRDJGZ Gratia/M Gratiana/M graticule/M gratification/M gratified/U gratifying/Y gratify/NDSXG grating/YM gratis gratitude/IMS gratuitousness/MS gratuitous/PY gratuity/SM gravamen/SM gravedigger/SM gravel/SGMYD graven graveness/MS graver/M graveside/S Graves/M grave/SRDPGMZTY gravestone/SM graveyard/MS gravidness/M gravid/PY gravimeter/SM gravimetric gravitas gravitate/XVGNSD gravitational/Y gravitation/M graviton/SM gravity/MS gravy/SM graybeard/MS Grayce/M grayish Gray/M grayness/S gray/PYRDGTS Grayson/M graze/GZSRD grazer/M Grazia/M grazing/M grease/GMZSRD greasepaint/MS greaseproof greaser/M greasily greasiness/SM greasy/PRT greatcoat/DMS greaten/DG greathearted greatness/MS great/SPTYRN grebe/MS Grecian/S Greece/M greed/C greedily greediness/SM greeds greed's greedy/RTP Greek/SM Greeley/M greenback/MS greenbelt/S Greenberg/M Greenblatt/M Greenbriar/M Greene/M greenery/MS Greenfeld/M greenfield Greenfield/M greenfly/M greengage/SM greengrocer/SM greengrocery/M greenhorn/SM greenhouse/SM greening/M greenish/P Greenland/M Green/M greenmail/GDS greenness/MS Greenpeace/M greenroom/SM Greensboro/M Greensleeves/M Greensville/M greensward/SM green/SYRDMPGT Greentree/M Greenville/M Greenwich/M greenwood/MS Greer/M greeter/M greeting/M greets/A greet/SRDJGZ gregariousness/MS gregarious/PY Gregg/M Greggory/M Greg/M Gregoire/M Gregoor/M Gregorian Gregorio/M Gregorius/M Gregor/M Gregory/M gremlin/SM Grenada/M grenade/MS Grenadian/S grenadier/SM Grenadines grenadine/SM Grendel/M Grenier/M Grenoble/M Grenville/M Gresham/M Gretal/M Greta/M Gretchen/M Gretel/M Grete/M Grethel/M Gretna/M Gretta/M Gretzky/M grew/A greybeard/M greyhound/MS Grey/M greyness/M gridded griddlecake/SM griddle/DSGM gridiron/GSMD gridlock/DSG grids/A grid/SGM grief/MS Grieg/M Grier/M grievance/SM griever/M grieve/SRDGZ grieving/Y grievousness/SM grievous/PY Griffie/M Griffin/M griffin/SM Griffith/M Griff/M griffon's Griffy/M griller/M grille/SM grill/RDGS grillwork/M grimace/DRSGM grimacer/M Grimaldi/M grime/MS Grimes griminess/MS grimmer grimmest Grimm/M grimness/MS grim/PGYD grimy/TPR Grinch/M grind/ASG grinder/MS grinding/SY grindstone/SM gringo/SM grinned grinner/M grinning/Y grin/S griper/M gripe/S grippe/GMZSRD gripper/M gripping/Y grip/SGZMRD Griselda/M grisliness/SM grisly/RPT Gris/M Grissel/M gristle/SM gristliness/M gristly/TRP gristmill/MS grist/MYS Griswold/M grit/MS gritted gritter/MS grittiness/SM gritting gritty/PRT Griz/M grizzle/DSG grizzling/M grizzly/TRS Gr/M groaner/M groan/GZSRDM groat/SM grocer/MS grocery/MS groggily grogginess/SM groggy/RPT grog/MS groin/MGSD grokked grokking grok/S grommet/GMDS Gromyko/M groofs groomer/M groom/GZSMRD groomsman/M groomsmen Groot/M groover/M groove/SRDGM groovy/TR groper/M grope/SRDJGZ Gropius/M grosbeak/SM grosgrain/MS Gross Grosset/M gross/GTYSRDP Grossman/M grossness/MS Grosvenor/M Grosz/M grotesqueness/MS grotesque/PSY Grotius/M Groton/M grottoes grotto/M grouch/GDS grouchily grouchiness/MS grouchy/RPT groundbreaking/S grounded/U grounder/M groundhog/SM ground/JGZMDRS groundlessness/M groundless/YP groundnut/MS groundsheet/M groundskeepers groundsman/M groundswell/S groundwater/S groundwork/SM grouped/A grouper/M groupie/MS grouping/M groups/A group/ZJSMRDG grouse/GMZSRD grouser/M grouter/M grout/GSMRD groveler/M grovelike groveling/Y grovel/SDRGZ Grover/M Grove/RM grove/SRMZ grower/M grow/GZYRHS growing/I growingly growler/M growling/Y growl/RDGZS growly/RP grown/IA grownup/MS grows/A growth/IMA growths/IA grubbed grubber/SM grubbily grubbiness/SM grubbing grubby/RTP grub/MS grubstake/MSDG grudge/GMSRDJ grudger/M grudging/Y grueling/Y gruel/MDGJS gruesomeness/SM gruesome/RYTP gruffness/MS gruff/PSGTYRD grumble/GZJDSR grumbler/M grumbling/Y Grumman/M grumpily grumpiness/MS grump/MDGS grumpy/TPR Grundy/M Grnewald/M grunge/S grungy/RT grunion/SM grunter/M grunt/SGRD Grusky/M Grus/M Gruyre Gruyeres gryphon's g's G's gs/A GSA gt GU guacamole/MS Guadalajara/M Guadalcanal/M Guadalquivir/M Guadalupe/M Guadeloupe/M Guallatiri/M Gualterio/M Guamanian/SM Guam/M Guangzhou guanine/MS guano/MS Guantanamo/M Guarani/M guarani/SM guaranteeing guarantee/RSDZM guarantor/SM guaranty/MSDG guardedness/UM guarded/UYP guarder/M guardhouse/SM Guardia/M guardianship/MS guardian/SM guardrail/SM guard/RDSGZ guardroom/SM guardsman/M guardsmen Guarnieri/M Guatemala/M Guatemalan/S guava/SM Guayaquil/M gubernatorial Gucci/M gudgeon/M Guelph/M Guendolen/M Guenevere/M Guenna/M Guenther/M guernsey/S Guernsey/SM Guerra/M Guerrero/M guerrilla/MS guessable/U guess/BGZRSD guessed/U guesser/M guesstimate/DSMG guesswork/MS guest/SGMD Guevara/M guffaw/GSDM guff/SM Guggenheim/M Guglielma/M Guglielmo/M Guhleman/M GUI Guiana/M guidance/MS guidebook/SM guided/U guide/GZSRD guideline/SM guidepost/MS guider/M Guido/M Guilbert/M guilder/M guildhall/SM guild/SZMR guileful guilelessness/MS guileless/YP guile/SDGM Guillaume/M Guillema/M Guillemette/M guillemot/MS Guillermo/M guillotine/SDGM guiltily guiltiness/MS guiltlessness/M guiltless/YP guilt/SM guilty/PTR Gui/M Guinea/M Guinean/S guinea/SM Guinevere/M Guinna/M Guinness/M guise's guise/SDEG guitarist/SM guitar/SM Guiyang Guizot/M Gujarati/M Gujarat/M Gujranwala/M gulag/S gulch/MS gulden/MS gulf/DMGS Gullah/M gullet/MS gulley's gullibility/MS gullible Gulliver/M gull/MDSG gully/SDMG gulp/RDGZS gumboil/MS gumbo/MS gumboots gumdrop/SM gummed gumminess/M gumming/C gum/MS gummy/RTP gumption/SM gumshoeing gumshoe/SDM gumtree/MS Gunar/M gunboat/MS Gunderson/M gunfighter/M gunfight/SRMGZ gunfire/SM gunflint/M gunfought Gunilla/M gunk/SM gunky/RT Gun/M gunman/M gunmen gunmetal/MS gun/MS Gunnar/M gunned gunnel's Gunner/M gunner/SM gunnery/MS gunning/M gunnysack/SM gunny/SM gunpoint/MS gunpowder/SM gunrunner/MS gunrunning/MS gunship/S gunshot/SM gunslinger/M gunsling/GZR gunsmith/M gunsmiths Guntar/M Gunter/M Gunther/M gunwale/MS Guofeng/M guppy/SM Gupta/M gurgle/SDG Gurkha/M gurney/S guru/MS Gusella/M gusher/M gush/SRDGZ gushy/TR Gus/M Guss gusset/MDSG Gussie/M Gussi/M gussy/GSD Gussy/M Gustaf/M Gustafson/M Gusta/M gustatory Gustave/M Gustav/M Gustavo/M Gustavus/M gusted/E Gustie/M gustily Gusti/M gustiness/M gusting/E gust/MDGS gustoes gusto/M gusts/E Gusty/M gusty/RPT Gutenberg/M Guthrey/M Guthrie/M Guthry/M Gutierrez/M gutlessness/S gutless/P gutser/M gutsiness/M gut/SM guts/R gutsy/PTR gutted gutter/GSDM guttering/M guttersnipe/M gutting gutturalness/M guttural/SPY gutty/RSMT Guyana/M Guyanese Guy/M guy/MDRZGS Guzman/M guzzle/GZRSD guzzler/M g/VBX Gwalior/M Gwendolen/M Gwendoline/M Gwendolin/M Gwendolyn/M Gweneth/M Gwenette/M Gwen/M Gwenneth/M Gwennie/M Gwenni/M Gwenny/M Gwenora/M Gwenore/M Gwyneth/M Gwyn/M Gwynne/M gymkhana/SM gym/MS gymnasia's gymnasium/SM gymnastically gymnastic/S gymnastics/M gymnast/SM gymnosperm/SM gynecologic gynecological/MS gynecologist/SM gynecology/MS gypped gypper/S gypping gyp/S gypsite gypster/S gypsum/MS gypsy/SDMG Gypsy/SM gyrate/XNGSD gyration/M gyrator/MS gyrfalcon/SM gyrocompass/M gyro/MS gyroscope/SM gyroscopic gyve/GDS H Haag/M Haas/M Habakkuk/M habeas haberdasher/SM haberdashery/SM Haber/M Haberman/M Habib/M habiliment/SM habitability/MS habitableness/M habitable/P habitant/ISM habitation/MI habitations habitat/MS habit/IBDGS habit's habitualness/SM habitual/SYP habituate/SDNGX habituation/M habitu/MS hacienda/MS hacker/M Hackett/M hack/GZSDRBJ hackler/M hackle/RSDMG hackney/SMDG hacksaw/SDMG hackwork/S Hadamard/M Hadar/M Haddad/M haddock/MS hades Hades had/GD hadji's hadj's Hadlee/M Hadleigh/M Hadley/M Had/M hadn't Hadria/M Hadrian/M hadron/MS hadst haemoglobin's haemophilia's haemorrhage's Hafiz/M hafnium/MS haft/GSMD Hagan/M Hagar/M Hagen/M Hager/M Haggai/M haggardness/MS haggard/SYP hagged hagging haggish haggis/SM haggler/M haggle/RSDZG Hagiographa/M hagiographer/SM hagiography/MS hag/SMN Hagstrom/M Hague/M ha/H hahnium/S Hahn/M Haifa/M haiku/M Hailee/M hailer/M Hailey/M hail/SGMDR hailstone/SM hailstorm/SM Haily/M Haiphong/M hairball/SM hairbreadth/M hairbreadths hairbrush/SM haircare haircloth/M haircloths haircut/MS haircutting hairdo/SM hairdresser/SM hairdressing/SM hairdryer/S hairiness/MS hairlessness/M hairless/P hairlike hairline/SM hairnet/MS hairpiece/MS hairpin/MS hairsbreadth hairsbreadths hair/SDM hairsplitter/SM hairsplitting/MS hairspray hairspring/SM hairstyle/SMG hairstylist/S hairy/PTR Haitian/S Haiti/M hajjes hajji/MS hajj/M Hakeem/M hake/MS Hakim/M Hakka/M Hakluyt/M halalled halalling halal/S halberd/SM halcyon/S Haldane/M Haleakala/M Haleigh/M hale/ISRDG Hale/M haler/IM halest Halette/M Haley/M halfback/SM halfbreed halfheartedness/MS halfhearted/PY halfpence/S halfpenny/MS halfpennyworth half/PM halftime/S halftone/MS halfway halfword/MS halibut/SM halide/SM Halie/M Halifax/M Hali/M Halimeda/M halite/MS halitoses halitosis/M hallelujah hallelujahs Halley/M halliard's Hallie/M Halli/M Hallinan/M Hall/M Hallmark/M hallmark/SGMD hallo/GDS halloo's Halloween/MS hallowing hallows hallow/UD hall/SMR Hallsy/M hallucinate/VNGSDX hallucination/M hallucinatory hallucinogenic/S hallucinogen/SM hallway/SM Hally/M halocarbon halogenated halogen/SM halon halo/SDMG Halpern/M Halsey/M Hal/SMY Halsy/M halter/GDM halt/GZJSMDR halting/Y halve/GZDS halves/M halyard/MS Ha/M Hamal/M Haman/M hamburger/M Hamburg/MS hamburg/SZRM Hamel/M Hamey/M Hamhung/M Hamid/M Hamilcar/M Hamil/M Hamiltonian/MS Hamilton/M Hamish/M Hamitic/M Hamlen/M Hamlet/M hamlet/MS Hamlin/M Ham/M Hammad/M Hammarskjold/M hammed hammerer/M hammerhead/SM hammering/M hammerless hammerlock/MS Hammerstein/M hammertoe/SM hammer/ZGSRDM Hammett/M hamming hammock/MS Hammond/M Hammurabi/M hammy/RT Hamnet/M hampered/U hamper/GSD Hampshire/M Hampton/M ham/SM hamster/MS hamstring/MGS hamstrung Hamsun/M Hana/M Hanan/M Hancock/M handbagged handbagging handbag/MS handball/SM handbarrow/MS handbasin handbill/MS handbook/SM handbrake/M handcar/SM handcart/MS handclasp/MS handcraft/GMDS handcuff/GSD handcuffs/M handedness/M handed/PY Handel/M hander/S handful/SM handgun/SM handhold/M handicapped handicapper/SM handicapping handicap/SM handicraftsman/M handicraftsmen handicraft/SMR handily/U handiness/SM handiwork/MS handkerchief/MS handleable handlebar/SM handle/MZGRSD handler/M handless handling/M handmade handmaiden/M handmaid/NMSX handout/SM handover handpick/GDS handrail/SM hand's handsaw/SM handset/SM handshake/GMSR handshaker/M handshaking/M handsomely/U handsomeness/MS handsome/RPTY handspike/SM handspring/SM handstand/MS hand/UDSG handwork/SM handwoven handwrite/GSJ handwriting/M handwritten Handy/M handyman/M handymen handy/URT Haney/M hangar/SGDM hangdog/S hanged/A hanger/M hang/GDRZBSJ hanging/M hangman/M hangmen hangnail/MS hangout/MS hangover/SM hangs/A Hangul/M hangup/S Hangzhou Hankel/M hankerer/M hanker/GRDJ hankering/M hank/GZDRMS hankie/SM Hank/M hanky's Hannah/M Hanna/M Hannibal/M Hannie/M Hanni/MS Hanny/M Hanoi/M Hanoverian Hanover/M Hansel/M Hansen/M Hansiain/M Han/SM Hans/N hansom/MS Hanson/M Hanuka/S Hanukkah/M Hanukkahs Hapgood/M haphazardness/SM haphazard/SPY haplessness/MS hapless/YP haploid/S happed happening/M happen/JDGS happenstance/SM happily/U happiness/UMS happing Happy/M happy/UTPR Hapsburg/M hap/SMY Harald/M harangue/GDRS haranguer/M Harare harasser/M harass/LSRDZG harassment/SM Harbert/M harbinger/DMSG Harbin/M harborer/M harbor/ZGRDMS Harcourt/M hardback/SM hardball/SM hardboard/SM hardboiled hardbound hardcore/MS hardcover/SM hardened/U hardener/M hardening/M harden/ZGRD hardhat/S hardheadedness/SM hardheaded/YP hardheartedness/SM hardhearted/YP hardihood/MS hardily hardiness/SM Harding/M Hardin/M hardliner/S hardness/MS hardscrabble hardshell hardship/MS hardstand/S hardtack/MS hardtop/MS hardware/SM hardwire/DSG hardwood/MS hardworking Hardy/M hard/YNRPJGXTS hardy/PTRS harebell/MS harebrained harelip/MS harelipped hare/MGDS harem/SM Hargreaves/M hark/GDS Harland/M Harlan/M Harlem/M Harlene/M Harlen/M Harlequin harlequin/MS Harley/M Harlie/M Harli/M Harlin/M harlotry/MS harlot/SM Harlow/M Harman/M harmed/U harmer/M harmfulness/MS harmful/PY harmlessness/SM harmless/YP harm/MDRGS Harmonia/M harmonically harmonica/MS harmonic/S harmonics/M Harmonie/M harmonious/IPY harmoniousness/MS harmoniousness's/I harmonium/MS harmonization/A harmonizations harmonization's harmonized/U harmonizer/M harmonizes/UA harmonize/ZGSRD Harmon/M harmony/EMS Harmony/M harness/DRSMG harnessed/U harnesser/M harnesses/U Harold/M Haroun/M harper/M Harper/M harping/M harpist/SM harp/MDRJGZS Harp/MR harpooner/M harpoon/SZGDRM harpsichordist/MS harpsichord/SM harpy/SM Harpy/SM Harrell/M harridan/SM Harrie/M harrier/M Harriet/M Harrietta/M Harriette/M Harriett/M Harrington/M Harriot/M Harriott/M Harrisburg/M Harri/SM Harrisonburg/M Harrison/M harrower/M harrow/RDMGS harrumph/SDG Harry/M harry/RSDGZ harshen/GD harshness/SM harsh/TRNYP Harte/M Hartford/M Hartley/M Hartline/M Hart/M Hartman/M hart/MS Hartwell/M Harvard/M harvested/U harvester/M harvestman/M harvest/MDRZGS Harvey/MS Harv/M Harwell/M Harwilll/M has Hasbro/M hash/AGSD Hasheem/M hasher/M Hashim/M hashing/M hashish/MS hash's Hasidim Haskell/M Haskel/M Haskins/M Haslett/M hasn't hasp/GMDS hassle/MGRSD hassock/MS haste/MS hastener/M hasten/GRD hast/GXJDN Hastie/M hastily hastiness/MS Hastings/M Hasty/M hasty/RPT hatchback/SM hatcheck/S hatched/U hatcher/M hatchery/MS hatchet/MDSG hatching/M hatch/RSDJG Hatchure/M hatchway/MS hatefulness/MS hateful/YP hater/M hate/S Hatfield/M Hathaway/M hatless hat/MDRSZG hatred/SM hatstands hatted Hatteras/M hatter/SM Hattie/M Hatti/M hatting Hatty/M hauberk/SM Haugen/M haughtily haughtiness/SM haughty/TPR haulage/MS hauler/M haul/SDRGZ haunch/GMSD haunter/M haunting/Y haunt/JRDSZG Hauptmann/M Hausa/M Hausdorff/M Hauser/M hauteur/MS Havana/SM Havarti Havel/M haven/DMGS Haven/M haven't haver/G haversack/SM have/ZGSR havocked havocking havoc/SM Haw Hawaiian/S Hawaii/M hawker/M hawk/GZSDRM Hawking hawking/M Hawkins/M hawkishness/S hawkish/P Hawley/M haw/MDSG hawser/M haws/RZ Hawthorne/M hawthorn/MS haycock/SM Hayden/M Haydn/M Haydon/M Hayes hayfield/MS hay/GSMDR Hayley/M hayloft/MS haymow/MS Haynes hayrick/MS hayride/MS hayseed/MS Hay/SM haystack/SM haywain Hayward/M haywire/MS Haywood/M Hayyim/M hazard/MDGS hazardousness/M hazardous/PY haze/DSRJMZG Hazel/M hazel/MS hazelnut/SM Haze/M hazer/M hazily haziness/MS hazing/M Hazlett/M Hazlitt/M hazy/PTR HBO/M hdqrs HDTV headache/MS headband/SM headboard/MS headcount headdress/MS header/M headfirst headgear/SM headhunter/M headhunting/M headhunt/ZGSRDMJ headily headiness/S heading/M headlamp/S headland/MS headlessness/M headless/P headlight/MS headline/DRSZMG headliner/M headlock/MS headlong Head/M headman/M headmaster/MS headmastership/M headmen headmistress/MS headphone/SM headpiece/SM headpin/MS headquarter/GDS headrest/MS headroom/SM headscarf/M headset/SM headship/SM headshrinker/MS head/SJGZMDR headsman/M headsmen headstall/SM headstand/MS headstock/M headstone/MS headstrong headwaiter/SM headwall/S headwater/S headway/MS headwind/SM headword/MS heady/PTR heal/DRHSGZ healed/U healer/M Heall/M healthfully healthfulness/SM healthful/U healthily/U healthiness/MSU health/M healths healthy/URPT heap/SMDG heard/UA hearer/M hearing/AM hearken/SGD hearsay/SM hearse/M hears/SDAG Hearst/M heartache/SM heartbeat/MS heartbreak/GMS heartbreaking/Y heartbroke heartbroken heartburning/M heartburn/SGM hearted/Y hearten/EGDS heartening/EY heartfelt hearth/M hearthrug hearths hearthstone/MS heartily heartiness/SM heartland/SM heartlessness/SM heartless/YP heartrending/Y heartsickness/MS heartsick/P heart/SMDNXG heartstrings heartthrob/MS heartwarming Heartwood/M heartwood/SM hearty/TRSP hear/ZTSRHJG heatedly heated/UA heater/M heathendom/SM heathenish/Y heathenism/MS heathen/M heather/M Heather/M heathery Heathkit/M heathland Heathman/M Heath/MR heath/MRNZX heaths heatproof heats/A heat/SMDRGZBJ heatstroke/MS heatwave heave/DSRGZ heavenliness/M heavenly/PTR heaven/SYM heavenward/S heaver/M heaves/M heavily heaviness/MS Heaviside/M heavyhearted heavyset heavy/TPRS heavyweight/SM Hebe/M hebephrenic Hebert/M Heb/M Hebraic Hebraism/MS Hebrew/SM Hebrides/M Hecate/M hecatomb/M heckler/M heckle/RSDZG heck/S hectare/MS hectically hectic/S hectogram/MS hectometer/SM Hector/M hector/SGD Hecuba/M he'd Heda/M Hedda/M Heddie/M Heddi/M hedge/DSRGMZ hedgehog/MS hedgehopped hedgehopping hedgehop/S hedger/M hedgerow/SM hedging/Y Hedi/M hedonism/SM hedonistic hedonist/MS Hedvige/M Hedvig/M Hedwiga/M Hedwig/M Hedy/M heeded/U heedfulness/M heedful/PY heeding/U heedlessness/SM heedless/YP heed/SMGD heehaw/DGS heeler/M heeling/M heelless heel/SGZMDR Heep/M Hefner/M heft/GSD heftily heftiness/SM hefty/TRP Hegelian Hegel/M hegemonic hegemony/MS Hegira/M hegira/S Heida/M Heidegger/M Heidelberg/M Heidie/M Heidi/M heifer/MS Heifetz/M heighten/GD height/SMNX Heimlich/M Heindrick/M Heineken/M Heine/M Heinlein/M heinousness/SM heinous/PY Heinrich/M Heinrick/M Heinrik/M Heinze/M Heinz/M heiress/MS heirloom/MS heir/SDMG Heisenberg/M Heiser/M heister/M heist/GSMRD Hejira's Helaina/M Helaine/M held Helena/M Helene/M Helenka/M Helen/M Helga/M Helge/M helical/Y helices/M helicon/M Helicon/M helicopter/GSMD heliocentric heliography/M Heliopolis/M Helios/M heliosphere heliotrope/SM heliport/MS helium/MS helix/M he'll hellbender/M hellbent hellcat/SM hellebore/SM Hellene/SM Hellenic Hellenism/MS Hellenistic Hellenist/MS Hellenization/M Hellenize heller/M Heller/M Hellespont/M hellfire/M hell/GSMDR hellhole/SM Helli/M hellion/SM hellishness/SM hellish/PY Hellman/M hello/GMS Hell's helluva helmed helmet/GSMD Helmholtz/M helming helms helm's helmsman/M helmsmen helm/U Helmut/M Hloise/M helot/S helper/M helpfulness/MS helpful/UY help/GZSJDR helping/M helplessness/SM helpless/YP helpline/S helpmate/SM helpmeet's Helsa/M Helsinki/M helve/GMDS Helvetian/S Helvetius/M Helyn/M He/M hematite/MS hematologic hematological hematologist/SM hematology/MS heme/MS Hemingway/M hemisphere/MSD hemispheric hemispherical hemline/SM hemlock/MS hemmed hemmer/SM hemming hem/MS hemoglobin/MS hemolytic hemophiliac/SM hemophilia/SM hemorrhage/GMDS hemorrhagic hemorrhoid/MS hemostat/SM hemp/MNS h/EMS hemstitch/DSMG henceforth henceforward hence/S Hench/M henchman/M henchmen Henderson/M Hendrick/SM Hendrickson/M Hendrika/M Hendrik/M Hendrix/M henge/M Henka/M Henley/M hen/MS henna/MDSG Hennessey/M henning henpeck/GSD Henrie/M Henrieta/M Henrietta/M Henriette/M Henrik/M Henri/M Henryetta/M henry/M Henry/M Hensley/M Henson/M heparin/MS hepatic/S hepatitides hepatitis/M Hepburn/M Hephaestus/M Hephzibah/M hepper heppest Hepplewhite hep/S heptagonal heptagon/SM heptane/M heptathlon/S her Heracles/M Heraclitus/M heralded/U heraldic herald/MDSG heraldry/MS Hera/M herbaceous herbage/MS herbalism herbalist/MS herbal/S Herbart/M Herbert/M herbicidal herbicide/MS Herbie/M herbivore/SM herbivorous/Y Herb/M herb/MS Herby/M Herc/M Herculaneum/M herculean Herculean Hercule/MS Herculie/M herder/M Herder/M herd/MDRGZS herdsman/M herdsmen hereabout/S hereafter/S hereby hereditary heredity/MS Hereford/SM herein hereinafter here/IS hereof hereon here's heres/M heresy/SM heretical heretic/SM hereto heretofore hereunder hereunto hereupon herewith Heriberto/M heritable heritage/MS heritor/IM Herkimer/M Herman/M Hermann/M hermaphrodite/SM hermaphroditic Hermaphroditus/M hermeneutic/S hermeneutics/M Hermes hermetical/Y hermetic/S Hermia/M Hermie/M Hermina/M Hermine/M Herminia/M Hermione/M hermitage/SM Hermite/M hermitian hermit/MS Hermon/M Hermosa/M Hermosillo/M Hermy/M Hernandez/M Hernando/M hernial hernia/MS herniate/NGXDS Herod/M Herodotus/M heroes heroically heroics heroic/U heroine/SM heroin/MS heroism/SM Herold/M hero/M heron/SM herpes/M herpetologist/SM herpetology/MS Herrera/M Herrick/M herringbone/SDGM Herring/M herring/SM Herrington/M Herr/MG Herschel/M Hersch/M herself Hersey/M Hershel/M Hershey/M Hersh/M Herta/M Hertha/M hertz/M Hertz/M Hertzog/M Hertzsprung/M Herve/M Hervey/M Herzegovina/M Herzl/M hes Hesiod/M hesitance/S hesitancy/SM hesitantly hesitant/U hesitater/M hesitate/XDRSNG hesitating/UY hesitation/M Hesperus/M Hesse/M Hessian/MS Hess/M Hester/M Hesther/M Hestia/M Heston/M heterodox heterodoxy/MS heterodyne heterogamous heterogamy/M heterogeneity/SM heterogeneousness/M heterogeneous/PY heterosexuality/SM heterosexual/YMS heterostructure heterozygous Hettie/M Hetti/M Hetty/M Heublein/M heuristically heuristic/SM Heusen/M Heuser/M he/VMZ hew/DRZGS Hewe/M hewer/M Hewet/M Hewett/M Hewie/M Hewitt/M Hewlett/M Hew/M hexachloride/M hexadecimal/YS hexafluoride/M hexagonal/Y hexagon/SM hexagram/SM hexameter/SM hex/DSRG hexer/M hey heyday/MS Heyerdahl/M Heywood/M Hezekiah/M hf HF Hf/M Hg/M hgt hgwy HHS HI Hialeah/M hiatus/SM Hiawatha/M hibachi/MS hibernate/XGNSD hibernation/M hibernator/SM Hibernia/M Hibernian/S hibiscus/MS hiccup/MDGS hickey/SM Hickey/SM Hickman/M Hickok/M hickory/MS hick/SM Hicks/M hi/D hidden/U hideaway/SM hidebound hideousness/SM hideous/YP hideout/MS hider/M hide/S hiding/M hid/ZDRGJ hieing hierarchal hierarchic hierarchical/Y hierarchy/SM hieratic hieroglyph hieroglyphic/S hieroglyphics/M hieroglyphs Hieronymus/M hie/S hifalutin Higashiosaka Higgins/M highball/GSDM highborn highboy/MS highbrow/SM highchair/SM highfalutin Highfield/M highhandedness/SM highhanded/PY highish Highlander/SM Highlands highland/ZSRM highlight/GZRDMS Highness/M highness/MS highpoint high/PYRT highroad/MS highs hight hightail/DGS highwayman/M highwaymen highway/MS hijacker/M hijack/JZRDGS hiker/M hike/ZGDSR Hilario/M hilariousness/MS hilarious/YP hilarity/MS Hilarius/M Hilary/M Hilbert/M Hildagarde/M Hildagard/M Hilda/M Hildebrand/M Hildegaard/M Hildegarde/M Hilde/M Hildy/M Hillard/M Hillary/M hillbilly/MS Hillcrest/M Hillel/M hiller/M Hillery/M hill/GSMDR Hilliard/M Hilliary/M Hillie/M Hillier/M hilliness/SM Hill/M hillman hillmen hillock/SM Hillsboro/M Hillsdale/M hillside/SM hilltop/MS hillwalking Hillyer/M Hilly/RM hilly/TRP hilt/MDGS Hilton/M Hi/M Himalaya/MS Himalayan/S Himmler/M him/S himself Hinayana/M Hinda/M Hindemith/M Hindenburg/M hindered/U hinderer/M hinder/GRD Hindi/M hindmost hindquarter/SM hindrance/SM hind/RSZ hindsight/SM Hinduism/SM Hindu/MS Hindustani/MS Hindustan/M Hines/M hinger hinge's hinge/UDSG Hinkle/M Hinsdale/M hinterland/MS hinter/M hint/GZMDRS Hinton/M Hinze/M hipbone/SM hipness/S Hipparchus/M hipped hipper hippest hippie/MTRS hipping/M Hippocrates/M Hippocratic hippodrome/MS hippo/MS hippopotamus/SM hip/PSM hippy's hipster/MS hiragana Hiram/M hire/AGSD hireling/SM hirer/SM Hirey/M hiring/S Hirohito/M Hiroshi/M Hiroshima/M Hirsch/M hirsuteness/MS hirsute/P his Hispanic/SM Hispaniola/M hiss/DSRMJG hisser/M hissing/M Hiss/M histamine/SM histidine/SM histochemic histochemical histochemistry/M histogram/MS histological histologist/MS histology/SM historian/MS historic historicalness/M historical/PY historicism/M historicist/M historicity/MS historiographer/SM historiography/MS history/MS histrionically histrionic/S histrionics/M hist/SDG Hitachi/M Hitchcock/M hitcher/MS hitchhike/RSDGZ hitch/UGSD hither hitherto Hitler/SM hitless hit/MS hittable hitter/SM hitting Hittite/SM HIV hive/MGDS h'm HM HMO Hmong HMS hoarder/M hoarding/M hoard/RDJZSGM hoarfrost/SM hoariness/MS hoar/M hoarseness/SM hoarse/RTYP hoary/TPR hoaxer/M hoax/GZMDSR Hobard/M Hobart/M hobbed Hobbes/M hobbing hobbit hobbler/M hobble/ZSRDG Hobbs/M hobbyhorse/SM hobbyist/SM hobby/SM Hobday/M Hobey/M hobgoblin/MS Hobie/M hobnail/GDMS hobnobbed hobnobbing hobnob/S Hoboken/M hobo/SDMG hob/SM hoc hocker/M hockey/SM hock/GDRMS Hockney/M hockshop/SM hodge/MS Hodge/MS hodgepodge/SM Hodgkin/M ho/DRYZ hod/SM Hoebart/M hoecake/SM hoedown/MS hoeing hoer/M hoe/SM Hoffa/M Hoff/M Hoffman/M Hofstadter/M Hogan/M hogan/SM Hogarth/M hogback/MS hogged hogger hogging hoggish/Y hogshead/SM hog/SM hogtie/SD hogtying hogwash/SM Hohenlohe/M Hohenstaufen/M Hohenzollern/M Hohhot/M hoister/M hoist/GRDS hoke/DSG hokey/PRT hokier hokiest Hokkaido/M hokum/MS Hokusai/M Holbein/M Holbrook/M Holcomb/M holdall/MS Holden/M holder/M Holder/M holding/IS holding's hold/NRBSJGZ holdout/SM holdover/SM holdup/MS hole/MGDS holey holiday/GRDMS Holiday/M holidaymaker/S holier/U Holiness/MS holiness/MSU holistic holistically hollandaise Hollandaise/M Hollander/M Holland/RMSZ holler/GDS Hollerith/M Holley/M Hollie/M Holli/SM Hollister/M Holloway/M hollowness/MS hollow/RDYTGSP hollowware/M Hollyanne/M hollyhock/MS Holly/M holly/SM Hollywood/M Holman/M Holmes holmium/MS Holm/M Holocaust holocaust/MS Holocene hologram/SM holograph/GMD holographic holographs holography/MS Holstein/MS holster/MDSG Holst/M Holt/M Holyoke/M holy/SRTP holystone/MS Holzman/M Ho/M homage/MGSRD homager/M hombre/SM homburg/SM homebody/MS homebound homeboy/S homebuilder/S homebuilding homebuilt homecoming/MS home/DSRMYZG homegrown homeland/SM homelessness/SM homeless/P homelike homeliness/SM homely/RPT homemade homemake/JRZG homemaker/M homemaking/M homeomorphic homeomorphism/MS homeomorph/M homeopath homeopathic homeopaths homeopathy/MS homeostases homeostasis/M homeostatic homeowner/S homeownership homepage Homere/M homer/GDM Homeric homerists Homer/M homeroom/MS Homerus/M homeschooling/S homesickness/MS homesick/P homespun/S homesteader/M homestead/GZSRDM homestretch/SM hometown/SM homeward homeworker/M homework/ZSMR homeyness/MS homey/PS homicidal/Y homicide/SM homier homiest homiletic/S homily/SM hominess's homing/M hominid/MS hominy/SM Hom/MR homogamy/M homogenate/MS homogeneity/ISM homogeneous/PY homogenization/MS homogenize/DRSGZ homogenizer/M homograph/M homographs homological homologous homologue/M homology/MS homomorphic homomorphism/SM homonym/SM homophobia/S homophobic homophone/MS homopolymers homosexuality/SM homosexual/YMS homo/SM homotopy homozygous/Y honcho/DSG Honda/M Hondo/M Honduran/S Honduras/M Honecker/M hone/SM honestly/E honest/RYT honesty/ESM honeybee/SM honeycomb/SDMG honeydew/SM honey/GSMD honeylocust Honey/M honeymooner/M honeymoon/RDMGZS honeysuckle/MS Honeywell/M hong/M Honiara/M honker/M honk/GZSDRM honky/SM Hon/M hon/MDRSZTG Honolulu/M honorableness/SM honorable/PSM honorables/U honorablies/U honorably/UE honorarily honorarium/SM honorary/S honored/U honoree/S honor/ERDBZGS honorer/EM Honoria/M honorific/S Honor/M honor's honors/A Honshu/M hooch/MS hoodedness/M hooded/P hoodlum/SM Hood/M hood/MDSG hoodoo/DMGS hoodwinker/M hoodwink/SRDG hooey/SM hoof/DRMSG hoofer/M hoofmark/S hookah/M hookahs hookedness/M hooked/P Hooke/MR hooker/M Hooker/M hookey's hook/GZDRMS hooks/U hookup/SM hookworm/MS hooky/SRMT hooliganism/SM hooligan/SM hooper/M Hooper/M hoopla/SM hoop/MDRSG hooray/SMDG hoosegow/MS Hoosier/SM hootch's hootenanny/SM hooter/M hoot/MDRSGZ Hoover/MS hooves/M hoped/U hopefulness/MS hopeful/SPY hopelessness/SM hopeless/YP Hope/M hoper/M hope/SM Hopewell/M Hopi/SM Hopkinsian/M Hopkins/M hopped Hopper/M hopper/MS hopping/M hoppled hopples hopscotch/MDSG hop/SMDRG Horace/M Horacio/M Horatia/M Horatio/M Horatius/M horde/DSGM horehound/MS horizon/MS horizontal/YS Hormel/M hormonal/Y hormone/MS Hormuz/M hornbeam/M hornblende/MS Hornblower/M hornedness/M horned/P Horne/M hornet/MS horn/GDRMS horniness/M hornless hornlike Horn/M hornpipe/MS horny/TRP horologic horological horologist/MS horology/MS horoscope/MS Horowitz/M horrendous/Y horribleness/SM horrible/SP horribly horridness/M horrid/PY horrific horrifically horrify/DSG horrifying/Y horror/MS hors/DSGX horseback/MS horsedom horseflesh/M horsefly/MS horsehair/SM horsehide/SM horselaugh/M horselaughs horseless horselike horsely horseman/M horsemanship/MS horsemen horseplayer/M horseplay/SMR horsepower/SM horseradish/SM horse's horseshoeing horseshoe/MRSD horseshoer/M horsetail/SM horse/UGDS horsewhipped horsewhipping horsewhip/SM horsewoman/M horsewomen horsey horsier horsiest horsing/M Horst/M hortatory Horten/M Hortense/M Hortensia/M horticultural horticulture/SM horticulturist/SM Hort/MN Horton/M Horus/M hosanna/SDG Hosea/M hose/M hosepipe hos/GDS hosier/MS hosiery/SM hosp hospice/MS hospitable/I hospitably/I hospitality/MS hospitality's/I hospitalization/MS hospitalize/GSD hospital/MS hostage/MS hosteler/M hostelry/MS hostel/SZGMRD hostess/MDSG hostile/YS hostility/SM hostler/MS Host/MS host/MYDGS hotbed/MS hotblooded hotbox/MS hotcake/S hotchpotch/M hotelier/MS hotelman/M hotel/MS hotfoot/DGS hothead/DMS hotheadedness/SM hotheaded/PY hothouse/MGDS hotness/MS hotplate/SM hotpot/M hot/PSY hotrod hotshot/S hotted Hottentot/SM hotter hottest hotting Houdaille/M Houdini/M hough/M hounder/M hounding/M hound/MRDSG hourglass/MS houri/MS hourly/S hour/YMS house/ASDG houseboat/SM housebound houseboy/SM housebreaker/M housebreaking/M housebreak/JSRZG housebroke housebroken housebuilding housecleaning/M houseclean/JDSG housecoat/MS housefly/MS houseful/SM householder/M household/ZRMS househusband/S housekeeper/M housekeeping/M housekeep/JRGZ houselights House/M housemaid/MS houseman/M housemen housemother/MS housemoving houseparent/SM houseplant/S houser house's housetop/MS housewares housewarming/MS housewifeliness/M housewifely/P housewife/YM housewives houseworker/M housework/ZSMR housing/MS Housman/M Houston/M Houyhnhnm/M HOV hovel/GSMD hovercraft/M hoverer/M hover/GRD hove/ZR Howard/M howbeit howdah/M howdahs howdy/GSD Howell/MS Howe/M however Howey/M Howie/M howitzer/MS howler/M howl/GZSMDR Howrah/M how/SM howsoever hoyden/DMGS hoydenish Hoyle/SM hoy/M Hoyt/M hp HP HQ hr HR HRH Hrothgar/M hrs h's H's HS HST ht HTML Hts/M HTTP Huang/M huarache/SM hubba Hubbard/M Hubble/M hubbub/SM hubby/SM hubcap/SM Huber/M Hube/RM Hubert/M Huberto/M Hubey/M Hubie/M hub/MS hubris/SM huckleberry/SM Huck/M huckster/SGMD HUD Huddersfield/M huddler/M huddle/RSDMG Hudson/M hue/MDS Huerta/M Huey/M huffily huffiness/SM Huff/M Huffman/M huff/SGDM huffy/TRP hugeness/MS huge/YP hugged hugger hugging/S Huggins Hughie/M Hugh/MS Hugibert/M Hugo/M hug/RTS Huguenot/SM Hugues/M huh huhs Hui/M Huitzilopitchli/M hula/MDSG Hulda/M hulk/GDMS hullabaloo/SM huller/M hulling/M Hull/M hull/MDRGZS hullo/GSDM humane/IY humaneness/SM humaner humanest human/IPY humanism/SM humanistic humanist/SM humanitarianism/SM humanitarian/S humanity/ISM humanization/CSM humanized/C humanizer/M humanize/RSDZG humanizes/IAC humanizing/C humankind/M humannesses humanness/IM humanoid/S humans Humbert/M Humberto/M humbleness/SM humble/TZGPRSDJ humbly Humboldt/M humbugged humbugging humbug/MS humdinger/MS humdrum/S Hume/M humeral/S humeri humerus/M Humfrey/M Humfrid/M Humfried/M humidification/MC humidifier/CM humidify/RSDCXGNZ humidistat/M humidity/MS humidor/MS humid/Y humiliate/SDXNG humiliating/Y humiliation/M humility/MS hummed Hummel/M hummer/SM humming hummingbird/SM hummock/MDSG hummocky hummus/S humongous humored/U humorist/MS humorlessness/MS humorless/PY humorousness/MS humorous/YP humor/RDMZGS humpback/SMD hump/GSMD humph/DG Humphrey/SM humphs Humpty/M hum/S humus/SM Humvee hunchback/DSM hunch/GMSD hundredfold/S hundred/SHRM hundredths hundredweight/SM Hunfredo/M hung/A Hungarian/MS Hungary/M hunger/SDMG Hung/M hungover hungrily hungriness/SM hungry/RTP hunker/DG hunky/RST hunk/ZRMS Hun/MS hunter/M Hunter/M hunt/GZJDRS hunting/M Huntington/M Huntlee/M Huntley/M Hunt/MR huntress/MS huntsman/M huntsmen Huntsville/M hurdle/JMZGRSD hurdler/M hurl/DRGZJS Hurlee/M Hurleigh/M hurler/M Hurley/M hurling/M Huron/SM hurray/SDG hurricane/MS hurriedness/M hurried/UY hurry/RSDG Hurst/M hurter/M hurtfulness/MS hurtful/PY hurting/Y hurtle/SDG hurts hurt/U Hurwitz/M Hus Husain's husbander/M husband/GSDRYM husbandman/M husbandmen husbandry/SM Husein/M hush/DSG husker/M huskily huskiness/MS husking/M husk/SGZDRM husky/RSPT hussar/MS Hussein/M Husserl/M hussy/SM hustings/M hustler/M hustle/RSDZG Huston/M Hutchins/M Hutchinson/M Hutchison/M hutch/MSDG hut/MS hutted hutting Hutton/M Hutu/M Huxley/M Huygens/M huzzah/GD huzzahs hwy Hyacintha/M Hyacinthe/M Hyacinthia/M Hyacinthie/M hyacinth/M Hyacinth/M hyacinths Hyades hyaena's Hyannis/M Hyatt/M hybridism/SM hybridization/S hybridize/GSD hybrid/MS Hyde/M Hyderabad/M Hydra/M hydra/MS hydrangea/SM hydrant/SM hydrate/CSDNGX hydrate's hydration/MC hydraulically hydraulicked hydraulicking hydraulic/S hydraulics/M hydrazine/M hydride/MS hydrocarbon/SM hydrocephali hydrocephalus/MS hydrochemistry hydrochloric hydrochloride/M hydrodynamical hydrodynamic/S hydrodynamics/M hydroelectric hydroelectrically hydroelectricity/SM hydrofluoric hydrofoil/MS hydrogenate/CDSGN hydrogenate's hydrogenation/MC hydrogenations hydrogen/MS hydrogenous hydrological/Y hydrologist/MS hydrology/SM hydrolysis/M hydrolyzed/U hydrolyze/GSD hydromagnetic hydromechanics/M hydrometer/SM hydrometry/MS hydrophilic hydrophobia/SM hydrophobic hydrophone/SM hydroplane/DSGM hydroponic/S hydroponics/M hydro/SM hydrosphere/MS hydrostatic/S hydrostatics/M hydrotherapy/SM hydrothermal/Y hydrous hydroxide/MS hydroxy hydroxylate/N hydroxyl/SM hydroxyzine/M hyena/MS hygiene/MS hygienically hygienic/S hygienics/M hygienist/MS hygrometer/SM hygroscopic hying Hy/M Hyman/M hymeneal/S Hymen/M hymen/MS Hymie/M hymnal/SM hymnbook/S hymn/GSDM Hynda/M hype/MZGDSR hyperactive/S hyperactivity/SM hyperbola/MS hyperbole/MS hyperbolic hyperbolically hyperboloidal hyperboloid/SM hypercellularity hypercritical/Y hypercube/MS hyperemia/M hyperemic hyperfine hypergamous/Y hypergamy/M hyperglycemia/MS hyperinflation Hyperion/M hypermarket/SM hypermedia/S hyperplane/SM hyperplasia/M hypersensitiveness/MS hypersensitive/P hypersensitivity/MS hypersonic hyperspace/M hypersphere/M hypertension/MS hypertensive/S hypertext/SM hyperthyroid hyperthyroidism/MS hypertrophy/MSDG hypervelocity hyperventilate/XSDGN hyperventilation/M hyphenated/U hyphenate/NGXSD hyphenation/M hyphen/DMGS hypnoses hypnosis/M hypnotherapy/SM hypnotically hypnotic/S hypnotism/MS hypnotist/SM hypnotize/SDG hypoactive hypoallergenic hypocellularity hypochondriac/SM hypochondria/MS hypocrisy/SM hypocrite/MS hypocritical/Y hypodermic/S hypo/DMSG hypoglycemia/SM hypoglycemic/S hypophyseal hypophysectomized hypotenuse/MS hypothalami hypothalamic hypothalamically hypothalamus/M hypothermia/SM hypotheses hypothesis/M hypothesizer/M hypothesize/ZGRSD hypothetic hypothetical/Y hypothyroid hypothyroidism/SM hypoxia/M hyssop/MS hysterectomy/MS hysteresis/M hysteria/SM hysterical/YU hysteric/SM Hyundai/M Hz i I IA Iaccoca/M Iago/M Iain/M Ia/M iambi iambic/S iamb/MS iambus/SM Ian/M Ianthe/M Ibadan/M Ibbie/M Ibby/M Iberia/M Iberian/MS Ibero/M ibex/MS ibid ibidem ibis/SM IBM/M Ibo/M Ibrahim/M Ibsen/M ibuprofen/S Icarus/M ICBM/S ICC iceberg/SM iceboat/MS icebound icebox/MS icebreaker/SM icecap/SM ice/GDSC Icelander/M Icelandic Iceland/MRZ Ice/M iceman/M icemen icepack icepick/S ice's Ichabod/M ichneumon/M ichthyologist/MS ichthyology/MS icicle/SM icily iciness/SM icing/MS icky/RT iconic icon/MS iconoclasm/MS iconoclastic iconoclast/MS iconography/MS icosahedra icosahedral icosahedron/M ictus/SM ICU icy/RPT I'd ID Idahoan/S Idahoes Idaho/MS Idalia/M Idalina/M Idaline/M Ida/M idealism/MS idealistic idealistically idealist/MS idealization/MS idealized/U idealize/GDRSZ idealizer/M ideal/MYS idealogical idea/SM ideate/SN ideation/M Idelle/M Idell/M idem idempotent/S identicalness/M identical/YP identifiability identifiable/U identifiably identification/M identified/U identifier/M identify/XZNSRDG identity/SM ideogram/MS ideographic ideograph/M ideographs ideological/Y ideologist/SM ideologue/S ideology/SM ides Idette/M idiocy/MS idiolect/M idiomatically idiomatic/P idiom/MS idiopathic idiosyncrasy/SM idiosyncratic idiosyncratically idiotic idiotically idiot/MS idleness/MS idle/PZTGDSR idler/M id/MY idolater/MS idolatress/S idolatrous idolatry/SM idolization/SM idolized/U idolizer/M idolize/ZGDRS idol/MS ids IDs idyllic idyllically idyll/MS IE IEEE Ieyasu/M if iffiness/S iffy/TPR Ifni/M ifs Iggie/M Iggy/M igloo/MS Ignace/M Ignacio/M Ignacius/M Ignatius/M Ignazio/M Ignaz/M igneous ignitable ignite/ASDG igniter/M ignition/MS ignobleness/M ignoble/P ignobly ignominious/Y ignominy/MS ignoramus/SM ignorance/MS ignorantness/M ignorant/SPY ignorer/M ignore/SRDGB Igor/M iguana/MS Iguassu/M ii iii Ijsselmeer/M Ike/M Ikey/M Ikhnaton/M ikon's IL Ilaire/M Ila/M Ilario/M ilea Ileana/M Ileane/M ileitides ileitis/M Ilene/M ileum/M ilia iliac Iliad/MS Ilise/M ilium/M Ilka/M ilk/MS I'll Illa/M illegality/MS illegal/YS illegibility/MS illegible illegibly illegitimacy/SM illegitimate/SDGY illiberality/SM illiberal/Y illicitness/MS illicit/YP illimitableness/M illimitable/P Illinoisan/MS Illinois/M illiquid illiteracy/MS illiterateness/M illiterate/PSY Ill/M illness/MS illogicality/SM illogicalness/M illogical/PY illogic/M ill/PS illume/DG illuminate/XSDVNG Illuminati illuminatingly illuminating/U illumination/M illumine/BGSD illusionary illusion/ES illusionist/MS illusion's illusiveness/M illusive/PY illusoriness/M illusory/P illustrated/U illustrate/VGNSDX illustration/M illustrative/Y illustrator/SM illustriousness/SM illustrious/PY illus/V illy Ilona/M Ilsa/M Ilse/M Ilysa/M Ilyse/M Ilyssa/M Ilyushin/M I'm image/DSGM Imagen/M imagery/MS imaginableness imaginable/U imaginably/U imaginariness/M imaginary/PS imagination/MS imaginativeness/M imaginative/UY imagined/U imaginer/M imagine/RSDJBG imagoes imago/M imam/MS imbalance/SDM imbecile/YMS imbecilic imbecility/MS imbiber/M imbibe/ZRSDG imbrication/SM Imbrium/M imbroglio/MS imbruing imbue/GDS Imelda/M IMF IMHO imitable/I imitate/SDVNGX imitation/M imitativeness/MS imitative/YP imitator/SM immaculateness/SM immaculate/YP immanence/S immanency/MS immanent/Y Immanuel/M immateriality/MS immaterialness/MS immaterial/PY immatureness/M immature/SPY immaturity/MS immeasurableness/M immeasurable/P immeasurably immediacy/MS immediateness/SM immediate/YP immemorial/Y immenseness/M immense/PRTY immensity/MS immerse/RSDXNG immersible immersion/M immigrant/SM immigrate/NGSDX immigration/M imminence/SM imminentness/M imminent/YP immobile immobility/MS immobilization/MS immobilize/DSRG immoderateness/M immoderate/NYP immoderation/M immodest/Y immodesty/SM immolate/SDNGX immolation/M immorality/MS immoral/Y immortality/SM immortalized/U immortalize/GDS immortal/SY immovability/SM immovableness/M immovable/PS immovably immune/S immunity/SM immunization/MS immunize/GSD immunoassay/M immunodeficiency/S immunodeficient immunologic immunological/Y immunologist/SM immunology/MS immure/GSD immutability/MS immutableness/M immutable/P immutably IMNSHO IMO Imogene/M Imogen/M Imojean/M impaction/SM impactor/SM impact/VGMRDS impaired/U impairer/M impair/LGRDS impairment/SM impala/MS impale/GLRSD impalement/SM impaler/M impalpable impalpably impanel/DGS impartation/M impart/GDS impartiality/SM impartial/Y impassableness/M impassable/P impassably impasse/SXBMVN impassibility/SM impassible impassibly impassion/DG impassioned/U impassiveness/MS impassive/YP impassivity/MS impasto/SM impatience/SM impatiens/M impatient/Y impeachable/U impeach/DRSZGLB impeacher/M impeachment/MS impeccability/SM impeccable/S impeccably impecuniousness/MS impecunious/PY impedance/MS impeded/U impeder/M impede/S imped/GRD impedimenta impediment/SM impelled impeller/MS impelling impel/S impend/DGS impenetrability/MS impenetrableness/M impenetrable/P impenetrably impenitence/MS impenitent/YS imperativeness/M imperative/PSY imperceivable imperceptibility/MS imperceptible imperceptibly imperceptive imperf imperfectability imperfection/MS imperfectness/SM imperfect/YSVP imperialism/MS imperialistic imperialistically imperialist/SM imperial/YS imperil/GSLD imperilment/SM imperiousness/MS imperious/YP imperishableness/M imperishable/SP imperishably impermanence/MS impermanent/Y impermeability/SM impermeableness/M impermeable/P impermeably impermissible impersonality/M impersonalized impersonal/Y impersonate/XGNDS impersonation/M impersonator/SM impertinence/SM impertinent/YS imperturbability/SM imperturbable imperturbably imperviousness/M impervious/PY impetigo/MS impetuosity/MS impetuousness/MS impetuous/YP impetus/MS impiety/MS impinge/LS impingement/MS imping/GD impiousness/SM impious/PY impishness/MS impish/YP implacability/SM implacableness/M implacable/P implacably implantation/SM implant/BGSDR implanter/M implausibility/MS implausible implausibly implementability implementable/U implementation/A implementations implementation's implemented/AU implementer/M implementing/A implementor/MS implement/SMRDGZB implicant/SM implicate/VGSD implication/M implicative/PY implicitness/SM implicit/YP implied/Y implode/GSD implore/GSD imploring/Y implosion/SM implosive/S imply/GNSDX impoliteness/MS impolite/YP impoliticness/M impolitic/PY imponderableness/M imponderable/PS importance/SM important/Y importation/MS importer/M importing/A import/SZGBRD importunateness/M importunate/PYGDS importuner/M importune/SRDZYG importunity/SM imposable impose/ASDG imposer/SM imposingly imposing/U imposition/SM impossibility/SM impossibleness/M impossible/PS impossibly imposter's impostor/SM impost/SGMD imposture/SM impotence/MS impotency/S impotent/SY impound/GDS impoundments impoverisher/M impoverish/LGDRS impoverishment/SM impracticableness/M impracticable/P impracticably impracticality/SM impracticalness/M impractical/PY imprecate/NGXSD imprecation/M impreciseness/MS imprecise/PYXN imprecision/M impregnability/MS impregnableness/M impregnable/P impregnably impregnate/DSXNG impregnation/M impresario/SM impress/DRSGVL impressed/U impresser/M impressibility/MS impressible impressionability/SM impressionableness/M impressionable/P impression/BMS impressionism/SM impressionistic impressionist/MS impressiveness/MS impressive/YP impressment/M imprimatur/SM imprinter/M imprinting/M imprint/SZDRGM imprison/GLDS imprisonment/MS improbability/MS improbableness/M improbable/P improbably impromptu/S improperness/M improper/PY impropitious impropriety/SM improved/U improvement/MS improver/M improve/SRDGBL improvidence/SM improvident/Y improvisational improvisation/MS improvisatory improviser/M improvise/RSDZG imprudence/SM imprudent/Y imp/SGMDRY impudence/MS impudent/Y impugner/M impugn/SRDZGB impulse/XMVGNSD impulsion/M impulsiveness/MS impulsive/YP impunity/SM impureness/M impure/RPTY impurity/MS imputation/SM impute/SDBG Imus/M IN inaction inactive inadequate/S inadvertence/MS inadvertent/Y inalienability/MS inalienably inalterableness/M inalterable/P Ina/M inamorata/MS inane/SRPYT inanimateness/S inanimate/P inanity/MS inappeasable inappropriate/P inarticulate/P in/AS inasmuch inaugural/S inaugurate/XSDNG inauguration/M inauthenticity inbound/G inbred/S inbreed/JG incalculableness/M incalculably incandescence/SM incandescent/YS incant incantation/SM incantatory incapable/S incapacitate/GNSD incapacitation/M incarcerate/XGNDS incarceration/M incarnadine/GDS incarnate/AGSDNX incarnation/AM Inca/SM incendiary/S incense/MGDS incentive/ESM incentively incept/DGVS inception/MS inceptive/Y inceptor/M incessant/Y incest/SM incestuousness/MS incestuous/PY inch/GMDS inchoate/DSG Inchon/M inchworm/MS incidence/MS incidental/YS incident/SM incinerate/XNGSD incineration/M incinerator/SM incipience/SM incipiency/M incipient/Y incise/SDVGNX incision/M incisiveness/MS incisive/YP incisor/MS incitement/MS inciter/M incite/RZL incl inclination/ESM incline/EGSD incliner/M inclining/M include/GDS inclusion/MS inclusiveness/MS inclusive/PY Inc/M incognito/S incoherency/M income/M incommode/DG incommunicado incomparable incompetent/MS incomplete/P inconceivability/MS inconceivableness/M inconceivable/P incondensable incongruousness/S inconsiderableness/M inconsiderable/P inconsistence inconsolableness/M inconsolable/P inconsolably incontestability/SM incontestably incontrovertibly inconvenience/DG inconvertibility inconvertible incorporable incorporated/UE incorporate/GASDXN incorrect/P incorrigibility/MS incorrigibleness/M incorrigible/SP incorrigibly incorruptible/S incorruptibly increase/JB increaser/M increasing/Y incredibleness/M incredible/P incremental/Y incrementation increment/DMGS incriminate/XNGSD incrimination/M incriminatory incrustation/SM inc/T incubate/XNGVDS incubation/M incubator/MS incubus/MS inculcate/SDGNX inculcation/M inculpate/SDG incumbency/MS incumbent/S incunabula incunabulum incurable/S incurious incursion/SM ind indebtedness/SM indebted/P indefatigableness/M indefatigable/P indefatigably indefeasible indefeasibly indefinableness/M indefinable/PS indefinite/S indelible indelibly indemnification/M indemnify/NXSDG indemnity/SM indentation/SM indented/U indenter/M indention/SM indent/R indenture/DG Independence/M indescribableness/M indescribable/PS indescribably indestructibleness/M indestructible/P indestructibly indeterminably indeterminacy/MS indeterminism indexation/S indexer/M index/MRDZGB India/M Indiana/M Indianan/S Indianapolis/M Indianian/S Indian/SM indicant/MS indicate/DSNGVX indication/M indicative/SY indicator/MS indices's indicter/M indictment/SM indict/SGLBDR indifference indigence/MS indigenousness/M indigenous/YP indigent/SY indigestible/S indignant/Y indignation/MS indigo/SM Indira/M indirect/PG indiscreet/P indiscriminateness/M indiscriminate/PY indispensability/MS indispensableness/M indispensable/SP indispensably indisputableness/M indisputable/P indissolubleness/M indissoluble/P indissolubly indistinguishableness/M indistinguishable/P indite/SDG indium/SM individualism/MS individualistic individualistically individualist/MS individuality/MS individualization/SM individualize/DRSGZ individualized/U individualizer/M individualizes/U individualizing/Y individual/YMS individuate/DSXGN individuation/M indivisibleness/M indivisible/SP indivisibly Ind/M Indochina/M Indochinese indoctrinate/GNXSD indoctrination/M indoctrinator/SM indolence/SM indolent/Y indomitableness/M indomitable/P indomitably Indonesia/M Indonesian/S indoor Indore/M Indra/M indubitableness/M indubitable/P indubitably inducement/MS inducer/M induce/ZGLSRD inducible inductance/MS inductee/SM induct/GV induction/SM inductiveness/M inductive/PY inductor/MS indulge/GDRS indulgence/SDGM indulgent/Y indulger/M Indus/M industrialism/MS industrialist/MS industrialization/MS industrialized/U industrialize/SDG industrial/SY industriousness/SM industrious/YP industry/SM Indy/SM inebriate/NGSDX inebriation/M inedible ineducable ineffability/MS ineffableness/M ineffable/P ineffably inelastic ineligibly ineluctable ineluctably ineptitude/SM ineptness/MS inept/YP inequivalent inerrant inertial/Y inertia/SM inertness/MS inert/SPY Ines inescapably Inesita/M Inessa/M inestimably inevitability/MS inevitableness/M inevitable/P inevitably inexact/P inexhaustibleness/M inexhaustible/P inexhaustibly inexorability/M inexorableness/M inexorable/P inexorably inexpedience/M inexplicableness/M inexplicable/P inexplicably inexplicit inexpressibility/M inexpressibleness/M inexpressible/PS inextricably Inez/M infamous infamy/SM infancy/M infanticide/MS infantile infant/MS infantryman/M infantrymen infantry/SM infarction/SM infarct/SM infatuate/XNGSD infatuation/M infauna infected/U infecter infect/ESGDA infection/EASM infectiousness/MS infectious/PY infective infer/B inference/GMSR inferential/Y inferiority/MS inferior/SMY infernal/Y inferno/MS inferred inferring infertile infestation/MS infester/M infest/GSDR infidel/SM infighting/M infill/MG infiltrate/V infiltrator/MS infinitesimal/SY infinite/V infinitival infinitive/YMS infinitude/MS infinitum infinity/SM infirmary/SM infirmity/SM infix/M inflammableness/M inflammable/P inflammation/MS inflammatory inflatable/MS inflate/NGBDRSX inflater/M inflationary inflation/ESM inflect/GVDS inflectional/Y inflection/SM inflexibleness/M inflexible/P inflexion/SM inflict/DRSGV inflicter/M infliction/SM inflow/M influenced/U influencer/M influence/SRDGM influent influential/SY influenza/MS infomercial/S Informatica/M informatics informational information/ES informativeness/S informative/UY informatory informed/U informer/M info/SM infotainment/S infra infrared/SM infrasonic infrastructural infrastructure/MS infrequence/S infringe/LR infringement/SM infringer/M infuriate/GNYSD infuriating/Y infuriation/M infuser/M infuse/RZ infusibleness/M infusible/P inf/ZT Ingaberg/M Ingaborg/M Inga/M Ingamar/M Ingar/M Ingeberg/M Ingeborg/M Ingelbert/M Ingemar/M ingeniousness/MS ingenious/YP ingnue/S ingenuity/SM ingenuous/EY ingenuousness/MS Inger/M Inge/RM Ingersoll/M ingest/DGVS ingestible ingestion/SM Inglebert/M inglenook/MS Inglewood/M Inglis/M Ingmar/M ingoing ingot/SMDG ingrained/Y Ingra/M Ingram/M ingrate/M ingratiate/DSGNX ingratiating/Y ingratiation/M ingredient/SM Ingres/M ingression/M ingress/MS Ingrid/M Ingrim/M ingrown/P inguinal Ingunna/M inhabitable/U inhabitance inhabited/U inhabiter/M inhabit/R inhalant/S inhalation/SM inhalator/SM inhale/Z inhere/DG inherent/Y inheritableness/M inheritable/P inheritance/EMS inherit/BDSG inherited/E inheriting/E inheritor/S inheritress/MS inheritrix/MS inherits/E inhibit/DVGS inhibited/U inhibiter's inhibition/MS inhibitor/MS inhibitory inhomogeneous inhospitableness/M inhospitable/P inhospitality Inigo/M inimical/Y inimitableness/M inimitable/P inimitably inion iniquitousness/M iniquitous/PY iniquity/MS initialer/M initial/GSPRDY initialization/A initializations initialization's initialize/ASDG initialized/U initializer/S initiates initiate/UD initiating initiation/SM initiative/SM initiator/MS initiatory injectable/U inject/GVSDB injection/MS injector/SM injunctive injured/U injurer/M injure/SRDZG injuriousness/M injurious/YP inkblot/SM inker/M inkiness/MS inkling/SM inkstand/SM inkwell/SM inky/TP ink/ZDRJ inland inlander/M inlay/RG inletting inly/G inmost Inna/M innards innateness/SM innate/YP innermost/S innersole/S innerspring innervate/GNSDX innervation/M inner/Y inning/M Innis/M innkeeper/MS innocence/SM Innocent/M innocent/SYRT innocuousness/MS innocuous/PY innovate/SDVNGX innovation/M innovative/P innovator/MS innovatory Innsbruck/M innuendo/MDGS innumerability/M innumerableness/M innumerable/P innumerably innumerate inn/ZGDRSJ inoculate/ASDG inoculation/MS inoculative inoffensive/P Inonu/M inopportuneness/M inopportune/P inordinateness/M inordinate/PY inorganic inpatient In/PM input/MRDG inquirer/M inquire/ZR inquiring/Y inquiry/MS inquisitional inquisition/MS Inquisition/MS inquisitiveness/MS inquisitive/YP inquisitorial/Y inquisitor/MS INRI inrush/M ins INS insalubrious insanitary insatiability/MS insatiableness/M insatiable/P insatiably inscribe/Z inscription/SM inscrutability/SM inscrutableness/SM inscrutable/P inscrutably inseam insecticidal insecticide/MS insectivore/SM insectivorous insecureness/M insecure/P inseminate/NGXSD insemination/M insensateness/M insensate/P insensible/P insentient inseparable/S insert/ADSG inserter/M insertion/AMS insetting inshore insider/M inside/Z insidiousness/MS insidious/YP insightful/Y insigne's insignia/SM insignificant insinuate/VNGXSD insinuating/Y insinuation/M insinuator/SM insipidity/MS insipid/Y insistence/SM insistent/Y insisting/Y insist/SGD insociable insofar insole/M insolence/SM insolent/YS insolubleness/M insoluble/P insolubly insomniac/S insomnia/MS insomuch insouciance/SM insouciant/Y inspect/AGSD inspection/SM inspective inspectorate/MS inspector/SM inspirational/Y inspiration/MS inspired/U inspire/R inspirer/M inspiring/U inspirit/DG Inst installable install/ADRSG installation/SM installer/MS installment/MS instance/GD instantaneousness/M instantaneous/PY instantiated/U instantiate/SDXNG instantiation/M instant/SRYMP instate/AGSD inst/B instead instigate/XSDVGN instigation/M instigator/SM instillation/SM instinctive/Y instinctual instinct/VMS instituter/M institutes/M institute/ZXVGNSRD institutionalism/M institutionalist/M institutionalization/SM institutionalize/GDS institutional/Y institution/AM institutor's instr instruct/DSVG instructed/U instructional instruction/MS instructiveness/M instructive/PY instructor/MS instrumentalist/MS instrumentality/SM instrumental/SY instrumentation/SM instrument/GMDS insubordinate insubstantial insufferable insufferably insularity/MS insular/YS insulate/DSXNG insulated/U insulation/M insulator/MS insulin/MS insult/DRSG insulter/M insulting/Y insuperable insuperably insupportableness/M insupportable/P insurance/MS insurance's/A insure/BZGS insured/S insurer/M insurgence/SM insurgency/MS insurgent/MS insurmountably insurrectionist/SM insurrection/SM intactness/M intact/P intaglio/GMDS intake/M intangible/M integer/MS integrability/M integrable integral/SYM integrand/MS integrate/AGNXEDS integration/EMA integrative/E integrator/MS integrity/SM integument/SM intellective/Y intellect/MVS intellectualism/MS intellectuality/M intellectualize/GSD intellectualness/M intellectual/YPS intelligence/MSR intelligencer/M intelligentsia/MS intelligent/UY intelligibilities intelligibility/UM intelligibleness/MU intelligible/PU intelligibly/U Intel/M Intelsat/M intemperate/P intendant/MS intendedness/M intended/SYP intender/M intensification/M intensifier/M intensify/GXNZRSD intensional/Y intensiveness/MS intensive/PSY intentionality/M intentional/UY intention/SDM intentness/SM intent/YP interaction/MS interactive/PY interactivity interact/VGDS interaxial interbank interbred interbreed/GS intercalate/GNVDS intercalation/M intercase intercaste interceder/M intercede/SRDG intercensal intercept/DGS interception/MS interceptor/MS intercession/MS intercessor/SM intercessory interchangeability/M interchangeableness/M interchangeable/P interchangeably interchange/DSRGJ interchanger/M intercity interclass intercohort intercollegiate intercommunicate/SDXNG intercommunication/M intercom/SM interconnectedness/M interconnected/P interconnect/GDS interconnection/SM interconnectivity intercontinental interconversion/M intercorrelated intercourse/SM Interdata/M interdenominational interdepartmental/Y interdependence/MS interdependency/SM interdependent/Y interdiction/MS interdict/MDVGS interdisciplinary interested/UYE interest/GEMDS interestingly/U interestingness/M interesting/YP inter/ESTL interface/SRDGM interfacing/M interfaith interference/MS interferer/M interfere/SRDG interfering/Y interferometer/SM interferometric interferometry/M interferon/MS interfile/GSD intergalactic intergenerational intergeneration/M interglacial intergovernmental intergroup interim/S interindex interindustry interior/SMY interj interject/GDS interjectional interjection/MS interlace/GSD interlard/SGD interlayer/G interleave/SDG interleukin/S interlibrary interlinear/S interline/JGSD interlingual interlingua/M interlining/M interlink/GDS interlisp/M interlobular interlocker/M interlock/RDSG interlocutor/MS interlocutory interlope/GZSRD interloper/M interlude/MSDG intermarriage/MS intermarry/GDS intermediary/MS intermediateness/M intermediate/YMNGSDP intermediation/M interment/SME intermeshed intermetrics intermezzi intermezzo/SM interminably intermingle/DSG intermission/MS intermittent/Y intermix/GSRD intermodule intermolecular/Y internalization/SM internalize/GDS internal/SY Internationale/M internationalism/SM internationalist/SM internationality/M internationalization/MS internationalize/DSG international/YS internecine internee/SM interne's Internet/M INTERNET/M internetwork internist/SM intern/L internment/SM internship/MS internuclear interocular interoffice interoperability interpenetrates interpersonal/Y interplanetary interplay/GSMD interpol interpolate/XGNVBDS interpolation/M Interpol/M interpose/GSRD interposer/M interposition/MS interpretable/U interpret/AGSD interpretation/MSA interpretative/Y interpreted/U interpreter/SM interpretive/Y interpretor/S interprocess interprocessor interquartile interracial interred/E interregional interregnum/MS interrelatedness/M interrelated/PY interrelate/GNDSX interrelation/M interrelationship/SM interring/E interrogate/DSXGNV interrogation/M interrogative/SY interrogator/SM interrogatory/S interrupted/U interrupter/M interruptibility interruptible interruption/MS interrupt/VGZRDS interscholastic intersect/GDS intersection/MS intersession/MS interspecies intersperse/GNDSX interspersion/M interstage interstate/S interstellar interstice/SM interstitial/SY intersurvey intertask intertwine/GSD interurban/S interval/MS intervene/GSRD intervener/M intervenor/M interventionism/MS interventionist/S intervention/MS interview/AMD interviewed/U interviewee/SM interviewer/SM interviewing interviews intervocalic interweave/GS interwove interwoven intestacy/SM intestinal/Y intestine/SM inti intifada intimacy/SM intimal intimateness/M intimater/M intimate/XYNGPDRS intimation/M intimidate/SDXNG intimidating/Y intimidation/M into intolerableness/M intolerable/P intolerant/PS intonate/NX intonation/M intoxicant/MS intoxicate/DSGNX intoxicated/Y intoxication/M intra intracellular intracity intraclass intracohort intractability/M intractableness/M intractable/P intradepartmental intrafamily intragenerational intraindustry intraline intrametropolitan intramural/Y intramuscular/Y intranasal intransigence/MS intransigent/YS intransitive/S intraoffice intraprocess intrapulmonary intraregional intrasectoral intrastate intratissue intrauterine intravenous/YS intrepidity/SM intrepidness/M intrepid/YP intricacy/SM intricateness/M intricate/PY intrigue/DRSZG intriguer/M intriguing/Y intrinsically intrinsic/S introduce/ADSG introducer/M introduction/ASM introductory introit/SM introject/SD intro/S introspection/MS introspectiveness/M introspective/YP introspect/SGVD introversion/SM introvert/SMDG intruder/M intrude/ZGDSR intrusion/SM intrusiveness/MS intrusive/SYP intubate/NGDS intubation/M intuit/GVDSB intuitionist/M intuitiveness/MS intuitive/YP int/ZR Inuit/MS inundate/SXNG inundation/M inure/GDS invader/M invade/ZSRDG invalid/GSDM invalidism/MS invariable/P invariant/M invasion/SM invasive/P invectiveness/M invective/PSMY inveigh/DRG inveigher/M inveighs inveigle/DRSZG inveigler/M invent/ADGS invented/U invention/ASM inventiveness/MS inventive/YP inventor/MS inventory/SDMG Inverness/M inverse/YV inverter/M invertible invert/ZSGDR invest/ADSLG investigate/XDSNGV investigation/MA investigator/MS investigatory investiture/SM investment/ESA investment's/A investor/SM inveteracy/MS inveterate/Y inviability invidiousness/MS invidious/YP invigilate/GD invigilator/SM invigorate/ANGSD invigorating/Y invigoration/AM invigorations invincibility/SM invincibleness/M invincible/P invincibly inviolability/MS inviolably inviolateness/M inviolate/YP inviscid invisibleness/M invisible/S invitational/S invitation/MS invited/U invitee/S inviter/M invite/SRDG inviting/Y invocable invocate invoked/A invoke/GSRDBZ invoker/M invokes/A involuntariness/S involuntary/P involute/XYN involution/M involutorial involvedly involved/U involve/GDSRL involvement/SM involver/M invulnerability/M invulnerableness/M inwardness/M inward/PY ioctl iodate/MGND iodation/M iodide/MS iodinate/DNG iodine/MS iodize/GSD Iolande/M Iolanthe/M Io/M Iona/M Ionesco/M Ionian/M ionic/S Ionic/S ionization's ionization/SU ionized/UC ionize/GNSRDJXZ ionizer's ionizer/US ionizes/U ionizing/U ionosphere/SM ionospheric ion's/I ion/SMU Iorgo/MS Iormina/M Iosep/M iota/SM IOU Iowan/S Iowa/SM IPA ipecac/MS Iphigenia/M ipso Ipswich/M IQ Iqbal/M Iquitos/M Ira/M Iranian/MS Iran/M Iraqi/SM Iraq/M IRA/S irascibility/SM irascible irascibly irateness/S irate/RPYT ireful Ireland/M ire/MGDS Irena/M Irene/M irenic/S iridescence/SM iridescent/Y irides/M iridium/MS irids Irina/M Iris iris/GDSM Irishman/M Irishmen Irish/R Irishwoman/M Irishwomen Irita/M irk/GDS irksomeness/SM irksome/YP Irkutsk/M Ir/M Irma/M ironclad/S iron/DRMPSGJ ironer/M ironic ironicalness/M ironical/YP ironing/M ironmonger/M ironmongery/M ironside/MS ironstone/MS ironware/SM ironwood/SM ironworker/M ironwork/MRS irony/SM Iroquoian/MS Iroquois/M irradiate/XSDVNG irradiation/M irrationality/MS irrationalness/M irrational/YSP Irrawaddy/M irreclaimable irreconcilability/MS irreconcilableness/M irreconcilable/PS irreconcilably irrecoverableness/M irrecoverable/P irrecoverably irredeemable/S irredeemably irredentism/M irredentist/M irreducibility/M irreducible irreducibly irreflexive irrefutable irrefutably irregardless irregularity/SM irregular/YS irrelevance/SM irrelevancy/MS irrelevant/Y irreligious irremediableness/M irremediable/P irremediably irremovable irreparableness/M irreparable/P irreparably irreplaceable/P irrepressible irrepressibly irreproachableness/M irreproachable/P irreproachably irreproducibility irreproducible irresistibility/M irresistibleness/M irresistible/P irresistibly irresoluteness/SM irresolute/PNXY irresolution/M irresolvable irrespective/Y irresponsibility/SM irresponsibleness/M irresponsible/PS irresponsibly irretrievable irretrievably irreverence/MS irreverent/Y irreversible irreversibly irrevocableness/M irrevocable/P irrevocably irrigable irrigate/DSXNG irrigation/M irritability/MS irritableness/M irritable/P irritably irritant/S irritate/DSXNGV irritated/Y irritating/Y irritation/M irrupt/GVSD irruption/SM IRS Irtish/M Irvine/M Irving/M Irvin/M Irv/MG Irwin/M Irwinn/M is i's Isaac/SM Isaak/M Isabelita/M Isabella/M Isabelle/M Isabel/M Isacco/M Isac/M Isadora/M Isadore/M Isador/M Isahella/M Isaiah/M Isak/M Isa/M ISBN Iscariot/M Iseabal/M Isfahan/M Isherwood/M Ishim/M Ishmael/M Ishtar/M Isiahi/M Isiah/M Isidora/M Isidore/M Isidor/M Isidoro/M Isidro/M isinglass/MS Isis/M Islamabad/M Islamic/S Islam/SM islander/M island/GZMRDS Islandia/M isle/MS islet/SM isl/GD Ismael/M ism/MCS isn't ISO isobaric isobar/MS Isobel/M isochronal/Y isochronous/Y isocline/M isocyanate/M isodine isolate/SDXNG isolationism/SM isolationistic isolationist/SM isolation/M isolator/MS Isolde/M isomeric isomerism/SM isomer/SM isometrically isometric/S isometrics/M isomorphic isomorphically isomorphism/MS isomorph/M isoperimetrical isopleth/M isopleths isosceles isostatic isothermal/Y isotherm/MS isotonic isotope/SM isotopic isotropic isotropically isotropy/M Ispahan's ispell/M Ispell/M Israeli/MS Israelite/SM Israel/MS Issac/M Issiah/M Issie/M Issi/M issuable issuance/MS issuant issued/A issue/GMZDSR issuer/AMS issues/A issuing/A Issy/M Istanbul/M isthmian/S isthmus/SM Istvan/M Isuzu/M It IT Itaipu/M ital Italianate/GSD Italian/MS italicization/MS italicized/U italicize/GSD italic/S Ital/M Italy/M Itasca/M itch/GMDS itchiness/MS Itch/M itchy/RTP ITcorp/M ITCorp/M it'd Itel/M itemization/SM itemized/U itemize/GZDRS itemizer/M itemizes/A item/MDSG iterate/ASDXVGN iteration/M iterative/YA iterator/MS Ithaca/M Ithacan itinerant/SY itinerary/MS it'll it/MUS Ito/M its itself ITT IUD/S IV Iva/M Ivanhoe/M Ivan/M Ivar/M I've Ive/MRS Iver/M Ivette/M Ivett/M Ivie/M iv/M Ivonne/M Ivor/M Ivory/M ivory/SM IVs Ivy/M ivy/MDS ix Izaak/M Izabel/M Izak/M Izanagi/M Izanami/M Izhevsk/M Izmir/M Izvestia/M Izzy/M jabbed jabberer/M jabber/JRDSZG jabbing Jabez/M Jablonsky/M jabot/MS jab/SM jacaranda/MS Jacenta/M Jacinda/M Jacinta/M Jacintha/M Jacinthe/M jackal/SM jackass/SM jackboot/DMS jackdaw/SM Jackelyn/M jacketed/U jacket/GSMD jack/GDRMS jackhammer/MDGS Jackie/M Jacki/M jackknife/MGSD jackknives Jacklin/M Jacklyn/M Jack/M Jackman/M jackpot/MS Jackqueline/M Jackquelin/M jackrabbit/DGS Jacksonian Jackson/SM Jacksonville/M jackstraw/MS Jacky/M Jaclin/M Jaclyn/M Jacobean Jacobian/M Jacobi/M Jacobin/M Jacobite/M Jacobo/M Jacobsen/M Jacob/SM Jacobs/N Jacobson/M Jacobus Jacoby/M jacquard/MS Jacquard/SM Jacqueline/M Jacquelin/M Jacquelyn/M Jacquelynn/M Jacquenetta/M Jacquenette/M Jacques/M Jacquetta/M Jacquette/M Jacquie/M Jacqui/M jacuzzi Jacuzzi/S Jacynth/M Jada/M jadedness/SM jaded/PY jadeite/SM Jade/M jade/MGDS Jaeger/M Jae/M jaggedness/SM jagged/RYTP Jagger/M jaggers jagging jag/S jaguar/MS jailbird/MS jailbreak/SM jailer/M jail/GZSMDR Jaime/M Jaimie/M Jaine/M Jainism/M Jain/M Jaipur/M Jakarta/M Jake/MS Jakie/M Jakob/M jalapeo/S jalopy/SM jalousie/MS Jamaal/M Jamaica/M Jamaican/S Jamal/M Jamar/M jambalaya/MS jamb/DMGS jamboree/MS Jamel/M Jame/MS Jameson/M Jamestown/M Jamesy/M Jamey/M Jamie/M Jamill/M Jamil/M Jami/M Jamima/M Jamison/M Jammal/M jammed/U Jammie/M jamming/U jam/SM Janacek/M Jana/M Janaya/M Janaye/M Jandy/M Janean/M Janeczka/M Janeen/M Janeiro/M Janek/M Janela/M Janella/M Janelle/M Janell/M Janel/M Jane/M Janene/M Janenna/M Janessa/M Janesville/M Janeta/M Janet/M Janetta/M Janette/M Janeva/M Janey/M jangler/M jangle/RSDGZ jangly Jania/M Janice/M Janie/M Janifer/M Janina/M Janine/M Janis/M janissary/MS Janith/M janitorial janitor/SM Janka/M Jan/M Janna/M Jannelle/M Jannel/M Jannie/M Janos/M Janot/M Jansenist/M Jansen/M January/MS Janus/M Jany/M Japanese/SM Japan/M japanned japanner japanning japan/SM jape/DSMG Japura/M Jaquelin/M Jaquelyn/M Jaquenetta/M Jaquenette/M Jaquith/M Jarad/M jardinire/MS Jard/M Jareb/M Jared/M jarful/S jargon/SGDM Jarib/M Jarid/M Jarlsberg jar/MS Jarrad/M jarred Jarred/M Jarret/M Jarrett/M Jarrid/M jarring/SY Jarrod/M Jarvis/M Jase/M Jasen/M Jasmina/M Jasmine/M jasmine/MS Jasmin/M Jason/M Jasper/M jasper/MS Jastrow/M Jasun/M jato/SM jaundice/DSMG jaundiced/U jauntily jauntiness/MS jaunt/MDGS jaunty/SRTP Javanese Java/SM javelin/SDMG Javier/M jawbone/SDMG jawbreaker/SM jawline jaw/SMDG Jaxartes/M Jayapura/M jaybird/SM Jaycee/SM Jaye/M Jay/M Jaymee/M Jayme/M Jaymie/M Jaynell/M Jayne/M jay/SM Jayson/M jaywalker/M jaywalk/JSRDZG Jazmin/M jazziness/M jazzmen jazz/MGDS jazzy/PTR JCS jct JD Jdavie/M jealousness/M jealous/PY jealousy/MS Jeana/M Jeanelle/M Jeane/M Jeanette/M Jeanie/M Jeanine/M Jean/M jean/MS Jeanna/M Jeanne/M Jeannette/M Jeannie/M Jeannine/M Jecho/M Jedd/M Jeddy/M Jedediah/M Jedidiah/M Jedi/M Jed/M jeep/GZSMD Jeep/S jeerer/M jeering/Y jeer/SJDRMG Jeeves/M jeez Jefferey/M Jeffersonian/S Jefferson/M Jeffery/M Jeffie/M Jeff/M Jeffrey/SM Jeffry/M Jeffy/M jehad's Jehanna/M Jehoshaphat/M Jehovah/M Jehu/M jejuna jejuneness/M jejune/PY jejunum/M Jekyll/M Jelene/M jell/GSD Jello/M jello's jellybean/SM jellyfish/MS jellying/M jellylike jellyroll/S jelly/SDMG Jemie/M Jemimah/M Jemima/M Jemmie/M jemmy/M Jemmy/M Jena/M Jenda/M Jenelle/M Jenica/M Jeniece/M Jenifer/M Jeniffer/M Jenilee/M Jeni/M Jenine/M Jenkins/M Jen/M Jenna/M Jennee/M Jenner/M jennet/SM Jennette/M Jennica/M Jennie/M Jennifer/M Jennilee/M Jenni/M Jennine/M Jennings/M Jenn/RMJ Jenny/M jenny/SM Jeno/M Jensen/M Jens/N jeopard jeopardize/GSD jeopardy/MS Jephthah/M Jerad/M Jerald/M Jeralee/M Jeramey/M Jeramie/M Jere/M Jereme/M jeremiad/SM Jeremiah/M Jeremiahs Jeremias/M Jeremie/M Jeremy/M Jericho/M Jeri/M jerker/M jerk/GSDRJ jerkily jerkiness/SM jerkin/SM jerkwater/S jerky/RSTP Jermaine/M Jermain/M Jermayne/M Jeroboam/M Jerold/M Jerome/M Jeromy/M Jerrie/M Jerrilee/M Jerrilyn/M Jerri/M Jerrine/M Jerrod/M Jerrold/M Jerrome/M jerrybuilt Jerrylee/M jerry/M Jerry/M jersey/MS Jersey/MS Jerusalem/M Jervis/M Jes Jessalin/M Jessalyn/M Jessa/M Jessamine/M jessamine's Jessamyn/M Jessee/M Jesselyn/M Jesse/M Jessey/M Jessica/M Jessie/M Jessika/M Jessi/M jess/M Jess/M Jessy/M jest/DRSGZM jester/M jesting/Y Jesuit/SM Jesus Jeth/M Jethro/M jetliner/MS jet/MS jetport/SM jetsam/MS jetted/M jetting/M jettison/DSG jetty/RSDGMT jeweler/M jewelery/S jewel/GZMRDS Jewelled/M Jewelle/M jewellery's Jewell/MD Jewel/M jewelry/MS Jewess/SM Jewishness/MS Jewish/P Jew/MS Jewry/MS Jezebel/MS j/F JFK/M jg/M jibbed jibbing jibe/S jib/MDSG Jidda/M jiff/S jiffy/SM jigged jigger/SDMG jigging/M jiggle/SDG jiggly/TR jig/MS jigsaw/GSDM jihad/SM Jilin Jillana/M Jillane/M Jillayne/M Jilleen/M Jillene/M Jillian/M Jillie/M Jilli/M Jill/M Jilly/M jilt/DRGS jilter/M Jimenez/M Jim/M Jimmie/M jimmy/GSDM Jimmy/M jimsonweed/S Jinan jingler/M jingle/RSDG jingly/TR jingoism/SM jingoistic jingoist/SM jingo/M Jinnah/M jinni's jinn/MS Jinny/M jinrikisha/SM jinx/GMDS jitney/MS jitterbugged jitterbugger jitterbugging jitterbug/SM jitter/S jittery/TR jiujitsu's Jivaro/M jive/MGDS Joachim/M Joana/M Joane/M Joanie/M Joan/M Joanna/M Joanne/SM Joann/M Joaquin/M jobbed jobber/MS jobbery/M jobbing/M Jobey/M jobholder/SM Jobie/M Jobi/M Jobina/M joblessness/MS jobless/P Jobrel/M job/SM Job/SM Jobye/M Joby/M Jobyna/M Jocasta/M Joceline/M Jocelin/M Jocelyne/M Jocelyn/M jockey/SGMD jock/GDMS Jock/M Jocko/M jockstrap/MS jocoseness/MS jocose/YP jocosity/SM jocularity/SM jocular/Y jocundity/SM jocund/Y Jodee/M jodhpurs Jodie/M Jodi/M Jody/M Joeann/M Joela/M Joelie/M Joella/M Joelle/M Joellen/M Joell/MN Joelly/M Joellyn/M Joel/MY Joelynn/M Joe/M Joesph/M Joete/M joey/M Joey/M jogged jogger/SM jogging/S joggler/M joggle/SRDG Jogjakarta/M jog/S Johan/M Johannah/M Johanna/M Johannes Johannesburg/M Johann/M Johansen/M Johanson/M Johna/MH Johnathan/M Johnath/M Johnathon/M Johnette/M Johnie/M Johnna/M Johnnie/M johnnycake/SM Johnny/M johnny/SM Johnsen/M john/SM John/SM Johns/N Johnson/M Johnston/M Johnstown/M Johny/M Joice/M join/ADGFS joined/U joiner/FSM joinery/MS jointed/EYP jointedness/ME joint/EGDYPS jointer/M jointly/F joint's jointures joist/GMDS Jojo/M joke/MZDSRG joker/M jokey jokier jokiest jokily joking/Y Jolee/M Joleen/M Jolene/M Joletta/M Jolie/M Joliet's Joli/M Joline/M Jolla/M jollification/MS jollily jolliness/SM jollity/MS jolly/TSRDGP Jolson/M jolt/DRGZS jolter/M Joly/M Jolyn/M Jolynn/M Jo/MY Jonah/M Jonahs Jonas Jonathan/M Jonathon/M Jonell/M Jone/MS Jones/S Jonie/M Joni/MS Jon/M jonquil/MS Jonson/M Joplin/M Jordain/M Jordana/M Jordanian/S Jordan/M Jordanna/M Jordon/M Jorey/M Jorgan/M Jorge/M Jorgensen/M Jorgenson/M Jorie/M Jori/M Jorrie/M Jorry/M Jory/M Joscelin/M Josee/M Josefa/M Josefina/M Josef/M Joseito/M Jose/M Josepha/M Josephina/M Josephine/M Joseph/M Josephs Josephson/M Josephus/M Josey/M josh/DSRGZ josher/M Joshia/M Josh/M Joshuah/M Joshua/M Josiah/M Josias/M Josie/M Josi/M Josselyn/M joss/M jostle/SDG Josue/M Josy/M jot/S jotted jotter/SM jotting/SM Joule/M joule/SM jounce/SDG jouncy/RT Jourdain/M Jourdan/M journalese/MS journal/GSDM journalism/SM journalistic journalist/SM journalize/DRSGZ journalized/U journalizer/M journey/DRMZSGJ journeyer/M journeyman/M journeymen jouster/M joust/ZSMRDG Jovanovich/M Jove/M joviality/SM jovial/Y Jovian jowl/SMD jowly/TR Joya/M Joyan/M Joyann/M Joycean Joycelin/M Joyce/M Joye/M joyfuller joyfullest joyfulness/SM joyful/PY joylessness/MS joyless/PY Joy/M joy/MDSG Joyner/M joyousness/MS joyous/YP joyridden joyride/SRZMGJ joyrode joystick/S Jozef/M JP Jpn Jr/M j's J's Jsandye/M Juana/M Juanita/M Juan/M Juarez Jubal/M jubilant/Y jubilate/XNGDS jubilation/M jubilee/SM Judah/M Judaic Judaical Judaism/SM Judas/S juddered juddering Judd/M Judea/M Jude/M judge/AGDS judger/M judge's judgeship/SM judgmental/Y judgment/MS judicable judicatory/S judicature/MS judicial/Y judiciary/S judicious/IYP judiciousness/SMI Judie/M Judi/MH Juditha/M Judith/M Jud/M judo/MS Judon/M Judson/M Judye/M Judy/M jugate/F jugful/SM jugged Juggernaut/M juggernaut/SM jugging juggler/M juggle/RSDGZ jugglery/MS jug/MS jugular/S juice/GMZDSR juicer/M juicily juiciness/MS juicy/TRP Juieta/M jujitsu/MS jujube/SM juju/M jujutsu's jukebox/SM juke/GS Julee/M Jule/MS julep/SM Julia/M Juliana/M Juliane/M Julian/M Julianna/M Julianne/M Juliann/M Julie/M julienne/GSD Julienne/M Julieta/M Juliet/M Julietta/M Juliette/M Juli/M Julina/M Juline/M Julio/M Julissa/M Julita/M Julius/M Jul/M Julys July/SM jumble/GSD jumbo/MS jumper/M jump/GZDRS jumpily jumpiness/MS jumpsuit/S jumpy/PTR jun junco/MS junction/IMESF juncture/SFM Juneau/M June/MS Junette/M Jungfrau/M Jungian jungle/SDM Jung/M Junia/M Junie/M Junina/M juniority/M junior/MS Junior/S juniper/SM junkerdom Junker/SM junketeer/SGDM junket/SMDG junk/GZDRMS junkie/RSMT junkyard/MS Jun/M Juno/M junta/MS Jupiter/M Jurassic juridic juridical/Y juried jurisdictional/Y jurisdiction/SM jurisprudence/SM jurisprudent jurisprudential/Y juristic jurist/MS juror/MS Jurua/M jury/IMS jurying juryman/M jurymen jurywoman/M jurywomen justed Justen/M juster/M justest Justice/M justice/MIS justiciable justifiability/M justifiable/U justifiably/U justification/M justified/UA justifier/M justify/GDRSXZN Justina/M Justine/M justing Justinian/M Justin/M Justinn/M Justino/M Justis/M justness/MS justness's/U justs just/UPY Justus/M jute/SM Jutish Jutland/M jut/S jutted jutting Juvenal/M juvenile/SM juxtapose/SDG juxtaposition/SM JV J/X Jyoti/M Kaaba/M kabob/SM kaboom Kabuki kabuki/SM Kabul/M Kacey/M Kacie/M Kacy/M Kaddish/M kaddish/S Kaela/M kaffeeklatch kaffeeklatsch/S Kafkaesque Kafka/M kaftan's Kagoshima/M Kahaleel/M Kahlil/M Kahlua/M Kahn/M Kaia/M Kaifeng/M Kaila/M Kaile/M Kailey/M Kai/M Kaine/M Kain/M kaiser/MS Kaiser/SM Kaitlin/M Kaitlyn/M Kaitlynn/M Kaja/M Kajar/M Kakalina/M Kalahari/M Kala/M Kalamazoo/M Kalashnikov/M Kalb/M Kaleb/M Kaleena/M kaleidescope kaleidoscope/SM kaleidoscopic kaleidoscopically Kale/M kale/MS Kalgoorlie/M Kalie/M Kalila/M Kalil/M Kali/M Kalina/M Kalinda/M Kalindi/M Kalle/M Kalli/M Kally/M Kalmyk Kalvin/M Kama/M Kamchatka/M Kamehameha/M Kameko/M Kamikaze/MS kamikaze/SM Kamilah/M Kamila/M Kamillah/M Kampala/M Kampuchea/M Kanchenjunga/M Kandace/M Kandahar/M Kandinsky/M Kandy/M Kane/M kangaroo/SGMD Kania/M Kankakee/M Kan/MS Kannada/M Kano/M Kanpur/M Kansan/S Kansas Kantian Kant/M Kanya/M Kaohsiung/M kaolinite/M kaolin/MS Kaplan/M kapok/SM Kaposi/M kappa/MS kaput/M Karachi/M Karaganda/M Karakorum/M karakul/MS Karalee/M Karalynn/M Kara/M Karamazov/M karaoke/S karate/MS karat/SM Karee/M Kareem/M Karel/M Kare/M Karena/M Karenina/M Karen/M Karia/M Karie/M Karil/M Karilynn/M Kari/M Karim/M Karina/M Karine/M Karin/M Kariotta/M Karisa/M Karissa/M Karita/M Karla/M Karlan/M Karlee/M Karleen/M Karlene/M Karlen/M Karlie/M Karlik/M Karlis Karl/MNX Karloff/M Karlotta/M Karlotte/M Karly/M Karlyn/M karma/SM Karmen/M karmic Karna/M Karney/M Karola/M Karole/M Karolina/M Karoline/M Karol/M Karoly/M Karon/M Karo/YM Karp/M Karrah/M Karrie/M Karroo/M Karry/M kart/MS Karylin/M Karyl/M Kary/M Karyn/M Kasai/M Kasey/M Kashmir/SM Kaspar/M Kasparov/M Kasper/M Kass Kassandra/M Kassey/M Kassia/M Kassie/M Kassi/M katakana Katalin/M Kata/M Katee/M Katelyn/M Kate/M Katerina/M Katerine/M Katey/M Katha/M Katharina/M Katharine/M Katharyn/M Kathe/M Katherina/M Katherine/M Katheryn/M Kathiawar/M Kathie/M Kathi/M Kathleen/M Kathlin/M Kath/M Kathmandu Kathrine/M Kathryne/M Kathryn/M Kathye/M Kathy/M Katie/M Kati/M Katina/M Katine/M Katinka/M Katleen/M Katlin/M Kat/M Katmai/M Katmandu's Katowice/M Katrina/M Katrine/M Katrinka/M Kattie/M Katti/M Katuscha/M Katusha/M Katya/M katydid/SM Katy/M Katz/M Kauai/M Kauffman/M Kaufman/M Kaunas/M Kaunda/M Kawabata/M Kawasaki/M kayak/SGDM Kaycee/M Kaye/M Kayla/M Kaylee/M Kayle/M Kayley/M Kaylil/M Kaylyn/M Kay/M Kayne/M kayo/DMSG Kazakh/M Kazakhstan Kazan/M Kazantzakis/M kazoo/SM Kb KB KC kcal/M kc/M KDE/M Keane/M Kean/M Kearney/M Keary/M Keaton/M Keats/M kebab/SM Keck/M Keefe/MR Keefer/M Keegan/M Keelby/M Keeley/M keel/GSMDR keelhaul/SGD Keelia/M Keely/M Keenan/M Keene/M keener/M keen/GTSPYDR keening/M Keen/M keenness/MS keeper/M keep/GZJSR keeping/M keepsake/SM Keewatin/M kegged kegging keg/MS Keillor/M Keir/M Keisha/M Keith/M Kelbee/M Kelby/M Kelcey/M Kelcie/M Kelci/M Kelcy/M Kele/M Kelila/M Kellby/M Kellen/M Keller/M Kelley/M Kellia/M Kellie/M Kelli/M Kellina/M Kellogg/M Kellsie/M Kellyann/M Kelly/M kelp/GZMDS Kelsey/M Kelsi/M Kelsy/M Kelt's Kelvin/M kelvin/MS Kelwin/M Kemerovo/M Kempis/M Kemp/M Kendall/M Kendal/M Kendell/M Kendra/M Kendre/M Kendrick/MS Kenilworth/M Ken/M Kenmore/M ken/MS Kenna/M Kennan/M Kennecott/M kenned Kennedy/M kennel/GSMD Kenneth/M Kennett/M Kennie/M kenning Kennith/M Kenn/M Kenny/M keno/M Kenon/M Kenosha/M Kensington/M Kent/M Kenton/M Kentuckian/S Kentucky/M Kenya/M Kenyan/S Kenyatta/M Kenyon/M Keogh/M Keokuk/M kepi/SM Kepler/M kept keratin/MS kerbside Kerby/M kerchief/MDSG Kerensky/M Kerianne/M Keriann/M Keri/M Kerk/M Ker/M Kermie/M Kermit/M Kermy/M kerned kernel/GSMD kerning Kern/M kerosene/MS Kerouac/M Kerrie/M Kerrill/M Kerri/M Kerrin/M Kerr/M Kerry/M Kerstin/M Kerwin/M Kerwinn/M Kesley/M Keslie/M Kessiah/M Kessia/M Kessler/M kestrel/SM ketch/MS ketchup/SM ketone/M ketosis/M Kettering/M Kettie/M Ketti/M kettledrum/SM kettleful kettle/SM Ketty/M Kevan/M Keven/M Kevina/M Kevin/M Kevlar Kev/MN Kevon/M Kevorkian/M Kevyn/M Kewaskum/M Kewaunee/M Kewpie/M keyboardist/S keyboard/RDMZGS keyclick/SM keyhole/MS Key/M Keynesian/M Keynes/M keynoter/M keynote/SRDZMG keypad/MS keypuncher/M keypunch/ZGRSD keyring key/SGMD keystone/SM keystroke/SDMG keyword/SM k/FGEIS kg K/G KGB Khabarovsk/M Khachaturian/M khaki/SM Khalid/M Khalil/M Khan/M khan/MS Kharkov/M Khartoum/M Khayyam/M Khmer/M Khoisan/M Khomeini/M Khorana/M Khrushchev/SM Khufu/M Khulna/M Khwarizmi/M Khyber/M kHz/M KIA Kiah/M Kial/M kibble/GMSD kibbutzim kibbutz/M kibitzer/M kibitz/GRSDZ kibosh/GMSD Kickapoo/M kickback/SM kickball/MS kicker/M kick/GZDRS kickoff/SM kickstand/MS kicky/RT kidded kidder/SM kiddie/SD kidding/YM kiddish Kidd/M kiddo/SM kiddying kiddy's kidless kid/MS kidnaper's kidnaping's kidnap/MSJ kidnapped kidnapper/SM kidnapping/S kidney/MS kidskin/SM Kieffer/M kielbasa/SM kielbasi Kiele/M Kiel/M Kienan/M kier/I Kierkegaard/M Kiersten/M Kieth/M Kiev/M Kigali/M Kikelia/M Kikuyu/M Kilauea/M Kile/M Kiley/M Kilian/M Kilimanjaro/M kill/BJGZSDR killdeer/SM Killebrew/M killer/M Killian/M Killie/M killing/Y killjoy/S Killy/M kiln/GDSM kilobaud/M kilobit/S kilobuck kilobyte/S kilocycle/MS kilogauss/M kilogram/MS kilohertz/M kilohm/M kilojoule/MS kiloliter/MS kilometer/SM kilo/SM kiloton/SM kilovolt/SM kilowatt/SM kiloword kilter/M kilt/MDRGZS Ki/M Kimball/M Kimbell/M Kimberlee/M Kimberley/M Kimberli/M Kimberly/M Kimberlyn/M Kimble/M Kimbra/M Kim/M Kimmie/M Kimmi/M Kimmy/M kimono/MS Kincaid/M kinda kindergarten/MS kindergrtner/SM kinder/U kindheartedness/MS kindhearted/YP kindle/AGRSD kindler/M kindliness/SM kindliness's/U kindling/M kindly/TUPR kindness's kindness/US kind/PSYRT kindred/S kinematic/S kinematics/M kinesics/M kine/SM kinesthesis kinesthetically kinesthetic/S kinetically kinetic/S kinetics/M kinfolk/S kingbird/M kingdom/SM kingfisher/MS kinglet/M kingliness/M kingly/TPR King/M kingpin/MS Kingsbury/M king/SGYDM kingship/SM Kingsley/M Kingsly/M Kingston/M Kingstown/M Kingwood/M kink/GSDM kinkily kinkiness/SM kinky/PRT Kin/M kin/MS Kinna/M Kinney/M Kinnickinnic/M Kinnie/M Kinny/M Kinsey/M kinsfolk/S Kinshasa/M Kinshasha/M kinship/SM Kinsley/M kinsman/M kinsmen/M kinswoman/M kinswomen kiosk/SM Kiowa/SM Kipling/M Kip/M kip/MS Kippar/M kipped kipper/DMSG Kipper/M Kippie/M kipping Kipp/MR Kippy/M Kira/M Kirbee/M Kirbie/M Kirby/M Kirchhoff/M Kirchner/M Kirchoff/M Kirghistan/M Kirghizia/M Kirghiz/M Kiribati Kiri/M Kirinyaga/M kirk/GDMS Kirkland/M Kirk/M Kirkpatrick/M Kirkwood/M Kirov/M kirsch/S Kirsteni/M Kirsten/M Kirsti/M Kirstin/M Kirstyn/M Kisangani/M Kishinev/M kismet/SM kiss/DSRBJGZ Kissee/M kisser/M Kissiah/M Kissie/M Kissinger/M Kitakyushu/M kitbag's kitchener/M Kitchener/M kitchenette/SM kitchen/GDRMS kitchenware/SM kiter/M kite/SM kith/MDG kiths Kit/M kit/MDRGS kitsch/MS kitschy kitted kittenishness/M kittenish/YP kitten/SGDM Kittie/M Kitti/M kitting kittiwakes Kitty/M kitty/SM Kiwanis/M kiwifruit/S kiwi/SM Kizzee/M Kizzie/M KKK kl Klan/M Klansman/M Klara/M Klarika/M Klarrisa/M Klaus/M klaxon/M Klee/M Kleenex/SM Klein/M Kleinrock/M Klemens/M Klement/M Kleon/M kleptomaniac/SM kleptomania/MS Kliment/M Kline/M Klingon/M Klondike/SDMG kludger/M kludge/RSDGMZ kludgey klutziness/S klutz/SM klutzy/TRP Klux/M klystron/MS km kn knacker/M knack/SGZRDM knackwurst/MS Knapp/M knapsack/MS Knauer/M knavery/MS knave/SM knavish/Y kneader/M knead/GZRDS kneecap/MS kneecapped kneecapping knee/DSM kneeing kneeler/M kneel/GRS kneepad/SM knell/SMDG knelt Knesset/M knew Kngwarreye/M Knickerbocker/MS knickerbocker/S knickknack/SM knick/ZR Knievel/M knife/DSGM knighthood/MS knightliness/MS knightly/P Knight/M knight/MDYSG knish/MS knit/AU knits knitted knitter/MS knitting/SM knitwear/M knives/M knobbly knobby/RT Knobeloch/M knob/MS knockabout/M knockdown/S knocker/M knock/GZSJRD knockoff/S knockout/MS knockwurst's knoll/MDSG Knopf/M Knossos/M knothole/SM knot/MS knotted knottiness/M knotting/M knotty/TPR knowable/U knower/M know/GRBSJ knowhow knowingly/U knowing/RYT knowings/U knowledgeableness/M knowledgeable/P knowledgeably knowledge/SM Knowles known/SU Knox/M Knoxville/M knuckleball/R knuckle/DSMG knuckleduster knucklehead/MS Knudsen/M Knudson/M knurl/DSG Knuth/M Knutsen/M Knutson/M KO koala/SM Kobayashi/M Kobe/M Kochab/M Koch/M Kodachrome/M Kodak/SM Kodaly/M Kodiak/M Koenig/M Koenigsberg/M Koenraad/M Koestler/M Kohinoor/M Kohler/M Kohl/MR kohlrabies kohlrabi/M kola/SM Kolyma/M Kommunizma/M Kong/M Kongo/M Konrad/M Konstance/M Konstantine/M Konstantin/M Konstanze/M kookaburra/SM kook/GDMS kookiness/S kooky/PRT Koo/M Koontz/M kopeck/MS Koppers/M Koralle/M Koral/M Kora/M Koranic Koran/SM Kordula/M Korea/M Korean/S Korella/M Kore/M Koren/M Koressa/M Korey/M Korie/M Kori/M Kornberg/M Korney/M Korrie/M Korry/M Kort/M Kory/M Korzybski/M Kosciusko/M kosher/DGS Kossuth/M Kosygin/M Kovacs/M Kowalewski/M Kowalski/M Kowloon/M kowtow/SGD KP kph kraal/SMDG Kraemer/M kraft/M Kraft/M Krakatau's Krakatoa/M Krakow/M Kramer/M Krasnodar/M Krasnoyarsk/M Krause/M kraut/S! Krebs/M Kremlin/M Kremlinologist/MS Kremlinology/MS Kresge/M Krieger/M kriegspiel/M krill/MS Kringle/M Krisha/M Krishnah/M Krishna/M Kris/M Krispin/M Krissie/M Krissy/M Kristal/M Krista/M Kristan/M Kristel/M Kriste/M Kristen/M Kristian/M Kristie/M Kristien/M Kristi/MN Kristina/M Kristine/M Kristin/M Kristofer/M Kristoffer/M Kristofor/M Kristoforo/M Kristo/MS Kristopher/M Kristy/M Kristyn/M Kr/M Kroc/M Kroger/M krna/M Kronecker/M krone/RM kronor krnur Kropotkin/M Krueger/M Kruger/M Krugerrand/S Krupp/M Kruse/M krypton/SM Krystalle/M Krystal/M Krysta/M Krystle/M Krystyna/M ks K's KS k's/IE kt Kublai/M Kubrick/M kuchen/MS kudos/M kudzu/SM Kuenning/M Kuhn/M Kuibyshev/M Ku/M Kumar/M kumquat/SM Kunming/M Kuomintang/M Kurdish/M Kurdistan/SM Kurd/SM Kurosawa/M Kurtis/M Kurt/M kurtosis/M Kusch/M Kuwaiti/SM Kuwait/M Kuznetsk/M Kuznets/M kvetch/DSG kw kW Kwakiutl/M Kwangchow's Kwangju/M Kwanzaa/S kWh KY Kyla/M kyle/M Kyle/M Kylen/M Kylie/M Kylila/M Kylynn/M Ky/MH Kym/M Kynthia/M Kyoto/M Kyrgyzstan Kyrstin/M Kyushu/M L LA Laban/M labeled/U labeler/M label/GAZRDS labellings/A label's labial/YS labia/M labile labiodental labium/M laboratory/MS laboredness/M labored/PMY labored's/U laborer/M laboring/MY laborings/U laboriousness/MS laborious/PY labor/RDMJSZG laborsaving Labradorean/S Labrador/SM lab/SM Lab/SM laburnum/SM labyrinthine labyrinth/M labyrinths laced/U Lacee/M lace/MS lacerate/NGVXDS laceration/M lacer/M laces/U lacewing/MS Lacey/M Lachesis/M lachrymal/S lachrymose Lacie/M lacing/M lackadaisic lackadaisical/Y Lackawanna/M lacker/M lackey/SMDG lack/GRDMS lackluster/S Lac/M laconic laconically lacquerer/M lacquer/ZGDRMS lacrosse/MS lac/SGMDR lactate/MNGSDX lactational/Y lactation/M lacteal lactic lactose/MS lacunae lacuna/M Lacy/M lacy/RT ladder/GDMS laddie/MS laded/U ladened ladening laden/U lade/S lading/M ladle/SDGM Ladoga/M Ladonna/M lad/XGSJMND ladybird/SM ladybug/MS ladyfinger/SM ladylike/U ladylove/MS Ladyship/MS ladyship/SM lady/SM Lady/SM Laetitia/M laetrile/S Lafayette/M Lafitte/M lager/DMG laggard/MYSP laggardness/M lagged lagging/MS lagniappe/SM lagoon/MS Lagos/M Lagrange/M Lagrangian/M Laguerre/M Laguna/M lag/ZSR Lahore/M laid/AI Laidlaw/M lain Laina/M Lainey/M Laird/M laird/MS lair/GDMS laissez laity/SM Laius/M lake/DSRMG Lakehurst/M Lakeisha/M laker/M lakeside Lakewood/M Lakisha/M Lakshmi/M lallygagged lallygagging lallygag/S Lalo/M La/M Lamaism/SM Lamarck/M Lamar/M lamasery/MS lama/SM Lamaze lambada/S lambaste/SDG lambda/SM lambency/MS lambent/Y Lambert/M lambkin/MS Lamb/M Lamborghini/M lambskin/MS lamb/SRDMG lambswool lamebrain/SM lamed/M lameness/MS lamentableness/M lamentable/P lamentably lamentation/SM lament/DGSB lamented/U lame/SPY la/MHLG laminae lamina/M laminar laminate/XNGSD lamination/M lam/MDRSTG lammed lammer lamming Lammond/M Lamond/M Lamont/M L'Amour lampblack/SM lamplighter/M lamplight/ZRMS lampooner/M lampoon/RDMGS Lamport/M lamppost/SM lamprey/MS lamp/SGMRD lampshade/MS LAN Lanae/M Lanai/M lanai/SM Lana/M Lancashire/M Lancaster/M Lancelot/M Lance/M lancer/M lance/SRDGMZ lancet/MS landau/MS lander/I landfall/SM landfill/DSG landforms landholder/M landhold/JGZR landing/M Landis/M landlady/MS landless landlines landlocked landlord/MS landlubber/SM Land/M landmark/GSMD landmass/MS Landon/M landowner/MS landownership/M landowning/SM Landry/M Landsat landscape/GMZSRD landscaper/M lands/I landslide/MS landslid/G landslip landsman/M landsmen land/SMRDJGZ Landsteiner/M landward/S Landwehr/M Lane/M lane/SM Lanette/M Laney/M Langeland/M Lange/M Langerhans/M Langford/M Langland/M Langley/M Lang/M Langmuir/M Langsdon/M Langston/M language/MS languidness/MS languid/PY languisher/M languishing/Y languish/SRDG languorous/Y languor/SM Lanie/M Lani/M Lanita/M lankiness/SM lankness/MS lank/PTYR lanky/PRT Lanna/M Lannie/M Lanni/M Lanny/M lanolin/MS Lansing/M lantern/GSDM lanthanide/M lanthanum/MS lanyard/MS Lanzhou Laocoon/M Lao/SM Laotian/MS lapboard/MS lapdog/S lapel/MS lapidary/MS lapin/MS Laplace/M Lapland/ZMR lapped lappet/MS lapping Lapp/SM lapsed/A lapse/KSDMG lapser/MA lapses/A lapsing/A lap/SM laps/SRDG laptop/SM lapwing/MS Laraine/M Lara/M Laramie/M larboard/MS larcenist/S larcenous larceny/MS larch/MS larder/M lard/MRDSGZ Lardner/M lardy/RT Laredo/M largehearted largemouth largeness/SM large/SRTYP largess/SM largish largo/S lariat/MDGS Lari/M Larina/M Larine/M Larisa/M Larissa/M larker/M lark/GRDMS Lark/M larkspur/MS Larousse/M Larry/M Larsen/M Lars/NM Larson/M larvae larval larva/M laryngeal/YS larynges laryngitides laryngitis/M larynx/M Laryssa/M lasagna/S lasagne's Lascaux/M lasciviousness/MS lascivious/YP lase laser/M lashed/U lasher/M lashing/M lash/JGMSRD Lassa/M Lassen/M Lassie/M lassie/SM lassitude/MS lassoer/M lasso/GRDMS las/SRZG lass/SM laster/M lastingness/M lasting/PY last/JGSYRD Laszlo/M Latasha/M Latashia/M latching/M latchkey/SM latch's latch/UGSD latecomer/SM lated/A late/KA lately latency/MS lateness/MS latent/YS later/A lateral/GDYS lateralization Lateran/M latest/S LaTeX/M latex/MS lathe/M latherer/M lather/RDMG lathery lathing/M lath/MSRDGZ Lathrop/M laths Latia/M latices/M Latina/SM Latinate Latino/S Latin/RMS latish Latisha/M latitude/SM latitudinal/Y latitudinarian/S latitudinary Lat/M Latonya/M Latoya/M Latrena/M Latrina/M latrine/MS Latrobe/M lat/SDRT latter/YM latte/SR lattice/SDMG latticework/MS latticing/M Lattimer/M Latvia/M Latvian/S laudably laudanum/MS laudatory Lauderdale/M lauder/M Lauder/M Laud/MR laud/RDSBG lauds/M Laue/M laughableness/M laughable/P laughably laugh/BRDZGJ laugher/M laughing/MY laughingstock/SM laughs laughter/MS Laughton/M Launce/M launch/AGSD launcher/MS launching/S launchpad/S laundered/U launderer/M launderette/MS launder/SDRZJG laundress/MS laundrette/S laundromat/S Laundromat/SM laundryman/M laundrymen laundry/MS laundrywoman/M laundrywomen Lauraine/M Lauralee/M Laural/M laura/M Laura/M Laurasia/M laureate/DSNG laureateship/SM Lauree/M Laureen/M Laurella/M Laurel/M laurel/SGMD Laure/M Laurena/M Laurence/M Laurene/M Lauren/SM Laurentian Laurent/M Lauretta/M Laurette/M Laurianne/M Laurice/M Laurie/M Lauri/M Lauritz/M Lauryn/M Lausanne/M lavage/MS lavaliere/MS Laval/M lava/SM lavatory/MS lave/GDS Lavena/M lavender/MDSG Laverna/M Laverne/M Lavern/M Lavina/M Lavinia/M Lavinie/M lavishness/MS lavish/SRDYPTG Lavoisier/M Lavonne/M Lawanda/M lawbreaker/SM lawbreaking/MS Lawford/M lawfulness/SMU lawful/PUY lawgiver/MS lawgiving/M lawlessness/MS lawless/PY Law/M lawmaker/MS lawmaking/SM lawman/M lawmen lawnmower/S lawn/SM Lawrence/M Lawrenceville/M lawrencium/SM Lawry/M law/SMDG Lawson/M lawsuit/MS Lawton/M lawyer/DYMGS laxativeness/M laxative/PSYM laxer/A laxes/A laxity/SM laxness/SM lax/PTSRY layabout/MS Layamon/M layaway/S lay/CZGSR layered/C layer/GJDM layering/M layer's/IC layette/SM Layla/M Lay/M layman/M laymen Layne/M Layney/M layoff/MS layout/SM layover/SM laypeople layperson/S lays/AI Layton/M layup/MS laywoman/M laywomen Lazare/M Lazar/M Lazaro/M Lazarus/M laze/DSG lazily laziness/MS lazuli/M lazybones/M lazy/PTSRDG lb LBJ/M lbs LC LCD LCM LDC leachate Leach/M leach/SDG Leadbelly/M leaded/U leadenness/M leaden/PGDY leaderless leader/M leadership/MS lead/SGZXJRDN leadsman/M leadsmen leafage/MS leaf/GSDM leafhopper/M leafiness/M leafless leaflet/SDMG leafstalk/SM leafy/PTR leaguer/M league/RSDMZG Leah/M leakage/SM leaker/M Leakey/M leak/GSRDM leakiness/MS leaky/PRT Lea/M lea/MS Leander/M Leandra/M leaner/M leaning/M Lean/M Leanna/M Leanne/M leanness/MS Leann/M Leanora/M Leanor/M lean/YRDGTJSP leaper/M leapfrogged leapfrogging leapfrog/SM leap/RDGZS Lear/M learnedly learnedness/M learned/UA learner/M learning/M learns/UA learn/SZGJRD Leary/M lease/ARSDG leaseback/MS leaseholder/M leasehold/SRMZ leaser/MA lease's leash's leash/UGSD leasing/M leas/SRDGZ least/S leastwise leatherette/S leather/MDSG leathern leatherneck/SM leathery leaven/DMJGS leavened/U leavening/M Leavenworth/M leaver/M leaves/M leave/SRDJGZ leaving/M Lebanese Lebanon/M Lebbie/M lebensraum Lebesgue/M Leblanc/M lecher/DMGS lecherousness/MS lecherous/YP lechery/MS lecithin/SM lectern/SM lecturer/M lecture/RSDZMG lectureship/SM led Leda/M Lederberg/M ledger/DMG ledge/SRMZ LED/SM Leeanne/M Leeann/M leech/MSDG Leeds/M leek/SM Leelah/M Leela/M Leeland/M Lee/M lee/MZRS Leena/M leer/DG leeriness/MS leering/Y leery/PTR Leesa/M Leese/M Leeuwenhoek/M Leeward/M leeward/S leeway/MS leftism/SM leftist/SM leftmost leftover/MS Left/S left/TRS leftward/S Lefty/M lefty/SM legacy/MS legalese/MS legalism/SM legalistic legality/MS legalization/MS legalize/DSG legalized/U legal/SY legate/AXCNGSD legatee/MS legate's/C legation/AMC legato/SM legendarily legendary/S Legendre/M legend/SM legerdemain/SM Leger/SM legged legginess/MS legging/MS leggy/PRT leghorn/SM Leghorn/SM legibility/MS legible legibly legionary/S legionnaire/SM legion/SM legislate/SDXVNG legislation/M legislative/SY legislator/SM legislature/MS legitimacy/MS legitimate/SDNGY legitimation/M legitimatize/SDG legitimization/MS legitimize/RSDG legit/S legless legman/M legmen leg/MS Lego/M Legra/M Legree/M legroom/MS legstraps legume/SM leguminous legwork/SM Lehigh/M Lehman/M Leia/M Leibniz/M Leicester/SM Leiden/M Leif/M Leigha/M Leigh/M Leighton/M Leilah/M Leila/M lei/MS Leipzig/M Leisha/M leisureliness/MS leisurely/P leisure/SDYM leisurewear leitmotif/SM leitmotiv/MS Lek/M Lelah/M Lela/M Leland/M Lelia/M Lemaitre/M Lemar/M Lemke/M Lem/M lemma/MS lemme/GJ Lemmie/M lemming/M Lemmy/M lemonade/SM lemon/GSDM lemony Lemuel/M Lemuria/M lemur/MS Lena/M Lenard/M Lenci/M lender/M lend/SRGZ Lenee/M Lenette/M lengthener/M lengthen/GRD lengthily lengthiness/MS length/MNYX lengths lengthwise lengthy/TRP lenience/S leniency/MS lenient/SY Leningrad/M Leninism/M Leninist Lenin/M lenitive/S Lenka/M Len/M Le/NM Lenna/M Lennard/M Lennie/M Lennon/M Lenny/M Lenoir/M Leno/M Lenora/M Lenore/M lens/SRDMJGZ lent/A lenticular lentil/SM lento/S Lent/SMN Leodora/M Leoine/M Leola/M Leoline/M Leo/MS Leona/M Leonanie/M Leonard/M Leonardo/M Leoncavallo/M Leonelle/M Leonel/M Leone/M Leonerd/M Leonhard/M Leonidas/M Leonid/M Leonie/M leonine Leon/M Leonora/M Leonore/M Leonor/M Leontine/M Leontyne/M leopardess/SM leopard/MS leopardskin Leopold/M Leopoldo/M Leopoldville/M Leora/M leotard/MS leper/SM Lepidus/M Lepke/M leprechaun/SM leprosy/MS leprous lepta lepton/SM Lepus/M Lerner/M Leroi/M Leroy/M Lesa/M lesbianism/MS lesbian/MS Leshia/M lesion/DMSG Lesley/M Leslie/M Lesli/M Lesly/M Lesotho/M lessee/MS lessen/GDS Lesseps/M lesser lesses Lessie/M lessing lesson/DMSG lessor/MS less/U Lester/M lest/R Les/Y Lesya/M Leta/M letdown/SM lethality/M lethal/YS Letha/M lethargic lethargically lethargy/MS Lethe/M Lethia/M Leticia/M Letisha/M let/ISM Letitia/M Letizia/M Letta/M letterbox/S lettered/U letterer/M letterhead/SM lettering/M letter/JSZGRDM letterman/M Letterman/M lettermen letterpress/MS Lettie/M Letti/M letting/S lettuce/SM Letty/M letup/MS leukemia/SM leukemic/S leukocyte/MS Leupold/M Levant/M leveeing levee/SDM leveled/U leveler/M levelheadedness/S levelheaded/P leveling/U levelness/SM level/STZGRDYP leverage/MGDS lever/SDMG Levesque/M Levey/M Leviathan leviathan/MS levier/M Levi/MS Levine/M Levin/M levitate/XNGDS levitation/M Leviticus/M Levitt/M levity/MS Lev/M Levon/M Levy/M levy/SRDZG lewdness/MS lewd/PYRT Lewellyn/M Lewes Lewie/M Lewinsky/M lewis/M Lewis/M Lewiss Lew/M lex lexeme/MS lexical/Y lexicographer/MS lexicographic lexicographical/Y lexicography/SM lexicon/SM Lexie/M Lexi/MS Lexine/M Lexington/M Lexus/M Lexy/M Leyden/M Leyla/M Lezley/M Lezlie/M lg Lhasa/SM Lhotse/M liability/SAM liable/AP liaise/GSD liaison/SM Lia/M Liam/M Liana/M Liane/M Lian/M Lianna/M Lianne/M liar/MS libation/SM libbed Libbey/M Libbie/M Libbi/M libbing Libby/M libeler/M libel/GMRDSZ libelous/Y Liberace/M liberalism/MS liberality/MS liberalization/SM liberalized/U liberalize/GZSRD liberalizer/M liberalness/MS liberal/YSP liberate/NGDSCX liberationists liberation/MC liberator/SCM Liberia/M Liberian/S libertarianism/M libertarian/MS libertine/MS liberty/MS libidinal libidinousness/M libidinous/PY libido/MS Lib/M lib/MS librarian/MS library/MS Libra/SM libretoes libretos librettist/MS libretto/MS Libreville/M Librium/M Libya/M Libyan/S lice/M licensed/AU licensee/SM license/MGBRSD licenser/M licenses/A licensing/A licensor/M licentiate/MS licentiousness/MS licentious/PY Licha/M lichee's lichen/DMGS Lichtenstein/M Lichter/M licit/Y licked/U lickerish licker/M lick/GRDSJ licking/M licorice/SM Lida/M lidded lidding Lidia/M lidless lid/MS lido/MS Lieberman/M Liebfraumilch/M Liechtenstein/RMZ lied/MR lie/DRS Lief/M liefs/A lief/TSR Liege/M liege/SR Lie/M lien/SM lier/IMA lies/A Liesa/M lieu/SM lieut lieutenancy/MS lieutenant/SM Lieut/M lifeblood/SM lifeboat/SM lifebuoy/S lifeforms lifeguard/MDSG lifelessness/SM lifeless/PY lifelikeness/M lifelike/P lifeline/SM lifelong life/MZR lifer/M lifesaver/SM lifesaving/S lifespan/S lifestyle/S lifetaking lifetime/MS lifework/MS LIFO lifter/M lift/GZMRDS liftoff/MS ligament/MS ligand/MS ligate/XSDNG ligation/M ligature/DSGM light/ADSCG lighted/U lightener/M lightening/M lighten/ZGDRS lighter/CM lightered lightering lighters lightest lightface/SDM lightheaded lightheartedness/MS lighthearted/PY lighthouse/MS lighting/MS lightly lightness/MS lightning/SMD lightproof light's lightship/SM lightweight/S ligneous lignite/MS lignum likability/MS likableness/MS likable/P likeability's liked/E likelihood/MSU likely/UPRT likeness/MSU liken/GSD liker/E liker's likes/E likest like/USPBY likewise liking/SM lilac/MS Lilah/M Lila/SM Lilia/MS Liliana/M Liliane/M Lilian/M Lilith/M Liliuokalani/M Lilla/M Lille/M Lillian/M Lillie/M Lilli/MS lilliputian/S Lilliputian/SM Lilliput/M Lilllie/M Lilly/M Lil/MY Lilongwe/M lilting/YP lilt/MDSG Lilyan/M Lily/M lily/MSD Lima/M Limbaugh/M limbered/U limberness/SM limber/RDYTGP limbers/U limbic limbless Limbo limbo/GDMS limb/SGZRDM Limburger/SM limeade/SM lime/DSMG limekiln/M limelight/DMGS limerick/SM limestone/SM limitability limitably limitation/MCS limit/CSZGRD limitedly/U limitedness/M limited/PSY limiter/M limiting/S limitlessness/SM limitless/PY limit's limn/GSD Limoges/M limo/S limousine/SM limper/M limpet/SM limpidity/MS limpidness/SM limpid/YP limpness/MS Limpopo/M limp/SGTPYRD Li/MY limy/TR linage/MS Lina/M linchpin/MS Linc/M Lincoln/SM Linda/M Lindbergh/M Lindberg/M linden/MS Lindholm/M Lindie/M Lindi/M Lind/M Lindon/M Lindquist/M Lindsay/M Lindsey/M Lindstrom/M Lindsy/M Lindy/M line/AGDS lineage/SM lineal/Y Linea/M lineament/MS linearity/MS linearize/SDGNB linear/Y linebacker/SM lined/U linefeed Linell/M lineman/M linemen linen/SM liner/SM line's linesman/M linesmen Linet/M Linette/M lineup/S lingerer/M lingerie/SM lingering/Y linger/ZGJRD lingoes lingo/M lingual/SY lingua/M linguine linguini's linguistically linguistic/S linguistics/M linguist/SM ling/ZR liniment/MS lining/SM linkable linkage/SM linked/A linker/S linking/S Link/M link's linkup/S link/USGD Lin/M Linnaeus/M Linnea/M Linnell/M Linnet/M linnet/SM Linnie/M Linn/M Linoel/M linoleum/SM lino/M Linotype/M linseed/SM lintel/SM linter/M Linton/M lint/SMR linty/RST Linus/M Linux/M Linwood/M Linzy/M Lionello/M Lionel/M lioness/SM lionhearted lionization/SM lionizer/M lionize/ZRSDG Lion/M lion/MS lipase/M lipid/MS lip/MS liposuction/S lipped lipper Lippi/M lipping Lippmann/M lippy/TR lipread/GSRJ Lipschitz/M Lipscomb/M lipstick/MDSG Lipton/M liq liquefaction/SM liquefier/M liquefy/DRSGZ liqueur/DMSG liquidate/GNXSD liquidation/M liquidator/SM liquidity/SM liquidizer/M liquidize/ZGSRD liquidness/M liquid/SPMY liquorice/SM liquorish liquor/SDMG lira/M Lira/M lire Lisabeth/M Lisa/M Lisbeth/M Lisbon/M Lise/M Lisetta/M Lisette/M Lisha/M Lishe/M Lisle/M lisle/SM lisper/M lisp/MRDGZS Lissajous/M Lissa/M Lissie/M Lissi/M Liss/M lissomeness/M lissome/P lissomness/M Lissy/M listed/U listener/M listen/ZGRD Listerine/M lister/M Lister/M listing/M list/JMRDNGZXS listlessness/SM listless/PY Liston/M Liszt/M Lita/M litany/MS litchi/SM literacy/MS literalism/M literalistic literalness/MS literal/PYS literariness/SM literary/P literate/YNSP literati literation/M literature/SM liter/M lite/S litheness/SM lithe/PRTY lithesome lithium/SM lithograph/DRMGZ lithographer/M lithographic lithographically lithographs lithography/MS lithology/M lithosphere/MS lithospheric Lithuania/M Lithuanian/S litigant/MS litigate/NGXDS litigation/M litigator/SM litigiousness/MS litigious/PY litmus/SM litotes/M lit/RZS littrateur/S litterbug/SM litter/SZGRDM Little/M littleneck/M littleness/SM little/RSPT Littleton/M Litton/M littoral/S liturgical/Y liturgic/S liturgics/M liturgist/MS liturgy/SM Liuka/M livability/MS livableness/M livable/U livably Liva/M lived/A livelihood/SM liveliness/SM livelong/S lively/RTP liveness/M liven/SDG liver/CSGD liveried liverish Livermore/M Liverpool/M Liverpudlian/MS liver's liverwort/SM liverwurst/SM livery/CMS liveryman/MC liverymen/C lives/A lives's livestock/SM live/YHZTGJDSRPB Livia/M lividness/M livid/YP livingness/M Livingstone/M Livingston/M living/YP Liv/M Livonia/M Livvie/M Livvy/M Livvyy/M Livy/M Lizabeth/M Liza/M lizard/MS Lizbeth/M Lizette/M Liz/M Lizzie/M Lizzy/M l/JGVXT Ljubljana/M LL llama/SM llano/SM LLB ll/C LLD Llewellyn/M Lloyd/M Llywellyn/M LNG lo loadable loaded/A loader/MU loading/MS load's/A loads/A loadstar's loadstone's load/SURDZG loafer/M Loafer/S loaf/SRDMGZ loam/SMDG loamy/RT loaner/M loaning/M loan/SGZRDMB loansharking/S loanword/S loathe loather/M loathing/M loath/JPSRDYZG loathness/M loathsomeness/MS loathsome/PY loaves/M Lobachevsky/M lobar lobbed lobber/MS lobbing lobby/GSDM lobbyist/MS lobe/SM lob/MDSG lobotomist lobotomize/GDS lobotomy/MS lobster/MDGS lobularity lobular/Y lobule/SM locale/MS localisms locality/MS localization/MS localized/U localizer/M localizes/U localize/ZGDRS local/SGDY locatable locate/AXESDGN locater/M locational/Y location/EMA locative/S locator's Lochinvar/M loch/M lochs loci/M lockable Lockean/M locked/A Locke/M locker/SM locket/SM Lockhart/M Lockheed/M Lockian/M locking/S lockjaw/SM Lock/M locknut/M lockout/MS lock's locksmithing/M locksmith/MG locksmiths lockstep/S lock/UGSD lockup/MS Lockwood/M locomotion/SM locomotive/YMS locomotor locomotory loco/SDMG locoweed/MS locus/M locust/SM locution/MS lode/SM lodestar/MS lodestone/MS lodged/E lodge/GMZSRDJ Lodge/M lodgepole lodger/M lodges/E lodging/M lodgment/M Lodovico/M Lodowick/M Lodz Loeb/M Loella/M Loewe/M Loewi/M lofter/M loftily loftiness/SM loft/SGMRD lofty/PTR loganberry/SM Logan/M logarithmic logarithmically logarithm/MS logbook/MS loge/SMNX logged/U loggerhead/SM logger/SM loggia/SM logging/MS logicality/MS logicalness/M logical/SPY logician/SM logic/SM login/S logion/M logistical/Y logistic/MS logjam/SM LOGO logo/SM logotype/MS logout logrolling/SM log's/K log/SM logy/RT Lohengrin/M loincloth/M loincloths loin/SM Loire/M Loise/M Lois/M loiterer/M loiter/RDJSZG Loki/M Lola/M Loleta/M Lolita/M loller/M lollipop/MS loll/RDGS Lolly/M lolly/SM Lombardi/M Lombard/M Lombardy/M Lomb/M Lome Lona/M Londonderry/M Londoner/M London/RMZ Lonee/M loneliness/SM lonely/TRP loneness/M lone/PYZR loner/M lonesomeness/MS lonesome/PSY longboat/MS longbow/SM longed/K longeing longer/K longevity/MS Longfellow/M longhair/SM longhand/SM longhorn/SM longing/MY longish longitude/MS longitudinal/Y long/JGTYRDPS Long/M longness/M longshoreman/M longshoremen longsighted longs/K longstanding Longstreet/M longsword longterm longtime Longueuil/M longueur/SM longways longword/SM Loni/M Lon/M Lonna/M Lonnard/M Lonnie/M Lonni/M Lonny/M loofah/M loofahs lookahead lookalike/S looker/M look/GZRDS lookout/MS lookup/SM looming/M Loomis/M loom/MDGS loon/MS loony/SRT looper/M loophole/MGSD loop/MRDGS loopy/TR loosed/U looseleaf loosener/M looseness/MS loosen/UDGS loose/SRDPGTY looses/U loosing/M looter/M loot/MRDGZS loper/M lope/S Lopez/M lopped lopper/MS lopping lop/SDRG lopsidedness/SM lopsided/YP loquaciousness/MS loquacious/YP loquacity/SM Loraine/M Lorain/M Loralee/M Loralie/M Loralyn/M Lora/M Lorant/M lording/M lordliness/SM lordly/PTR Lord/MS lord/MYDGS lordship/SM Lordship/SM Loree/M Loreen/M Lorelei/M Lorelle/M lore/MS Lorena/M Lorene/M Loren/SM Lorentzian/M Lorentz/M Lorenza/M Lorenz/M Lorenzo/M Loretta/M Lorette/M lorgnette/SM Loria/M Lorianna/M Lorianne/M Lorie/M Lorilee/M Lorilyn/M Lori/M Lorinda/M Lorine/M Lorin/M loris/SM Lorita/M lorn Lorna/M Lorne/M Lorraine/M Lorrayne/M Lorre/M Lorrie/M Lorri/M Lorrin/M lorryload/S Lorry/M lorry/SM Lory/M Los loser/M lose/ZGJBSR lossage lossless loss/SM lossy/RT lost/P Lothaire/M Lothario/MS lotion/MS Lot/M lot/MS Lotta/M lotted Lotte/M lotter lottery/MS Lottie/M Lotti/M lotting Lott/M lotto/MS Lotty/M lotus/SM louden/DG loudhailer/S loudly/RT loudmouth/DM loudmouths loudness/MS loudspeaker/SM loudspeaking loud/YRNPT Louella/M Louie/M Louisa/M Louise/M Louisette/M Louisiana/M Louisianan/S Louisianian/S Louis/M Louisville/M Lou/M lounger/M lounge/SRDZG Lourdes/M lour/GSD louse/CSDG louse's lousewort/M lousily lousiness/MS lousy/PRT loutishness/M loutish/YP Loutitia/M lout/SGMD louver/DMS L'Ouverture Louvre/M lovableness/MS lovable/U lovably lovebird/SM lovechild Lovecraft/M love/DSRMYZGJB loved/U Lovejoy/M Lovelace/M Loveland/M lovelessness/M loveless/YP lovelies lovelinesses loveliness/UM Lovell/M lovelornness/M lovelorn/P lovely/URPT Love/M lovemaking/SM lover/YMG lovesick lovestruck lovingly lovingness/M loving/U lowborn lowboy/SM lowbrow/MS lowdown/S Lowell/M Lowe/M lowercase/GSD lower/DG lowermost Lowery/M lowish lowland/RMZS Lowlands/M lowlife/SM lowlight/MS lowliness/MS lowly/PTR lowness/MS low/PDRYSZTG Lowrance/M lox/MDSG loyaler loyalest loyal/EY loyalism/SM loyalist/SM loyalty/EMS Loyang/M Loydie/M Loyd/M Loy/M Loyola/M lozenge/SDM LP LPG LPN/S Lr ls l's L's LSD ltd Ltd/M Lt/M Luanda/M Luann/M luau/MS lubber/YMS Lubbock/M lube/DSMG lubricant/SM lubricate/VNGSDX lubrication/M lubricator/MS lubricious/Y lubricity/SM Lubumbashi/M Lucais/M Luca/MS Luce/M lucent/Y Lucerne/M Lucho/M Lucia/MS Luciana/M Lucian/M Luciano/M lucidity/MS lucidness/MS lucid/YP Lucie/M Lucien/M Lucienne/M Lucifer/M Lucila/M Lucile/M Lucilia/M Lucille/M Luci/MN Lucina/M Lucinda/M Lucine/M Lucio/M Lucita/M Lucite/MS Lucius/M luck/GSDM luckier/U luckily/U luckiness/UMS luckless Lucknow/M Lucky/M lucky/RSPT lucrativeness/SM lucrative/YP lucre/MS Lucretia/M Lucretius/M lucubrate/GNSDX lucubration/M Lucy/M Luddite/SM Ludhiana/M ludicrousness/SM ludicrous/PY Ludlow/M Ludmilla/M ludo/M Ludovico/M Ludovika/M Ludvig/M Ludwig/M Luella/M Luelle/M luff/GSDM Lufthansa/M Luftwaffe/M luge/MC Luger/M luggage/SM lugged lugger/SM lugging Lugosi/M lug/RS lugsail/SM lugubriousness/MS lugubrious/YP Luigi/M Luisa/M Luise/M Luis/M Lukas/M Luke/M lukewarmness/SM lukewarm/PY Lula/M Lulita/M lullaby/GMSD lull/SDG lulu/M Lulu/M Lu/M lumbago/SM lumbar/S lumberer/M lumbering/M lumberjack/MS lumberman/M lumbermen lumber/RDMGZSJ lumberyard/MS lumen/M Lumire/M luminance/M luminary/MS luminescence/SM luminescent luminosity/MS luminousness/M luminous/YP lummox/MS lumper/M lumpiness/MS lumpishness/M lumpish/YP lump/SGMRDN lumpy/TPR lunacy/MS Luna/M lunar/S lunary lunate/YND lunatic/S lunation/M luncheonette/SM luncheon/SMDG luncher/M lunch/GMRSD lunchpack lunchroom/MS lunchtime/MS Lundberg/M Lund/M Lundquist/M lune/M lunge/MS lunger/M lungfish/SM lungful lung/SGRDM lunkhead/SM Lupe/M lupine/SM Lupus/M lupus/SM Lura/M lurcher/M lurch/RSDG lure/DSRG lurer/M Lurette/M lurex Luria/M luridness/SM lurid/YP lurker/M lurk/GZSRD Lurleen/M Lurlene/M Lurline/M Lusaka/M Lusa/M lusciousness/MS luscious/PY lushness/MS lush/YSRDGTP Lusitania/M luster/GDM lustering/M lusterless lustfulness/M lustful/PY lustily lustiness/MS lust/MRDGZS lustrousness/M lustrous/PY lusty/PRT lutanist/MS lute/DSMG lutenist/MS Lutero/M lutetium/MS Lutheranism/MS Lutheran/SM Luther/M luting/M Lutz Luxembourgian Luxembourg/RMZ Luxemburg's luxe/MS luxuriance/MS luxuriant/Y luxuriate/GNSDX luxuriation/M luxuriousness/SM luxurious/PY luxury/MS Luz/M Luzon/M L'vov Lyallpur/M lyceum/MS lychee's lycopodium/M Lycra/S Lycurgus/M Lyda/M Lydia/M Lydian/S Lydie/M Lydon/M lye/JSMG Lyell/M lying/Y Lyle/M Lyly/M Lyman/M Lyme/M lymphatic/S lymph/M lymphocyte/SM lymphoid lymphoma/MS lymphs Ly/MY Lynchburg/M lyncher/M lynching/M Lynch/M lynch/ZGRSDJ Lynda/M Lyndell/M Lyndel/M Lynde/M Lyndon/M Lyndsay/M Lyndsey/M Lyndsie/M Lyndy/M Lynea/M Lynelle/M Lynette/M Lynett/M Lyn/M Lynna/M Lynnea/M Lynnelle/M Lynnell/M Lynne/M Lynnet/M Lynnette/M Lynnett/M Lynn/M Lynsey/M lynx/MS Lyon/SM Lyra/M lyrebird/MS lyre/SM lyricalness/M lyrical/YP lyricism/SM lyricist/SM lyric/S Lysenko/M lysine/M Lysistrata/M Lysol/M Lyssa/M LyX/M MA Maalox/M ma'am Mabelle/M Mabel/M Mable/M Mab/M macabre/Y macadamize/SDG macadam/SM Macao/M macaque/SM macaroni/SM macaroon/MS Macarthur/M MacArthur/M Macaulay/M macaw/SM Macbeth/M Maccabees/M Maccabeus/M Macdonald/M MacDonald/M MacDraw/M Macedonia/M Macedonian/S Macedon/M mace/MS Mace/MS macerate/DSXNG maceration/M macer/M Macgregor/M MacGregor/M machete/SM Machiavellian/S Machiavelli/M machinate/SDXNG machination/M machinelike machine/MGSDB machinery/SM machinist/MS machismo/SM Mach/M macho/S Machs Macias/M Macintosh/M MacIntosh/M macintosh's Mackenzie/M MacKenzie/M mackerel/SM Mackinac/M Mackinaw mackinaw/SM mackintosh/SM mack/M Mack/M MacLeish/M Macmillan/M MacMillan/M Macon/SM MacPaint/M macram/S macrobiotic/S macrobiotics/M macrocosm/MS macrodynamic macroeconomic/S macroeconomics/M macromolecular macromolecule/SM macron/MS macrophage/SM macroscopic macroscopically macrosimulation macro/SM macrosocioeconomic Mac/SGMD mac/SGMDR Macy/M Madagascan/SM Madagascar/M Madalena/M Madalyn/M Mada/M madame/M Madame/MS madam/SM madcap/S Maddalena/M madded madden/GSD maddening/Y Madden/M madder/MS maddest Maddie/M Maddi/M madding Maddox/M Maddy/M made/AU Madeira/SM Madelaine/M Madeleine/M Madelena/M Madelene/M Madelina/M Madeline/M Madelin/M Madella/M Madelle/M Madel/M Madelon/M Madelyn/M mademoiselle/MS Madge/M madhouse/SM Madhya/M Madison/M Madlen/M Madlin/M madman/M madmen madness/SM Madonna/MS mad/PSY Madras madras/SM Madrid/M madrigal/MSG Madsen/M Madurai/M madwoman/M madwomen Mady/M Maegan/M Maelstrom/M maelstrom/SM Mae/M maestro/MS Maeterlinck/M Mafia/MS mafia/S mafiosi mafioso/M Mafioso/S MAG magazine/DSMG Magdaia/M Magdalena/M Magdalene/M Magdalen/M Magda/M Magellanic Magellan/M magenta/MS magged Maggee/M Maggie/M Maggi/M magging maggot/MS maggoty/RT Maggy/M magi magical/Y magician/MS magicked magicking magic/SM Magill/M Magi/M Maginot/M magisterial/Y magistracy/MS magistrate/MS Mag/M magma/SM magnanimity/SM magnanimosity magnanimous/PY magnate/SM magnesia/MS magnesite/M magnesium/SM magnetically magnetic/S magnetics/M magnetism/SM magnetite/SM magnetizable magnetization/ASCM magnetize/CGDS magnetized/U magnetodynamics magnetohydrodynamical magnetohydrodynamics/M magnetometer/MS magneto/MS magnetosphere/M magnetron/M magnet/SM magnification/M magnificence/SM magnificent/Y magnified/U magnify/DRSGNXZ magniloquence/MS magniloquent Magnitogorsk/M magnitude/SM magnolia/SM Magnum magnum/SM Magnuson/M Magog/M Magoo/M magpie/SM Magritte/M Magruder/M mag/S Magsaysay/M Maguire/SM Magus/M Magyar/MS Mahabharata Mahala/M Mahalia/M maharajah/M maharajahs maharanee's maharani/MS Maharashtra/M maharishi/SM mahatma/SM Mahavira/M Mahayana/M Mahayanist Mahdi/M Mahfouz/M Mahican/SM mahjong's Mahler/M Mahmoud/M Mahmud/M mahogany/MS Mahomet's mahout/SM Maia/M Maible/M maidenhair/MS maidenhead/SM maidenhood/SM maidenly/P maiden/YM maidservant/MS maid/SMNX maier Maier/M Maiga/M Maighdiln/M Maigret/M mailbag/MS mailbox/MS mail/BSJGZMRD mailer/M Mailer/M Maillol/M maillot/SM mailman/M mailmen Maiman/M maimedness/M maimed/P maimer/M Maimonides/M Mai/MR maim/SGZRD mainbrace/M Maine/MZR Mainer/M mainframe/MS mainlander/M mainland/SRMZ mainliner/M mainline/RSDZG mainly mainmast/SM main/SA mainsail/SM mains/M mainspring/SM mainstay/MS mainstream/DRMSG maintainability maintainable/U maintain/BRDZGS maintained/U maintainer/M maintenance/SM maintop/SM maiolica's Maire/M Mair/M Maisey/M Maisie/M maisonette/MS Maison/M Maitilde/M maize/MS Maj Maje/M majestic majestically majesty/MS Majesty/MS majolica/SM Majorca/M major/DMGS majordomo/S majorette/SM majority/SM Major/M Majuro/M makable Makarios/M makefile/S makeover/S Maker/M maker/SM makeshift/S make/UGSA makeup/MS making/SM Malabar/M Malabo/M Malacca/M Malachi/M malachite/SM maladapt/DV maladjust/DLV maladjustment/MS maladministration maladroitness/MS maladroit/YP malady/MS Malagasy/M malaise/SM Mala/M Malamud/M malamute/SM Malanie/M malaprop malapropism/SM Malaprop/M malarial malaria/MS malarious malarkey/SM malathion/S Malawian/S Malawi/M Malayalam/M Malaya/M Malayan/MS Malaysia/M Malaysian/S Malay/SM Malchy/M Malcolm/M malcontentedness/M malcontented/PY malcontent/SMD Maldive/SM Maldivian/S Maldonado/M maledict malediction/MS malefaction/MS malefactor/MS malefic maleficence/MS maleficent Male/M Malena/M maleness/MS male/PSM malevolence/S malevolencies malevolent/Y malfeasance/SM malfeasant malformation/MS malformed malfunction/SDG Malia/M Malian/S Malibu/M malice/MGSD maliciousness/MS malicious/YU malignancy/SM malignant/YS malign/GSRDYZ malignity/MS Mali/M Malina/M Malinda/M Malinde/M malingerer/M malinger/GZRDS Malinowski/M Malissa/M Malissia/M mallard/SM Mallarm/M malleability/SM malleableness/M malleable/P mallet/MS Mallissa/M Mallorie/M Mallory/M mallow/MS mall/SGMD Mal/M malnourished malnutrition/SM malocclusion/MS malodorous Malone/M Malorie/M Malory/M malposed malpractice/SM Malraux/M Malta/M malted/S Maltese Malthusian/S Malthus/M malting/M maltose/SM maltreat/GDSL maltreatment/S malt/SGMD malty/RT Malva/M Malvina/M Malvin/M Malynda/M mama/SM mamba/SM mambo/GSDM Mame/M Mamet/M ma/MH Mamie/M mammalian/SM mammal/SM mammary mamma's mammogram/S mammography/S Mammon's mammon/SM mammoth/M mammoths mammy/SM Mamore/M manacle/SDMG manageability/S manageableness manageable/U managed/U management/SM manageress/M managerial/Y manager/M managership/M manage/ZLGRSD Managua/M Manama/M maana/M mananas Manasseh/M manatee/SM Manaus's Manchester/M Manchu/MS Manchuria/M Manchurian/S Mancini/M manciple/M Mancunian/MS mandala/SM Mandalay/M Manda/M mandamus/GMSD Mandarin mandarin/MS mandate/SDMG mandatory/S Mandela Mandelbrot/M Mandel/M mandible/MS mandibular Mandie/M Mandi/M Mandingo/M mandolin/MS mandrake/MS mandrel/SM mandrill/SM Mandy/M mange/GSD mane/MDS Manet/M maneuverability/MS maneuverer/M maneuver/MRDSGB Manfred/M manful/Y manganese/MS mange/GMSRDZ manger/M manginess/S mangler/M mangle/RSDG mangoes mango/M mangrove/MS mangy/PRT manhandle/GSD Manhattan/SM manhole/MS manhood/MS manhunt/SM maniacal/Y maniac/SM mania/SM manically Manichean/M manic/S manicure/MGSD manicurist/SM manifestation/SM manifesto/GSDM manifest/YDPGS manifolder/M manifold/GPYRDMS manifoldness/M manikin/MS Manila/MS manila/S manilla's Mani/M manioc/SM manipulability manipulable manipulate/SDXBVGN manipulative/PM manipulator/MS manipulatory Manitoba/M Manitoulin/M Manitowoc/M mankind/M Mankowski/M Manley/M manlike manliness/SM manliness's/U manly/URPT manna/MS manned/U mannequin/MS mannered/U mannerism/SM mannerist/M mannerliness/MU mannerly/UP manner/SDYM Mann/GM Mannheim/M Mannie/M mannikin's Manning/M manning/U mannishness/SM mannish/YP Manny/M Manolo/M Mano/M manometer/SM Manon/M manorial manor/MS manpower/SM manqu/M man's mansard/SM manservant/M manse/XNM Mansfield/M mansion/M manslaughter/SM Man/SM Manson/M mans/S manta/MS Mantegna/M mantelpiece/MS mantel/SM mantes mantilla/MS mantissa/SM mantis/SM mantle/ESDG Mantle/M mantle's mantling/M mantra/MS mantrap/SM manual/SMY Manuela/M Manuel/M manufacture/JZGDSR manufacturer/M manumission/MS manumit/S manumitted manumitting manure/RSDMZG manuscript/MS man/USY Manville/M Manx many Manya/M Maoism/MS Maoist/S Mao/M Maori/SM Maplecrest/M maple/MS mapmaker/S mappable mapped/UA mapper/S mapping/MS Mapplethorpe/M maps/AU map/SM Maputo/M Marabel/M marabou/MS marabout's Maracaibo/M maraca/MS Mara/M maraschino/SM Marathi marathoner/M Marathon/M marathon/MRSZ Marat/M marauder/M maraud/ZGRDS marbleize/GSD marble/JRSDMG marbler/M marbling/M Marceau/M Marcela/M Marcelia/M Marcelino/M Marcella/M Marcelle/M Marcellina/M Marcelline/M Marcello/M Marcellus/M Marcel/M Marcelo/M Marchall/M Marchelle/M marcher/M marchioness/SM March/MS march/RSDZG Marcia/M Marciano/M Marcie/M Marcile/M Marcille/M Marci/M Marc/M Marconi/M Marco/SM Marcotte/M Marcus/M Marcy/M Mardi/SM Marduk/M Mareah/M mare/MS Marena/M Maren/M Maressa/M Margalit/M Margalo/M Marga/M Margareta/M Margarete/M Margaretha/M Margarethe/M Margaret/M Margaretta/M Margarette/M margarine/MS Margarita/M margarita/SM Margarito/M Margaux/M Margeaux/M Marge/M Margery/M Marget/M Margette/M Margie/M Margi/M marginalia marginality marginalization marginalize/SDG marginal/YS margin/GSDM Margit/M Margo/M Margot/M Margrethe/M Margret/M Marguerite/M Margy/M mariachi/SM maria/M Maria/M Mariam/M Mariana/SM Marian/MS Marianna/M Marianne/M Mariann/M Mariano/M Maribelle/M Maribel/M Maribeth/M Maricela/M Marice/M Maridel/M Marieann/M Mariejeanne/M Mariele/M Marielle/M Mariellen/M Mariel/M Marie/M Marietta/M Mariette/M Marigold/M marigold/MS Marijn/M Marijo/M marijuana/SM Marika/M Marilee/M Marilin/M Marillin/M Marilyn/M marimba/SM Mari/MS marinade/MGDS Marina/M marina/MS marinara/SM marinate/NGXDS marination/M mariner/M Marine/S marine/ZRS Marin/M Marinna/M Marino/M Mario/M marionette/MS Marion/M Mariquilla/M Marisa/M Mariska/M Marisol/M Marissa/M Maritain/M marital/Y Marita/M maritime/R Maritsa/M Maritza/M Mariupol/M Marius/M Mariya/M Marja/M Marje/M Marjie/M Marji/M Marj/M marjoram/SM Marjorie/M Marjory/M Marjy/M Markab/M markdown/SM marked/AU markedly marker/M marketability/SM marketable/U Marketa/M marketeer/S marketer/M market/GSMRDJBZ marketing/M marketplace/MS mark/GZRDMBSJ Markham/M marking/M Markism/M markkaa markka/M Mark/MS Markos Markov Markovian Markovitz/M marks/A marksman/M marksmanship/S marksmen markup/SM Markus/M Marla/M Marlane/M Marlboro/M Marlborough/M Marleah/M Marlee/M Marleen/M Marlena/M Marlene/M Marley/M Marlie/M Marline/M marlinespike/SM Marlin/M marlin/SM marl/MDSG Marlo/M Marlon/M Marlowe/M Marlow/M Marlyn/M Marmaduke/M marmalade/MS Marmara/M marmoreal marmoset/MS marmot/SM Marna/M Marne/M Marney/M Marnia/M Marnie/M Marni/M maroon/GRDS marquee/MS Marquesas/M marque/SM marquess/MS marquetry/SM Marquette/M Marquez/M marquise/M marquisette/MS Marquis/M marquis/SM Marquita/M Marrakesh/M marred/U marriageability/SM marriageable marriage/ASM married/US Marrilee/M marring Marriott/M Marris/M Marrissa/M marrowbone/MS marrow/GDMS marry/SDGA mar/S Marseillaise/SM Marseilles Marseille's marshal/GMDRSZ Marshalled/M marshaller Marshall/GDM Marshalling/M marshallings Marshal/M Marsha/M marshiness/M marshland/MS Marsh/M marshmallow/SM marsh/MS marshy/PRT Marsiella/M Mar/SMN marsupial/MS Martainn/M Marta/M Martelle/M Martel/M marten/M Marten/M Martguerita/M Martha/M Marthe/M Marthena/M Martial martial/Y Martian/S Martica/M Martie/M Marti/M Martina/M martinet/SM Martinez/M martingale/MS martini/MS Martinique/M Martin/M Martino/M martin/SM Martinson/M Martita/M mart/MDNGXS Mart/MN Marty/M Martyn/M Martynne/M martyrdom/SM martyr/GDMS Marva/M marvel/DGS Marvell/M marvelous/PY Marve/M Marven/M Marvin/M Marv/NM Marwin/M Marxian/S Marxism/SM Marxist/SM Marx/M Marya/M Maryanna/M Maryanne/M Maryann/M Marybelle/M Marybeth/M Maryellen/M Maryjane/M Maryjo/M Maryland/MZR Marylee/M Marylinda/M Marylin/M Maryl/M Marylou/M Marylynne/M Mary/M Maryrose/M Marys Marysa/M marzipan/SM Masada/M Masai/M Masaryk/M masc Mascagni/M mascara/SGMD mascot/SM masculineness/M masculine/PYS masculinity/SM Masefield/M maser/M Maseru/M MASH Masha/M Mashhad/M mash/JGZMSRD m/ASK masked/U masker/M mask/GZSRDMJ masks/U masochism/MS masochistic masochistically masochist/MS masonic Masonic Masonite/M masonry/MS mason/SDMG Mason/SM masquerader/M masquerade/RSDGMZ masquer/M masque/RSMZ Massachusetts/M massacre/DRSMG massager/M massage/SRDMG Massasoit/M Massenet/M masseur/MS masseuse/SM Massey/M massif/SM Massimiliano/M Massimo/M massing/R massiveness/SM massive/YP massless mas/SRZ Mass/S mass/VGSD mastectomy/MS masterclass mastered/A masterfulness/M masterful/YP master/JGDYM masterliness/M masterly/P mastermind/GDS masterpiece/MS mastership/M Master/SM masterstroke/MS masterwork/S mastery/MS mast/GZSMRD masthead/SDMG masticate/SDXGN mastication/M mastic/SM mastiff/MS mastodon/MS mastoid/S masturbate/SDNGX masturbation/M masturbatory matador/SM Mata/M matchable/U match/BMRSDZGJ matchbook/SM matchbox/SM matched/UA matcher/M matches/A matchless/Y matchlock/MS matchmake/GZJR matchmaker/M matchmaking/M matchplay match's/A matchstick/MS matchwood/SM mated/U mate/IMS Matelda/M Mateo/M materialism/SM materialistic materialistically materialist/SM materiality/M materialization/SM materialize/CDS materialized/A materializer/SM materializes/A materializing materialness/M material/SPYM matriel/MS mater/M maternal/Y maternity/MS mates/U mathematical/Y Mathematica/M mathematician/SM mathematic/S mathematics/M Mathematik/M Mather/M Mathe/RM Mathew/MS Mathewson/M Mathian/M Mathias Mathieu/M Mathilda/M Mathilde/M Mathis math/M maths Matias/M Matilda/M Matilde/M matine/S mating/M matins/M Matisse/SM matriarchal matriarch/M matriarchs matriarchy/MS matrices matricidal matricide/MS matriculate/XSDGN matriculation/M matrimonial/Y matrimony/SM matrix/M matron/YMS mat/SJGMDR Matsumoto/M matte/JGMZSRD Mattel/M Matteo/M matter/GDM Matterhorn/M Matthaeus/M Mattheus/M Matthew/MS Matthias Matthieu/M Matthiew/M Matthus/M Mattias/M Mattie/M Matti/M matting/M mattins's Matt/M mattock/MS mattress/MS matt's Matty/M maturate/DSNGVX maturational maturation/M matureness/M maturer/M mature/RSDTPYG maturity/MS matzo/SHM matzot Maude/M Maudie/M maudlin/Y Maud/M Maugham/M Maui/M mauler/M maul/RDGZS maunder/GDS Maupassant/M Maura/M Maureene/M Maureen/M Maure/M Maurene/M Mauriac/M Maurice/M Mauricio/M Maurie/M Maurine/M Maurise/M Maurita/M Mauritania/M Mauritanian/S Mauritian/S Mauritius/M Maurits/M Maurizia/M Maurizio/M Maurois/M Mauro/M Maury/M Mauser/M mausoleum/SM mauve/SM maven/S maverick/SMDG mavin's Mavis/M Mavra/M mawkishness/SM mawkish/PY Mawr/M maw/SGMD max/GDS Maxie/M maxillae maxilla/M maxillary/S Maxi/M maximality maximal/SY maxima's Maximilian/M Maximilianus/M Maximilien/M maximization/SM maximizer/M maximize/RSDZG Maxim/M Maximo/M maxim/SM maximum/MYS Maxine/M maxi/S Max/M Maxtor/M Maxwellian maxwell/M Maxwell/M Maxy/M Maya/MS Mayan/S Maybelle/M maybe/S mayday/S may/EGS Maye/M mayer Mayer/M mayest Mayfair/M Mayflower/M mayflower/SM mayfly/MS mayhap mayhem/MS Maynard/M Mayne/M Maynord/M mayn't Mayo/M mayonnaise/MS mayoral mayoralty/MS mayoress/MS Mayor/M mayor/MS mayorship/M mayo/S maypole/MS Maypole/SM Mayra/M May/SMR mayst Mazama/M Mazarin/M Mazatlan/M Mazda/M mazedness/SM mazed/YP maze/MGDSR mazurka/SM Mazzini/M Mb MB MBA Mbabane/M Mbini/M MC McAdam/MS McAllister/M McBride/M McCabe/M McCain/M McCall/M McCarthyism/M McCarthy/M McCartney/M McCarty/M McCauley/M McClain/M McClellan/M McClure/M McCluskey/M McConnell/M McCormick/M McCoy/SM McCracken/M McCray/M McCullough/M McDaniel/M McDermott/M McDonald/M McDonnell/M McDougall/M McDowell/M McElhaney/M McEnroe/M McFadden/M McFarland/M McGee/M McGill/M McGovern/M McGowan/M McGrath/M McGraw/M McGregor/M McGuffey/M McGuire/M MCI/M McIntosh/M McIntyre/M McKay/M McKee/M McKenzie/M McKesson/M McKinley/M McKinney/M McKnight/M McLanahan/M McLaughlin/M McLean/M McLeod/M McLuhan/M McMahon/M McMartin/M McMillan/M McNamara/M McNaughton/M McNeil/M McPherson/M MD Md/M mdse MDT ME Meade/M Mead/M meadowland meadowlark/SM meadow/MS Meadows meadowsweet/M mead/SM Meagan/M meagerness/SM meager/PY Meaghan/M meagres mealiness/MS meal/MDGS mealtime/MS mealybug/S mealymouthed mealy/PRST meander/JDSG meaneing meanie/MS meaningfulness/SM meaningful/YP meaninglessness/SM meaningless/PY meaning/M meanness/S means/M meantime/SM meant/U meanwhile/S Meany/M mean/YRGJTPS meany's Meara/M measle/SD measles/M measly/TR measurable/U measurably measure/BLMGRSD measured/Y measureless measurement/SM measurer/M measures/A measuring/A meas/Y meataxe meatball/MS meatiness/MS meatless meatloaf meatloaves meat/MS meatpacking/S meaty/RPT Mecca/MS mecca/S mechanical/YS mechanic/MS mechanism/SM mechanistic mechanistically mechanist/M mechanization/SM mechanized/U mechanizer/M mechanize/RSDZGB mechanizes/U mechanochemically Mechelle/M med medalist/MS medallion/MS medal/SGMD Medan/M meddle/GRSDZ meddlesome Medea/M Medellin Medfield/M mediaeval's medial/AY medials median/YMS media/SM mediateness/M mediate/PSDYVNGX mediation/ASM mediator/SM Medicaid/SM medical/YS medicament/MS Medicare/MS medicate/DSXNGV medication/M Medici/MS medicinal/SY medicine/DSMG medico/SM medic/SM medievalist/MS medieval/YMS Medina/M mediocre mediocrity/MS meditate/NGVXDS meditation/M meditativeness/M meditative/PY Mediterranean/MS mediumistic medium/SM medley/SM medulla/SM Medusa/M meed/MS meekness/MS meek/TPYR meerschaum/MS meeter/M meetinghouse/S meeting/M meet/JGSYR me/G mega megabit/MS megabuck/S megabyte/S megacycle/MS megadeath/M megadeaths megahertz/M megalithic megalith/M megaliths megalomaniac/SM megalomania/SM megalopolis/SM Megan/M megaphone/SDGM megaton/MS megavolt/M megawatt/SM megaword/S Megen/M Meggie/M Meggi/M Meggy/M Meghan/M Meghann/M Meg/MN megohm/MS Mehetabel/M Meier/M Meighen/M Meiji/M Mei/MR meioses meiosis/M meiotic Meir/M Meister/M Meistersinger/M Mejia/M Mekong/M Mela/M Melamie/M melamine/SM melancholia/SM melancholic/S melancholy/MS Melanesia/M Melanesian/S melange/S Melania/M Melanie/M melanin/MS melanoma/SM Melantha/M Melany/M Melba/M Melbourne/M Melcher/M Melchior/M meld/SGD mle/MS Melendez/M Melesa/M Melessa/M Melicent/M Melina/M Melinda/M Melinde/M meliorate/XSDVNG melioration/M Melisa/M Melisande/M Melisandra/M Melisenda/M Melisent/M Melissa/M Melisse/M Melita/M Melitta/M Mella/M Mellicent/M Mellie/M mellifluousness/SM mellifluous/YP Melli/M Mellisa/M Mellisent/M Melloney/M Mellon/M mellowness/MS mellow/TGRDYPS Melly/M Mel/MY Melodee/M melodically melodic/S Melodie/M melodiousness/S melodious/YP melodrama/SM melodramatically melodramatic/S Melody/M melody/MS Melonie/M melon/MS Melony/M Melosa/M Melpomene/M meltdown/S melter/M melting/Y Melton/M melt/SAGD Melva/M Melville/M Melvin/M Melvyn/M Me/M member/DMS membered/AE members/EA membership/SM membrane/MSD membranous memento/SM Memling/M memoir/MS memorabilia memorability/SM memorableness/M memorable/P memorably memorandum/SM memorialize/DSG memorialized/U memorial/SY memoriam memorization/MS memorized/U memorizer/M memorize/RSDZG memorizes/A memoryless memory/MS memo/SM Memphis/M menace/GSD menacing/Y menagerie/SM menage/S Menander/M menarche/MS Menard/M Mencius/M Mencken/M mendaciousness/M mendacious/PY mendacity/MS Mendeleev/M mendelevium/SM Mendelian Mendel/M Mendelssohn/M mender/M Mendez/M mendicancy/MS mendicant/S Mendie/M mending/M Mendocino/M Mendoza/M mend/RDSJGZ Mendy/M Menelaus/M Menes/M menfolk/S menhaden/M menial/YS meningeal meninges meningitides meningitis/M meninx menisci meniscus/M Menkalinan/M Menkar/M Menkent/M Menlo/M men/MS Mennonite/SM Menominee menopausal menopause/SM menorah/M menorahs Menotti/M Mensa/M Mensch/M mensch/S menservants/M mens/SDG menstrual menstruate/NGDSX menstruation/M mensurable/P mensuration/MS menswear/M mentalist/MS mentality/MS mental/Y mentholated menthol/SM mentionable/U mentioned/U mentioner/M mention/ZGBRDS mentor/DMSG Menuhin/M menu/SM Menzies/M meow/DSG Mephistopheles/M Merak/M Mercado/M mercantile Mercator/M Mercedes mercenariness/M mercenary/SMP mercerize/SDG Mercer/M mercer/SM merchandiser/M merchandise/SRDJMZG merchantability merchantman/M merchantmen merchant/SBDMG Mercie/M mercifully/U mercifulness/M merciful/YP mercilessness/SM merciless/YP Merci/M Merck/M mercurial/SPY mercuric Mercurochrome/M mercury/MS Mercury/MS Mercy/M mercy/SM Meredeth/M Meredithe/M Meredith/M Merell/M meretriciousness/SM meretricious/YP mere/YS merganser/MS merger/M merge/SRDGZ Meridel/M meridian/MS meridional Meridith/M Meriel/M Merilee/M Merill/M Merilyn/M meringue/MS merino/MS Meris Merissa/M merited/U meritocracy/MS meritocratic meritocrats meritoriousness/MS meritorious/PY merit/SCGMD Meriwether/M Merla/M Merle/M Merlina/M Merline/M merlin/M Merlin/M Merl/M mermaid/MS merman/M mermen Merna/M Merola/M meromorphic Merralee/M Merrel/M Merriam/M Merrick/M Merridie/M Merrielle/M Merrie/M Merrilee/M Merrile/M Merrili/M Merrill/M merrily Merrily/M Merrimack/M Merrimac/M merriment/MS merriness/S Merritt/M Merry/M merrymaker/MS merrymaking/SM merry/RPT Mersey/M mer/TGDR Merton/M Mervin/M Merv/M Merwin/M Merwyn/M Meryl/M Mesa Mesabi/M mesa/SM mescaline/SM mescal/SM mesdames/M mesdemoiselles/M Meshed's meshed/U mesh/GMSD mesmeric mesmerism/SM mesmerized/U mesmerizer/M mesmerize/SRDZG Mesolithic/M mesomorph/M mesomorphs meson/MS Mesopotamia/M Mesopotamian/S mesosphere/MS mesozoic Mesozoic mesquite/MS mes/S message/SDMG messeigneurs messenger/GSMD Messerschmidt/M mess/GSDM Messiaen/M messiah Messiah/M messiahs Messiahs messianic Messianic messieurs/M messily messiness/MS messmate/MS Messrs/M messy/PRT mestizo/MS meta metabolic metabolically metabolism/MS metabolite/SM metabolize/GSD metacarpal/S metacarpi metacarpus/M metacircular metacircularity metalanguage/MS metalization/SM metalized metallic/S metalliferous metallings metallography/M metalloid/M metallurgic metallurgical/Y metallurgist/S metallurgy/MS metal/SGMD metalsmith/MS metalworking/M metalwork/RMJGSZ Meta/M metamathematical metamorphic metamorphism/SM metamorphose/GDS metamorphosis/M metaphoric metaphorical/Y metaphor/MS metaphosphate/M metaphysical/Y metaphysic/SM metastability/M metastable metastases metastasis/M metastasize/DSG metastatic metatarsal/S metatarsi metatarsus/M metatheses metathesis/M metathesized metathesizes metathesizing metavariable metempsychoses metempsychosis/M meteoric meteorically meteorite/SM meteoritic/S meteoritics/M meteoroid/SM meteorologic meteorological meteorologist/S meteorology/MS meteor/SM meter/GDM mete/ZDGSR methadone/SM methane/MS methanol/SM methinks methionine/M methodicalness/SM methodical/YP methodism Methodism/SM methodist/MS Methodist/MS method/MS methodological/Y methodologists methodology/MS methought Methuen/M Methuselah/M Methuselahs methylated methylene/M methyl/SM meticulousness/MS meticulous/YP mtier/S metonymy/M Metrecal/M metrical/Y metricate/SDNGX metricize/GSD metrics/M metric/SM metronome/MS metropolis/SM metropolitanization metropolitan/S metro/SM mets Metternich/M mettle/SDM mettlesome met/U Metzler/M Meuse/M mewl/GSD mew/SGD mews/SM Mex Mexicali/M Mexican/S Mexico/M Meyerbeer/M Meyer/SM mezzanine/MS mezzo/S MFA mfg mfr/S mg M/GB Mg/M MGM/M mgr Mgr MHz MI MIA Mia/M Miami/SM Miaplacidus/M miasmal miasma/SM Micaela/M Micah/M mica/MS micelles mice/M Michaela/M Michaelangelo/M Michaelina/M Michaeline/M Michaella/M Michaelmas/MS Michael/SM Michaelson/M Michail/M Michale/M Michal/M Micheal/M Micheil/M Michelangelo/M Michele/M Michelina/M Micheline/M Michelin/M Michelle/M Michell/M Michel/M Michelson/M Michigander/S Michiganite/S Michigan/M Mich/M Mickelson/M Mickey/M mickey/SM Mickie/M Micki/M Mick/M Micky/M Mic/M Micmac/M micra's microamp microanalysis/M microanalytic microbe/MS microbial microbicidal microbicide/M microbiological microbiologist/MS microbiology/SM microbrewery/S microchemistry/M microchip/S microcircuit/MS microcode/GSD microcomputer/MS microcosmic microcosm/MS microdensitometer microdot/MS microeconomic/S microeconomics/M microelectronic/S microelectronics/M microfiber/S microfiche/M microfilm/DRMSG microfossils micrography/M microgroove/MS microhydrodynamics microinstruction/SM microjoule microlevel microlight/S micromanage/GDSL micromanagement/S micrometeorite/MS micrometeoritic micrometer/SM Micronesia/M Micronesian/S micron/MS microorganism/SM microphone/SGM Microport/M microprocessing microprocessor/SM microprogrammed microprogramming microprogram/SM micro/S microscope/SM microscopic microscopical/Y microscopy/MS microsecond/MS microsimulation/S Microsystems micros/M Microsoft/M microsomal microstore microsurgery/SM MicroVAXes MicroVAX/M microvolt/SM microwaveable microwave/BMGSD microword/S midair/MS midas Midas/M midband/M midday/MS midden/SM middest middlebrow/SM Middlebury/M middle/GJRSD middleman/M middlemen middlemost Middlesex/M Middleton/M Middletown/M middleweight/SM middling/Y middy/SM Mideastern Mideast/M midfield/RM Midge/M midge/SM midget/MS midi/S midland/MRS Midland/MS midlife midlives midmorn/G midmost/S midnight/SYM midpoint/MS midrange midrib/MS midriff/MS mid/S midscale midsection/M midshipman/M midshipmen midship/S midspan midstream/MS midst/SM midsummer/MS midterm/MS midtown/MS Midway/M midway/S midweek/SYM Midwesterner/M Midwestern/ZR Midwest/M midwicket midwifery/SM midwife/SDMG midwinter/YMS midwives midyear/MS mien/M miff/GDS mightily mightiness/MS mightn't might/S mighty/TPR mignon mignonette/SM Mignon/M Mignonne/M migraine/SM migrant/MS migrate/ASDG migration/MS migrative migratory/S MIG/S Miguela/M Miguelita/M Miguel/M mikado/MS Mikaela/M Mikael/M mike/DSMG Mikel/M Mike/M Mikey/M Mikhail/M Mikkel/M Mikol/M Mikoyan/M milady/MS Milagros/M Milanese Milan/M milch/M mildew/DMGS mildness/MS Mildred/M Mildrid/M mild/STYRNP mileage/SM Milena/M milepost/SM miler/M mile/SM Mile/SM milestone/MS Milford/M Milicent/M milieu/SM Milissent/M militancy/MS militantness/M militant/YPS militarily militarism/SM militaristic militarist/MS militarization/SCM militarize/SDCG military militate/SDG militiaman/M militiamen militia/SM Milka/M Milken/M milker/M milk/GZSRDM milkiness/MS milkmaid/SM milkman/M milkmen milkshake/S milksop/SM milkweed/MS milky/RPT millage/S Millard/M Millay/M millenarian millenarianism/M millennial millennialism millennium/MS millepede's miller/M Miller/M Millet/M millet/MS milliamp milliampere/S milliard/MS millibar/MS Millicent/M millidegree/S Millie/M milligram/MS millijoule/S Millikan/M milliliter/MS Milli/M millimeter/SM milliner/SM millinery/MS milling/M millionaire/MS million/HDMS millionth/M millionths millipede/SM millisecond/MS Millisent/M millivoltmeter/SM millivolt/SM milliwatt/S millpond/MS millrace/SM mill/SGZMRD Mill/SMR millstone/SM millstream/SM millwright/MS Milly/M mil/MRSZ Mil/MY Milne/M Milo/M Milquetoast/S milquetoast/SM Miltiades/M Miltie/M Milt/M milt/MDSG Miltonic Milton/M Miltown/M Milty/M Milwaukee/M Milzie/M MIMD mime/DSRMG mimeograph/GMDS mimeographs mimer/M mimesis/M mimetic mimetically mimicked mimicker/SM mimicking mimicry/MS mimic/S Mimi/M mi/MNX Mimosa/M mimosa/SM Mina/M minaret/MS minatory mincemeat/MS mincer/M mince/SRDGZJ mincing/Y Minda/M Mindanao/M mind/ARDSZG mindbogglingly minded/P minder/M mindfully mindfulness/MS mindful/U mindlessness/SM mindless/YP Mindoro/M min/DRZGJ mind's mindset/S Mindy/M minefield/MS mineralization/C mineralized/U mineralogical mineralogist/SM mineralogy/MS mineral/SM miner/M Miner/M Minerva/M mineshaft mine/SNX minestrone/MS minesweeper/MS Minetta/M Minette/M mineworkers mingle/SDG Ming/M Mingus/M miniature/GMSD miniaturist/SM miniaturization/MS miniaturize/SDG minibike/S minibus/SM minicab/M minicam/MS minicomputer/SM minidress/SM minify/GSD minimalism/S minimalistic minimalist/MS minimality minimal/SY minima's minimax/M minimization/MS minimized/U minimizer/M minimize/RSDZG minim/SM minimum/MS mining/M minion/M mini/S miniseries miniskirt/MS ministerial/Y minister/MDGS ministrant/S ministration/SM ministry/MS minivan/S miniver/M minke mink/SM Min/MR Minna/M Minnaminnie/M Minneapolis/M Minne/M minnesinger/MS Minnesota/M Minnesotan/S Minnie/M Minni/M Minn/M Minnnie/M minnow/SM Minny/M Minoan/S Minolta/M minor/DMSG minority/MS Minor/M Minos Minotaur/M minotaur/S Minot/M minoxidil/S Minsk/M Minsky/M minster/SM minstrel/SM minstrelsy/MS mintage/SM Mintaka/M Minta/M minter/M mint/GZSMRD minty/RT minuend/SM minuet/SM Minuit/M minuscule/SM minus/S minuteman Minuteman/M minutemen minuteness/SM minute/RSDPMTYG minutiae minutia/M minx/MS Miocene MIPS Miquela/M Mirabeau/M Mirabella/M Mirabelle/M Mirabel/M Mirach/M miracle/MS miraculousness/M miraculous/PY mirage/GSDM Mira/M Miranda/M Miran/M Mireielle/M Mireille/M Mirella/M Mirelle/M mire/MGDS Mirfak/M Miriam/M Mirilla/M Mir/M Mirna/M Miro mirror/DMGS mirthfulness/SM mirthful/PY mirthlessness/M mirthless/YP mirth/M mirths MIRV/DSG miry/RT Mirzam/M misaddress/SDG misadventure/SM misalign/DSGL misalignment/MS misalliance/MS misanalysed misanthrope/MS misanthropic misanthropically misanthropist/S misanthropy/SM misapplier/M misapply/GNXRSD misapprehend/GDS misapprehension/MS misappropriate/GNXSD misbegotten misbehaver/M misbehave/RSDG misbehavior/SM misbrand/DSG misc miscalculate/XGNSD miscalculation/M miscall/SDG miscarriage/MS miscarry/SDG miscast/GS miscegenation/SM miscellanea miscellaneous/PY miscellany/MS Mischa/M mischance/MGSD mischief/MDGS mischievousness/MS mischievous/PY miscibility/S miscible/C misclassification/M misclassified misclassifying miscode/SDG miscommunicate/NDS miscomprehended misconceive/GDS misconception/MS misconduct/GSMD misconfiguration misconstruction/MS misconstrue/DSG miscopying miscount/DGS miscreant/MS miscue/MGSD misdeal/SG misdealt misdeed/MS misdemeanant/SM misdemeanor/SM misdiagnose/GSD misdid misdirect/GSD misdirection/MS misdirector/S misdoes misdo/JG misdone miserableness/SM miserable/SP miserably miser/KM miserliness/MS miserly/P misery/MS mises/KC misfeasance/MS misfeature/M misfield misfile/SDG misfire/SDG misfit/MS misfitted misfitting misfortune/SM misgauge/GDS misgiving/MYS misgovern/LDGS misgovernment/S misguidance/SM misguidedness/M misguided/PY misguide/DRSG misguider/M Misha/M mishandle/SDG mishap/MS mishapped mishapping misheard mishear/GS mishitting mishmash/SM misidentification/M misidentify/GNSD misinformation/SM misinform/GDS misinterpretation/MS misinterpreter/M misinterpret/RDSZG misjudge/DSG misjudging/Y misjudgment/MS Miskito mislabel/DSG mislaid mislay/GS misleader/M mislead/GRJS misleading/Y misled mismanage/LGSD mismanagement/MS mismatch/GSD misname/GSD misnomer/GSMD misogamist/MS misogamy/MS misogynistic misogynist/MS misogynous misogyny/MS misperceive/SD misplace/GLDS misplacement/MS misplay/GSD mispositioned misprint/SGDM misprision/SM mispronounce/DSG mispronunciation/MS misquotation/MS misquote/GDS misreader/M misread/RSGJ misrelated misremember/DG misreport/DGS misrepresentation/MS misrepresenter/M misrepresent/SDRG misroute/DS misrule/SDG missal/ESM misshape/DSG misshapenness/SM misshapen/PY Missie/M missile/MS missilery/SM mission/AMS missionary/MS missioned missioner/SM missioning missis's Mississauga/M Mississippian/S Mississippi/M missive/MS Missoula/M Missourian/S Missouri/M misspeak/SG misspecification misspecified misspelling/M misspell/SGJD misspend/GS misspent misspoke misspoken mis/SRZ miss/SDEGV Miss/SM misstate/GLDRS misstatement/MS misstater/M misstep/MS misstepped misstepping missus/SM Missy/M mistakable/U mistake/BMGSR mistaken/Y mistaker/M mistaking/Y Mistassini/M mister/GDM Mister/SM mistily Misti/M mistime/GSD mistiness/S mistletoe/MS mist/MRDGZS mistook mistral/MS mistranslated mistranslates mistranslating mistranslation/SM mistreat/DGSL mistreatment/SM Mistress/MS mistress/MSY mistrial/SM mistruster/M mistrustful/Y mistrust/SRDG Misty/M mistype/SDGJ misty/PRT misunderstander/M misunderstanding/M misunderstand/JSRZG misunderstood misuser/M misuse/RSDMG miswritten Mitchael/M Mitchell/M Mitchel/M Mitch/M miterer/M miter/GRDM mite/SRMZ Mitford/M Mithra/M Mithridates/M mitigated/U mitigate/XNGVDS mitigation/M MIT/M mitoses mitosis/M mitotic MITRE/SM Mitsubishi/M mitten/M Mitterrand/M mitt/XSMN Mitty/M Mitzi/M mitzvahs mixable mix/AGSD mixed/U mixer/SM mixture/SM Mizar/M mizzenmast/SM mizzen/MS Mk mks ml Mlle/M mm MM MMe Mme/SM MN mnemonically mnemonics/M mnemonic/SM Mnemosyne/M Mn/M MO moan/GSZRDM moat/SMDG mobbed mobber mobbing mobcap/SM Mobile/M mobile/S mobility/MS mobilizable mobilization/AMCS mobilize/CGDS mobilized/U mobilizer/MS mobilizes/A Mobil/M mob/MS mobster/MS Mobutu/M moccasin/SM mocha/SM mockers/M mockery/MS mock/GZSRD mockingbird/MS mocking/Y mo/CSK modality/MS modal/Y modeled/A modeler/M modeling/M models/A model/ZGSJMRD mode/MS modem/SM moderated/U moderateness/SM moderate/PNGDSXY moderation/M moderator/MS modernism/MS modernistic modernist/S modernity/SM modernization/MS modernized/U modernizer/M modernize/SRDGZ modernizes/U modernness/SM modern/PTRYS Modesta/M Modestia/M Modestine/M Modesto/M modest/TRY Modesty/M modesty/MS modicum/SM modifiability/M modifiableness/M modifiable/U modification/M modified/U modifier/M modify/NGZXRSD Modigliani/M modishness/MS modish/YP mod/TSR Modula/M modularity/SM modularization modularize/SDG modular/SY modulate/ADSNCG modulation/CMS modulator/ACSM module/SM moduli modulo modulus/M modus Moe/M Moen/M Mogadiscio's Mogadishu mogul/MS Mogul/MS mohair/SM Mohamed/M Mohammad/M Mohammedanism/MS Mohammedan/SM Mohammed's Mohandas/M Mohandis/M Mohawk/MS Mohegan/S Mohican's Moho/M Mohorovicic/M Mohr/M moiety/MS moil/SGD Moina/M Moines/M Moira/M moire/MS Moise/MS Moiseyev/M Moishe/M moistener/M moisten/ZGRD moistness/MS moist/TXPRNY moisture/MS moisturize/GZDRS Mojave/M molal molarity/SM molar/MS molasses/MS Moldavia/M Moldavian/S moldboard/SM molder/DG moldiness/SM molding/M mold/MRDJSGZ Moldova moldy/PTR molecularity/SM molecular/Y molecule/MS molehill/SM mole/MTS moleskin/MS molestation/SM molested/U molester/M molest/RDZGS Moliere Molina/M Moline/M Mollee/M Mollie/M mollification/M mollify/XSDGN Molli/M Moll/M moll/MS mollusc's mollusk/S mollycoddler/M mollycoddle/SRDG Molly/M molly/SM Molnar/M Moloch/M Molokai/M Molotov/M molter/M molt/RDNGZS Moluccas molybdenite/M molybdenum/MS Mombasa/M momenta momentarily momentariness/SM momentary/P moment/MYS momentousness/MS momentous/YP momentum/SM momma/S Mommy/M mommy/SM Mo/MN mom/SM Monaco/M monadic monad/SM Monah/M Mona/M monarchic monarchical monarchism/MS monarchistic monarchist/MS monarch/M monarchs monarchy/MS Monash/M monastery/MS monastical/Y monasticism/MS monastic/S monaural/Y Mondale/M Monday/MS Mondrian/M Monegasque/SM Monera/M monetarily monetarism/S monetarist/MS monetary monetization/CMA monetize/CGADS Monet/M moneybag/SM moneychangers moneyer/M moneylender/SM moneymaker/MS moneymaking/MS money/SMRD Monfort/M monger/SGDM Mongolia/M Mongolian/S Mongolic/M mongolism/SM mongoloid/S Mongoloid/S Mongol/SM mongoose/SM mongrel/SM Monica/M monies/M Monika/M moniker/MS Monique/M monism/MS monist/SM monition/SM monitored/U monitor/GSMD monitory/S monkeyshine/S monkey/SMDG monkish Monk/M monk/MS monkshood/SM Monmouth/M monochromatic monochromator monochrome/MS monocle/SDM monoclinic monoclonal/S monocotyledonous monocotyledon/SM monocular/SY monodic monodist/S monody/MS monogamist/MS monogamous/PY monogamy/MS monogrammed monogramming monogram/MS monograph/GMDS monographs monolingualism monolingual/S monolithic monolithically monolith/M monoliths monologist/S monologue/GMSD monomaniacal monomaniac/MS monomania/MS monomeric monomer/SM monomial/SM mono/MS Monongahela/M mononuclear mononucleoses mononucleosis/M monophonic monoplane/MS monopole/S monopolistic monopolist/MS monopolization/MS monopolized/U monopolize/GZDSR monopolizes/U monopoly/MS monorail/SM monostable monosyllabic monosyllable/MS monotheism/SM monotheistic monotheist/S monotone/SDMG monotonic monotonically monotonicity monotonousness/MS monotonous/YP monotony/MS monovalent monoxide/SM Monroe/M Monro/M Monrovia/M Monsanto/M monseigneur monsieur/M Monsignori Monsignor/MS monsignor/S Mon/SM monsoonal monsoon/MS monster/SM monstrance/ASM monstrosity/SM monstrousness/M monstrous/YP montage/SDMG Montague/M Montaigne/M Montana/M Montanan/MS Montcalm/M Montclair/M Monte/M Montenegrin Montenegro/M Monterey/M Monterrey/M Montesquieu/M Montessori/M Monteverdi/M Montevideo/M Montezuma Montgomery/M monthly/S month/MY months Monticello/M Monti/M Mont/M Montmartre/M Montoya/M Montpelier/M Montrachet/M Montreal/M Montserrat/M Monty/M monumentality/M monumental/Y monument/DMSG mooch/ZSRDG moodily moodiness/MS mood/MS Moody/M moody/PTR Moog moo/GSD moonbeam/SM Mooney/M moon/GDMS moonless moonlight/GZDRMS moonlighting/M moonlit Moon/M moonscape/MS moonshiner/M moonshine/SRZM moonshot/MS moonstone/SM moonstruck moonwalk/SDG Moore/M moor/GDMJS mooring/M Moorish moorland/MS Moor/MS moose/M moot/RDGS moped/MS moper/M mope/S mopey mopier mopiest mopish mopped moppet/MS mopping mop/SZGMDR moraine/MS morale/MS Morales/M moralistic moralistically moralist/MS morality/UMS moralization/CS moralize/CGDRSZ moralled moraller moralling moral/SMY Mora/M Moran/M morass/SM moratorium/SM Moravia/M Moravian moray/SM morbidity/SM morbidness/S morbid/YP mordancy/MS mordant/GDYS Mordecai/M Mord/M Mordred/M Mordy/M more/DSN Moreen/M Morehouse/M Moreland/M morel/SM More/M Morena/M Moreno/M moreover Morey/M Morgana/M Morganica/M Morgan/MS Morganne/M morgen/M Morgen/M morgue/SM Morgun/M Moria/M Moriarty/M moribundity/M moribund/Y Morie/M Morin/M morion/M Morison/M Morissa/M Morita/M Moritz/M Morlee/M Morley/M Morly/M Mormonism/MS Mormon/SM Morna/M morning/MY morn/SGJDM Moroccan/S Morocco/M morocco/SM Moro/M moronic moronically Moroni/M moron/SM moroseness/MS morose/YP morpheme/DSMG morphemic/S Morpheus/M morph/GDJ morphia/S morphine/MS morphism/MS morphologic morphological/Y morphology/MS morphophonemic/S morphophonemics/M morphs Morrie/M morris Morris/M Morrison/M Morristown/M Morrow/M morrow/MS Morry/M morsel/GMDS Morse/M mortality/SM mortal/SY mortarboard/SM mortar/GSDM Morten/M mortgageable mortgagee/SM mortgage/MGDS mortgagor/SM mortice's mortician/SM Mortie/M mortification/M mortified/Y mortifier/M mortify/DRSXGN Mortimer/M mortise/MGSD Mort/MN Morton/M mortuary/MS Morty/M Mosaic mosaicked mosaicking mosaic/MS Moscone/M Moscow/M Moseley/M Moselle/M Mose/MSR Moser/M mosey/SGD Moshe/M Moslem's Mosley/M mosque/SM mosquitoes mosquito/M mos/S mossback/MS Mossberg/M Moss/M moss/SDMG mossy/SRT most/SY Mosul/M mote/ASCNK motel/MS mote's motet/SM mothball/DMGS motherboard/MS motherfucker/MS! motherfucking/! motherhood/SM mothering/M motherland/SM motherless motherliness/MS motherly/P mother/RDYMZG moths moth/ZMR motif/MS motile/S motility/MS motional/K motioner/M motion/GRDMS motionlessness/S motionless/YP motion's/ACK motions/K motivated/U motivate/XDSNGV motivational/Y motivation/M motivator/S motiveless motive/MGSD motley/S motlier motliest mot/MSV motocross/SM motorbike/SDGM motorboat/MS motorcade/MSDG motorcar/MS motorcycle/GMDS motorcyclist/SM motor/DMSG motoring/M motorist/SM motorization/SM motorize/DSG motorized/U motorman/M motormen motormouth motormouths Motorola/M motorway/SM Motown/M mottle/GSRD mottler/M Mott/M mottoes motto/M moue/DSMG moulder/DSG moult/GSD mound/GMDS mountable mountaineering/M mountaineer/JMDSG mountainousness/M mountainous/PY mountainside/MS mountain/SM mountaintop/SM Mountbatten/M mountebank/SGMD mounted/U mount/EGACD mounter/SM mounties Mountie/SM mounting/MS Mount/M mounts/AE mourner/M mournfuller mournfullest mournfulness/S mournful/YP mourning/M mourn/ZGSJRD mouser/M mouse/SRDGMZ mousetrapped mousetrapping mousetrap/SM mousiness/MS mousing/M mousse/MGSD Moussorgsky/M mousy/PRT Mouthe/M mouthful/MS mouthiness/SM mouth/MSRDG mouthorgan mouthpiece/SM mouths mouthwash/SM mouthwatering mouthy/PTR Mouton/M mouton/SM movable/ASP movableness/AM move/ARSDGZB moved/U movement/SM mover/AM moviegoer/S movie/SM moving/YS mower/M Mowgli/M mowing/M mow/SDRZG moxie/MS Moyer/M Moyna/M Moyra/M Mozambican/S Mozambique/M Mozart/M Mozelle/M Mozes/M Mozilla/M mozzarella/MS mp MP mpg mph MPH MRI Mr/M Mrs ms M's MS MSG Msgr/M m's/K Ms/S MST MSW mt MT mtg mtge Mt/M MTS MTV Muawiya/M Mubarak/M muchness/M much/SP mucilage/MS mucilaginous mucker/M muck/GRDMS muckraker/M muckrake/ZMDRSG mucky/RT mucosa/M mucous mucus/SM mudded muddily muddiness/SM mudding muddle/GRSDZ muddleheaded/P muddlehead/SMD muddler/M muddy/TPGRSD mudflat/S mudguard/SM mudlarks mud/MS mudroom/S mudslide/S mudslinger/M mudslinging/M mudsling/JRGZ Mueller/M Muenster muenster/MS muesli/M muezzin/MS muff/GDMS Muffin/M muffin/SM muffler/M muffle/ZRSDG Mufi/M Mufinella/M mufti/MS Mugabe/M mugged mugger/SM mugginess/S mugging/S muggy/RPT mugshot/S mug/SM mugwump/MS Muhammadanism/S Muhammadan/SM Muhammad/M Muire/M Muir/M Mukden/M mukluk/SM mulattoes mulatto/M mulberry/MS mulch/GMSD mulct/SDG Mulder/M mule/MGDS muleskinner/S muleteer/MS mulishness/MS mulish/YP mullah/M mullahs mullein/MS Mullen/M muller/M Muller/M mullet/MS Mulligan/M mulligan/SM mulligatawny/SM Mullikan/M Mullins mullion/MDSG mull/RDSG Multan/M multi Multibus/M multicellular multichannel/M multicollinearity/M multicolor/SDM multicolumn multicomponent multicomputer/MS Multics/M MULTICS/M multicultural multiculturalism/S multidimensional multidimensionality multidisciplinary multifaceted multifamily multifariousness/SM multifarious/YP multifigure multiform multifunction/D multilateral/Y multilayer multilevel/D multilingual multilingualism/S multimedia/S multimegaton/M multimeter/M multimillionaire/SM multinational/S multinomial/M multiphase multiple/SM multiplet/SM multiplex/GZMSRD multiplexor's multipliable multiplicand/SM multiplication/M multiplicative/YS multiplicity/MS multiplier/M multiply/ZNSRDXG multiprocess/G multiprocessor/MS multiprogram multiprogrammed multiprogramming/MS multipurpose multiracial multistage multistory/S multisyllabic multitasking/S multitude/MS multitudinousness/M multitudinous/YP multiuser multivalent multivalued multivariate multiversity/M multivitamin/S mu/M mumbler/M mumbletypeg/S mumble/ZJGRSD Mumford/M mummed mummer/SM mummery/MS mummification/M mummify/XSDGN mumming mum/MS mummy/GSDM mumps/M muncher/M Mnchhausen/M munchies Munch/M munch/ZRSDG Muncie/M mundane/YSP Mundt/M munge/JGZSRD Munich/M municipality/SM municipal/YS munificence/MS munificent/Y munition/SDG Munmro/M Munoz/M Munroe/M Munro/M mun/S Munsey/M Munson/M Munster/MS Muong/M muon/M Muppet/M muralist/SM mural/SM Murasaki/M Murat/M Murchison/M Murcia/M murderer/M murderess/S murder/GZRDMS murderousness/M murderous/YP Murdoch/M Murdock/M Mureil/M Murial/M muriatic Murielle/M Muriel/M Murillo/M murkily murkiness/S murk/TRMS murky/RPT Murmansk/M murmurer/M murmuring/U murmurous murmur/RDMGZSJ Murphy/M murrain/SM Murray/M Murrow/M Murrumbidgee/M Murry/M Murvyn/M muscatel/MS Muscat/M muscat/SM musclebound muscle/SDMG Muscovite/M muscovite/MS Muscovy/M muscularity/SM muscular/Y musculature/SM muse Muse/M muser/M musette/SM museum/MS mus/GJDSR musher/M mushiness/MS mush/MSRDG mushroom/DMSG mushy/PTR Musial/M musicale/SM musicality/SM musicals musical/YU musician/MYS musicianship/MS musicked musicking musicological musicologist/MS musicology/MS music/SM musing/Y Muskegon/M muskeg/SM muskellunge/SM musketeer/MS musketry/MS musket/SM musk/GDMS muskie/M muskiness/MS muskmelon/MS muskox/N muskrat/MS musky/RSPT Muslim/MS muslin/MS mussel/MS Mussolini/MS Mussorgsky/M muss/SDG mussy/RT mustache/DSM mustachio/MDS mustang/MS mustard/MS muster/GD mustily mustiness/MS mustn't must/RDGZS must've musty/RPT mutability/SM mutableness/M mutable/P mutably mutagen/SM mutant/MS mutate/XVNGSD mutational/Y mutation/M mutator/S muted/Y muteness/S mute/PDSRBYTG mutilate/XDSNG mutilation/M mutilator/MS mutineer/SMDG mutinous/Y mutiny/MGSD Mutsuhito/M mutterer/M mutter/GZRDJ muttonchops mutton/SM mutt/ZSMR mutuality/S mutual/SY muumuu/MS muzak Muzak/SM Muzo/M muzzled/U muzzle/MGRSD muzzler/M MVP MW Myanmar Mycah/M Myca/M Mycenaean Mycenae/M Mychal/M mycologist/MS mycology/MS myelitides myelitis/M Myer/MS myers mylar Mylar/S Myles/M Mylo/M My/M myna/SM Mynheer/M myocardial myocardium/M myopia/MS myopically myopic/S Myrah/M Myra/M Myranda/M Myrdal/M myriad/S Myriam/M Myrilla/M Myrle/M Myrlene/M myrmidon/S Myrna/M Myron/M myrrh/M myrrhs Myrta/M Myrtia/M Myrtice/M Myrtie/M Myrtle/M myrtle/SM Myrvyn/M Myrwyn/M mys my/S myself Mysore/M mysteriousness/MS mysterious/YP mystery/MDSG mystical/Y mysticism/MS mystic/SM mystification/M mystifier/M mystify/CSDGNX mystifying/Y mystique/MS Myst/M mythic mythical/Y myth/MS mythographer/SM mythography/M mythological/Y mythologist/MS mythologize/CSDG mythology/SM myths N NAACP nabbed nabbing Nabisco/M nabob/SM Nabokov/M nab/S nacelle/SM nacho/S NaCl/M nacre/MS nacreous Nada/M Nadean/M Nadeen/M Nader/M Nadia/M Nadine/M nadir/SM Nadiya/M Nadya/M Nady/M nae/VM Nagasaki/M nagged nagger/S nagging/Y nag/MS Nagoya/M Nagpur/M Nagy/M Nahuatl/SM Nahum/M naiad/SM naifs nailbrush/SM nailer/M nail/SGMRD Naipaul/M Nair/M Nairobi/M Naismith/M naive/SRTYP naivet/SM naivety/MS Nakamura/M Nakayama/M nakedness/MS naked/TYRP Nakoma/M Nalani/M Na/M Namath/M nameable/U name/ADSG namedrop namedropping named's named/U nameless/PY namely nameplate/MS namer/SM name's namesake/SM Namibia/M Namibian/S naming/M Nam/M Nanak/M Nana/M Nananne/M Nancee/M Nance/M Nancey/M Nanchang/M Nancie/M Nanci/M Nancy/M Nanete/M Nanette/M Nanice/M Nani/M Nanine/M Nanjing Nanking's Nan/M Nannette/M Nannie/M Nanni/M Nanny/M nanny/SDMG nanometer/MS Nanon/M Nanook/M nanosecond/SM Nansen/M Nantes/M Nantucket/M Naoma/M Naomi/M napalm/MDGS nape/SM Naphtali/M naphthalene/MS naphtha/SM Napier/M napkin/SM Naples/M napless Nap/M Napoleonic napoleon/MS Napoleon/MS napped napper/MS Nappie/M napping Nappy/M nappy/TRSM nap/SM Nara/M Narbonne/M narc/DGS narcissism/MS narcissistic narcissist/MS narcissus/M Narcissus/M narcoleptic narcoses narcosis/M narcotic/SM narcotization/S narcotize/GSD Nariko/M Nari/M nark's Narmada/M Narragansett/M narrate/VGNSDX narration/M narrative/MYS narratology narrator/SM narrowing/P narrowness/SM narrow/RDYTGPS narwhal/MS nary nasality/MS nasalization/MS nasalize/GDS nasal/YS NASA/MS nascence/ASM nascent/A NASDAQ Nash/M Nashua/M Nashville/M Nassau/M Nasser/M nastily nastiness/MS nasturtium/SM nasty/TRSP natal Natala/M Natalee/M Natale/M Natalia/M Natalie/M Natalina/M Nataline/M natalist natality/M Natal/M Natalya/M Nata/M Nataniel/M Natasha/M Natassia/M Natchez natch/S Nate/XMN Nathalia/M Nathalie/M Nathanael/M Nathanial/M Nathaniel/M Nathanil/M Nathan/MS nationalism/SM nationalistic nationalistically nationalist/MS nationality/MS nationalization/MS nationalize/CSDG nationalized/AU nationalizer/SM national/YS nationhood/SM nation/MS nationwide nativeness/M native/PYS Natividad/M Nativity/M nativity/MS Natka/M natl Nat/M NATO/SM natter/SGD nattily nattiness/SM Natty/M natty/TRP naturalism/MS naturalistic naturalist/MS naturalization/SM naturalized/U naturalize/GSD naturalness/US natural/PUY naturals nature/ASDCG nature's naturist Naugahyde/S naughtily naughtiness/SM naught/MS naughty/TPRS Naur/M Nauru/M nausea/SM nauseate/DSG nauseating/Y nauseousness/SM nauseous/P nautical/Y nautilus/MS Navaho's Navajoes Navajo/S naval/Y Navarro/M navel/MS nave/SM navigability/SM navigableness/M navigable/P navigate/DSXNG navigational navigation/M navigator/MS Navona/M Navratilova/M navvy/M Navy/S navy/SM nay/MS naysayer/S Nazarene/MS Nazareth/M Nazi/SM Nazism/S NB NBA NBC Nb/M NBS NC NCAA NCC NCO NCR ND N'Djamena Ndjamena/M Nd/M Ne NE Neala/M Neale/M Neall/M Neal/M Nealon/M Nealson/M Nealy/M Neanderthal/S neap/DGS Neapolitan/SM nearby nearly/RT nearness/MS nearside/M nearsightedness/S nearsighted/YP near/TYRDPSG neaten/DG neath neatness/MS neat/YRNTXPS Neb/M Nebraska/M Nebraskan/MS Nebr/M Nebuchadnezzar/MS nebulae nebula/M nebular nebulousness/SM nebulous/PY necessaries necessarily/U necessary/U necessitate/DSNGX necessitation/M necessitous necessity/SM neckband/M neckerchief/MS neck/GRDMJS necking/M necklace/DSMG neckline/MS necktie/MS necrology/SM necromancer/MS necromancy/MS necromantic necrophiliac/S necrophilia/M necropolis/SM necropsy/M necroses necrosis/M necrotic nectarine/SM nectarous nectar/SM nectary/MS Neda/M Nedda/M Neddie/M Neddy/M Nedi/M Ned/M ne needed/U needer/M needful/YSP Needham/M neediness/MS needlecraft/M needle/GMZRSD needlepoint/SM needlessness/S needless/YP needlewoman/M needlewomen needlework/RMS needn't need/YRDGS needy/TPR Neel/M Neely/M ne'er nefariousness/MS nefarious/YP Nefen/M Nefertiti/M negated/U negater/M negate/XRSDVNG negation/M negativeness/SM negative/PDSYG negativism/MS negativity/MS negator/MS Negev/M neglecter/M neglectfulness/SM neglectful/YP neglect/SDRG negligee/SM negligence/MS negligent/Y negligibility/M negligible negligibly negotiability/MS negotiable/A negotiant/M negotiate/ASDXGN negotiation/MA negotiator/MS Negress/MS negritude/MS Negritude/S Negroes negroid Negroid/S Negro/M neg/S Nehemiah/M Nehru/M neighbored/U neighborer/M neighborhood/SM neighborlinesses neighborliness/UM neighborly/UP neighbor/SMRDYZGJ neigh/MDG neighs Neila/M Neile/M Neilla/M Neille/M Neill/M Neil/SM neither Nelda/M Nelia/M Nelie/M Nelle/M Nellie/M Nelli/M Nell/M Nelly/M Nelsen/M Nels/N Nelson/M nelson/MS nematic nematode/SM Nembutal/M nemeses nemesis Nemesis/M neoclassical neoclassicism/MS neoclassic/M neocolonialism/MS neocortex/M neodymium/MS Neogene neolithic Neolithic/M neologism/SM neomycin/M neonatal/Y neonate/MS neon/DMS neophyte/MS neoplasm/SM neoplastic neoprene/SM Nepalese Nepali/MS Nepal/M nepenthe/MS nephew/MS nephrite/SM nephritic nephritides nephritis/M nepotism/MS nepotist/S Neptune/M neptunium/MS nerd/S nerdy/RT Nereid/M Nerf/M Nerissa/M Nerita/M Nero/M Neron/M Nerta/M Nerte/M Nertie/M Nerti/M Nert/M Nerty/M Neruda/M nervelessness/SM nerveless/YP nerve's nerve/UGSD nerviness/SM nerving/M nervousness/SM nervous/PY nervy/TPR Nessa/M Nessie/M Nessi/M Nessy/M Nesta/M nester/M Nester/M Nestle/M nestler/M nestle/RSDG nestling/M Nestorius/M Nestor/M nest/RDGSBM netball/M nether Netherlander/SM Netherlands/M nethermost netherworld/S Netscape/M net/SM Netta/M Nettie/M Netti/M netting/M nett/JGRDS Nettle/M nettle/MSDG nettlesome Netty/M network/SJMDG Netzahualcoyotl/M Neumann/M neuralgia/MS neuralgic neural/Y neurasthenia/MS neurasthenic/S neuritic/S neuritides neuritis/M neuroanatomy neurobiology/M neurological/Y neurologist/MS neurology/SM neuromuscular neuronal neurone/S neuron/MS neuropathology/M neurophysiology/M neuropsychiatric neuroses neurosis/M neurosurgeon/MS neurosurgery/SM neurotically neurotic/S neurotransmitter/S neuter/JZGRD neutralise's neutralism/MS neutralist/S neutrality/MS neutralization/MS neutralized/U neutralize/GZSRD neutral/PYS neutrino/MS neutron/MS neut/ZR Nevada/M Nevadan/S Nevadian/S Neva/M never nevermore nevertheless nevi Nevile/M Neville/M Nevil/M Nevin/SM Nevis/M Nev/M Nevsa/M Nevsky/M nevus/M Newark/M newbie/S newborn/S Newbury/M Newburyport/M Newcastle/M newcomer/MS newed/A Newell/M newel/MS newer/A newfangled newfound newfoundland Newfoundlander/M Newfoundland/SRMZ newish newline/SM newlywed/MS Newman/M newness/MS Newport/M news/A newsagent/MS newsboy/SM newscaster/M newscasting/M newscast/SRMGZ newsdealer/MS newsed newses newsflash/S newsgirl/S newsgroup/SM newsing newsletter/SM NeWS/M newsman/M newsmen newspaperman/M newspapermen newspaper/SMGD newspaperwoman/M newspaperwomen newsprint/MS new/SPTGDRY newsreader/MS newsreel/SM newsroom/S news's newsstand/MS Newsweekly/M newsweekly/S Newsweek/MY newswire newswoman/M newswomen newsworthiness/SM newsworthy/RPT newsy/TRS newt/MS Newtonian Newton/M newton/SM Nexis/M next nexus/SM Neysa/M NF NFC NFL NFS Ngaliema/M Nguyen/M NH NHL niacin/SM Niagara/M Niall/M Nial/M Niamey/M nibbed nibbing nibbler/M nibble/RSDGZ Nibelung/M nib/SM Nicaean Nicaragua/M Nicaraguan/S Niccolo/M Nice/M Nicene niceness/MS nicety/MS nice/YTPR niche/SDGM Nicholas Nichole/M Nicholle/M Nichol/MS Nicholson/M nichrome nickelodeon/SM nickel/SGMD nicker/GD Nickey/M nick/GZRDMS Nickie/M Nicki/M Nicklaus/M Nick/M nicknack's nickname/MGDRS nicknamer/M Nickolai/M Nickola/MS Nickolaus/M Nicko/M Nicky/M Nicobar/M Nicodemus/M Nicolai/MS Nicola/MS Nicolea/M Nicole/M Nicolette/M Nicoli/MS Nicolina/M Nicoline/M Nicolle/M Nicol/M Nico/M Nicosia/M nicotine/MS Niebuhr/M niece/MS Niel/MS Nielsen/M Niels/N Nielson/M Nietzsche/M Nieves/M nifty/TRS Nigel/M Nigeria/M Nigerian/S Nigerien Niger/M niggardliness/SM niggardly/P niggard/SGMDY nigger/SGDM! niggler/M niggle/RSDGZJ niggling/Y nigh/RDGT nighs nightcap/SM nightclothes nightclubbed nightclubbing nightclub/MS nightdress/MS nightfall/SM nightgown/MS nighthawk/MS nightie/MS Nightingale/M nightingale/SM nightlife/MS nightlong nightmare/MS nightmarish/Y nightshade/SM nightshirt/MS night/SMYDZ nightspot/MS nightstand/SM nightstick/S nighttime/S nightwear/M nighty's NIH nihilism/MS nihilistic nihilist/MS Nijinsky/M Nikaniki/M Nike/M Niki/M Nikita/M Nikkie/M Nikki/M Nikko/M Nikolai/M Nikola/MS Nikolaos/M Nikolaus/M Nikolayev's Nikoletta/M Nikolia/M Nikolos/M Niko/MS Nikon/M Nile/SM nilled nilling Nil/MS nil/MYS nilpotent Nilsen/M Nils/N Nilson/M Nilsson/M Ni/M nimbi nimbleness/SM nimble/TRP nimbly nimbus/DM NIMBY Nimitz/M Nimrod/MS Nina/M nincompoop/MS ninefold nine/MS ninepence/M ninepin/S ninepins/M nineteen/SMH nineteenths ninetieths Ninetta/M Ninette/M ninety/MHS Nineveh/M ninja/S Ninnetta/M Ninnette/M ninny/SM Ninon/M Nintendo/M ninth ninths Niobe/M niobium/MS nipped nipper/DMGS nippiness/S nipping/Y nipple/GMSD Nipponese Nippon/M nippy/TPR nip/S Nirenberg/M nirvana/MS Nirvana/S nisei Nisei/MS Nissa/M Nissan/M Nisse/M Nissie/M Nissy/M Nita/M niter/M nitpick/DRSJZG nitrate/MGNXSD nitration/M nitric nitride/MGS nitriding/M nitrification/SM nitrite/MS nitrocellulose/MS nitrogenous nitrogen/SM nitroglycerin/MS nitrous nitwit/MS nit/ZSMR Niven/M nixer/M nix/GDSR Nixie/M Nixon/M NJ Nkrumah/M NLRB nm NM no/A NOAA Noach/M Noah/M Noak/M Noami/M Noam/M Nobelist/SM nobelium/MS Nobel/M Nobe/M Nobie/M nobility/MS Noble/M nobleman/M noblemen nobleness/SM noblesse/M noble/TPSR noblewoman noblewomen nob/MY nobody/MS Noby/M nocturnal/SY nocturne/SM nodal/Y nodded nodding noddle/MSDG noddy/M node/MS NoDoz/M nod/SM nodular nodule/SM Noelani/M Noella/M Noelle/M Noell/M Noellyn/M Noel/MS noel/S Noelyn/M Noe/M Noemi/M noes/S noggin/SM nohow noise/GMSD noiselessness/SM noiseless/YP noisemaker/M noisemake/ZGR noisily noisiness/MS noisome noisy/TPR Nola/M Nolana/M Noland/M Nolan/M Nolie/M Nollie/M Noll/M Nolly/M No/M nomadic nomad/SM Nome/M nomenclature/MS Nomi/M nominalized nominal/K nominally nominals nominate/CDSAXNG nomination/MAC nominative/SY nominator/CSM nominee/MS non nonabrasive nonabsorbent/S nonacademic/S nonacceptance/MS nonacid/MS nonactive nonadaptive nonaddictive nonadhesive nonadjacent nonadjustable nonadministrative nonage/MS nonagenarian/MS nonaggression/SM nonagricultural Nonah/M nonalcoholic/S nonaligned nonalignment/SM nonallergic Nona/M nonappearance/MS nonassignable nonathletic nonattendance/SM nonautomotive nonavailability/SM nonbasic nonbeliever/SM nonbelligerent/S nonblocking nonbreakable nonburnable nonbusiness noncaloric noncancerous noncarbohydrate/M nonce/MS nonchalance/SM nonchalant/YP nonchargeable nonclerical/S nonclinical noncollectable noncombatant/MS noncombustible/S noncommercial/S noncommissioned noncommittal/Y noncom/MS noncommunicable noncompeting noncompetitive noncompliance/MS noncomplying/S noncomprehending nonconducting nonconductor/MS nonconforming nonconformist/SM nonconformity/SM nonconsecutive nonconservative nonconstructive noncontagious noncontiguous noncontinuous noncontributing noncontributory noncontroversial nonconvertible noncooperation/SM noncorroding/S noncorrosive noncredit noncriminal/S noncritical noncrystalline noncumulative noncustodial noncyclic nondairy nondecreasing nondeductible nondelivery/MS nondemocratic nondenominational nondepartmental nondepreciating nondescript/YS nondestructive/Y nondetachable nondeterminacy nondeterminate/Y nondeterminism nondeterministic nondeterministically nondisciplinary nondisclosure/SM nondiscrimination/SM nondiscriminatory nondramatic nondrinker/SM nondrying nondurable noneconomic noneducational noneffective/S nonelastic nonelectrical nonelectric/S nonemergency nonempty nonenforceable nonentity/MS nonequivalence/M nonequivalent/S none/S nones/M nonessential/S nonesuch/SM nonetheless nonevent/MS nonexchangeable nonexclusive nonexempt nonexistence/MS nonexistent nonexplosive/S nonextensible nonfactual nonfading nonfat nonfatal nonfattening nonferrous nonfictional nonfiction/SM nonflammable nonflowering nonfluctuating nonflying nonfood/M nonfreezing nonfunctional nongovernmental nongranular nonhazardous nonhereditary nonhuman nonidentical Nonie/M Noni/M noninclusive nonindependent nonindustrial noninfectious noninflammatory noninflationary noninflected nonintellectual/S noninteracting noninterchangeable noninterference/MS nonintervention/SM nonintoxicating nonintuitive noninvasive nonionic nonirritating nonjudgmental nonjudicial nonlegal nonlethal nonlinearity/MS nonlinear/Y nonlinguistic nonliterary nonliving nonlocal nonmagical nonmagnetic nonmalignant nonmember/SM nonmetallic nonmetal/MS nonmigratory nonmilitant/S nonmilitary Nonnah/M Nonna/M nonnarcotic/S nonnative/S nonnegative nonnegotiable nonnuclear nonnumerical/S nonobjective nonobligatory nonobservance/MS nonobservant nonoccupational nonoccurence nonofficial nonogenarian nonoperational nonoperative nonorthogonal nonorthogonality nonparallel/S nonparametric nonpareil/SM nonparticipant/SM nonparticipating nonpartisan/S nonpaying nonpayment/SM nonperformance/SM nonperforming nonperishable/S nonperson/S nonperturbing nonphysical/Y nonplus/S nonplussed nonplussing nonpoisonous nonpolitical nonpolluting nonporous nonpracticing nonprejudicial nonprescription nonprocedural/Y nonproductive nonprofessional/S nonprofit/SB nonprogrammable nonprogrammer nonproliferation/SM nonpublic nonpunishable nonracial nonradioactive nonrandom nonreactive nonreciprocal/S nonreciprocating nonrecognition/SM nonrecoverable nonrecurring nonredeemable nonreducing nonrefillable nonrefundable nonreligious nonrenewable nonrepresentational nonresidential nonresident/SM nonresidual nonresistance/SM nonresistant/S nonrespondent/S nonresponse nonrestrictive nonreturnable/S nonrhythmic nonrigid nonsalaried nonscheduled nonscientific nonscoring nonseasonal nonsectarian nonsecular nonsegregated nonsense/MS nonsensicalness/M nonsensical/PY nonsensitive nonsexist nonsexual nonsingular nonskid nonslip nonsmoker/SM nonsmoking nonsocial nonspeaking nonspecialist/MS nonspecializing nonspecific nonspiritual/S nonstaining nonstandard nonstarter/SM nonstick nonstop nonstrategic nonstriking nonstructural nonsuccessive nonsupervisory nonsupport/GS nonsurgical nonsustaining nonsympathizer/M nontarnishable nontaxable/S nontechnical/Y nontenured nonterminal/MS nonterminating nontermination/M nontheatrical nonthinking/S nonthreatening nontoxic nontraditional nontransferable nontransparent nontrivial nontropical nonuniform nonunion/S nonuser/SM nonvenomous nonverbal/Y nonveteran/MS nonviable nonviolence/SM nonviolent/Y nonvirulent nonvocal nonvocational nonvolatile nonvolunteer/S nonvoter/MS nonvoting nonwhite/SM nonworking nonyielding nonzero noodle/GMSD nook/MS noonday/MS noon/GDMS nooning/M noontide/MS noontime/MS noose/SDGM nope/S NORAD/M noradrenalin noradrenaline/M Norah/M Nora/M Norbert/M Norberto/M Norbie/M Norby/M Nordhoff/M Nordic/S Nordstrom/M Norean/M Noreen/M Norene/M Norfolk/M nor/H Norina/M Norine/M normalcy/MS normality/SM normalization/A normalizations normalization's normalized/AU normalizes/AU normalize/SRDZGB normal/SY Norma/M Normand/M Normandy/M Norman/SM normativeness/M normative/YP Normie/M norm/SMGD Normy/M Norplant Norrie/M Norri/SM Norristown/M Norry/M Norse Norseman/M Norsemen Northampton/M northbound northeastern northeaster/YM Northeast/SM northeastward/S northeast/ZSMR northerly/S norther/MY Northerner/M northernmost northern/RYZS Northfield/M northing/M northland North/M northmen north/MRGZ Northrop/M Northrup/M norths Norths Northumberland/M northward/S northwestern northwester/YM northwest/MRZS Northwest/MS northwestward/S Norton/M Norwalk/M Norway/M Norwegian/S Norwich/M Norw/M nosebag/M nosebleed/SM nosecone/S nosedive/DSG nosed/V nosegay/MS nose/M Nosferatu/M nos/GDS nosh/MSDG nosily nosiness/MS nosing/M nostalgia/SM nostalgically nostalgic/S Nostradamus/M Nostrand/M nostril/SM nostrum/SM nosy/SRPMT notability/SM notableness/M notable/PS notably notarial notarization/S notarize/DSG notary/MS notate/VGNXSD notational/CY notation/CMSF notative/CF notch/MSDG not/DRGB notebook/MS note/CSDFG notedness/M noted/YP notepad/S notepaper/MS note's noteworthiness/SM noteworthy/P nothingness/SM nothing/PS noticeable/U noticeably noticeboard/S noticed/U notice/MSDG notifiable notification/M notifier/M notify/NGXSRDZ notional/Y notion/MS notoriety/S notoriousness/M notorious/YP Notre/M Nottingham/M notwithstanding Nouakchott/M nougat/MS Noumea/M noun/SMK nourish/DRSGL nourished/U nourisher/M nourishment/SM nous/M nouveau nouvelle novae Novak/M Nova/M nova/MS novelette/SM Novelia/M novelist/SM novelization/S novelize/GDS Novell/SM novella/SM novel/SM novelty/MS November/SM novena/SM novene Novgorod/M novice/MS novitiate/MS Nov/M Novocaine/M Novocain/S Novokuznetsk/M Novosibirsk/M NOW nowadays noway/S Nowell/M nowhere/S nowise now/S noxiousness/M noxious/PY Noyce/M Noyes/M nozzle/MS Np NP NRA nroff/M N's NS n's/CI NSF n/T NT nth nuance/SDM nubbin/SM nubby/RT Nubia/M Nubian/M nubile nub/MS nuclear/K nuclease/M nucleated/A nucleate/DSXNG nucleation/M nucleic nuclei/M nucleoli nucleolus/M nucleon/MS nucleotide/MS nucleus/M nuclide/M nude/CRS nudely nudeness/M nudest nudge/GSRD nudger/M nudism/MS nudist/MS nudity/MS nugatory Nugent/M nugget/SM nuisance/MS nuke/DSMG Nukualofa null/DSG nullification/M nullifier/M nullify/RSDXGNZ nullity/SM nu/M numbered/UA numberer/M numberless numberplate/M number/RDMGJ numbers/A Numbers/M numbing/Y numbness/MS numb/SGZTYRDP numbskull's numerable/IC numeracy/SI numeral/YMS numerate/SDNGX numerates/I numeration/M numerator/MS numerical/Y numeric/S numerological numerologist/S numerology/MS numerousness/M numerous/YP numinous/S numismatic/S numismatics/M numismatist/MS numskull/SM Nunavut/M nuncio/SM Nunez/M Nunki/M nun/MS nunnery/MS nuptial/S Nuremberg/M Nureyev/M nursemaid/MS nurser/M nurseryman/M nurserymen nursery/MS nurse/SRDJGMZ nursling/M nurturer/M nurture/SRDGZM nus nutate/NGSD nutation/M nutcracker/M nutcrack/RZ nuthatch/SM nutmeat/SM nutmegged nutmegging nutmeg/MS nut/MS nutpick/MS Nutrasweet/M nutria/SM nutrient/MS nutriment/MS nutritional/Y nutritionist/MS nutrition/SM nutritiousness/MS nutritious/PY nutritive/Y nutshell/MS nutted nuttiness/SM nutting nutty/TRP nuzzle/GZRSD NV NW NWT NY Nyasa/M NYC Nydia/M Nye/M Nyerere/M nylon/SM nymphet/MS nymph/M nympholepsy/M nymphomaniac/S nymphomania/MS nymphs Nyquist/M NYSE Nyssa/M NZ o O oafishness/S oafish/PY oaf/MS Oahu/M Oakland/M Oakley/M Oakmont/M oak/SMN oakum/MS oakwood oar/GSMD oarlock/MS oarsman/M oarsmen oarswoman oarswomen OAS oases oasis/M oatcake/MS oater/M Oates/M oath/M oaths oatmeal/SM oat/SMNR Oaxaca/M ob OB Obadiah/M Obadias/M obbligato/S obduracy/S obdurateness/S obdurate/PDSYG Obediah/M obedience/EMS obedient/EY Obed/M obeisance/MS obeisant/Y obelisk/SM Oberlin/M Oberon/M obese obesity/MS obey/EDRGS obeyer/EM obfuscate/SRDXGN obfuscation/M obfuscatory Obidiah/M Obie/M obi/MDGS obit/SMR obituary/SM obj objectify/GSDXN objectionableness/M objectionable/U objectionably objection/SMB objectiveness/MS objective/PYS objectivity/MS objector/SM object/SGVMD objurgate/GNSDX objurgation/M oblate/NYPSX oblation/M obligate/NGSDXY obligational obligation/M obligatorily obligatory obliged/E obliger/M obliges/E oblige/SRDG obligingness/M obliging/PY oblique/DSYGP obliqueness/S obliquity/MS obliterate/VNGSDX obliteration/M obliterative/Y oblivion/MS obliviousness/MS oblivious/YP oblongness/M oblong/SYP obloquies obloquy/M Ob/MD obnoxiousness/MS obnoxious/YP oboe/SM oboist/S obos O'Brien/M obs obscene/RYT obscenity/MS obscurantism/MS obscurantist/MS obscuration obscureness/M obscure/YTPDSRGL obscurity/MS obsequies obsequiousness/S obsequious/YP obsequy observability/M observable/SU observably observance/MS observantly observants observant/U observational/Y observation/MS observatory/MS observed/U observer/M observe/ZGDSRB observing/Y obsess/GVDS obsessional obsession/MS obsessiveness/S obsessive/PYS obsidian/SM obsolesce/GSD obsolescence/S obsolescent/Y obsolete/GPDSY obsoleteness/M obstacle/SM obstetrical obstetrician/SM obstetric/S obstetrics/M obstinacy/SM obstinateness/M obstinate/PY obstreperousness/SM obstreperous/PY obstructed/U obstructer/M obstructionism/SM obstructionist/MS obstruction/SM obstructiveness/MS obstructive/PSY obstruct/RDVGS obtainable/U obtainably obtain/LSGDRB obtainment/S obtrude/DSRG obtruder/M obtrusion/S obtrusiveness/MSU obtrusive/UPY obtuseness/S obtuse/PRTY obverse/YS obviate/XGNDS obviousness/SM obvious/YP Oby/M ocarina/MS O'Casey Occam/M occasional/Y occasion/MDSJG Occidental/S occidental/SY occident/M Occident/SM occipital/Y occlude/GSD occlusion/MS occlusive/S occulter/M occultism/SM occult/SRDYG occupancy/SM occupant/MS occupational/Y occupation/SAM occupied/AU occupier/M occupies/A occupy/RSDZG occur/AS occurred/A occurrence/SM occurring/A oceanfront/MS oceangoing Oceania/M oceanic ocean/MS oceanographer/SM oceanographic oceanography/SM oceanology/MS oceanside Oceanside/M Oceanus/M ocelot/SM ocher/DMGS Ochoa/M o'clock O'Clock O'Connell/M O'Connor/M Oconomowoc/M OCR octagonal/Y octagon/SM octahedral octahedron/M octal/S octane/MS octant/M octave/MS Octavia/M Octavian/M Octavio/M Octavius/M octavo/MS octennial octet/SM octile octillion/M Oct/M October/MS octogenarian/MS octopus/SM octoroon/M ocular/S oculist/SM OD odalisque/SM oddball/SM oddity/MS oddment/MS oddness/MS odd/TRYSPL Odele/M Odelia/M Odelinda/M Odella/M Odelle/M Odell/M O'Dell/M ode/MDRS Ode/MR Oderberg/MS Oder/M Odessa/M Odets/M Odetta/M Odette/M Odey/M Odie/M Odilia/M Odille/M Odin/M odiousness/MS odious/PY Odis/M odium/MS Odo/M odometer/SM Odom/M O'Donnell/M odor/DMS odoriferous odorless odorous/YP ODs O'Dwyer/M Ody/M Odysseus/M Odyssey/M odyssey/S OE OED oedipal Oedipal/Y Oedipus/M OEM/M OEMS oenology/MS oenophile/S o'er O'Er Oersted/M oesophagi oeuvre/SM Ofelia/M Ofella/M offal/MS offbeat/MS offcuts Offenbach/M offender/M offend/SZGDR offense/MSV offensively/I offensiveness/MSI offensive/YSP offerer/M offering/M offer/RDJGZ offertory/SM offhand/D offhandedness/S offhanded/YP officeholder/SM officemate/S officer/GMD officership/S office/SRMZ officialdom/SM officialism/SM officially/U official/PSYM officiant/SM officiate/XSDNG officiation/M officiator/MS officio officiousness/MS officious/YP offing/M offish offload/GDS offprint/GSDM offramp offset/SM offsetting offshoot/MS offshore offside/RS offspring/M offstage/S off/SZGDRJ offtrack Ofilia/M of/K often/RT oftentimes oft/NRT ofttimes Ogbomosho/M Ogdan/M Ogden/M Ogdon/M Ogilvy/M ogive/M Oglethorpe/M ogle/ZGDSR ogreish ogre/MS ogress/S oh OH O'Hara O'Hare/M O'Higgins Ohioan/S Ohio/M ohmic ohmmeter/MS ohm/SM oho/S ohs OHSA/M oilcloth/M oilcloths oiler/M oilfield/MS oiliness/SM oilman/M oil/MDRSZG oilmen oilseed/SM oilskin/MS oily/TPR oink/GDS ointment/SM Oise/M OJ Ojibwa/SM Okamoto/M okapi/SM Okayama/M okay/M Okeechobee/M O'Keeffe Okefenokee Okhotsk/M Okinawa/M Okinawan/S Oklahoma/M Oklahoman/SM Okla/M OK/MDG okra/MS OKs Oktoberfest Olaf/M Olag/M Ola/M Olav/M Oldenburg/M olden/DG Oldfield/M oldie/MS oldish oldness/S Oldsmobile/M oldster/SM Olduvai/M old/XTNRPS ol oleaginous oleander/SM O'Leary/M olefin/M Oleg/M Ole/MV Olenek/M Olenka/M Olen/M Olenolin/M oleomargarine/SM oleo/S oles olfactory Olga/M Olia/M oligarchic oligarchical oligarch/M oligarchs oligarchy/SM Oligocene oligopolistic oligopoly/MS Olimpia/M Olin/M olive/MSR Olive/MZR Oliver/M Olivero/M Olivette/M Olivetti/M Olivia/M Olivier/M Olivie/RM Oliviero/M Oliy/M Ollie/M Olly/M Olmec Olmsted/M Olsen/M Olson/M Olva/M Olvan/M Olwen/M Olympe/M Olympiad/MS Olympian/S Olympia/SM Olympic/S Olympie/M Olympus/M Omaha/SM Oman/M Omar/M ombudsman/M ombudsmen Omdurman/M omega/MS omelet/SM omelette's omen/DMG Omero/M omicron/MS ominousness/SM ominous/YP omission/MS omit/S omitted omitting omnibus/MS omni/M omnipotence/SM Omnipotent omnipotent/SY omnipresence/MS omnipresent/Y omniscience/SM omniscient/YS omnivore/MS omnivorousness/MS omnivorous/PY oms Omsk/M om/XN ON onanism/M Onassis/M oncer/M once/SR oncogene/S oncologist/S oncology/SM oncoming/S Ondrea/M Oneal/M Onega/M Onegin/M Oneida/SM O'Neil O'Neill oneness/MS one/NPMSX oner/M onerousness/SM onerous/YP oneself onetime oneupmanship Onfre/M Onfroi/M ongoing/S Onida/M onion/GDM onionskin/MS onlooker/MS onlooking only/TP Onofredo/M Ono/M onomatopoeia/SM onomatopoeic onomatopoetic Onondaga/MS onrush/GMS on/RY ons Onsager/M onset/SM onsetting onshore onside onslaught/MS Ontarian/S Ontario/M Ont/M onto ontogeny/SM ontological/Y ontology/SM onus/SM onward/S onyx/MS oodles ooh/GD oohs oolitic Oona/M OOo/M oops/S Oort/M ooze/GDS oozy/RT opacity/SM opalescence/S opalescent/Y Opalina/M Opaline/M Opal/M opal/SM opaque/GTPYRSD opaqueness/SM opcode/MS OPEC Opel/M opencast opened/AU opener/M openhandedness/SM openhanded/P openhearted opening/M openness/S OpenOffice.org/M opens/A openwork/MS open/YRDJGZTP operable/I operandi operand/SM operant/YS opera/SM operate/XNGVDS operatically operatic/S operationalization/S operationalize/D operational/Y operation/M operative/IP operatively operativeness/MI operatives operator/SM operetta/MS ope/S Ophelia/M Ophelie/M Ophiuchus/M ophthalmic/S ophthalmologist/SM ophthalmology/MS opiate/GMSD opine/XGNSD opinionatedness/M opinionated/PY opinion/M opioid opium/MS opossum/SM opp Oppenheimer/M opponent/MS opportune/IY opportunism/SM opportunistic opportunistically opportunist/SM opportunity/MS oppose/BRSDG opposed/U opposer/M oppositeness/M opposite/SXYNP oppositional opposition/M oppress/DSGV oppression/MS oppressiveness/MS oppressive/YP oppressor/MS opprobrious/Y opprobrium/SM Oprah/M ops opt/DSG opthalmic opthalmologic opthalmology optical/Y optician/SM optic/S optics/M optima optimality optimal/Y optimise's optimism/SM optimistic optimistically optimist/SM optimization/SM optimize/DRSZG optimized/U optimizer/M optimizes/U optimum/SM optionality/M optional/YS option/GDMS optoelectronic optometric optometrist/MS optometry/SM opulence/SM opulent/Y opus/SM op/XGDN OR oracle/GMSD oracular Oralee/M Oralia/M Oralie/M Oralla/M Oralle/M oral/YS Ora/M orangeade/MS Orange/M orange/MS orangery/SM orangutan/MS Oranjestad/M Oran/M orate/SDGNX oration/M oratorical/Y oratorio/MS orator/MS oratory/MS Orazio/M Orbadiah/M orbicular orbiculares orbital/MYS orbit/MRDGZS orb/SMDG orchard/SM orchestral/Y orchestra/MS orchestrate/GNSDX orchestrater's orchestration/M orchestrator/M orchid/SM ordainer/M ordainment/MS ordain/SGLDR ordeal/SM order/AESGD ordered/U orderer ordering/S orderless orderliness/SE orderly/PS order's/E ordinal/S ordinance/MS ordinarily ordinariness/S ordinary/RSPT ordinated ordinate/I ordinates ordinate's ordinating ordination/SM ordnance/SM Ordovician ordure/MS oregano/SM Oreg/M Oregonian/S Oregon/M Orelee/M Orelia/M Orelie/M Orella/M Orelle/M Orel/M Oren/M Ore/NM ore/NSM Oreo Orestes organdie's organdy/MS organelle/MS organically/I organic/S organismic organism/MS organist/MS organizable/UMS organizational/MYS organization/MEAS organize/AGZDRS organized/UE organizer/MA organizes/E organizing/E organ/MS organometallic organza/SM orgasm/GSMD orgasmic orgiastic orgy/SM Oriana/M oriel/MS orientable Oriental/S oriental/SY orientated/A orientate/ESDXGN orientates/A orientation/AMES orienteering/M orienter orient/GADES orient's Orient/SM orifice/MS orig origami/MS originality/SM originally original/US originate/VGNXSD origination/M originative/Y originator/SM origin/MS Orin/M Orinoco/M oriole/SM Orion/M orison/SM Oriya/M Orizaba/M Orkney/M Orland/M Orlando/M Orlan/M Orleans Orlick/M Orlon/SM Orly/M ormolu/SM or/MY ornamental/SY ornamentation/SM ornament/GSDM ornateness/SM ornate/YP orneriness/SM ornery/PRT ornithological ornithologist/SM ornithology/MS orographic/M orography/M Orono/M orotund orotundity/MS orphanage/MS orphanhood/M orphan/SGDM Orpheus/M Orphic Orran/M Orren/M Orrin/M orris/SM Orr/MN ors Orsa/M Orsola/M Orson/M Ortega/M Ortensia/M orthodontia/S orthodontic/S orthodontics/M orthodontist/MS orthodoxies orthodoxly/U Orthodox/S orthodoxy's orthodox/YS orthodoxy/U orthogonality/M orthogonalization/M orthogonalized orthogonal/Y orthographic orthographically orthography/MS orthonormal orthopedic/S orthopedics/M orthopedist/SM orthophosphate/MS orthorhombic Ortiz/M Orton/M Orval/M Orville/M Orv/M Orwellian Orwell/M o's Osage/SM Osaka/M Osbert/M Osborne/M Osborn/M Osbourne/M Osbourn/M Oscar/SM Osceola/M oscillate/SDXNG oscillation/M oscillator/SM oscillatory oscilloscope/SM osculate/XDSNG osculation/M Osgood/M OSHA Oshawa/M O'Shea/M Oshkosh/M osier/MS Osiris/M Oslo/M Os/M OS/M Osman/M osmium/MS Osmond/M osmoses osmosis/M osmotic Osmund/M osprey/SM osseous/Y Ossie/M ossification/M ossify/NGSDX ostensible ostensibly ostentation/MS ostentatiousness/M ostentatious/PY osteoarthritides osteoarthritis/M osteology/M osteopathic osteopath/M osteopaths osteopathy/MS osteoporoses osteoporosis/M ostracise's ostracism/MS ostracize/GSD Ostrander/M ostrich/MS Ostrogoth/M Ostwald/M O'Sullivan/M Osvaldo/M Oswald/M Oswell/M OT OTB OTC Otes Otha/M Othelia/M Othella/M Othello/M otherness/M other/SMP otherwise otherworldly/P otherworld/Y Othilia/M Othilie/M Otho/M otiose Otis/M OTOH Ottawa/MS otter/DMGS Ottilie/M Otto/M Ottoman ottoman/MS Ouagadougou/M oubliette/SM ouch/SDG oughtn't ought/SGD Ouija/MS ounce/MS our/S ourself ourselves ouster/M oust/RDGZS outage/MS outargue/GDS outback/MRS outbalance/GDS outbidding outbid/S outboard/S outboast/GSD outbound/S outbreak/SMG outbroke outbroken outbuilding/SM outburst/MGS outcast/GSM outclass/SDG outcome/SM outcropped outcropping/S outcrop/SM outcry/MSDG outdated/P outdid outdistance/GSD outdoes outdo/G outdone outdoor/S outdoorsy outdraw/GS outdrawn outdrew outermost outerwear/M outface/SDG outfall/MS outfielder/M outfield/RMSZ outfight/SG outfit/MS outfitted outfitter/MS outfitting outflank/SGD outflow/SMDG outfought outfox/GSD outgeneraled outgoes outgo/GJ outgoing/P outgrew outgrip outgrow/GSH outgrown outgrowth/M outgrowths outguess/SDG outhit/S outhitting outhouse/SM outing/M outlaid outlander/M outlandishness/MS outlandish/PY outland/ZR outlast/GSD outlawry/M outlaw/SDMG outlay/GSM outlet/SM outliers outline/SDGM outlive/GSD outlook/MDGS outlying outmaneuver/GSD outmatch/SDG outmigration outmoded outness/M outnumber/GDS outpaced outpatient/SM outperform/DGS out/PJZGSDR outplacement/S outplay/GDS outpoint/GDS outpost/SM outpouring/M outpour/MJG outproduce/GSD output/SM outputted outputting outrace/GSD outrage/GSDM outrageousness/M outrageous/YP outran outrank/GSD outr outreach/SDG outrider/MS outrigger/SM outright/Y outrunning outrun/S outscore/GDS outsell/GS outset/MS outsetting outshine/SG outshone outshout/GDS outsider/PM outside/ZSR outsize/S outskirt/SM outsmart/SDG outsold outsource/SDJG outspend/SG outspent outspoke outspokenness/SM outspoken/YP outspread/SG outstanding/Y outstate/NX outstation/M outstay/SDG outstretch/GSD outstripped outstripping outstrip/S outtake/S outvote/GSD outwardness/M outward/SYP outwear/SG outweigh/GD outweighs outwit/S outwitted outwitting outwore outwork/SMDG outworn ouzo/SM oval/MYPS ovalness/M ova/M ovarian ovary/SM ovate/SDGNX ovation/GMD ovenbird/SM oven/MS overabundance/MS overabundant overachieve/SRDGZ overact/DGVS overage/S overaggressive overallocation overall/SM overambitious overanxious overarching overarm/GSD overate overattentive overawe/GDS overbalance/DSG overbear/GS overbearingness/M overbearing/YP overbidding overbid/S overbite/MS overblown overboard overbold overbook/SDG overbore overborne overbought overbuild/GS overbuilt overburdening/Y overburden/SDG overbuy/GS overcame overcapacity/M overcapitalize/DSG overcareful overcast/GS overcasting/M overcautious overcerebral overcharge/DSG overcloud/DSG overcoating/M overcoat/SMG overcomer/M overcome/RSG overcommitment/S overcompensate/XGNDS overcompensation/M overcomplexity/M overcomplicated overconfidence/MS overconfident/Y overconscientious overconsumption/M overcook/SDG overcooled overcorrection overcritical overcrowd/DGS overcurious overdecorate/SDG overdependent overdetermined overdevelop/SDG overdid overdoes overdo/G overdone overdose/DSMG overdraft/SM overdraw/GS overdrawn overdress/GDS overdrew overdrive/GSM overdriven overdrove overdubbed overdubbing overdub/S overdue overeagerness/M overeager/PY overeater/M overeat/GNRS overeducated overemotional overemphases overemphasis/M overemphasize/GZDSR overenthusiastic overestimate/DSXGN overestimation/M overexcite/DSG overexercise/SDG overexert/GDS overexertion/SM overexploitation overexploited overexpose/GDS overexposure/SM overextend/DSG overextension overfall/M overfed overfeed/GS overfill/GDS overfishing overflew overflight/SM overflow/DGS overflown overfly/GS overfond overfull overgeneralize/GDS overgenerous overgraze/SDG overgrew overground overgrow/GSH overgrown overgrowth/M overgrowths overhand/DGS overhang/GS overhasty overhaul/GRDJS overhead/S overheard overhearer/M overhear/SRG overheat/SGD overhung overincredulous overindulgence/SM overindulgent overindulge/SDG overinflated overjoy/SGD overkill/SDMG overladed overladen overlaid overlain overland/S overlap/MS overlapped overlapping overlarge overlay/GS overleaf overlie overload/SDG overlong overlook/DSG overlord/DMSG overloud overly/GRS overmanning overmaster/GSD overmatching overmodest overmuch/S overnice overnight/SDRGZ overoptimism/SM overoptimistic overpaid overparticular overpass/GMSD overpay/LSG overpayment/M overplay/SGD overpopulate/DSNGX overpopulation/M overpopulous overpower/GSD overpowering/Y overpraise/DSG overprecise overpressure overprice/SDG overprint/DGS overproduce/SDG overproduction/S overprotect/GVDS overprotection/M overqualified overran overrate/DSG overreach/DSRG overreaction/SM overreact/SGD overred overrefined overrepresented overridden overrider/M override/RSG overripe overrode overrule/GDS overrunning overrun/S oversample/DG oversaturate oversaw oversea/S overseeing overseen overseer/M oversee/ZRS oversell/SG oversensitiveness/S oversensitive/P oversensitivity oversexed overshadow/GSD overshoe/SM overshoot/SG overshot/S oversight/SM oversimple oversimplification/M oversimplify/GXNDS oversize/GS oversleep/GS overslept oversoftness/M oversoft/P oversold overspecialization/MS overspecialize/GSD overspend/SG overspent overspill/DMSG overspread/SG overstaffed overstatement/SM overstate/SDLG overstay/GSD overstepped overstepping overstep/S overstimulate/DSG overstock/SGD overstraining overstressed overstretch/D overstrict overstrike/GS overstrung overstuffed oversubscribe/SDG oversubtle oversupply/MDSG oversuspicious overtaken overtake/RSZG overtax/DSG overthrew overthrow/GS overthrown overtightened overtime/MGDS overtire/DSG overtone/MS overtook overt/PY overture/DSMG overturn/SDG overuse/DSG overvalue/GSD overview/MS overweening overweight/GSD overwhelm/GDS overwhelming/Y overwinter/SDG overwork/GSD overwrap overwrite/SG overwritten overwrote overwrought over/YGS overzealousness/M overzealous/P Ovid/M oviduct/SM oviform oviparous ovoid/S ovular ovulate/GNXDS ovulatory ovule/MS ovum/MS ow/DYG Owen/MS owe/S owlet/SM owl/GSMDR owlishness/M owlish/PY owned/U own/EGDS ownership/MS owner/SM oxalate/M oxalic oxaloacetic oxblood/S oxbow/SM oxcart/MS oxen/M oxford/MS Oxford/MS oxidant/SM oxidate/NVX oxidation/M oxidative/Y oxide/SM oxidization/MS oxidized/U oxidize/JDRSGZ oxidizer/M oxidizes/A ox/MNS Oxnard Oxonian oxtail/M Oxus/M oxyacetylene/MS oxygenate/XSDMGN oxygenation/M oxygen/MS oxyhydroxides oxymora oxymoron/M oyster/GSDM oystering/M oz Ozark/SM Oz/M ozone/SM Ozymandias/M Ozzie/M Ozzy/M P PA Pablo/M Pablum/M pablum/S Pabst/M pabulum/SM PAC pace/DRSMZG Pace/M pacemaker/SM pacer/M pacesetter/MS pacesetting Pacheco/M pachyderm/MS pachysandra/MS pacific pacifically pacification/M Pacific/M pacifier/M pacifism/MS pacifistic pacifist/MS pacify/NRSDGXZ package/ARSDG packaged/U packager/S package's packages/U packaging/SM Packard/SM packed/AU packer/MUS packet/MSDG pack/GZSJDRMB packhorse/M packinghouse/S packing/M packsaddle/SM Packston/M packs/UA Packwood/M Paco/M Pacorro/M pact/SM Padang/M padded/U Paddie/M padding/SM paddle/MZGRSD paddler/M paddock/SDMG Paddy/M paddy/SM Padget/M Padgett/M Padilla/M padlock/SGDM pad/MS Padraic/M Padraig/M padre/MS Padrewski/M Padriac/M paean/MS paediatrician/MS paediatrics/M paedophilia's paella/SM paeony/M Paganini/M paganism/MS pagan/SM pageantry/SM pageant/SM pageboy/SM paged/U pageful Page/M page/MZGDRS pager/M paginate/DSNGX Paglia/M pagoda/MS Pahlavi/M paid/AU Paige/M pailful/SM Pail/M pail/SM Paine/M painfuller painfullest painfulness/MS painful/YP pain/GSDM painkiller/MS painkilling painlessness/S painless/YP painstaking/SY paint/ADRZGS paintbox/M paintbrush/SM painted/U painterly/P painter/YM painting/SM paint's paintwork paired/UA pair/JSDMG pairs/A pairwise paisley/MS pajama/MDS Pakistani/S Pakistan/M palace/MS paladin/MS palaeolithic palaeontologists palaeontology/M palanquin/MS palatability/M palatableness/M palatable/P palatalization/MS palatalize/SDG palatal/YS palate/BMS palatial/Y palatinate/SM Palatine palatine/S palaver/GSDM paleface/SM Palembang/M paleness/S Paleocene Paleogene paleographer/SM paleography/SM paleolithic Paleolithic paleontologist/S paleontology/MS Paleozoic Palermo/M pale/SPY Palestine/M Palestinian/S Palestrina/M palette/MS Paley/M palfrey/MS palimony/S palimpsest/MS palindrome/MS palindromic paling/M palisade/MGSD Palisades/M palish Palladio/M palladium/SM pallbearer/SM palletized pallet/SMGD pall/GSMD palliate/SDVNGX palliation/M palliative/SY pallidness/MS pallid/PY Pall/M pallor/MS palmate palmer/M Palmer/M Palmerston/M palmetto/MS palm/GSMDR palmist/MS palmistry/MS Palm/MR Palmolive/M palmtop/S Palmyra/M palmy/RT Palo/M Paloma/M Palomar/M palomino/MS palpable palpably palpate/SDNGX palpation/M palpitate/NGXSD palpitation/M pal/SJMDRYTG palsy/GSDM paltriness/SM paltry/TRP paludal Pa/M Pamela/M Pamelina/M Pamella/M pa/MH Pamirs Pam/M Pammie/M Pammi/M Pammy/M pampas/M pamperer/M pamper/RDSG Pampers pamphleteer/DMSG pamphlet/SM panacea/MS panache/MS Panama/MS Panamanian/S panama/S pancake/MGSD Panchito/M Pancho/M panchromatic pancreas/MS pancreatic panda/SM pandemic/S pandemonium/SM pander/ZGRDS Pandora/M panegyric/SM pane/KMS paneling/M panelist/MS panelization panelized panel/JSGDM Pangaea/M pang/GDMS pangolin/M panhandle/RSDGMZ panicked panicking panicky/RT panic/SM panier's panjandrum/M Pankhurst/M Pan/M Panmunjom/M panned pannier/SM panning panoply/MSD panorama/MS panoramic panpipes Pansie/M pan/SMD Pansy/M pansy/SM Pantagruel/M Pantaloon/M pantaloons pant/GDS pantheism/MS pantheistic pantheist/S pantheon/MS panther/SM pantie/SM pantiled pantograph/M pantomime/SDGM pantomimic pantomimist/SM pantry/SM pantsuit/SM pantyhose pantyliner pantywaist/SM Panza/M Paola/M Paoli/M Paolina/M Paolo/M papacy/SM Papagena/M Papageno/M papal/Y papa/MS paparazzi papaw/SM papaya/MS paperback/GDMS paperboard/MS paperboy/SM paperer/M papergirl/SM paper/GJMRDZ paperhanger/SM paperhanging/SM paperiness/M paperless paperweight/MS paperwork/SM papery/P papillae papilla/M papillary papist/MS papoose/SM Pappas/M papped papping pappy/RST paprika/MS pap/SZMNR papyri papyrus/M Paquito/M parable/MGSD parabola/MS parabolic paraboloidal/M paraboloid/MS Paracelsus/M paracetamol/M parachuter/M parachute/RSDMG parachutist/MS Paraclete/M parader/M parade/RSDMZG paradigmatic paradigm/SM paradisaic paradisaical Paradise/M paradise/MS paradoxic paradoxicalness/M paradoxical/YP paradox/MS paraffin/GSMD paragon/SGDM paragrapher/M paragraph/MRDG paragraphs Paraguayan/S Paraguay/M parakeet/MS paralegal/S paralinguistic parallax/SM parallel/DSG paralleled/U parallelepiped/MS parallelism/SM parallelization/MS parallelize/ZGDSR parallelogram/MS paralysis/M paralytically paralytic/S paralyzedly/S paralyzed/Y paralyzer/M paralyze/ZGDRS paralyzingly/S paralyzing/Y paramagnetic paramagnet/M Paramaribo/M paramecia paramecium/M paramedical/S paramedic/MS parameterization/SM parameterize/BSDG parameterized/U parameterless parameter/SM parametric parametrically parametrization parametrize/DS paramilitary/S paramount/S paramour/MS para/MS Paramus/M Paran paranoiac/S paranoia/SM paranoid/S paranormal/SY parapet/SMD paraphernalia paraphrase/GMSRD paraphraser/M paraplegia/MS paraplegic/S paraprofessional/SM parapsychologist/S parapsychology/MS paraquat/S parasite/SM parasitically parasitic/S parasitism/SM parasitologist/M parasitology/M parasol/SM parasympathetic/S parathion/SM parathyroid/S paratrooper/M paratroop/RSZ paratyphoid/S parboil/DSG parceled/U parceling/M parcel/SGMD Parcheesi/M parch/GSDL parchment/SM PARC/M pardonableness/M pardonable/U pardonably/U pardoner/M pardon/ZBGRDS paregoric/SM parentage/MS parental/Y parenteral parentheses parenthesis/M parenthesize/GSD parenthetic parenthetical/Y parenthood/MS parent/MDGJS pare/S paresis/M pares/S Pareto/M parfait/SM pariah/M pariahs parietal/S parimutuel/S paring/M parishioner/SM parish/MS Parisian/SM Paris/M parity/ESM parka/MS Parke/M Parker/M Parkersburg/M park/GJZDRMS Parkhouse/M parking/M Parkinson/M parkish parkland/M parklike Parkman Park/RMS parkway/MS parlance/SM parlay/DGS parley/MDSG parliamentarian/SM parliamentary/U parliament/MS Parliament/MS parlor/SM parlous Parmesan/S parmigiana Parnassus/SM Parnell/M parochialism/SM parochiality parochial/Y parodied/U parodist/SM parody/SDGM parolee/MS parole/MSDG paroxysmal paroxysm/MS parquetry/SM parquet/SMDG parrakeet's parred parricidal parricide/MS parring Parrish/M Parr/M Parrnell/M parrot/GMDS parrotlike parry/GSD Parry/M parse parsec/SM parsed/U Parsee's parser/M Parsifal/M parsimonious/Y parsimony/SM pars/JDSRGZ parsley/MS parsnip/MS parsonage/MS parson/MS Parsons/M partaken partaker/M partake/ZGSR part/CDGS parterre/MS parter/S parthenogeneses parthenogenesis/M Parthenon/M Parthia/M partiality/MS partial/SY participant/MS participate/NGVDSX participation/M participator/S participatory participial/Y participle/MS particleboard/S particle/MS particolored particularistic particularity/SM particularization/MS particularize/GSD particular/SY particulate/S parting/MS partisanship/SM partisan/SM partition/AMRDGS partitioned/U partitioner/M partitive/S partizan's partly partner/DMGS partnership/SM partook partridge/MS part's parturition/SM partway party/RSDMG parvenu/SM par/ZGSJBMDR Pasadena/M PASCAL Pascale/M Pascal/M pascal/SM paschal/S pasha/MS Paso/M Pasquale/M pas/S passably passage/MGSD passageway/MS Passaic/M passband passbook/MS passel/MS pass/M passenger/MYS passerby passer/M passersby passim passing/Y passionated passionate/EYP passionateness/EM passionates passionating passioned passionflower/MS passioning passionless passion/SEM Passion/SM passivated passiveness/S passive/SYP passivity/S pass/JGVBZDSR passkey/SM passmark passover Passover/MS passport/SM password/SDM pasta/MS pasteboard/SM pasted/UA pastel/MS paste/MS Pasternak/M pastern/SM pasteup pasteurization/MS pasteurized/U pasteurizer/M pasteurize/RSDGZ Pasteur/M pastiche/MS pastille/SM pastime/SM pastiness/SM pastoralization/M pastoral/SPY pastorate/MS pastor/GSDM past/PGMDRS pastrami/MS pastry/SM past's/A pasts/A pasturage/SM pasture/MGSRD pasturer/M pasty/PTRS Patagonia/M Patagonian/S patch/EGRSD patcher/EM patchily patchiness/S patch's patchwork/RMSZ patchy/PRT patellae patella/MS Patel/M Pate/M paten/M Paten/M patentee/SM patent/ZGMRDYSB paterfamilias/SM pater/M paternalism/MS paternalist paternalistic paternal/Y paternity/SM paternoster/SM Paterson/M pate/SM pathetic pathetically pathfinder/MS pathless/P path/M pathname/SM pathogenesis/M pathogenic pathogen/SM pathologic pathological/Y pathologist/MS pathology/SM pathos/SM paths pathway/MS Patience/M patience/SM patient/MRYTS patient's/I patients/I patina/SM patine Patin/M patio/MS Pat/MN pat/MNDRS Patna/M patois/M Paton/M patresfamilias patriarchal patriarchate/MS patriarch/M patriarchs patriarchy/MS Patrica/M Patrice/M Patricia/M patrician/MS patricide/MS Patricio/M Patrick/M Patric/M patrimonial patrimony/SM patriotically patriotic/U patriotism/SM patriot/SM patristic/S Patrizia/M Patrizio/M Patrizius/M patrolled patrolling patrolman/M patrolmen patrol/MS patrolwoman patrolwomen patronage/MS patroness/S patronization patronized/U patronize/GZRSDJ patronizer/M patronizes/A patronizing's/U patronizing/YM patronymically patronymic/S patron/YMS patroon/MS patsy/SM Patsy/SM patted Patten/M patten/MS patterer/M pattern/GSDM patternless patter/RDSGJ Patterson/M Pattie/M Patti/M patting Pattin/M Patton/M Patty/M patty/SM paucity/SM Paula/M Paule/M Pauletta/M Paulette/M Paulie/M Pauli/M Paulina/M Pauline Pauling/M Paulita/M Paul/MG Paulo/M Paulsen/M Paulson/M Paulus/M Pauly/M paunch/GMSD paunchiness/M paunchy/RTP pauperism/SM pauperize/SDG pauper/SGDM pause/DSG Pavarotti paved/UA pave/GDRSJL Pavel/M pavement/SGDM paver/M paves/A Pavia/M pavilion/SMDG paving/A paving's Pavla/M Pavlova/MS Pavlovian Pavlov/M pawl/SM paw/MDSG pawnbroker/SM pawnbroking/S Pawnee/SM pawner/M pawn/GSDRM pawnshop/MS pawpaw's Pawtucket/M paxes Paxon/M Paxton/M payable/S pay/AGSLB payback/S paycheck/SM payday/MS payed payee/SM payer/SM payload/SM paymaster/SM payment/ASM Payne/SM payoff/MS payola/MS payout/S payroll/MS payslip/S Payson/M Payton/M Paz/M Pb/M PBS PBX PCB PC/M PCP PCs pct pd PD Pd/M PDP PDQ PDT PE Peabody/M peaceableness/M peaceable/P peaceably peacefuller peacefullest peacefulness/S peaceful/PY peace/GMDS peacekeeping/S Peace/M peacemaker/MS peacemaking/MS peacetime/MS peach/GSDM Peachtree/M peachy/RT peacock/SGMD Peadar/M peafowl/SM peahen/MS peaked/P peakiness/M peak/SGDM peaky/P pealed/A Peale/M peal/MDSG peals/A pea/MS peanut/SM Pearce/M Pearla/M Pearle/M pearler/M Pearlie/M Pearline/M Pearl/M pearl/SGRDM pearly/TRS Pearson/M pear/SYM peartrees Peary/M peasanthood peasantry/SM peasant/SM peashooter/MS peats/A peat/SM peaty/TR pebble/MGSD pebbling/M pebbly/TR Pebrook/M pecan/SM peccadilloes peccadillo/M peccary/MS Pechora/M pecker/M peck/GZSDRM Peckinpah/M Peck/M Pecos/M pectic pectin/SM pectoral/S peculate/NGDSX peculator/S peculiarity/MS peculiar/SY pecuniary pedagogical/Y pedagogic/S pedagogics/M pedagogue/SDGM pedagogy/MS pedal/SGRDM pedantic pedantically pedantry/MS pedant/SM peddler/M peddle/ZGRSD pederast/SM pederasty/SM Peder/M pedestal/GDMS pedestrianization pedestrianize/GSD pedestrian/MS pediatrician/SM pediatric/S pedicab/SM pedicure/DSMG pedicurist/SM pedigree/DSM pediment/DMS pedlar's pedometer/MS pedophile/S pedophilia Pedro/M peduncle/MS peeing peekaboo/SM peek/GSD peeler/M peeling/M Peel/M peel/SJGZDR peen/GSDM peeper/M peephole/SM peep/SGZDR peepshow/MS peepy peerage/MS peer/DMG peeress/MS peerlessness/M peerless/PY peeve/GZMDS peevers/M peevishness/SM peevish/YP peewee/S pee/ZDRS Pegasus/MS pegboard/SM Pegeen/M pegged Peggie/M Peggi/M pegging Peggy/M Peg/M peg/MS peignoir/SM Pei/M Peiping/M Peirce/M pejoration/SM pejorative/SY peke/MS Pekinese's pekingese Pekingese/SM Peking/SM pekoe/SM pelagic Pelee/M Pele/M pelf/SM Pelham/M pelican/SM pellagra/SM pellet/SGMD pellucid Peloponnese/M pelter/M pelt/GSDR pelvic/S pelvis/SM Pembroke/M pemmican/SM penalization/SM penalized/U penalize/SDG penalty/MS penal/Y Pena/M penance/SDMG pence/M penchant/MS pencil/SGJMD pendant/SM pend/DCGS pendent/CS Penderecki/M Pendleton/M pendulous pendulum/MS Penelopa/M Penelope/M penetrability/SM penetrable penetrate/SDVGNX penetrating/Y penetration/M penetrativeness/M penetrative/PY penetrator/MS penguin/MS penicillin/SM penile peninsular peninsula/SM penis/MS penitence/MS penitential/YS penitentiary/MS penitent/SY penknife/M penknives penlight/MS pen/M Pen/M penman/M penmanship/MS penmen Penna pennant/SM penned Penney/M Pennie/M penniless Penni/M penning Pennington/M pennis Penn/M pennon/SM Pennsylvania/M Pennsylvanian/S Penny/M penny/SM pennyweight/SM pennyworth/M penologist/MS penology/MS Penrod/M Pensacola/M pensioner/M pension/ZGMRDBS pensiveness/S pensive/PY pens/V pentacle/MS pentagonal/SY Pentagon/M pentagon/SM pentagram/MS pentameter/SM pent/AS Pentateuch/M pentathlete/S pentathlon/MS pentatonic pentecostal Pentecostalism/S Pentecostal/S Pentecost/SM penthouse/SDGM Pentium/M penuche/SM penultimate/SY penumbrae penumbra/MS penuriousness/MS penurious/YP penury/SM peonage/MS peon/MS peony/SM people/SDMG Peoria/M Pepe/M Pepillo/M Pepi/M Pepin/M Pepita/M Pepito/M pepped peppercorn/MS pepperer/M peppergrass/M peppermint/MS pepperoni/S pepper/SGRDM peppery peppiness/SM pepping peppy/PRT Pepsico/M PepsiCo/M Pepsi/M pepsin/SM pep/SM peptic/S peptidase/SM peptide/SM peptizing Pepys/M Pequot/M peradventure/S perambulate/DSNGX perambulation/M perambulator/MS percale/MS perceivably perceive/DRSZGB perceived/U perceiver/M percentage/MS percentile/SM percent/MS perceptible perceptibly perceptional perception/MS perceptiveness/MS perceptive/YP perceptual/Y percept/VMS Perceval/M perchance perch/GSDM perchlorate/M perchlorination percipience/MS percipient/S Percival/M percolate/NGSDX percolation/M percolator/MS percuss/DSGV percussionist/MS percussion/SAM percussiveness/M percussive/PY percutaneous/Y Percy/M perdition/MS perdurable peregrinate/XSDNG peregrination/M peregrine/S Perelman/M peremptorily peremptory/P perennial/SY pres perestroika/S Perez/M perfecta/S perfect/DRYSTGVP perfecter/M perfectibility/MS perfectible perfectionism/MS perfectionist/MS perfection/MS perfectiveness/M perfective/PY perfectness/MS perfidiousness/M perfidious/YP perfidy/MS perforated/U perforate/XSDGN perforation/M perforce performance/MS performed/U performer/M perform/SDRZGB perfumer/M perfumery/SM perfume/ZMGSRD perfunctorily perfunctoriness/M perfunctory/P perfused perfusion/M Pergamon/M pergola/SM perhaps/S Peria/M pericardia pericardium/M Perice/M Periclean Pericles/M perigee/SM perihelia perihelion/M peril/GSDM Perilla/M perilousness/M perilous/PY Peri/M perimeter/MS perinatal perinea perineum/M periodic periodical/YMS periodicity/MS period/MS periodontal/Y periodontics/M periodontist/S peripatetic/S peripheral/SY periphery/SM periphrases periphrasis/M periphrastic periscope/SDMG perishable/SM perish/BZGSRD perishing/Y peristalses peristalsis/M peristaltic peristyle/MS peritoneal peritoneum/SM peritonitis/MS periwigged periwigging periwig/MS periwinkle/SM perjurer/M perjure/SRDZG perjury/MS per/K perk/GDS perkily perkiness/S Perkin/SM perky/TRP Perla/M Perle/M Perl/M permafrost/MS permalloy/M Permalloy/M permanence/SM permanency/MS permanentness/M permanent/YSP permeability/SM permeableness/M permeable/P permeate/NGVDSX Permian permissibility/M permissibleness/M permissible/P permissibly permission/SM permissiveness/MS permissive/YP permit/SM permitted permitting Perm/M perm/MDGS permutation/MS permute/SDG Pernell/M perniciousness/MS pernicious/PY Pernod/M Peron/M peroration/SM Perot/M peroxidase/M peroxide/MGDS perpend/DG perpendicularity/SM perpendicular/SY perpetrate/NGXSD perpetration/M perpetrator/SM perpetual/SY perpetuate/NGSDX perpetuation/M perpetuity/MS perplex/DSG perplexed/Y perplexity/MS perquisite/SM Perren/M Perri/M Perrine/M Perry/MR persecute/XVNGSD persecution/M persecutor/MS persecutory Perseid/M Persephone/M Perseus/M perseverance/MS persevere/GSD persevering/Y Pershing/M Persia/M Persian/S persiflage/MS persimmon/SM Persis/M persist/DRSG persistence/SM persistent/Y persnickety personableness/M personable/P personae personage/SM personality/SM personalization/CMS personalize/CSDG personalized/U personalty/MS personal/YS persona/M person/BMS personification/M personifier/M personify/XNGDRS personnel/SM person's/U persons/U perspective/YMS perspex perspicaciousness/M perspicacious/PY perspicacity/S perspicuity/SM perspicuousness/M perspicuous/YP perspiration/MS perspire/DSG persuaded/U persuader/M persuade/ZGDRSB persuasion/SM persuasively persuasiveness/MS persuasive/U pertain/GSD Perth/M pertinaciousness/M pertinacious/YP pertinacity/MS pertinence/S pertinent/YS pertness/MS perturbation/MS perturbed/U perturb/GDS pertussis/SM pert/YRTSP peruke/SM Peru/M perusal/SM peruser/M peruse/RSDZG Peruvian/S pervade/SDG pervasion/M pervasiveness/MS pervasive/PY perverseness/SM perverse/PXYNV perversion/M perversity/MS pervert/DRSG perverted/YP perverter/M perviousness peseta/SM Peshawar/M peskily peskiness/S pesky/RTP peso/MS pessimal/Y pessimism/SM pessimistic pessimistically pessimist/SM pester/DG pesticide/MS pestiferous pestilence/SM pestilential/Y pestilent/Y pestle/SDMG pesto/S pest/RZSM PET Ptain/M petal/SDM Peta/M petard/MS petcock/SM Pete/M peter/GD Peter/M Petersburg/M Petersen/M Peters/N Peterson/M Peterus/M Petey/M pethidine/M petiole/SM petiteness/M petite/XNPS petitioner/M petition/GZMRD petition's/A petitions/A petits Petkiewicz/M Pet/MRZ Petra/M Petrarch/M petrel/SM petri petrifaction/SM petrify/NDSG Petrina/M Petr/M petrochemical/SM petrodollar/MS petroglyph/M petrolatum/MS petroleum/MS petrolled petrolling petrol/MS petrologist/MS petrology/MS Petronella/M Petronia/M Petronilla/M Petronille/M pet/SMRZ petted petter/MS Pettibone/M petticoat/SMD pettifogged pettifogger/SM pettifogging pettifog/S pettily pettiness/S petting pettis pettishness/M pettish/YP Petty/M petty/PRST petulance/MS petulant/Y Petunia/M petunia/SM Peugeot/M Pewaukee/M pewee/MS pewit/MS pew/SM pewter/SRM peyote/SM Peyter/M Peyton/M pf Pfc PFC pfennig/SM Pfizer/M pg PG Phaedra/M Phaethon/M phaeton/MS phage/M phagocyte/SM Phaidra/M phalanger/MS phalanges phalanx/SM phalli phallic phallus/M Phanerozoic phantasmagoria/SM phantasmal phantasm/SM phantasy's phantom/MS pharaoh Pharaoh/M pharaohs Pharaohs pharisaic Pharisaic Pharisaical pharisee/S Pharisee/SM pharmaceutical/SY pharmaceutic/S pharmaceutics/M pharmacist/SM pharmacological/Y pharmacologist/SM pharmacology/SM pharmacopoeia/SM pharmacy/SM pharyngeal/S pharynges pharyngitides pharyngitis/M pharynx/M phase/DSRGZM phaseout/S PhD pheasant/SM Phebe/M Phedra/M Phekda/M Phelia/M Phelps/M phenacetin/MS phenobarbital/SM phenolic phenol/MS phenolphthalein/M phenomenal/Y phenomena/SM phenomenological/Y phenomenology/MS phenomenon/SM phenotype/MS phenylalanine/M phenyl/M pheromone/MS phew/S phialled phialling phial/MS Phidias/M Philadelphia/M philanderer/M philander/SRDGZ philanthropic philanthropically philanthropist/MS philanthropy/SM philatelic philatelist/MS philately/SM Philbert/M Philco/M philharmonic/S Philipa/M Philip/M Philippa/M Philippe/M Philippians/M philippic/SM Philippine/SM Philis/M philistine/S Philistine/SM philistinism/S Phillida/M Phillie/M Phillipa/M Phillipe/M Phillip/MS Phillipp/M Phillis/M Philly/SM Phil/MY philodendron/MS philological/Y philologist/MS philology/MS Philomena/M philosopher/MS philosophic philosophical/Y philosophized/U philosophizer/M philosophizes/U philosophize/ZDRSG philosophy/MS philter/SGDM philtre/DSMG Phineas/M Phip/M Phipps/M phi/SM phlebitides phlebitis/M phlegmatic phlegmatically phlegm/SM phloem/MS phlox/M pH/M Ph/M phobia/SM phobic/S Phobos/M Phoebe/M phoebe/SM Phoenicia/M Phoenician/SM Phoenix/M phoenix/MS phone/DSGM phoneme/SM phonemically phonemic/S phonemics/M phonetically phonetician/SM phonetic/S phonetics/M phonically phonic/S phonics/M phoniness/MS phonographer/M phonographic phonograph/RM phonographs phonologic phonological/Y phonologist/MS phonology/MS phonon/M phony/PTRSDG phooey/S phosphatase/M phosphate/MS phosphide/M phosphine/MS phosphoresce phosphorescence/SM phosphorescent/Y phosphoric phosphor/MS phosphorous phosphorus/SM photocell/MS photochemical/Y photochemistry/M photocopier/M photocopy/MRSDZG photoelectric photoelectrically photoelectronic photoelectrons photoengraver/M photoengrave/RSDJZG photoengraving/M photofinishing/MS photogenic photogenically photograph/AGD photographer/SM photographic photographically photograph's photographs/A photography/MS photojournalism/SM photojournalist/SM photoluminescence/M photolysis/M photolytic photometer/SM photometric photometrically photometry/M photomicrograph/M photomicrography/M photomultiplier/M photon/MS photorealism photosensitive photo/SGMD photosphere/M photostatic Photostat/MS Photostatted Photostatting photosyntheses photosynthesis/M photosynthesize/DSG photosynthetic phototypesetter phototypesetting/M phrasal phrase/AGDS phrasebook phrasemaking phraseology/MS phrase's phrasing/SM phrenological/Y phrenologist/MS phrenology/MS phylactery/MS phylae phyla/M Phylis/M Phyllida/M Phyllis/M Phyllys/M phylogeny/MS phylum/M Phylys/M phys physicality/M physical/PYS physician/SM physicist/MS physicked physicking physic/SM physiochemical physiognomy/SM physiography/MS physiologic physiological/Y physiologist/SM physiology/MS physiotherapist/MS physiotherapy/SM physique/MSD phytoplankton/M Piaf/M Piaget/M Pia/M pianism/M pianissimo/S pianistic pianist/SM pianoforte/MS pianola Pianola/M piano/SM piaster/MS piazza/SM pibroch/M pibrochs picador/MS picaresque/S pica/SM Picasso/M picayune/S Piccadilly/M piccalilli/MS piccolo/MS pickaback's pickaxe's pickax/GMSD pickerel/MS Pickering/M picker/MG picketer/M picket/MSRDZG Pickett/M Pickford/M pick/GZSJDR pickle/SDMG Pickman/M pickoff/S pickpocket/GSM pickup/SM Pickwick/M picky/RT picnicked picnicker/MS picnicking picnic/SM picofarad/MS picojoule picoseconds picot/DMGS Pict/M pictograph/M pictographs pictorialness/M pictorial/PYS picture/MGSD picturesqueness/SM picturesque/PY piddle/GSD piddly pidgin/SM piebald/S piece/GMDSR piecemeal piecer/M piecewise pieceworker/M piecework/ZSMR piedmont Piedmont/M pieing pie/MS Pierce/M piercer/M pierce/RSDZGJ piercing/Y Pierette/M pier/M Pier/M Pierre/M Pierrette/M Pierrot/M Pierson/M Pieter/M Pietra/M Pietrek/M Pietro/M piety/SM piezoelectric piezoelectricity/M piffle/MGSD pigeon/DMGS pigeonhole/SDGM pigged piggery/M pigging piggishness/SM piggish/YP piggyback/MSDG Piggy/M piggy/RSMT pigheadedness/S pigheaded/YP piglet/MS pigmentation/MS pigment/MDSG pig/MLS Pigmy's pigpen/SM pigroot pigskin/MS pigsty/SM pigswill/M pigtail/SMD Pike/M pike/MZGDRS piker/M pikestaff/MS pilaf/MS pilaster/SM Pilate/M pilau's pilchard/SM Pilcomayo/M pile/JDSMZG pileup/MS pilferage/SM pilferer/M pilfer/ZGSRD Pilgrim pilgrimage/DSGM pilgrim/MS piling/M pillage/RSDZG pillar/DMSG pillbox/MS pill/GSMD pillion/DMGS pillory/MSDG pillowcase/SM pillow/GDMS pillowslip/S Pillsbury/M pilot/DMGS pilothouse/SM piloting/M pimento/MS pimiento/SM pimpernel/SM pimp/GSMYD pimple/SDM pimplike pimply/TRM PIN pinafore/MS piata/S Pinatubo/M pinball/MS Pincas/M pincer/GSD Pinchas/M pincher/M pinch/GRSD pincushion/SM Pincus/M Pindar/M pineapple/MS pined/A Pinehurst/M pine/MNGXDS pines/A pinfeather/SM ping/GDRM pinheaded/P pinhead/SMD pinhole/SM pining/A pinion/DMG Pinkerton/M pinkeye/MS pink/GTYDRMPS pinkie/SM pinkish/P pinkness/S pinko/MS pinky's pinnacle/MGSD pinnate pinned/U pinning/S Pinocchio/M Pinochet/M pinochle/SM pion/S pinpoint/SDG pinprick/MDSG pin's pinsetter/SM Pinsky/M pinstripe/SDM pintail/SM Pinter/M pint/MRS pinto/S pinup/MS pin/US pinwheel/DMGS pinyin Pinyin piny/RT pioneer/SDMG pion/M Piotr/M piousness/MS pious/YP pipeline/DSMG pipe/MS piper/M Piper/M Pipestone/M pipet's pipette/MGSD pipework piping/YM pipit/MS pip/JSZMGDR Pip/MR Pippa/M pipped pipping pippin/SM Pippo/M Pippy/M pipsqueak/SM piquancy/MS piquantness/M piquant/PY pique/GMDS piracy/MS Piraeus/M Pirandello/M piranha/SM pirate/MGSD piratical/Y pirogi pirogies pirouette/MGSD pis Pisa/M piscatorial Pisces/M Pisistratus/M pismire/SM Pissaro/M piss/DSRG! pistachio/MS piste/SM pistillate pistil/MS pistoleers pistole/M pistol/SMGD piston/SM pitapat/S pitapatted pitapatting pita/SM Pitcairn/M pitchblende/SM pitcher/M pitchfork/GDMS pitching/M pitchman/M pitchmen pitch/RSDZG pitchstone/M piteousness/SM piteous/YP pitfall/SM pithily pithiness/SM pith/MGDS piths pithy/RTP pitiableness/M pitiable/P pitiably pitier/M pitifuller pitifullest pitifulness/M pitiful/PY pitilessness/SM pitiless/PY pitman/M pit/MS Pitney/M piton/SM pittance/SM pitted pitting Pittman/M Pittsburgh/ZM Pittsfield/M Pitt/SM Pittston/M pituitary/SM pitying/Y pity/ZDSRMG Pius/M pivotal/Y pivot/DMSG pivoting/M pix/DSG pixel/SM pixie/MS pixiness pixmap/SM Pizarro/M pizazz/S pi/ZGDRH pizza/SM pizzeria/SM pizzicati pizzicato pj's PJ's pk pkg pkt pkwy Pkwy pl placard/DSMG placate/NGVXDRS placatory placeable/A placebo/SM placed/EAU place/DSRJLGZM placeholder/S placekick/DGS placeless/Y placement/AMES placental/S placenta/SM placer/EM places/EA placidity/SM placidness/M placid/PY placing/AE placket/SM plagiarism/MS plagiarist/MS plagiarize/GZDSR plagiary/SM plagued/U plague/MGRSD plaguer/M plaice/M plaid/DMSG plainclothes plainclothesman plainclothesmen Plainfield/M plainness/MS plainsman/M plainsmen plainsong/SM plainspoken plain/SPTGRDY plaintiff/MS plaintiveness/M plaintive/YP plaint/VMS Plainview/M plaiting/M plait/SRDMG planar planarity Planck/M plan/DRMSGZ planeload planer/M plane's plane/SCGD planetarium/MS planetary planetesimal/M planet/MS planetoid/SM plangency/S plangent planking/M plank/SJMDG plankton/MS planned/U planner/SM planning Plano planoconcave planoconvex Plantagenet/M plantain/MS plantar plantation/MS planter/MS planting/S plantlike plant's plant/SADG plaque/MS plash/GSDM plasma/MS plasmid/S plasm/M plasterboard/MS plasterer/M plastering/M plaster/MDRSZG plasterwork/M plastically plasticine Plasticine/M plasticity/SM plasticize/GDS plastic/MYS plateau/GDMS plateful/S platelet/SM platen/M plater/M plate/SM platform/SGDM Plath/M plating/M platinize/GSD platinum/MS platitude/SM platitudinous/Y plat/JDNRSGXZ Plato/M platonic Platonic Platonism/M Platonist platoon/MDSG platted Platte/M platter/MS Platteville/M platting platypus/MS platys platy/TR plaudit/MS plausibility/S plausible/P plausibly Plautus/M playability/U playable/U playacting/M playact/SJDG playback/MS playbill/SM Playboy/M playboy/SM play/DRSEBG played/A player's/E player/SM playfellow/S playfulness/MS playful/PY playgirl/SM playgoer/MS playground/MS playgroup/S playhouse/SM playing/S playmate/MS playoff/S playpen/SM playroom/SM plays/A Playtex/M plaything/MS playtime/SM playwright/SM playwriting/M plaza/SM pleader/MA pleading/MY plead/ZGJRDS pleasanter pleasantest pleasantness/SMU pleasantry/MS pleasant/UYP pleased/EU pleaser/M pleases/E please/Y pleasingness/M pleasing/YP plea/SM pleas/RSDJG pleasurableness/M pleasurable/P pleasurably pleasureful pleasure/MGBDS pleasure's/E pleasures/E pleater/M pleat/RDMGS plebeian/SY plebe/MS plebiscite/SM plectra plectrum/SM pledger/M pledge/RSDMG Pleiads Pleistocene plenary/S plenipotentiary/S plenitude/MS plenteousness/M plenteous/PY plentifulness/M plentiful/YP plenty/SM plenum/M pleonasm/MS plethora/SM pleurae pleural pleura/M pleurisy/SM Plexiglas/MS plexus/SM pliability/MS pliableness/M pliable/P pliancy/MS pliantness/M pliant/YP plication/MA plier/MA plight/GMDRS plimsolls plinker/M plink/GRDS plinth/M plinths Pliny/M Pliocene/S PLO plodded plodder/SM plodding/SY plod/S plopped plopping plop/SM plosive plot/SM plotted/A plotter/MDSG plotting plover/MS plowed/U plower/M plowman/M plowmen plow/SGZDRM plowshare/MS ploy's ploy/SCDG plucker/M pluckily pluckiness/SM pluck/SGRD plucky/TPR pluggable plugged/UA plugging/AU plughole plug's plug/US plumage/DSM plumbago/M plumbed/U plumber/M plumbing/M plumb/JSZGMRD plume/SM plummer plummest plummet/DSG plummy plumper/M plumpness/S plump/RDNYSTGP plum/SMDG plumy/TR plunder/GDRSZ plunger/M plunge/RSDZG plunker/M plunk/ZGSRD pluperfect/S pluralism/MS pluralistic pluralist/S plurality/SM pluralization/MS pluralize/GZRSD pluralizer/M plural/SY plushness/MS plush/RSYMTP plushy/RPT plus/S plussed plussing Plutarch/M plutocracy/MS plutocratic plutocrat/SM Pluto/M plutonium/SM pluvial/S ply/AZNGRSD Plymouth/M plywood/MS pm PM Pm/M PMS pneumatically pneumatic/S pneumatics/M pneumonia/MS PO poacher/M poach/ZGSRD Pocahontas/M pocketbook/SM pocketful/SM pocketing/M pocketknife/M pocketknives pocket/MSRDG pock/GDMS pockmark/MDSG Pocono/MS podded podding podge/ZR Podgorica/M podiatrist/MS podiatry/MS podium/MS pod/SM Podunk/M Poe/M poem/MS poesy/GSDM poetaster/MS poetess/MS poetically poeticalness poetical/U poetic/S poetics/M poet/MS poetry/SM pogo Pogo/M pogrom/GMDS poignancy/MS poignant/Y Poincar/M poinciana/SM Poindexter/M poinsettia/SM pointblank pointedness/M pointed/PY pointer/M pointillism/SM pointillist/SM pointing/M pointlessness/SM pointless/YP point/RDMZGS pointy/TR poise/M pois/GDS poi/SM poisoner/M poisoning/M poisonous/PY poison/RDMZGSJ Poisson/M poke/DRSZG Pokemon/M pokerface/D poker/M poky/SRT Poland/M Polanski/M polarimeter/SM polarimetry polariscope/M Polaris/M polarity/MS polarization/CMS polarized/UC polarize/RSDZG polarizes/C polarizing/C polarogram/SM polarograph polarography/M Polaroid/SM polar/S polecat/SM polemical/Y polemicist/S polemic/S polemics/M pole/MS Pole/MS poler/M polestar/S poleward/S pol/GMDRS policeman/M policemen/M police/MSDG policewoman/M policewomen policyholder/MS policymaker/S policymaking policy/SM poliomyelitides poliomyelitis/M polio/SM Polish polished/U polisher/M polish/RSDZGJ polis/M Politburo/M politburo/S politeness/MS polite/PRTY politesse/SM politically political/U politician/MS politicization/S politicize/CSDG politicked politicking/SM politico/SM politic/S politics/M polity/MS polka/SDMG Polk/M pollack/SM Pollard/M polled/U pollen/GDM pollinate/XSDGN pollination/M pollinator/MS polliwog/SM poll/MDNRSGX pollock's Pollock/SM pollster/MS pollutant/MS polluted/U polluter/M pollute/RSDXZVNG pollution/M Pollux/M Pollyanna/M Polly/M pollywog's Pol/MY Polo/M polo/MS polonaise/MS polonium/MS poltergeist/SM poltroon/MS polyandrous polyandry/MS polyatomic polybutene/MS polycarbonate polychemicals polychrome polyclinic/MS polycrystalline polyelectrolytes polyester/SM polyether/S polyethylene/SM polygamist/MS polygamous/Y polygamy/MS polyglot/S polygonal/Y polygon/MS polygraph/MDG polygraphs polygynous polyhedral polyhedron/MS Polyhymnia/M polyisobutylene polyisocyanates polymath/M polymaths polymerase/S polymeric polymerization/SM polymerize/SDG polymer/MS polymorphic polymorphism/MS polymorph/M polymyositis Polynesia/M Polynesian/S polynomial/YMS Polyphemus/M polyphonic polyphony/MS polyphosphate/S polyp/MS polypropylene/MS polystyrene/SM polysyllabic polysyllable/SM polytechnic/MS polytheism/SM polytheistic polytheist/SM polythene/M polytonal/Y polytopes polyunsaturated polyurethane/SM polyvinyl/MS Po/M pomade/MGSD pomander/MS pomegranate/SM Pomerania/M Pomeranian pommel/GSMD Pomona/M Pompadour/M pompadour/MDS pompano/SM Pompeian/S Pompeii/M Pompey/M pompom/SM pompon's pomposity/MS pompousness/S pompous/YP pomp/SM ponce/M Ponce/M Ponchartrain/M poncho/MS ponderer/M ponderousness/MS ponderous/PY ponder/ZGRD pond/SMDRGZ pone/SM pongee/MS poniard/GSDM pons/M Pontchartrain/M Pontiac/M Pontianak/M pontiff/MS pontifical/YS pontificate/XGNDS pontoon/SMDG pony/DSMG ponytail/SM pooch/GSDM poodle/MS poof/MS pooh/DG Pooh/M poohs Poole/M pool/MDSG poolroom/MS poolside Poona/M poop/MDSG poorboy poorhouse/MS poorness/MS poor/TYRP popcorn/MS Popek/MS pope/SM Pope/SM Popeye/M popgun/SM popinjay/MS poplar/SM poplin/MS Popocatepetl/M popover/SM poppa/MS popped Popper/M popper/SM poppet/M popping Poppins/M poppycock/MS Poppy/M poppy/SDM poppyseed Popsicle/MS pop/SM populace/MS popularism popularity/UMS popularization/SM popularize/A popularized popularizer/MS popularizes/U popularizing popular/YS populate/CXNGDS populated/UA populates/A populating/A population/MC populism/S populist/SM populousness/MS populous/YP porcelain/SM porch/SM porcine porcupine/MS pore/ZGDRS Porfirio/M porgy/SM poring/Y porker/M porky/TSR pork/ZRMS pornographer/SM pornographic pornographically pornography/SM porno/S porn/S porosity/SM porousness/MS porous/PY porphyritic porphyry/MS porpoise/DSGM porridge/MS Porrima/M porringer/MS Porsche/M portability/S portables portable/U portably port/ABSGZMRD portage/ASM portaged portaging portal/SM portamento/M portcullis/MS ported/CE Porte/M portend/SDG portentousness/M portentous/PY portent/SM porterage/M porter/DMG porterhouse/SM Porter/M porter's/A portfolio/MS porthole/SM Portia/M porticoes portico/M Portie/M portire/SM porting/E portion/KGSMD Portland/M portliness/SM portly/PTR portmanteau/SM Port/MR Prto/M portraitist/SM portrait/MS portraiture/MS portrayal/SM portrayer/M portray/GDRS ports/CE Portsmouth/M Portugal/M Portuguese/M portulaca/MS Porty/M posed/CA Poseidon/M poser/KME poses/CA poseur/MS pose/ZGKDRSE posh/DSRGT posing/CA positifs positionable positional/KY position/KGASMD position's/EC positions/EC positiveness/S positive/RSPYT positivism/M positivist/S positivity positron/SM posit/SCGD Posner/M posse/M possess/AGEDS possessed/PY possession/AEMS possessional possessiveness/MS possessive/PSMY possessor/MS possibility/SM possible/TRS possibly poss/S possum/MS postage/MS postal/S post/ASDRJG postbag/M postbox/SM postcard/SM postcode/SM postcondition/S postconsonantal postdate/DSG postdoctoral posteriori posterior/SY posterity/SM poster/MS postfix/GDS postgraduate/SM posthaste/S posthumousness/M posthumous/YP posthypnotic postilion/MS postindustrial posting/M postlude/MS Post/M postman/M postmarital postmark/GSMD postmaster/SM postmen postmeridian postmistress/MS postmodern postmodernist postmortem/S postnasal postnatal postoperative/Y postorder postpaid postpartum postpone/GLDRS postponement/S postpositions postprandial post's postscript/SM postsecondary postulate/XGNSD postulation/M postural posture/MGSRD posturer/M postvocalic postwar posy/SM potability/SM potableness/M potable/SP potage/M potash/MS potassium/MS potatoes potato/M potbelly/MSD potboiler/M potboil/ZR pot/CMS Potemkin/M potency/MS potentate/SM potentiality/MS potential/SY potentiating potentiometer/SM potent/YS potful/SM pothead/MS potherb/MS pother/GDMS potholder/MS pothole/SDMG potholing/M pothook/SM potion/SM potlatch/SM potluck/MS Potomac/M potpie/SM potpourri/SM Potsdam/M potsherd/MS potshot/S pottage/SM Pottawatomie/M potted Potter/M potter/RDMSG pottery/MS potting Potts/M potty/SRT pouch/SDMG Poughkeepsie/M Poul/M poulterer/MS poultice/DSMG poultry/MS pounce/SDG poundage/MS pounder/MS pound/KRDGS Pound/M pour/DSG pourer's Poussin/MS pouter/M pout/GZDRS poverty/MS POW powderpuff powder/RDGMS powdery Powell/M powerboat/MS powerfulness/M powerful/YP power/GMD powerhouse/MS powerlessness/SM powerless/YP Powers Powhatan/M pow/RZ powwow/GDMS pox/GMDS Poznan/M pp PP ppm ppr PPS pr PR practicability/S practicable/P practicably practicality/SM practicalness/M practical/YPS practice/BDRSMG practiced/U practicer/M practicum/SM practitioner/SM Pradesh/M Prado/M Praetorian praetorian/S praetor/MS pragmatical/Y pragmatic/S pragmatics/M pragmatism/MS pragmatist/MS Prague/M Praia prairie/MS praise/ESDG praiser/S praise's praiseworthiness/MS praiseworthy/P praising/Y Prakrit/M praline/MS pram/MS prancer/M prance/ZGSRD prancing/Y prank/SMDG prankster/SM praseodymium/SM Pratchett/M prate/DSRGZ prater/M pratfall/MS prating/Y prattle/DRSGZ prattler/M prattling/Y Pratt/M Prattville/M Pravda/M prawn/MDSG praxes praxis/M Praxiteles/M pray/DRGZS prayerbook prayerfulness/M prayerful/YP prayer/M PRC preach/DRSGLZJ preacher/M preaching/Y preachment/MS preachy/RT preadolescence/S Preakness/M preallocate/XGNDS preallocation/M preallocator/S preamble/MGDS preamp preamplifier/M prearrange/LSDG prearrangement/SM preassign/SDG preauthorize prebendary/M Precambrian precancel/DGS precancerous precariousness/MS precarious/PY precautionary precaution/SGDM precede/DSG precedence/SM precedented/U precedent/SDM preceptive/Y preceptor/MS precept/SMV precess/DSG precession/M precinct/MS preciosity/MS preciousness/S precious/PYS precipice/MS precipitable precipitant/S precipitateness/M precipitate/YNGVPDSX precipitation/M precipitousness/M precipitous/YP preciseness/SM precise/XYTRSPN precision/M prcis/MDG preclude/GDS preclusion/S precociousness/MS precocious/YP precocity/SM precode/D precognition/SM precognitive precollege/M precolonial precomputed preconceive/GSD preconception/SM precondition/GMDS preconscious precook/GDS precursor/SM precursory precut predate/NGDSX predation/CMS predator/SM predatory predecease/SDG predecessor/MS predeclared predecline predefine/GSD predefinition/SM predesignate/GDS predestination/SM predestine/SDG predetermination/MS predeterminer/M predetermine/ZGSRD predicable/S predicament/SM predicate/VGNXSD predication/M predicator predictability/UMS predictable/U predictably/U predict/BSDGV predicted/U prediction/MS predictive/Y predictor/MS predigest/GDS predilect predilection/SM predispose/SDG predisposition/MS predoctoral predominance/SM predominant/Y predominate/YSDGN predomination/M preemie/MS preeminence/SM preeminent/Y preemployment/M preempt/GVSD preemption/SM preemptive/Y preemptor/M preener/M preen/SRDG preexist/DSG preexistence/SM preexistent prefabbed prefabbing prefab/MS prefabricate/XNGDS prefabrication/M preface/DRSGM prefacer/M prefatory prefect/MS prefecture/MS preferableness/M preferable/P preferably prefer/BL preference/MS preferential/Y preferment/SM preferred preferring prefiguration/M prefigure/SDG prefix/MDSG preflight/SGDM preform/DSG pref/RZ pregnancy/SM pregnant/Y preheat/GDS prehensile prehistoric prehistorical/Y prehistory/SM preindustrial preinitialize/SDG preinterview/M preisolated prejudge/DRSG prejudger/M prejudgment/SM prejudiced/U prejudice/MSDG prejudicial/PY prekindergarten/MS prelacy/MS prelate/SM preliminarily preliminary/S preliterate/S preloaded prelude/GMDRS preluder/M premarital/Y premarket prematureness/M premature/SPY prematurity/M premedical premeditated/Y premeditate/XDSGNV premeditation/M premed/S premenstrual premiere/MS premier/GSDM premiership/SM Preminger/M premise/GMDS premiss's premium/MS premix/GDS premolar/S premonition/SM premonitory prenatal/Y Pren/M Prenticed/M Prentice/MGD Prenticing/M Prentiss/M Prent/M prenuptial preoccupation/MS preoccupy/DSG preoperative preordain/DSLG prepackage/GSD prepaid preparation/SM preparative/SYM preparatory preparedly preparedness/USM prepared/UP prepare/ZDRSG prepay/GLS prepayment/SM prepender/S prepends preplanned preponderance/SM preponderant/Y preponderate/DSYGN prepositional/Y preposition/SDMG prepossess/GSD prepossessing/U prepossession/MS preposterousness/M preposterous/PY prepped prepping preppy/RST preprepared preprint/SGDM preprocessed preprocessing preprocessor/S preproduction preprogrammed prep/SM prepubescence/S prepubescent/S prepublication/M prepuce/SM prequel/S preradiation prerecord/DGS preregister/DSG preregistration/MS prerequisite/SM prerogative/SDM Pres presage/GMDRS presager/M presbyopia/MS presbyterian Presbyterianism/S Presbyterian/S presbyter/MS presbytery/MS preschool/RSZ prescience/SM prescient/Y Prescott/M prescribed/U prescriber/M prescribe/RSDG prescription/SM prescriptive/Y prescript/SVM preselect/SGD presence/SM presentableness/M presentable/P presentably/A presentational/A presentation/AMS presented/A presenter/A presentiment/MS presentment/SM presents/A present/SLBDRYZGP preservationist/S preservation/SM preservative/SM preserve/DRSBZG preserved/U preserver/M preset/S presetting preshrank preshrink/SG preshrunk preside/DRSG presidency/MS presidential/Y president/SM presider/M presidia presidium/M Presley/M presoaks presort/GDS pres/S press/ACDSG pressed/U presser/MS pressingly/C pressing/YS pressman/M pressmen pressure/DSMG pressurization/MS pressurize/DSRGZ pressurized/U prestidigitate/NX prestidigitation/M prestidigitatorial prestidigitator/M prestige/MS prestigious/PY Preston/M presto/S presumably presume/BGDRS presumer/M presuming/Y presumption/MS presumptive/Y presumptuousness/SM presumptuous/YP presuppose/GDS presupposition/S pretax preteen/S pretended/Y pretender/M pretending/U pretend/SDRZG pretense/MNVSX pretension/GDM pretentiousness/S pretentious/UYP preterite's preterit/SM preternatural/Y pretest/SDG pretext/SMDG Pretoria/M pretreated pretreatment/S pretrial prettify/SDG prettily prettiness/SM pretty/TGPDRS pretzel/SM prevailing/Y prevail/SGD prevalence/MS prevalent/SY prevaricate/DSXNG prevaricator/MS preventable/U preventably preventative/S prevent/BSDRGV preventer/M prevention/MS preventiveness/M preventive/SPY preview/ZGSDRM previous/Y prevision/SGMD prewar prexes preyer's prey/SMDG Priam/M priapic Pribilof/M price/AGSD priced/U priceless Price/M pricer/MS price's pricey pricier priciest pricker/M pricking/M prickle/GMDS prickliness/S prickly/RTP prick/RDSYZG prideful/Y pride/GMDS prier/M priestess/MS priesthood/SM Priestley/M priestliness/SM priestly/PTR priest/SMYDG prigged prigging priggishness/S priggish/PYM prig/SM primacy/MS primal primarily primary/MS primate/MS primed/U primely/M primeness/M prime/PYS primer/M Prime's primeval/Y priming/M primitiveness/SM primitive/YPS primitivism/M primmed primmer primmest primming primness/MS primogenitor/MS primogeniture/MS primordial/YS primp/DGS primrose/MGSD prim/SPJGZYDR princedom/MS princeliness/SM princely/PRT Prince/M prince/SMY princess/MS Princeton/M principality/MS principal/SY Principe/M Principia/M principled/U principle/SDMG printable/U printably print/AGDRS printed/U printer/AM printers printing/SM printmaker/M printmake/ZGR printmaking/M printout/S Prinz/M prioress/MS priori prioritize/DSRGZJ priority/MS prior/YS priory/SM Pris Prisca/M Priscella/M Priscilla/M prised prise/GMAS prismatic prism/MS prison/DRMSGZ prisoner/M Prissie/M prissily prissiness/SM prissy/RSPT pristine/Y prithee/S privacy/MS privateer/SMDG privateness/M private/NVYTRSXP privation/MCS privative/Y privatization/S privatize/GSD privet/SM privileged/U privilege/SDMG privily privy/SRMT prized/A prize/DSRGZM prizefighter/M prizefighting/M prizefight/SRMGJZ prizewinner/S prizewinning Pr/MN PRO proactive probabilist probabilistic probabilistically probability/SM probable/S probably probated/A probate/NVMX probates/A probating/A probational probationary/S probationer/M probation/MRZ probation's/A probative/A prober/M probity/SM problematical/UY problematic/S problem/SM proboscis/MS prob/RBJ procaine/MS procedural/SY procedure/MS proceeder/M proceeding/M proceed/JRDSG process/BSDMG processed/UA processes/A processional/YS procession/GD processor/MS proclamation/MS proclivity/MS proconsular procrastinate/XNGDS procrastination/M procrastinator/MS procreational procreatory procrustean Procrustean Procrustes/M proctor/GSDM proctorial procurable/U procure/L procurement/MS Procyon/M prodded prodding prodigality/S prodigal/SY prodigiousness/M prodigious/PY prodigy/MS prod/S produce/AZGDRS producer/AM producible/A production/ASM productively/UA productiveness/MS productive/PY productivities productivity/A productivity's productize/GZRSD product/V Prof profanation/S profaneness/MS profane/YPDRSG profanity/MS professed/Y professionalism/SM professionalize/GSD professional/USY profession/SM professorial/Y professorship/SM professor/SM proffer/GSD proficiency/SM proficient/YS profitability/MS profitableness/MU profitable/UP profitably/U profiteer/GSMD profiterole/MS profit/GZDRB profitless profligacy/S profligate/YS proforma/S profoundity profoundness/SM profound/PTYR prof/S profundity/MS profuseness/MS profuse/YP progenitor/SM progeny/M progesterone/SM prognathous prognoses prognosis/M prognosticate/NGVXDS prognostication/M prognosticator/S prognostic/S program/CSA programed programing programmability programmable/S programmed/CA programmer/ASM programming/CA programmings progression/SM progressiveness/SM progressive/SPY progressivism progress/MSDVG prohibiter/M prohibitionist/MS prohibition/MS Prohibition/MS prohibitiveness/M prohibitive/PY prohibitory prohibit/VGSRD projected/AU projectile/MS projectionist/MS projection/MS projective/Y project/MDVGS projector/SM Prokofieff/M Prokofiev/M prolegomena proletarianization/M proletarianized proletarian/S proletariat/SM proliferate/GNVDSX proliferation/M prolifically prolific/P prolixity/MS prolix/Y prologize prologue/MGSD prologuize prolongate/NGSDX prolongation/M prolonger/M prolong/G promenade/GZMSRD promenader/M Promethean Prometheus/M promethium/SM prominence/MS prominent/Y promiscuity/MS promiscuousness/M promiscuous/PY promise/GD promising/UY promissory promontory/MS promote/GVZBDR promoter/M promotiveness/M promotive/P prompted/U prompter/M promptitude/SM promptness/MS prompt/SGJTZPYDR pro/MS promulgate/NGSDX promulgation/M promulgator/MS pron proneness/MS prone/PY pronghorn/SM prong/SGMD pronominalization pronominalize pronounceable/U pronouncedly pronounced/U pronounce/GLSRD pronouncement/SM pronouncer/M pronto pronunciation/SM proofed/A proofer proofing/M proofreader/M proofread/GZSR proof/SEAM propaganda/SM propagandistic propagandist/SM propagandize/DSG propagated/U propagate/SDVNGX propagation/M propagator/MS propellant/MS propelled propeller/MS propelling propel/S propensity/MS properness/M proper/PYRT propertied/U property/SDM prophecy/SM prophesier/M prophesy/GRSDZ prophetess/S prophetic prophetical/Y prophet/SM prophylactic/S prophylaxes prophylaxis/M propinquity/MS propionate/M propitiate/GNXSD propitiatory propitiousness/M propitious/YP proponent/MS proportionality/M proportional/SY proportionate/YGESD proportioner/M proportion/ESGDM proportionment/M proposal/SM propped propping proprietary/S proprietorial proprietorship/SM proprietor/SM proprietress/MS propriety/MS proprioception proprioceptive prop/SZ propulsion/MS propulsive propylene/M prorogation/SM prorogue prosaic prosaically proscenium/MS prosciutti prosciutto/SM proscription/SM proscriptive pros/DSRG prosecute/SDBXNG prosecution/M prosecutor/MS proselyte/SDGM proselytism/MS proselytize/ZGDSR prose/M proser/M Proserpine/M prosodic/S prosody/MS prospect/DMSVG prospection/SM prospectiveness/M prospective/SYP prospector/MS prospectus/SM prosper/GSD prosperity/MS prosperousness/M prosperous/PY prostate prostheses prosthesis/M prosthetic/S prosthetics/M prostitute/DSXNGM prostitution/M prostrate/SDXNG prostration/M prosy/RT protactinium/MS protagonist/SM Protagoras/M protean/S protease/M protect/DVGS protected/UY protectionism/MS protectionist/MS protection/MS protectiveness/S protective/YPS protectorate/SM protector/MS protges protg/SM protein/MS proteolysis/M proteolytic Proterozoic/M protestantism Protestantism/MS protestant/S Protestant/SM protestation/MS protest/G protesting/Y Proteus/M protocol/DMGS protoplasmic protoplasm/MS prototype/SDGM prototypic prototypical/Y protozoa protozoan/MS protozoic protozoon's protract/DG protrude/SDG protrusile protrusion/MS protrusive/PY protuberance/S protuberant Proudhon/M proud/TRY Proust/M provabilities provability's provability/U provableness/M provable/P provably prov/DRGZB proved/U proven/U prove/ESDAG provenance/SM Provenal Provencals Provence/M provender/SDG provenience/SM provenly proverb/DG proverbial/Y Proverbs/M prover/M provide/DRSBGZ provided/U providence/SM Providence/SM providential/Y provident/Y provider/M province/SM provincialism/SM provincial/SY provisional/YS provisioner/M provision/R proviso/MS provocateur/S provocativeness/SM provocative/P provoked/U provoke/GZDRS provoking/Y provolone/SM Provo/M provost/MS prowess/SM prowler/M prowl/RDSZG prow/TRMS proximal/Y proximateness/M proximate/PY proximity/MS Proxmire/M proxy/SM Prozac prude/MS Prudence/M prudence/SM Prudential/M prudential/SY prudent/Y prudery/MS Prudi/M prudishness/SM prudish/YP Prudy/M Prue/M Pruitt/M Pru/M prune/DSRGZM pruner/M prurience/MS prurient/Y Prussia/M Prussian/S prussic Prut/M Pryce/M pry/DRSGTZ pryer's prying/Y P's PS p's/A psalmist/SM psalm/SGDM Psalms/M psalter Psalter/SM psaltery/MS psephologist/M pseudonymous pseudonym/SM pseudopod pseudo/S pseudoscience/S pshaw/SDG psi/S psittacoses psittacosis/M psoriases psoriasis/M psst/S PST psychedelically psychedelic/S psyche/M Psyche/M psychiatric psychiatrist/SM psychiatry/MS psychical/Y psychic/MS psychoacoustic/S psychoacoustics/M psychoactive psychoanalysis/M psychoanalyst/S psychoanalytic psychoanalytical psychoanalyze/SDG psychobabble/S psychobiology/M psychocultural psychodrama/MS psychogenic psychokinesis/M psycholinguistic/S psycholinguistics/M psycholinguists psychological/Y psychologist/MS psychology/MS psychometric/S psychometrics/M psychometry/M psychoneuroses psychoneurosis/M psychopathic/S psychopath/M psychopathology/M psychopaths psychopathy/SM psychophysical/Y psychophysic/S psychophysics/M psychophysiology/M psychosis/M psycho/SM psychosocial/Y psychosomatic/S psychosomatics/M psychos/S psychotherapeutic/S psychotherapist/MS psychotherapy/SM psychotically psychotic/S psychotropic/S psychs psych/SDG PT PTA Ptah/M ptarmigan/MS pt/C pterodactyl/SM Pt/M PTO Ptolemaic Ptolemaists Ptolemy/MS ptomaine/MS Pu pubbed pubbing pubertal puberty/MS pubes pubescence/S pubescent pubic pubis/M publican/AMS publication/AMS publicist/SM publicity/SM publicized/U publicize/SDG publicness/M publics/A public/YSP publishable/U published/UA publisher/ASM publishes/A publishing/M publish/JDRSBZG pub/MS Puccini/M puce/SM pucker/DG Puckett/M puck/GZSDRM puckishness/S puckish/YP Puck/M pudding/MS puddle/JMGRSD puddler/M puddling/M puddly pudenda pudendum/M pudginess/SM pudgy/PRT Puebla/M Pueblo/MS pueblo/SM puerile/Y puerility/SM puerperal puers Puerto/M puffball/SM puffer/M puffery/M puffiness/S puffin/SM Puff/M puff/SGZDRM puffy/PRT Puget/M pugged pugging Pugh/M pugilism/SM pugilistic pugilist/S pug/MS pugnaciousness/MS pugnacious/YP pugnacity/SM puissant/Y puke/GDS pukka Pulaski/SM pulchritude/SM pulchritudinous/M pule/GDS Pulitzer/SM pullback/S pull/DRGZSJ pullet/SM pulley/SM Pullman/MS pullout/S pullover/SM pulmonary pulpiness/S pulpit/MS pulp/MDRGS pulpwood/MS pulpy/PTR pulsar/MS pulsate/NGSDX pulsation/M pulse/ADSG pulser pulse's pulverable pulverization/MS pulverized/U pulverize/GZSRD pulverizer/M pulverizes/UA puma/SM pumice/SDMG pummel/SDG pumpernickel/SM pump/GZSMDR pumping/M pumpkin/MS punchbowl/M punched/U puncheon/MS puncher/M punch/GRSDJBZ punchline/S Punch/M punchy/RT punctilio/SM punctiliousness/SM punctilious/PY punctualities punctuality/UM punctualness/M punctual/PY punctuate/SDXNG punctuational punctuation/M puncture/SDMG punditry/S pundit/SM pungency/MS pungent/Y Punic puniness/MS punished/U punisher/M punishment/MS punish/RSDGBL punitiveness/M punitive/YP Punjabi/M Punjab/M punk/TRMS punky/PRS pun/MS punned punning punster/SM punter/M punt/GZMDRS puny/PTR pupae pupal pupa/M pupate/NGSD pupillage/M pupil/SM pup/MS pupped puppeteer/SM puppetry/MS puppet/SM pupping puppy/GSDM puppyish purblind Purcell/M purchasable purchase/GASD purchaser/MS purdah/M purdahs Purdue/M purebred/S puree/DSM pureeing pureness/MS pure/PYTGDR purgation/M purgative/MS purgatorial purgatory/SM purge/GZDSR purger/M purify/GSRDNXZ Purim/SM Purina/M purine/SM purism/MS puristic purist/MS puritanic puritanical/Y Puritanism/MS puritanism/S puritan/SM Puritan/SM purity/SM purlieu/SM purl/MDGS purloin/DRGS purloiner/M purple/MTGRSD purplish purport/DRSZG purported/Y purposefulness/S purposeful/YP purposelessness/M purposeless/PY purpose/SDVGYM purposiveness/M purposive/YP purr/DSG purring/Y purse/DSRGZM purser/M pursuance/MS pursuant pursuer/M pursue/ZGRSD pursuit/MS purulence/MS purulent Purus purveyance/MS purvey/DGS purveyor/MS purview/SM Pusan/M Pusey/M pushbutton/S pushcart/SM pushchair/SM pushdown push/DSRBGZ pusher/M pushily pushiness/MS Pushkin/M pushover/SM Pushtu/M pushy/PRT pusillanimity/MS pusillanimous/Y pus/SM puss/S pussycat/S pussyfoot/DSG pussy/TRSM pustular pustule/MS putative/Y Putin/M put/IS Putnam/M Putnem/M putout/S putrefaction/SM putrefactive putrefy/DSG putrescence/MS putrescent putridity/M putridness/M putrid/YP putsch/S putted/I puttee/MS putter/RDMGZ putting/I putt/SGZMDR puttying/M putty/SDMG puzzle/JRSDZLG puzzlement/MS puzzler/M PVC pvt Pvt/M PW PX p/XTGJ Pygmalion/M pygmy/SM Pygmy/SM Pyhrric/M pyknotic Pyle/M pylon/SM pylori pyloric pylorus/M Pym/M Pynchon/M Pyongyang/M pyorrhea/SM Pyotr/M pyramidal/Y pyramid/GMDS pyre/MS Pyrenees Pyrex/SM pyridine/M pyrimidine/SM pyrite/MS pyroelectric pyroelectricity/SM pyrolysis/M pyrolyze/RSM pyromaniac/SM pyromania/MS pyrometer/MS pyrometry/M pyrophosphate/M pyrotechnical pyrotechnic/S pyrotechnics/M pyroxene/M pyroxenite/M Pyrrhic Pythagoras/M Pythagorean/S Pythias Python/M python/MS pyx/MDSG q Q QA Qaddafi/M Qantas/M Qatar/M QB QC QED Qingdao Qiqihar/M QM Qom/M qr q's Q's qt qty qua Quaalude/M quackery/MS quackish quack/SDG quadded quadding quadrangle/MS quadrangular/M quadrant/MS quadraphonic/S quadrapole quadratical/Y quadratic/SM quadrature/MS quadrennial/SY quadrennium/MS quadric quadriceps/SM quadrilateral/S quadrille/XMGNSD quadrillion/MH quadripartite/NY quadriplegia/SM quadriplegic/SM quadrivia quadrivium/M quadrupedal quadruped/MS quadruple/GSD quadruplet/SM quadruplicate/GDS quadruply/NX quadrupole quad/SM quadword/MS quaffer/M quaff/SRDG quagmire/DSMG quahog/MS quail/GSDM quaintness/MS quaint/PTYR quake/GZDSR Quakeress/M Quakerism/S Quaker/SM quaky/RT qualification/ME qualified/UY qualifier/SM qualify/EGXSDN qualitative/Y quality/MS qualmish qualm/SM quandary/MS quangos quanta/M Quantico/M quantifiable/U quantified/U quantifier/M quantify/GNSRDZX quantile/S quantitativeness/M quantitative/PY quantity/MS quantization/MS quantizer/M quantize/ZGDRS quantum/M quarantine/DSGM quark/SM quarreler/M quarrellings quarrelsomeness/MS quarrelsome/PY quarrel/SZDRMG quarrier/M quarryman/M quarrymen quarry/RSDGM quarterback/SGMD quarterdeck/MS quarterer/M quarterfinal/MS quartering/M quarterly/S quartermaster/MS quarter/MDRYG quarterstaff/M quarterstaves quartet/SM quartic/S quartile/SM quarto/SM quart/RMSZ quartzite/M quartz/SM quasar/SM quash/GSD quasi quasilinear Quasimodo/M Quaternary quaternary/S quaternion/SM quatrain/SM quaver/GDS quavering/Y quavery Quayle/M quayside/M quay/SM queasily queasiness/SM queasy/TRP Quebec/M Quechua/M Queenie/M queenly/RT queen/SGMDY Queensland/M Queen/SM queerness/S queer/STGRDYP queller/M quell/SRDG Que/M quenchable/U quenched/U quencher/M quench/GZRSDB quenchless Quentin/M Quent/M Querida/M quern/M querulousness/S querulous/YP query/MGRSD quested/A quester/AS quester's quest/FSIM questing questionableness/M questionable/P questionably/U questioned/UA questioner/M questioning/UY questionnaire/MS question/SMRDGBZJ quests/A Quetzalcoatl/M queued/C queue/GZMDSR queuer/M queues/C queuing/C Quezon/M quibble/GZRSD quibbler/M quiche/SM quicken/RDG quickie/MS quicklime/SM quickness/MS quick/RNYTXPS quicksand/MS quicksilver/GDMS quickstep/SM quid/SM quiesce/D quiescence/MS quiescent/YP quieted/E quieten/SGD quieter/E quieter's quieting/E quietly/E quietness/MS quiets/E quietude/IEMS quietus/MS quiet/UTGPSDRY Quillan/M quill/GSDM Quill/M quilter/M quilting/M quilt/SZJGRDM quincentenary/M quince/SM Quincey/M quincy/M Quincy/M quinine/MS Quinlan/M Quinn/M quinquennial/Y quinsy/SM Quinta/M Quintana/M quintessence/SM quintessential/Y quintet/SM quintic quintile/SM Quintilian/M Quintilla/M quintillion/MH quintillionth/M Quintina/M Quintin/M Quint/M quint/MS Quinton/M quintuple/SDG quintuplet/MS Quintus/M quip/MS quipped quipper quipping quipster/SM quired/AI quire/MDSG quires/AI Quirinal/M quiring/IA quirkiness/SM quirk/SGMD quirky/PTR quirt/SDMG Quisling/M quisling/SM quitclaim/GDMS quit/DGS quite/SADG Quito/M quittance/SM quitter/SM quitting quiver/GDS quivering/Y quivery Quixote/M quixotic quixotically Quixotism/M quiz/M quizzed quizzer/SM quizzes quizzical/Y quizzing quo/H quoin/SGMD quoit/GSDM quondam quonset Quonset quorate/I quorum/MS quotability/S quota/MS quotation/SM quoter/M quote/UGSD quot/GDRB quotidian/S quotient/SM qwerty qwertys Rabat/M rabbet/GSMD Rabbi/M rabbi/MS rabbinate/MS rabbinic rabbinical/Y rabbiter/M rabbit/MRDSG rabble/GMRSD rabbler/M Rabelaisian Rabelais/M rabidness/SM rabid/YP rabies Rabi/M Rabin/M rabis Rab/M raccoon/SM racecourse/MS racegoers racehorse/SM raceme/MS race/MZGDRSJ racer/M racetrack/SMR raceway/SM Rachael/M Rachele/M Rachelle/M Rachel/M Rachmaninoff/M racialism/MS racialist/MS racial/Y racily Racine/M raciness/MS racism/S racist/MS racketeer/MDSJG racket/SMDG rackety rack/GDRMS raconteur/SM racoon's racquetball/S racquet's racy/RTP radarscope/MS radar/SM Radcliffe/M radded radder raddest Raddie/M radding Raddy/M radial/SY radiance/SM radian/SM radiant/YS radiate/XSDYVNG radiation/M radiative/Y radiator/MS radicalism/MS radicalization/S radicalize/GSD radicalness/M radical/SPY radices's radii/M radioactive/Y radioactivity/MS radioastronomical radioastronomy radiocarbon/MS radiochemical/Y radiochemistry/M radiogalaxy/S radiogram/SM radiographer/MS radiographic radiography/MS radioisotope/SM radiologic radiological/Y radiologist/MS radiology/MS radioman/M radiomen radiometer/SM radiometric radiometry/MS radionics radionuclide/M radiopasteurization radiophone/MS radiophysics radioscopy/SM radio/SMDG radiosonde/SM radiosterilization radiosterilized radiotelegraph radiotelegraphs radiotelegraphy/MS radiotelephone/SM radiotherapist/SM radiotherapy/SM radish/MS radium/MS radius/M radix/SM Rad/M radon/SM rad/S Raeann/M Rae/M RAF Rafaela/M Rafaelia/M Rafaelita/M Rafaellle/M Rafaello/M Rafael/M Rafa/M Rafe/M Raffaello/M Raffarty/M Rafferty/M raffia/SM raffishness/SM raffish/PY raffle/MSDG Raff/M Rafi/M Raf/M rafter/DM raft/GZSMDR raga/MS ragamuffin/MS ragbag/SM rage/MS raggedness/SM ragged/PRYT raggedy/TR ragging rag/GSMD raging/Y raglan/MS Ragnar/M Ragnark ragout/SMDG ragtag/MS ragtime/MS ragweed/MS ragwort/M Rahal/M rah/DG Rahel/M rahs raider/M raid/MDRSGZ railbird/S rail/CDGS railer/SM railhead/SM railing/MS raillery/MS railroader/M railroading/M railroad/SZRDMGJ rail's railwaymen railway/MS raiment/SM Raimondo/M Raimund/M Raimundo/M Raina/M rainbow/MS raincloud/S raincoat/SM raindrop/SM Raine/MR Rainer/M rainfall/SM rainforest's rain/GSDM Rainier/M rainless rainmaker/SM rainmaking/MS rainproof/GSD rainstorm/SM rainwater/MS rainy/RT raise/DSRGZ raiser/M raising/M raisin/MS rajah/M rajahs Rajive/M raj/M Rakel/M rake/MGDRS raker/M rakishness/MS rakish/PY Raleigh/M Ralf/M Ralina/M rally/GSD Ralph/M Ralston/M Ra/M Ramada/M Ramadan/SM Ramakrishna/M Rama/M Raman/M Ramayana/M ramble/JRSDGZ rambler/M rambling/Y Rambo/M rambunctiousness/S rambunctious/PY ramekin/SM ramie/MS ramification/M ramify/XNGSD Ramirez/M Ramiro/M ramjet/SM Ram/M rammed ramming Ramo/MS Ramona/M Ramonda/M Ramon/M rampage/SDG rampancy/S rampant/Y rampart/SGMD ramp/GMDS ramrodded ramrodding ramrod/MS RAM/S Ramsay/M Ramses/M Ramsey/M ramshackle ram/SM rams/S ran/A Rana/M Rancell/M Rance/M rancher/M rancho/SM ranch/ZRSDMJG rancidity/MS rancidness/SM rancid/P rancorous/Y rancor/SM Randall/M Randal/M Randa/M Randee/M Randell/M Randene/M Randie/M Randi/M randiness/S Rand/M rand/MDGS Randolf/M Randolph/M randomization/SM randomize/SRDG randomness/SM random/PYS Randy/M randy/PRST Ranee/M ranee/SM ranged/C rangeland/S ranger/M ranges/C range/SM rang/GZDR ranginess/S ranging/C Rangoon/M rangy/RPT Rania/M Ranice/M Ranier/M Rani/MR Ranique/M rani's ranked/U ranker/M rank/GZTYDRMPJS Rankine/M ranking/M Rankin/M rankle/SDG rankness/MS Ranna/M ransacker/M ransack/GRDS Ransell/M ransomer/M Ransom/M ransom/ZGMRDS ranter/M rant/GZDRJS ranting/Y Raoul/M rapaciousness/MS rapacious/YP rapacity/MS rapeseed/M rape/SM Raphaela/M Raphael/M rapidity/MS rapidness/S rapid/YRPST rapier/SM rapine/SM rapist/MS rap/MDRSZG rapped rappelled rappelling rappel/S rapper/SM rapping/M rapporteur/SM rapport/SM rapprochement/SM rapscallion/MS raptness/S rapture/MGSD rapturousness/M rapturous/YP rapt/YP Rapunzel/M Raquela/M Raquel/M rarebit/MS rarefaction/MS rarefy/GSD rareness/MS rare/YTPGDRS rarity/SM Rasalgethi/M Rasalhague/M rascal/SMY rasher/M rashness/S rash/PZTYSR Rasia/M Rasla/M Rasmussen/M raspberry/SM rasper/M rasping/Y rasp/SGJMDR Rasputin/M raspy/RT Rastaban/M Rastafarian/M raster/MS Rastus/M ratchet/MDSG rateable rated/U rate/KNGSD ratepayer/SM rater/M rate's Ratfor/M rather Rather/M rathskeller/SM ratifier/M ratify/ZSRDGXN rating/M ratiocinate/VNGSDX ratiocination/M ratio/MS rationale/SM rationalism/SM rationalistic rationalist/S rationality/MS rationalization/SM rationalizer/M rationalize/ZGSRD rationalness/M rational/YPS ration/DSMG Ratliff/M ratlike ratline/SM rat/MDRSJZGB rattail rattan/MS ratted ratter/MS ratting rattlebrain/DMS rattle/RSDJGZ rattlesnake/MS rattletrap/MS rattling/Y rattly/TR rattrap/SM ratty/RT raucousness/SM raucous/YP Raul/M raunchily raunchiness/S raunchy/RTP ravage/GZRSD ravager/M raveling/S Ravel/M ravel/UGDS raven/JGMRDS Raven/M ravenous/YP raver/M rave/ZGDRSJ Ravid/M Ravi/M ravine/SDGM ravioli/SM ravisher/M ravishing/Y ravish/LSRDZG ravishment/SM Raviv/M Rawalpindi/M rawboned rawhide/SDMG Rawley/M Rawlings/M Rawlins/M Rawlinson/M rawness/SM raw/PSRYT Rawson/M Rayburn/M Raychel/M Raye/M ray/GSMD Rayleigh/M Ray/M Raymond/M Raymondville/M Raymund/M Raymundo/M Rayna/M Raynard/M Raynell/M Rayner/M Raynor/M rayon/SM Rayshell/M Raytheon/M raze/DRSG razer/M razorback/SM razorblades razor/MDGS razz/GDS razzmatazz/S Rb RBI/S RC RCA rcpt RCS rd RD RDA Rd/M reabbreviate reachability reachable/U reachably reached/U reacher/M reach/GRB reacquisition reactant/SM reacted/U reaction reactionary/SM reactivity readability/MS readable/P readably readdress/G Reade/M reader/M readership/MS Read/GM readied readies readily readinesses readiness/UM reading/M Reading/M read/JGZBR readopt/G readout/MS reads/A readying ready/TUPR Reagan/M Reagen/M realisms realism's realism/U realistically/U realistic/U realist/SM reality/USM realizability/MS realizableness/M realizable/SMP realizably/S realization/MS realized/U realize/JRSDBZG realizer/M realizes/U realizing/MY realm/M realness/S realpolitik/SM real/RSTP realtor's Realtor/S realty/SM Rea/M reamer/M ream/MDRGZ Reamonn/M reanimate reaper/M reappraise/G reap/SGZ rear/DRMSG rearguard/MS rearmost rearrange/L rearward/S reasonableness/SMU reasonable/UP reasonably/U Reasoner/M reasoner/SM reasoning/MS reasonless reasons reason/UBDMG reassess/GL reassuringly/U reattach/GSL reawakening/M Reba/M rebate/M Rebbecca/M Rebeca/M Rebecca's Rebecka/M Rebekah/M Rebeka/M Rebekkah/M rebeller rebellion/SM rebelliousness/MS rebellious/YP rebel/MS Rebe/M rebid rebidding rebind/G rebirth reboil/G rebook reboot/ZR rebound/G rebroadcast/MG rebuke/RSDG rebuking/Y rebus rebuttal/SM rebutting rec recalcitrance/SM recalcitrant/S recalibrate/N recantation/S recant/G recap recappable recapping recast/G recd rec'd recede receipt/SGDM receivable/S received/U receiver/M receivership/SM receive/ZGRSDB recency/M recension/M recentness/SM recent/YPT receptacle/SM receptionist/MS reception/MS receptiveness/S receptive/YP receptivity/S receptor/MS recessional/S recessionary recessiveness/M recessive/YPS recess/SDMVG rechargeable recheck/G recherch recherches recidivism/MS recidivist/MS Recife/M recipe/MS recipiency recipient/MS reciprocal/SY reciprocate/NGXVDS reciprocation/M reciprocity/MS recitalist/S recital/MS recitative/MS reciter/M recite/ZR recked recking recklessness/S reckless/PY reckoner/M reckoning/M reckon/SGRDJ reclaim/B reclamation/SM recliner/M recline/RSDZG recluse/MVNS reclusion/M recode/G recognizability recognizable/U recognizably recognize/BZGSRD recognizedly/S recognized/U recognizer/M recognizingly/S recognizing/UY recoilless recoinage recolor/GD recombinant recombine recommended/U recompense/GDS recompute/B reconciled/U reconciler/M reconcile/SRDGB reconditeness/M recondite/YP reconfigurability reconfigure/R reconnaissance/MS reconnect/R reconnoiter/GSD reconquer/G reconsecrate reconstitute reconstructed/U Reconstruction/M reconsult/G recontact/G recontaminate/N recontribute recook/G recopy/G recorded/AU records/A record/ZGJ recourse recoverability recoverable/U recover/B recovery/MS recreant/S recreational recriminate/GNVXDS recrimination/M recriminatory recross/G recrudesce/GDS recrudescence/MS recrudescent recruiter/M recruitment/MS recruit/ZSGDRML recrystallize rectal/Y rectangle/SM rectangular/Y recta's rectifiable rectification/M rectifier/M rectify/DRSGXZN rectilinear/Y rectitude/MS recto/MS rector/SM rectory/MS rectum/SM recumbent/Y recuperate/VGNSDX recuperation/M recur recurrence/MS recurrent recurse/NX recursion/M recusant/M recuse recyclable/S recycle/BZ redact/DGS redaction/SM redactor/MS redbird/SM redbreast/SM redbrick/M redbud/M redcap/MS redcoat/SM redcurrant/M redden/DGS redder reddest redding reddish/P Redd/M redeclaration redecorate redeemable/U redeem/BRZ redeemed/U redeemer/M Redeemer/M redemptioner/M redemption/RMS redemptive redeposit/M redetermination Redford/M Redgrave/M redhead/DRMS Redhook/M redial/G redirect/G redirection redlining/S Redmond/M redneck/SMD redness/MS redo/G redolence/MS redolent Redondo/M redouble/S redoubtably redound/GDS red/PYS redshift/S redskin/SM Redstone/M reduced/U reducer/M reduce/RSDGZ reducibility/M reducible reducibly reductionism/M reductionist/S reduction/SM reduct/V redundancy/SM redundant/Y redwood/SM redye redyeing Reeba/M Reebok/M Reece/M reecho/G reed/GMDR reediness/SM reeding/M Reed/M Reedville/M reedy/PTR reefer/M reef/GZSDRM reeker/M reek/GSR reeler/M reel's reel/USDG Ree/MDS Reena/M reenforcement reentrant Reese/M reestimate/M Reeta/M Reeva/M reeve/G Reeves reexamine refection/SM refectory/SM refer/B refereed/U refereeing referee/MSD reference/CGSRD referenced/U reference's referencing/U referendum/MS referentiality referential/YM referent/SM referral/SM referred referrer/S referring reffed reffing refile refinance refined/U refine/LZ refinement/MS refinish/G refit reflectance/M reflected/U reflectional reflection/SM reflectiveness/M reflective/YP reflectivity/M reflector/MS reflect/SDGV reflexion/MS reflexiveness/M reflexive/PSY reflexivity/M reflex/YV reflooring refluent reflux/G refocus/G refold/G reforestation reforge/G reformatory/SM reform/B reformed/U reformer/M reformism/M reformist/S refract/DGVS refractiveness/M refractive/PY refractometer/MS refractoriness/M refractory/PS refrain/DGS refreshed/U refreshing/Y refresh/LB refreshment/MS refrigerant/MS refrigerated/U refrigerate/XDSGN refrigeration/M refrigerator/MS refrozen refry/GS refugee/MS refuge/SDGM Refugio/M refulgence/SM refulgent refund/B refunder/M refurbish/L refurbishment/S refusal/SM refuse/R refuser/M refutation/MS refute/GZRSDB refuter/M ref/ZS reg regale/L regalement/S regal/GYRD regalia/M Regan/M regard/EGDS regardless/PY regather/G regatta/MS regency/MS regeneracy/MS regenerately regenerateness/M regenerate/U Regen/M reggae/SM Reggie/M Reggi/MS Reggy/M regicide/SM regime/MS regimen/MS regimental/S regimentation/MS regiment/SDMG Reginae Reginald/M Regina/M Reginauld/M Regine/M regionalism/MS regional/SY region/SM Regis/M register's register/UDSG registrable registrant/SM registrar/SM registration/AM registrations registry/MS Reg/MN regnant Regor/M regress/DSGV regression/MS regressiveness/M regressive/PY regressors regretfulness/M regretful/PY regret/S regrettable regrettably regretted regretting reground regroup/G regrow/G regularity/MS regularization/MS regularize/SDG regular/YS regulate/CSDXNG regulated/U regulation/M regulative regulator/SM regulatory Regulus/M regurgitate/XGNSD regurgitation/M rehabbed rehabbing rehabilitate/SDXVGN rehabilitation/M rehab/S rehang/G rehear/GJ rehearsal/SM rehearse rehearsed/U rehearser/M rehears/R reheat/G reheating/M Rehnquist rehydrate Reichenberg/M Reich/M Reichstags Reichstag's Reidar/M Reider/M Reid/MR reign/MDSG Reiko/M Reilly/M reimburse/GSDBL reimbursement/MS Reinald/M Reinaldo/MS Reina/M reindeer/M Reine/M reinforced/U reinforce/GSRDL reinforcement/MS reinforcer/M rein/GDM Reinhard/M Reinhardt/M Reinhold/M Reinold/M reinstate/L reinstatement/MS reinsurance Reinwald/M reissue REIT reiterative/SP rejecter/M rejecting/Y rejection/SM rejector/MS reject/RDVGS rejigger rejoice/RSDJG rejoicing/Y rejoinder/SM rejuvenate/NGSDX rejuvenatory relapse relatedly relatedness/MS related/U relater/M relate/XVNGSZ relational/Y relation/M relationship/MS relativeness/M relative/SPY relativism/M relativistic relativistically relativist/MS relativity/MS relator's relaxant/SM relaxation/MS relaxedness/M relaxed/YP relax/GZD relaxing/Y relay/GDM relearn/G releasable/U release/B released/U relenting/U relentlessness/SM relentless/PY relent/SDG relevance/SM relevancy/MS relevant/Y reliability/UMS reliables reliable/U reliably/U reliance/MS reliant/Y relicense/R relic/MS relict/C relict's relief/M relievedly relieved/U reliever/M relieve/RSDZG religionists religion/SM religiosity/M religiousness/MS religious/PY relink/G relinquish/GSDL relinquishment/SM reliquary/MS relish/GSD relive/GB reload/GR relocate/B reluctance/MS reluctant/Y rel/V rely/DG rem Re/M remade/S remainder/SGMD remain/GD remake/M remand/DGS remap remapping remarkableness/S remarkable/U remarkably remark/BG remarked/U Remarque/M rematch/G Rembrandt/M remeasure/D remediableness/M remediable/P remedy/SDMG remembered/U rememberer/M remember/GR remembrance/MRS remembrancer/M Remington/M reminisce/GSD reminiscence/SM reminiscent/Y remissness/MS remiss/YP remit/S remittance/MS remitted remitting/U Rem/M remnant/MS remodel/G remolding remonstrant/MS remonstrate/SDXVNG remonstration/M remonstrative/Y remorsefulness/M remorseful/PY remorselessness/MS remorseless/YP remorse/SM remoteness/MS remote/RPTY remoulds removal/MS REM/S remunerated/U remunerate/VNGXSD remuneration/M remunerativeness/M remunerative/YP Remus/M Remy/M Renado/M Renae/M renaissance/S Renaissance/SM renal Renaldo/M Rena/M Renard/M Renascence/SM Renata/M Renate/M Renato/M renaturation Renaud/M Renault/MS rend renderer/M render/GJRD rendering/M rendezvous/DSMG rendition/GSDM rend/RGZS Renee/M renegade/SDMG renege/GZRSD reneger/M Renelle/M Renell/M Rene/M renewal/MS renew/BG renewer/M Renie/M rennet/MS Rennie/M rennin/SM Renoir/M Reno/M renounce/LGRSD renouncement/MS renouncer/M renovate/NGXSD renovation/M renovator/SM renown/SGDM Rensselaer/M rentaller rental/SM renter/M rent/GZMDRS renumber/G renumeration renunciate/VNX renunciation/M Renville/M reoccupy/G reopen/G reorganized/U repack/G repairable/U repair/BZGR repairer/M repairman/M repairmen repairs/E repaper reparable reparation/SM reparteeing repartee/MDS repartition/Z repast/G repatriate/SDXNG repave repealer/M repeal/GR repeatability/M repeatable/U repeatably repeated/Y repeater/M repeat/RDJBZG repelled repellent/SY repelling/Y repel/S repentance/SM repentant/SY repent/RDG repertoire/SM repertory/SM repetition repetitiousness/S repetitious/YP repetitiveness/MS repetitive/PY repine/R repiner/M replace/RL replay/GM replenish/LRSDG replenishment/S repleteness/MS replete/SDPXGN repletion/M replica/SM replicate/SDVG replicator/S replug reply/X Rep/M repopulate reported/Y reportorial/Y reposeful repose/M repository/MS reprehend/GDS reprehensibility/MS reprehensibleness/M reprehensible/P reprehensibly reprehension/MS representable/U representational/Y representativeness/M Representative/S representative/SYMP representativity represented/U represent/GB repression/SM repressiveness/M repressive/YP repress/V reprieve/GDS reprimand/SGMD reprint/M reprisal/MS reproacher/M reproachfulness/M reproachful/YP reproach/GRSDB reproaching/Y reprobate/N reprocess/G reproducibility/MS reproducible/S reproducibly reproductive/S reproof/G reprove/R reproving/Y rep/S reptile/SM reptilian/S Republicanism/S republicanism/SM Republican/S republic/M republish/G repudiate/XGNSD repudiation/M repudiator/S repugnance/MS repugnant/Y repulse/VNX repulsion/M repulsiveness/MS repulsive/PY reputability/SM reputably/E reputation/SM reputed/Y repute/ESB reputing requested/U request/G Requiem/MS requiem/SM require/LR requirement/MS requisiteness/M requisite/PNXS requisitioner/M requisition/GDRM requital/MS requited/U requiter/M requite/RZ reread/G rerecord/G rerouteing rerunning res/C rescale rescind/SDRG rescission/SM rescue/GZRSD reseal/BG research/MB reselect/G resemblant resemble/DSG resend/G resent/DSLG resentfulness/SM resentful/PY resentment/MS reserpine/MS reservation/MS reservednesses reservedness/UM reserved/UYP reservist/SM reservoir/MS reset/RDG resettle/L reshipping reshow/G reshuffle/M reside/G residence/MS residency/SM residential/Y resident/SM resider/M residua residual/YS residuary residue/SM residuum/M resignation/MS resigned/YP resilience/MS resiliency/S resilient/Y resin/D resinlike resinous resiny resistance/SM Resistance/SM resistantly resistants resistant/U resisted/U resistible resistibly resisting/U resistiveness/M resistive/PY resistivity/M resistless resistor/MS resist/RDZVGS resize/G resold resole/G resoluble resoluteness/MS resolute/PYTRV resolvability/M resolvable/U resolved/U resolvent resonance/SM resonant/YS resonate/DSG resonator/MS resorption/MS resort/R resound/G resourcefulness/SM resourceful/PY resp respectability/SM respectable/SP respectably respect/BSDRMZGV respected/E respectful/EY respectfulness/SM respecting/E respectiveness/M respective/PY respect's/E respects/E respell/G respiration/MS respirator/SM respiratory/M resplendence/MS resplendent/Y respondent/MS respond/SDRZG responser/M response/RSXMV responsibility/MS responsibleness/M responsible/P responsibly responsiveness/MSU responsive/YPU respray/G restart/B restate/L restaurant/SM restaurateur/SM rest/DRSGVM rested/U rester/M restfuller restfullest restfulness/MS restful/YP restitution/SM restiveness/SM restive/PY restlessness/MS restless/YP restorability Restoration/M restoration/MS restorative/PYS restorer/M restore/Z restrained/UY restraint/MS restrict/DVGS restricted/YU restriction/SM restrictively restrictiveness/MS restrictives restrictive/U restroom/SM restructurability restructure rest's/U rests/U restudy/M restyle resubstitute resultant/YS result/SGMD resume/SDBG resumption/MS resurface resurgence/MS resurgent resurrect/GSD resurrection/SM resurvey/G resuscitate/XSDVNG resuscitation/M resuscitator/MS retail/Z retainer/M retain/LZGSRD retake retaliate/VNGXSD retaliation/M retaliatory Reta/M retardant/SM retardation/SM retarder/M retard/ZGRDS retch/SDG retention/SM retentiveness/S retentive/YP retentivity/M retest/G Retha/M rethought reticence/S reticent/Y reticle/SM reticular reticulate/GNYXSD reticulation/M reticule/MS reticulum/M retinal/S retina/SM retinue/MS retiredness/M retiree/MS retire/L retirement/SM retiring/YP retort/GD retract/DG retractile retrench/L retrenchment/MS retributed retribution/MS retributive retrieval/SM retriever/M retrieve/ZGDRSB retroactive/Y retrofire/GMSD retrofit/S retrofitted retrofitting retroflection retroflex/D retroflexion/M retrogradations retrograde/GYDS retrogression/MS retrogressive/Y retrogress/SDVG retrorocket/MS retro/SM retrospection/MS retrospective/SY retrospect/SVGMD retrovirus/S retrovision retry/G retsina/SM returnable/S returned/U returnee/SM retype Reube/M Reuben/M Reub/NM Reunion/M reuse/B Reuters Reuther/M reutilization Reuven/M Reva/M revanchist revealed/U revealingly revealing/U reveal/JBG reveille/MS revelation/MS Revelation/MS revelatory revelry/MS revel/SJRDGZ revenge/MGSRD revenger/M revenuer/M revenue/ZR reverberant reverberate/XVNGSD reverberation/M revere/GSD Revere/M reverencer/M reverence/SRDGM Reverend reverend/SM reverential/Y reverent/Y reverie/SM reversal/MS reverser/M reverse/Y reversibility/M reversible/S reversibly reversioner/M reversion/R revers/M reverter/M revertible revert/RDVGS revet/L revetment/SM review/G revile/GZSDL revilement/MS reviler/M revise/BRZ revised/U revisionary revisionism/SM revisionist/SM revitalize/ZR revivalism/MS revivalist/MS revival/SM reviver/M revive/RSDG revivification/M revivify/X Revkah/M Revlon/M Rev/M revocable revoke/GZRSD revolter/M revolt/GRD revolting/Y revolutionariness/M revolutionary/MSP revolutionist/MS revolutionize/GDSRZ revolutionizer/M revolution/SM revolve/BSRDZJG revolver/M revue/MS revulsion/MS revved revving rev/ZM rewarded/U rewarding/Y rewarm/G reweave rewedding reweigh/G rewind/BGR rewire/G rework/G rexes Rex/M Reyes Reykjavik/M re/YM Rey/M Reynaldo/M Reyna/M Reynard/M Reynold/SM rezone Rf RF RFC RFD R/G rhapsodic rhapsodical rhapsodize/GSD rhapsody/SM Rhea/M rhea/SM Rheba/M Rhee/M Rheims/M Rheinholdt/M Rhenish rhenium/MS rheology/M rheostat/MS rhesus/S Rheta/M rhetorical/YP rhetorician/MS rhetoric/MS Rhetta/M Rhett/M rheumatically rheumatic/S rheumatics/M rheumatism/SM rheumatoid rheum/MS rheumy/RT Rhiamon/M Rhianna/M Rhiannon/M Rhianon/M Rhinelander/M Rhineland/RM Rhine/M rhinestone/SM rhinitides rhinitis/M rhinoceros/MS rhino/MS rhinotracheitis rhizome/MS Rh/M Rhoda/M Rhodes Rhodesia/M Rhodesian/S Rhodia/M Rhodie/M rhodium/MS rhododendron/SM rhodolite/M rhodonite/M Rhody/M rhombic rhomboidal rhomboid/SM rhombus/SM rho/MS Rhona/M Rhonda/M Rhone rhubarb/MS rhyme/DSRGZM rhymester/MS Rhys/M rhythmical/Y rhythmic/S rhythmics/M rhythm/MS RI rial/MS Riane/M Riannon/M Rianon/M ribaldry/MS ribald/S ribbed Ribbentrop/M ribber/S ribbing/M ribbon/DMSG ribcage rib/MS riboflavin/MS ribonucleic ribosomal ribosome/MS Rica/M Rican/SM Ricard/M Ricardo/M Ricca/M Riccardo/M rice/DRSMZG Rice/M ricer/M Richard/MS Richardo/M Richardson/M Richart/M Richelieu/M richen/DG Richey/M Richfield/M Richie/M Richland/M Rich/M Richmond/M Richmound/M richness/MS Richter/M Richthofen/M Richy/M rich/YNSRPT Rici/M Rickard/M Rickenbacker/M Rickenbaugh/M Rickert/M rickets/M rickety/RT Rickey/M rick/GSDM Rickie/M Ricki/M Rick/M Rickover/M rickrack/MS rickshaw/SM Ricky/M Ric/M ricochet/GSD Rico/M Ricoriki/M ricotta/MS riddance/SM ridden ridding riddle/GMRSD Riddle/M ride/CZSGR Ride/M rider/CM riderless ridership/S ridge/DSGM Ridgefield/M ridgepole/SM Ridgway/M ridgy/RT ridicule/MGDRS ridiculer/M ridiculousness/MS ridiculous/PY riding/M rid/ZGRJSB Riemann/M Riesling/SM rife/RT riff/GSDM riffle/SDG riffraff/SM rifled/U rifle/GZMDSR rifleman/M riflemen rifler/M rifling/M rift/GSMD Riga/M rigamarole's rigatoni/M Rigel/M rigged rigger/SM rigging/MS Riggs/M righteousnesses/U righteousness/MS righteous/PYU rightfulness/MS rightful/PY rightism/SM rightist/S rightmost rightness/MS Right/S right/SGTPYRDN rightsize/SDG rights/M rightward/S rigidify/S rigidity/S rigidness/S rigid/YP rigmarole/MS rig/MS Rigoberto/M Rigoletto/M rigor/MS rigorousness/S rigorous/YP Riki/M Rikki/M Rik/M rile/DSG Riley/M Rilke/M rill/GSMD Rimbaud/M rime/MS rimer/M rim/GSMDR rimless rimmed rimming Rinaldo/M Rina/M rind/MDGS Rinehart/M ringer/M ring/GZJDRM ringing/Y ringleader/MS ringlet/SM ringlike Ringling/M Ring/M ringmaster/MS Ringo/M ringside/ZMRS ringworm/SM rink/GDRMS rinse/DSRG Riobard/M Rio/MS Riordan/M rioter/M riotousness/M riotous/PY riot/SMDRGZJ RIP riparian/S ripcord/SM ripened/U ripenesses ripeness/UM ripen/RDG ripe/PSY riper/U ripest/U Ripley/M Rip/M rip/NDRSXTG ripoff/S riposte/SDMG ripped ripper/SM ripping rippler/M ripple/RSDGM ripply/TR ripsaw/GDMS riptide/SM Risa/M RISC risen riser/M rise/RSJZG risibility/SM risible/S rising/M risker/M risk/GSDRM riskily riskiness/MS risky/RTP risotto/SM risqu rissole/M Ritalin Rita/M Ritchie/M rite/DSM Ritter/M ritualism/SM ritualistic ritualistically ritualized ritual/MSY Ritz/M ritzy/TR rivaled/U Rivalee/M rivalry/MS rival/SGDM Riva/MS rive/CSGRD Rivera/M riverbank/SM riverbed/S riverboat/S river/CM riverfront riverine Rivers Riverside/M riverside/S Riverview/M riveter/M rivet/GZSRDM riveting/Y Riviera/MS Rivi/M Rivkah/M rivulet/SM Rivy/M riv/ZGNDR Riyadh/M riyal/SM rm RMS RN RNA Rn/M roach/GSDM Roach/M roadbed/MS roadblock/SMDG roadhouse/SM roadie/S roadkill/S road/MIS roadrunner/MS roadshow/S roadside/S roadsigns roadster/SM roadsweepers roadway/SM roadwork/SM roadworthy roam/DRGZS Roana/M Roanna/M Roanne/M Roanoke/M roan/S roar/DRSJGZ roarer/M roaring/T Roarke/M roaster/M roast/SGJZRD robbed robber/SM Robbert/M robbery/SM Robbie/M Robbi/M robbing Robbin/MS Robb/M Robby/M Robbyn/M robe/ESDG Robena/M Robenia/M Robers/M Roberson/M Roberta/M Robert/MS Roberto/M Robertson/SM robe's Robeson/M Robespierre/M Robina/M Robinet/M Robinetta/M Robinette/M Robinett/M Robinia/M Robin/M robin/MS Robinson/M Robinsonville/M Robles/M Rob/MZ robotic/S robotism robotize/GDS robot/MS rob/SDG Robson/M Robt/M robustness/SM robust/RYPT Roby/M Robyn/M Rocco/M Rocha/M Rochambeau/M Rochella/M Rochelle/M Rochell/M Roche/M Rochester/M Rochette/M Roch/M rockabilly/MS rockabye Rockaway/MS rockbound Rockefeller/M rocker/M rocketry/MS rocket/SMDG Rockey/M rockfall/S Rockford/M rock/GZDRMS Rockie/M rockiness/MS Rockland/M Rock/M Rockne/M Rockville/M Rockwell/M Rocky/SM rocky/SRTP rococo/MS Roda/M rodded Roddenberry/M rodder Roddie/M rodding Rodd/M Roddy/M rodent/MS rodeo/SMDG Roderich/M Roderick/M Roderic/M Roderigo/M rode/S Rodger/M Rodge/ZMR Rodie/M Rodi/M Rodina/M Rodin/M Rod/M Rodney/M Rodolfo/M Rodolphe/M Rodolph/M Rodrick/M Rodrigo/M Rodriguez/M Rodrique/M Rodriquez/M rod/SGMD roebuck/SM Roentgen's roentgen/SM roe/SM ROFL Rogelio/M roger/GSD Rogerio/M Roger/M Roget/M Rog/MRZ rogued/K rogue/GMDS roguery/MS rogues/K roguing/K roguishness/SM roguish/PY roil/SGD Roi/SM roisterer/M roister/SZGRD Rojas/M Roland/M Rolando/M Roldan/M role/MS Roley/M Rolfe/M Rolf/M Rolland/M rollback/SM rolled/A Rollerblade/S rollerskating roller/SM rollick/DGS rollicking/Y Rollie/M rolling/S Rollin/SM Rollo/M rollover/S roll/UDSG Rolodex Rolph/M Rolvaag/M ROM romaine/MS Romain/M Roma/M romancer/M romance/RSDZMG Romanesque/S Romania/M Romanian/SM Romano/MS Romanov/M roman/S Romansh/M Romans/M Roman/SM romantically/U romanticism/MS Romanticism/S romanticist/S romanticize/SDG romantic/MS Romany/SM Romeo/MS romeo/S Romero/M Rome/SM Rommel/M Romney/M Romola/M Romona/M Romonda/M romper/M romp/GSZDR Rom/SM Romulus/M Romy/M Ronalda/M Ronald/M Rona/M Ronda/M rondo/SM Ronica/M Ron/M Ronna/M Ronnica/M Ronnie/M Ronni/M Ronny/M Ronstadt/M Rontgen Roobbie/M rood/MS roof/DRMJGZS roofer/M roofgarden roofing/M roofless rooftop/S rookery/MS rook/GDMS rookie/SRMT roomer/M roomette/SM roomful/MS roominess/MS roommate/SM room/MDRGZS roomy/TPSR Rooney/M Rooseveltian Roosevelt/M rooster/M roost/SGZRDM rooted/P rooter/M rootlessness/M rootless/P rootlet/SM Root/M root/MGDRZS rootstock/M rope/DRSMZG roper/M roping/M Roquefort/MS Roquemore/M Rora/M Rorie/M Rori/M Rorke/M Rorschach Rory/M Rosabella/M Rosabelle/M Rosabel/M Rosaleen/M Rosales/M Rosalia/M Rosalie/M Rosalinda/M Rosalinde/M Rosalind/M Rosaline/M Rosalynd/M Rosalyn/M Rosa/M Rosamond/M Rosamund/M Rosana/M Rosanna/M Rosanne/M Rosario/M rosary/SM Roscoe/M Rosco/M Roseanna/M Roseanne/M Roseann/M roseate/Y Roseau rosebud/MS rosebush/SM Rosecrans/M Roseland/M Roselia/M Roseline/M Roselin/M Rosella/M Roselle/M Rose/M Rosemaria/M Rosemarie/M Rosemary/M rosemary/MS rose/MGDS Rosemonde/M Rosenberg/M Rosenblum/M Rosendo/M Rosene/M Rosen/M Rosenthal/M Rosenzweig/M Rosetta/M Rosette/M rosette/SDMG rosewater rosewood/SM Roshelle/M Rosicrucian/M Rosie/M rosily Rosina/M rosiness/MS rosin/SMDG Rosita/M Roslyn/M Rosmunda/M Ros/N Ross Rossetti/M Rossie/M Rossi/M Rossini/M Rossy/M Rostand/M roster/DMGS Rostov/M rostra's rostrum/SM Roswell/M Rosy/M rosy/RTP rota/MS Rotarian/SM rotary/S rotated/U rotate/VGNXSD rotational/Y rotation/M rotative/Y rotator/SM rotatory ROTC rote/MS rotgut/MS Roth/M Rothschild/M rotisserie/MS rotogravure/SM rotor/MS rototill/RZ rot/SDG rotted rottenness/S rotten/RYSTP Rotterdam/M rotter/M rotting rotunda/SM rotundity/S rotundness/S rotund/SDYPG Rouault/M rou/MS rouge/GMDS roughage/SM roughen/DG rougher/M roughhouse/GDSM roughish roughneck/MDSG roughness/MS roughs roughshod rough/XPYRDNGT roulette/MGDS roundabout/PSM roundedness/M rounded/P roundelay/SM roundels rounder/M roundhead/D roundheadedness/M roundheaded/P roundhouse/SM roundish roundness/MS roundoff roundup/MS roundworm/MS round/YRDSGPZT Rourke/M rouse/DSRG rouser/M Rousseau/M roustabout/SM roust/SGD route/ASRDZGJ router/M route's rout/GZJMDRS routine/SYM routing/M routinize/GSD Rouvin/M rover/M Rover/M rove/ZGJDRS roving/M Rowan/M rowboat/SM rowdily rowdiness/MS rowdyism/MS rowdy/PTSR rowel/DMSG Rowe/M Rowena/M rowen/M Rowen/M rower/M Rowland/M Rowley/M Row/MN Rowney/M row/SJZMGNDR Roxana/M Roxane/M Roxanna/M Roxanne/M Roxie/M Roxi/M Roxine/M Roxy/M royalist/SM Royall/M Royal/M royal/SY royalty/MS Royce/M Roy/M Rozalie/M Rozalin/M Rozamond/M Rozanna/M Rozanne/M Rozele/M Rozella/M Rozelle/M Roze/M Rozina/M Roz/M RP rpm RPM rps RR Rriocard/M rs r's R's RSFSR RSI RSV RSVP RSX rt rte Rte RTFM r/TGVJ Rubaiyat/M rubato/MS rubbed rubberize/GSD rubberneck/DRMGSZ rubber/SDMG rubbery/TR rubbing/M rubbish/DSMG rubbishy rubble/GMSD rubdown/MS rubella/MS Rube/M Ruben/MS rube/SM Rubetta/M Rubia/M Rubicon/SM rubicund rubidium/SM Rubie/M Rubik/M Rubi/M Rubina/M Rubin/M Rubinstein/M ruble/MS rubout rubric/MS rub/S Ruby/M ruby/MTGDSR Ruchbah/M ruck/M rucksack/SM ruckus/SM ruction/SM rudderless rudder/MS Ruddie/M ruddiness/MS Rudd/M Ruddy/M ruddy/PTGRSD rudeness/MS rude/PYTR Rudie/M Rudiger/M rudimentariness/M rudimentary/P rudiment/SM Rudolf/M Rudolfo/M Rudolph/M Rudyard/M Rudy/M ruefulness/S rueful/PY rue/GDS Rufe/M ruff/GSYDM ruffian/GSMDY ruffled/U ruffler/M ruffle/RSDG ruffly/TR Rufus/M Rugby's rugby/SM ruggedness/S rugged/PYRT Ruggiero/M rugging rug/MS Ruhr/M ruination/MS ruiner/M ruin/MGSDR ruinousness/M ruinous/YP Ruiz/M rulebook/S ruled/U rule/MZGJDRS ruler/GMD ruling/M Rumanian's Rumania's rumba/GDMS rumble/JRSDG rumbler/M rumbustious rumen/M Rumford/M Ru/MH ruminant/YMS ruminate/VNGXSD ruminative/Y rummage/GRSD rummager/M Rummel/M rummer rummest rummy/TRSM rumored/U rumorer/M rumormonger/SGMD rumor/ZMRDSG Rumpelstiltskin/M rump/GMYDS rumple/SDG rumply/TR rumpus/SM rum/XSMN runabout/SM runaround/S run/AS runaway/S rundown/SM rune/MS Runge/M rung/MS runic runlet/SM runnable runnel/SM runner/MS running/S Runnymede/M runny/RT runoff/MS runtime runtiness/M runt/MS runty/RPT runway/MS Runyon/M rupee/MS Ruperta/M Rupert/M Ruperto/M rupiah/M rupiahs Ruppert/M Ruprecht/M rupture/GMSD rurality/M rural/Y Rurik/M ruse/MS Rushdie/M rush/DSRGZ rusher/M rushes/I rushing/M Rush/M Rushmore/M rushy/RT Ruskin/M rusk/MS Russell/M Russel/M russet/MDS russetting Russia/M Russian/SM Russo/M Russ/S Rustbelt/M rustically rusticate/GSD rustication/M rusticity/S rustic/S Rustie/M rustiness/MS Rustin/M rustler/M rustle/RSDGZ rust/MSDG rustproof/DGS Rusty/M rusty/XNRTP rutabaga/SM Rutger/SM Ruthanne/M Ruthann/M Ruthe/M ruthenium/MS rutherfordium/SM Rutherford/M Ruthie/M Ruthi/M ruthlessness/MS ruthless/YP Ruth/M Ruthy/M Rutland/M Rutledge/M rut/MS rutted Rutter/M Ruttger/M rutting rutty/RT Ruy/M RV RVs Rwandan/S Rwanda/SM Rwy/M Rx/M Ryan/M Ryann/M Rycca/M Rydberg/M Ryder/M rye/MS Ryley/M Ry/M Ryon/M Ryukyu/M Ryun/M S SA Saab/M Saar/M Saba/M sabbath Sabbath/M Sabbaths sabbatical/S sabered/U saber/GSMD Sabik/M Sabina/M Sabine/M Sabin/M sable/GMDS sabotage/DSMG saboteur/SM sabot/MS Sabra/M sabra/MS Sabrina/M SAC Sacajawea/M saccharides saccharine saccharin/MS Sacco/M sacerdotal Sacha/M sachem/MS sachet/SM Sachs/M sackcloth/M sackcloths sacker/M sackful/MS sack/GJDRMS sacking/M sacral sacra/L sacramental/S sacrament/DMGS Sacramento/M sacredness/S sacred/PY sacrificer/M sacrifice/RSDZMG sacrificial/Y sacrilege/MS sacrilegious/Y sacristan/SM sacristy/MS sacroiliac/S sacrosanctness/MS sacrosanct/P sacrum/M sac/SM Sada/M Sadat/M Saddam/M sadden/DSG sadder saddest saddlebag/SM saddler/M saddle's saddle/UGDS Sadducee/M Sadella/M Sade/M sades Sadie/M sadism/MS sadistic sadistically sadist/MS sadness/SM sadomasochism/MS sadomasochistic sadomasochist/S sad/PY Sadr/M Sadye/M safari/GMDS safeguard/MDSG safekeeping/MS safeness/MS safeness's/U safes safety/SDMG safe/URPTY safflower/SM saffron/MS sagaciousness/M sagacious/YP sagacity/MS saga/MS Sagan/M sagebrush/SM sage/MYPS sagged sagger sagging saggy/RT Saginaw/M Sagittarius/MS sago/MS sag/TSR saguaro/SM Sahara/M Saharan/M Sahel sahib/MS Saidee/M saids said/U Saigon/M sailboard/DGS sailboat/SRMZG sailcloth/M sailcloths sailer/M sailfish/SM sail/GJMDRS sailing/M sailor/YMS sailplane/SDMG sainthood/MS saintlike saintliness/MS saintly/RTP saint/YDMGS Saiph/M saith saiths Sakai/M sake/MRS saker/M Sakhalin/M Sakharov/M Saki/M saki's salaam/GMDS salable/U salaciousness/MS salacious/YP salacity/MS Saladin/M Salado/M salad/SM Salaidh/M salamander/MS salami/MS salary/SDMG Salas/M Salazar/M saleability/M sale/ABMS Saleem/M Salem/M Salerno/M salesclerk/SM salesgirl/SM saleslady/S salesman/M salesmanship/SM salesmen salespeople/M salesperson/MS salesroom/M saleswoman saleswomen salience/MS saliency salient/SY Salim/M Salina/MS saline/S salinger Salinger/M salinity/MS Salisbury/M Salish/M saliva/MS salivary salivate/XNGSD salivation/M Salk/M Sallee/M Salle/M Sallie/M Salli/M sallowness/MS sallow/TGRDSP Sallust/M Sallyanne/M Sallyann/M sally/GSDM Sally/M salmonellae salmonella/M Salmon/M salmon/SM Sal/MY Saloma/M Salome/M Salomi/M Salomo/M Salomone/M Salomon/M Salonika/M salon/SM saloonkeeper saloon/MS salsa/MS salsify/M SALT saltcellar/SM salted/UC salter/M salt/GZTPMDRS saltine/MS saltiness/SM saltness/M Salton/M saltpeter/SM salts/C saltshaker/S saltwater salty/RSPT salubriousness/M salubrious/YP salubrity/M salutariness/M salutary/P salutation/SM salutatory/S saluter/M salute/RSDG Salvadoran/S Salvadorian/S Salvador/M salvageable salvage/MGRSD salvager/M salvation/MS Salvatore/M salve/GZMDSR salver/M Salvidor/M salvo/GMDS Salween/M Salyut/M Salz/M SAM Samantha/M Samara/M Samaria/M Samaritan/MS samarium/MS Samarkand/M samba/GSDM sameness/MS same/SP Sam/M Sammie/M Sammy/M Samoa Samoan/S Samoset/M samovar/SM Samoyed/M sampan/MS sampler/M sample/RSDJGMZ sampling/M Sampson/M Samsonite/M Samson/M Samuele/M Samuel/SM Samuelson/M samurai/M San'a Sana/M sanatorium/MS Sanborn/M Sanchez/M Sancho/M sanctification/M sanctifier/M sanctify/RSDGNX sanctimoniousness/MS sanctimonious/PY sanctimony/MS sanctioned/U sanction/SMDG sanctity/SM sanctuary/MS sanctum/SM sandal/MDGS sandalwood/SM sandbagged sandbagging sandbag/MS sandbank/SM sandbar/S sandblaster/M sandblast/GZSMRD sandbox/MS Sandburg/M sandcastle/S Sande/M Sanderling/M sander/M Sander/M Sanderson/M sandhill sandhog/SM Sandia/M Sandie/M Sandi/M sandiness/S Sandinista sandlot/SM sandlotter/S sandman/M sandmen Sand/MRZ Sandor/M Sandoval/M sandpaper/DMGS sandpile sandpiper/MS sandpit/M Sandra/M Sandro/M sand/SMDRGZ sandstone/MS sandstorm/SM Sandusky/M sandwich/SDMG Sandye/M Sandy/M sandy/PRT saned sane/IRYTP saneness/MS saneness's/I sanes Sanford/M Sanforized Sanger/M sangfroid/S sangria/SM Sang/RM sang/S sanguinary sanguined sanguine/F sanguinely sanguineness/M sanguineous/F sanguines sanguining Sanhedrin/M saning sanitarian/S sanitarium/SM sanitary/S sanitate/NX sanitation/M sanitizer/M sanitize/RSDZG sanity/SIM sank Sankara/M San/M sans sanserif Sanskritic Sanskritize/M Sanskrit/M Sansone/M Sanson/M Santa/M Santana/M Santayana/M Santeria Santiago/M Santo/MS sapience/MS sapient sapless sapling/SM sap/MS sapped sapper/SM Sapphira/M Sapphire/M sapphire/MS Sappho/M sappiness/SM sapping Sapporo/M sappy/RPT saprophyte/MS saprophytic sapsucker/SM sapwood/SM Saraann/M Saracen/MS Saragossa/M Sarah/M Sarajane/M Sarajevo/M Sara/M Saran/M saran/SM sarape's Sarasota/M Saratoga/M Saratov/M Sarawak/M sarcasm/MS sarcastic sarcastically sarcoma/MS sarcophagi sarcophagus/M sardine/SDMG Sardinia/M sardonic sardonically Saree/M Sarena/M Sarene/M Sarette/M Sargasso/M Sarge/M Sargent/M sarge/SM Sargon/M Sari/M sari/MS Sarina/M Sarine/M Sarita/M Sarnoff/M sarong/MS Saroyan/M sarsaparilla/MS Sarto/M sartorial/Y sartorius/M Sartre/M Sascha/M SASE Sasha/M sashay/GDS Sashenka/M sash/GMDS Saskatchewan/M Saskatoon/M Sask/M sassafras/MS sass/GDSM Sassoon/M sassy/TRS SAT satanic satanical/Y Satanism/M satanism/S Satanist/M satanist/S Satan/M satchel/SM sat/DG sateen/MS satellite/GMSD sate/S satiable/I satiate/GNXSD satiation/M satiety/MS satin/MDSG satinwood/MS satiny satire/SM satiric satirical/Y satirist/SM satirize/DSG satirizes/U satisfaction/ESM satisfactorily/U satisfactoriness/MU satisfactory/UP satisfiability/U satisfiable/U satisfied/UE satisfier/M satisfies/E satisfy/GZDRS satisfying/EU satisfyingly Sat/M satori/SM satrap/SM saturated/CUA saturater/M saturates/A saturate/XDRSNG saturation/M Saturday/MS saturnalia Saturnalia/M saturnine/Y Saturn/M Satyanarayanan/M satyriases satyriasis/M satyric satyr/MS sauce/DSRGZM saucepan/SM saucer/M saucily sauciness/S saucy/TRP Saudi/S Saud/M Saudra/M sauerkraut/SM Saukville/M Saul/M Sault/M sauna/DMSG Sauncho/M Saunder/SM Saunderson/M Saundra/M saunter/DRSG saurian/S sauropod/SM sausage/MS Saussure/M saut/DGS Sauternes/M Sauveur/M savage/GTZYPRSD Savage/M savageness/SM savagery/MS Savannah/M savanna/MS savant/SM saved/U saveloy/M saver/M save/ZGJDRSB Savina/M Savior/M savior/SM Saviour/M Savonarola/M savored/U savorer/M savorier savoriest savoriness/S savoringly/S savoring/Y savor/SMRDGZ savory/UMPS Savoyard/M Savoy/M savoy/SM savvy/GTRSD sawbones/M sawbuck/SM sawdust/MDSG sawer/M sawfly/SM sawhorse/MS Saw/M sawmill/SM saw/SMDRG sawtooth Sawyere/M Sawyer/M sawyer/MS Saxe/M saxifrage/SM Sax/M sax/MS Saxon/SM Saxony/M saxophone/MS saxophonist/SM Saxton/M Sayer/M sayer/SM sayest saying/MS Sayre/MS says/M say/USG Say/ZMR SBA Sb/M SC scabbard/SGDM scabbed scabbiness/SM scabbing scabby/RTP scabies/M scabrousness/M scabrous/YP scab/SM scad/SM scaffolding/M scaffold/JGDMS scalability Scala/M scalar/SM scalawag/SM scald/GJRDS scaled/AU scale/JGZMBDSR scaleless scalene scaler/M scales/A scaliness/MS scaling/A scallion/MS scalloper/M scallop/GSMDR scalloping/M scalpel/SM scalper/M scalp/GZRDMS scalping/M scaly/TPR scammed scamming scamper/GD scampi/M scamp/RDMGZS scam/SM Scan scan/AS scandal/GMDS scandalized/U scandalize/GDS scandalmonger/SM scandalousness/M scandalous/YP Scandinavia/M Scandinavian/S scandium/MS scanned/A scanner/SM scanning/A scansion/SM scant/CDRSG scantest scantily scantiness/MS scantly scantness/MS scanty/TPRS scapegoat/SGDM scapegrace/MS scape/M scapulae scapula/M scapular/S scarab/SM Scaramouch/M Scarborough/M scarceness/SM scarce/RTYP scarcity/MS scar/DRMSG scarecrow/MS scaremongering/M scaremonger/SGM scarer/M scare/S scarface Scarface/M scarf/SDGM scarification/M scarify/DRSNGX scarily scariness/S scarlatina/MS Scarlatti/M Scarlet/M scarlet/MDSG Scarlett/M scarp/SDMG scarred scarring scarves/M scary/PTR scathe/DG scathed/U scathing/Y scatological scatology/SM scat/S scatted scatterbrain/MDS scatter/DRJZSG scatterer/M scattergun scattering/YM scatting scavenge/GDRSZ scavenger/M SCCS scenario/SM scenarist/MS scene/GMDS scenery/SM scenically scenic/S scented/U scent/GDMS scentless scent's/C scents/C scepter/DMSG scepters/U sceptically sch Schaefer/M Schaeffer/M Schafer/M Schaffner/M Schantz/M Schapiro/M Scheat/M Schedar/M schedule/ADSRG scheduled/U scheduler/MS schedule's Scheherazade/M Scheherezade/M Schelling/M schema/M schemata schematically schematic/S scheme/JSRDGMZ schemer/M schemta Schenectady/M scherzo/MS Schick/M Schiller/M schilling/SM schismatic/S schism/SM schist/SM schizoid/S schizomycetes schizophrenia/SM schizophrenically schizophrenic/S schizo/S schlemiel/MS schlepped schlepping schlep/S Schlesinger/M Schliemann/M Schlitz/M schlock/SM schlocky/TR Schloss/M schmaltz/MS schmaltzy/TR Schmidt/M Schmitt/M schmoes schmo/M schmooze/GSD schmuck/MS Schnabel/M schnapps/M schnauzer/MS Schneider/M schnitzel/MS schnook/SM schnoz/S schnozzle/MS Schoenberg/M Schofield/M scholarship/MS scholar/SYM scholastically scholastic/S schoolbag/SM schoolbook/SM schoolboy/MS schoolchild/M schoolchildren schooldays schooled/U schoolfellow/S schoolfriend schoolgirlish schoolgirl/MS schoolhouse/MS schooling/M schoolmarmish schoolmarm/MS schoolmaster/SGDM schoolmate/MS schoolmistress/MS schoolroom/SM schoolteacher/MS schoolwork/SM schoolyard/SM school/ZGMRDJS schooner/SM Schopenhauer/M Schottky/M Schrieffer/M Schrdinger/M Schroeder/M Schroedinger/M Schubert/M Schultz/M Schulz/M Schumacher/M Schuman/M Schumann/M schussboomer/S schuss/SDMG Schuster/M Schuyler/M Schuylkill/M Schwab/M Schwartzkopf/M Schwartz/M Schwarzenegger/M schwa/SM Schweitzer/M Schweppes/M Schwinger/M Schwinn/M sci sciatica/SM sciatic/S science/FMS scientifically/U scientific/U scientist/SM Scientology/M scimitar/SM scintilla/MS scintillate/GNDSX scintillation/M scintillator/SM scion/SM Scipio/M scissor/SGD scleroses sclerosis/M sclerotic/S Sc/M scoffer/M scofflaw/MS scoff/RDGZS scolder/M scold/GSJRD scolioses scoliosis/M scollop's sconce/SDGM scone/SM scooper/M scoop/SRDMG scooter/M scoot/SRDGZ scope/DSGM Scopes/M scops scorbutic scorcher/M scorching/Y scorch/ZGRSD scoreboard/MS scorecard/MS scored/M scorekeeper/SM scoreless scoreline score/ZMDSRJG scorner/M scornfulness/M scornful/PY scorn/SGZMRD scorpion/SM Scorpio/SM Scorpius/M Scorsese/M Scotchgard/M Scotchman/M Scotchmen scotch/MSDG scotchs Scotch/S Scotchwoman Scotchwomen Scotia/M Scotian/M Scotland/M Scot/MS Scotsman/M Scotsmen Scotswoman Scotswomen Scottie/SM Scotti/M Scottish Scott/M Scottsdale/M Scotty's scoundrel/YMS scourer/M scourge/MGRSD scourger/M scouring/M scour/SRDGZ scouter/M scouting/M scoutmaster/SM Scout's scout/SRDMJG scow/DMGS scowler/M scowl/SRDG scrabble/DRSZG scrabbler/M Scrabble/SM scragged scragging scraggly/TR scraggy/TR scrag/SM scrambler/MS scrambler's/U scramble/UDSRG scrammed scramming scram/S Scranton/M scrapbook/SM scraper/M scrape/S scrapheap/SM scrapped scrapper/SM scrapping scrappy/RT scrap/SGZJRDM scrapyard/S scratched/U scratcher/M scratches/M scratchily scratchiness/S scratch/JDRSZG scratchy/TRP scrawler/M scrawl/GRDS scrawly/RT scrawniness/MS scrawny/TRP screamer/M screaming/Y scream/ZGSRD screecher/M screech/GMDRS screechy/TR screed/MS scree/DSM screened/U screening/M screenplay/MS screen/RDMJSG screenwriter/MS screwball/SM screwdriver/SM screwer/M screw/GUSD screwiness/S screw's screwup screwworm/MS screwy/RTP Scriabin/M scribal scribble/JZDRSG scribbler/M scribe/CDRSGIK scriber/MKIC scribe's Scribner/MS scrimmager/M scrimmage/RSDMG scrimp/DGS scrimshaw/GSDM scrim/SM Scripps/M scrip/SM scripted/U script/FGMDS scriptural/Y scripture/MS Scripture/MS scriptwriter/SM scriptwriting/M scrivener/M scriven/ZR scrod/M scrofula/MS scrofulous scrollbar/SM scroll/GMDSB Scrooge/MS scrooge/SDMG scrota scrotal scrotum/M scrounge/ZGDRS scroungy/TR scrubbed scrubber/MS scrubbing scrubby/TR scrub/S scruffily scruffiness/S scruff/SM scruffy/PRT Scruggs/M scrummage/MG scrum/MS scrumptious/Y scrunch/DSG scrunchy/S scruple/SDMG scrupulosity/SM scrupulousness's scrupulousness/US scrupulous/UPY scrutable/I scrutinized/U scrutinizer/M scrutinize/RSDGZ scrutinizingly/S scrutinizing/UY scrutiny/MS SCSI scuba/SDMG scudded scudding Scud/M scud/S scuff/GSD scuffle/SDG sculler/M scullery/MS Sculley/M scullion/MS scull/SRDMGZ sculptor/MS sculptress/MS sculpt/SDG sculptural/Y sculpture/SDGM scumbag/S scummed scumming scum/MS scummy/TR scupper/SDMG scurf/MS scurfy/TR scurrility/MS scurrilousness/MS scurrilous/PY scurry/GJSD scurvily scurviness/M scurvy/SRTP scutcheon/SM scuttlebutt/MS scuttle/MGSD scuzzy/RT Scylla/M scythe/SDGM Scythia/M SD SDI SE seabed/S seabird/S seaboard/MS Seaborg/M seaborne Seabrook/M seacoast/MS seafare/JRZG seafarer/M seafood/MS seafront/MS Seagate/M seagoing Seagram/M seagull/S seahorse/S sealant/MS sealed/AU sealer/M seal/MDRSGZ sealskin/SM seals/UA seamail seamanship/SM seaman/YM seamer/M seaminess/M seamlessness/M seamless/PY seam/MNDRGS seams/I seamstress/MS Seamus/M sea/MYS seamy/TRP Seana/M sance/SM Sean/M seaplane/SM seaport/SM seaquake/M Seaquarium/M searcher/AM searching/YS searchlight/SM search/RSDAGZ sear/DRSJGT searing/Y Sears/M seascape/SM seashell/MS seashore/SM seasickness/SM seasick/P seaside/SM seasonableness/M seasonable/UP seasonably/U seasonality seasonal/Y seasoned/U seasoner/M seasoning/M season/JRDYMBZSG seatbelt seated/A seater/M seating/SM SEATO seat's Seattle/M seat/UDSG seawall/S seaward/S seawater/S seaway/MS seaweed/SM seaworthinesses seaworthiness/MU seaworthy/TRP sebaceous Sebastian/M Sebastiano/M Sebastien/M seborrhea/SM SEC secant/SM secede/GRSD secessionist/MS secession/MS secludedness/M secluded/YP seclude/GSD seclusion/SM seclusive Seconal secondarily secondary/PS seconder/M secondhand second/RDYZGSL secrecy/MS secretarial secretariat/MS secretaryship/MS secretary/SM secrete/XNS secretion/M secretiveness/S secretive/PY secretory secret/TVGRDYS sec/S sectarianism/MS sectarian/S sectary/MS sectionalism/MS sectionalized sectional/SY section/ASEM sectioned sectioning sect/ISM sectoral sectored sector/EMS sectoring sects/E secularism/MS secularist/MS secularity/M secularization/MS secularized/U secularize/GSD secular/SY secured/U securely/I secure/PGTYRSDJ security/MSI secy sec'y sedan/SM sedateness/SM sedate/PXVNGTYRSD sedation/M sedative/S sedentary Seder/SM sedge/SM Sedgwick/M sedgy/RT sedimentary sedimentation/SM sediment/SGDM sedition/SM seditiousness/M seditious/PY seducer/M seduce/RSDGZ seduction/MS seductiveness/MS seductive/YP seductress/SM sedulous/Y Seebeck/M seed/ADSG seedbed/MS seedcase/SM seeded/U seeder/MS seediness/MS seeding/S seedless seedling/SM seedpod/S seed's seedy/TPR seeings seeing's seeing/U seeker/M seek/GZSR seeking/Y Seeley/M See/M seem/GJSYD seeming/Y seemliness's seemliness/US seemly/UTPR seen/U seepage/MS seep/GSD seer/SM seersucker/MS sees seesaw/DMSG seethe/SDGJ see/U segmental/Y segmentation/SM segmented/U segment/SGDM Segovia/M segregant segregated/U segregate/XCNGSD segregation/CM segregationist/SM segregative Segre/M segue/DS segueing Segundo/M Se/H Seidel/M seigneur/MS seignior/SM Seiko/M seine/GZMDSR Seine/M seiner/M Seinfeld/M seismic seismically seismographer/M seismographic seismographs seismography/SM seismograph/ZMR seismologic seismological seismologist/MS seismology/SM seismometer/S seize/BJGZDSR seizer/M seizing/M seizin/MS seizor/MS seizure/MS Seka/M Sela/M Selassie/M Selby/M seldom selected/UAC selectional selection/MS selectiveness/M selective/YP selectivity/MS selectman/M selectmen selectness/SM selector/SM select/PDSVGB Selectric/M selects/A Selena/M selenate/M Selene/M selenite/M selenium/MS selenographer/SM selenography/MS Selestina/M Seleucid/M Seleucus/M self/GPDMS selfishness/SU selfish/PUY selflessness/MS selfless/YP selfness/M Selfridge/M selfsameness/M selfsame/P Selia/M Selie/M Selig/M Selim/M Selina/M Selinda/M Seline/M Seljuk/M Selkirk/M Sella/M sell/AZGSR seller/AM Sellers/M Selle/ZM sellout/MS Selma/M seltzer/S selvage/MGSD selves/M Selznick/M semantical/Y semanticist/SM semantic/S semantics/M semaphore/GMSD Semarang/M semblance/ASME semen/SM semester/SM semiannual/Y semiarid semiautomated semiautomatic/S semicircle/SM semicircular semicolon/MS semiconductor/SM semiconscious semidefinite semidetached semidrying/M semifinalist/MS semifinal/MS semilogarithmic semimonthly/S seminal/Y seminarian/MS seminar/SM seminary/MS Seminole/SM semiofficial semioticians semiotic/S semiotics/M semipermanent/Y semipermeable semiprecious semiprivate semiprofessional/YS semipublic semiquantitative/Y Semiramis/M semiretired semisecret semiskilled semi/SM semisolid/S semistructured semisweet Semite/SM Semitic/MS semitic/S semitone/SM semitrailer/SM semitrance semitransparent semitropical semivowel/MS semiweekly/S semiyearly semolina/SM sempiternal sempstress/SM Semtex sen Sen Sena/M senate/MS Senate/MS senatorial senator/MS Sendai/M sender/M sends/A send/SRGZ Seneca/MS Senegalese Senegal/M senescence/SM senescent senile/SY senility/MS seniority/SM senior/MS Senior/S Sennacherib/M senna/MS Sennett/M Seora/M senora/S senorita/S senor/MS sensately/I sensate/YNX sensationalism/MS sensationalist/S sensationalize/GSD sensational/Y sensation/M sens/DSG senselessness/SM senseless/PY sense/M sensibility/ISM sensibleness/MS sensible/PRST sensibly/I sensitiveness/MS sensitiveness's/I sensitives sensitive/YIP sensitivity/ISM sensitization/CSM sensitized/U sensitizers sensitize/SDCG sensor/MS sensory sensualist/MS sensuality/MS sensual/YF sensuousness/S sensuous/PY Sensurround/M sentence/SDMG sentential/Y sententious/Y sentience/ISM sentient/YS sentimentalism/SM sentimentalist/SM sentimentality/SM sentimentalization/SM sentimentalize/RSDZG sentimentalizes/U sentimental/Y sentiment/MS sentinel/GDMS sentry/SM sent/UFEA Seoul/M sepal/SM separability/MSI separableness/MI separable/PI separably/I separateness/MS separates/M separate/YNGVDSXP separation/M separatism/SM separatist/SM separator/SM Sephardi/M Sephira/M sepia/MS Sepoy/M sepses sepsis/M septa/M septate/N September/MS septennial/Y septet/MS septicemia/SM septicemic septic/S septillion/M sept/M Sept/M septuagenarian/MS Septuagint/MS septum/M sepulcher/MGSD sepulchers/UA sepulchral/Y seq sequel/MS sequenced/A sequence/DRSJZMG sequencer/M sequence's/F sequences/F sequent/F sequentiality/FM sequentialize/DSG sequential/YF sequester/SDG sequestrate/XGNDS sequestration/M sequin/SDMG sequitur Sequoia/M sequoia/MS Sequoya/M Serafin/M seraglio/SM serape/S seraphic seraphically seraphim's seraph/M seraphs sera's Serbia/M Serbian/S Serb/MS Serbo/M serenade/MGDRS serenader/M Serena/M serendipitous/Y serendipity/MS serene/GTYRSDP Serene/M sereneness/SM Serengeti/M serenity/MS sere/TGDRS serfdom/MS serf/MS Sergeant/M sergeant/SM serge/DSGM Sergei/M Serge/M Sergent/M Sergio/M serialization/MS serialize/GSD serial/MYS series/M serif/SMD serigraph/M serigraphs seriousness/SM serious/PY sermonize/GSD sermon/SGDM serological/Y serology/MS serons serous Serpens/M serpent/GSDM serpentine/GYS Serra/M Serrano/M serrate/GNXSD serration/M serried serum/MS servant/SDMG serve/AGCFDSR served/U server/MCF servers serviceability/SM serviceableness/M serviceable/P serviced/U serviceman/M servicemen service/MGSRD service's/E services/E servicewoman servicewomen serviette/MS servilely servileness/M serviles servile/U servility/SM serving/SM servitor/SM servitude/MS servomechanism/MS servomotor/MS servo/S sesame/MS sesquicentennial/S sessile session/SM setback/S Seth/M Set/M Seton/M set's setscrew/SM set/SIA settable/A sett/BJGZSMR settee/MS setter/M setting/AS setting's settle/AUDSG settlement/ASM settler/MS settling/S setup/MS Seumas/M Seurat/M Seuss/M Sevastopol/M sevenfold sevenpence seven/SMH seventeen/HMS seventeenths sevenths seventieths seventy/MSH severalfold severalty/M several/YS severance/SM severed/E severeness/SM severe/PY severing/E severity/MS Severn/M severs/E sever/SGTRD Severus/M Seville/M sewage/MS Seward/M sewerage/SM sewer/GSMD sewing/SM sewn sew/SAGD sexagenarian/MS sex/GMDS sexily sexiness/MS sexism/SM sexist/SM sexless sexologist/SM sexology/MS sexpot/SM Sextans/M sextant/SM sextet/SM sextillion/M Sexton/M sexton/MS sextuple/MDG sextuplet/MS sexuality/MS sexualized sexual/Y sexy/RTP Seychelles Seyfert Seymour/M sf SF Sgt shabbily shabbiness/SM shabby/RTP shack/GMDS shackler/M shackle's Shackleton/M shackle/UGDS shad/DRJGSM shaded/U shadeless shade/SM shadily shadiness/MS shading/M shadowbox/SDG shadower/M shadow/GSDRM shadowiness/M Shadow/M shadowy/TRP shady/TRP Shae/M Shafer/M Shaffer/M shafting/M shaft/SDMG shagged shagginess/SM shagging shaggy/TPR shag/MS shah/M shahs Shaina/M Shaine/M shakable/U shakably/U shakeable shakedown/S shaken/U shakeout/SM shaker/M Shaker/S Shakespearean/S Shakespeare/M Shakespearian shake/SRGZB shakeup/S shakily shakiness/S shaking/M shaky/TPR shale/SM shall shallot/SM shallowness/SM shallow/STPGDRY Shalna/M Shalne/M shalom Shalom/M shalt shamanic shaman/SM shamble/DSG shambles/M shamefaced/Y shamefulness/S shameful/YP shamelessness/SM shameless/PY shame/SM sham/MDSG shammed shammer shamming shammy's shampoo/DRSMZG shampooer/M shamrock/SM Shamus/M Shana/M Shanan/M Shanda/M Shandee/M Shandeigh/M Shandie/M Shandra/M shandy/M Shandy/M Shane/M Shanghai/GM Shanghaiing/M shanghai/SDG Shanie/M Shani/M shank/SMDG Shannah/M Shanna/M Shannan/M Shannen/M Shannon/M Shanon/M shan't Shanta/M Shantee/M shantis Shantung/M shantung/MS shanty/SM shantytown/SM shape/AGDSR shaped/U shapelessness/SM shapeless/PY shapeliness/S shapely/RPT shaper/S shape's Shapiro/M sharable/U Sharai/M Shara/M shard/SM shareable sharecropped sharecropper/MS sharecropping sharecrop/S share/DSRGZMB shared/U shareholder/MS shareholding/S sharer/M shareware/S Shari'a Sharia/M sharia/SM Shari/M Sharity/M shark/SGMD sharkskin/SM Sharla/M Sharleen/M Sharlene/M Sharline/M Sharl/M Sharona/M Sharon/M Sharpe/M sharpen/ASGD sharpened/U sharpener/S sharper/M sharpie/SM Sharp/M sharpness/MS sharp/SGTZXPYRDN sharpshooter/M sharpshooting/M sharpshoot/JRGZ sharpy's Sharron/M Sharyl/M Shasta/M shat shatter/DSG shattering/Y shatterproof Shaughn/M Shaula/M Shauna/M Shaun/M shave/DSRJGZ shaved/U shaver/M Shavian shaving/M Shavuot/M Shawano/M shawl/SDMG shaw/M Shaw/M Shawna/M Shawnee/SM Shawn/M Shaylah/M Shayla/M Shaylyn/M Shaylynn/M Shay/M shay/MS Shayna/M Shayne/M Shcharansky/M sh/DRS sheaf/MDGS Shea/M shearer/M shear/RDGZS sheather/M sheathe/UGSD sheath/GJMDRS sheathing/M sheaths sheave/SDG sheaves/M Sheba/M shebang/MS Shebeli/M Sheboygan/M she'd shedding Shedir/M sheds shed's shed/U Sheelagh/M Sheelah/M Sheela/M Sheena/M sheen/MDGS sheeny/TRSM sheepdog/SM sheepfold/MS sheepherder/MS sheepishness/SM sheepish/YP sheep/M sheepskin/SM Sheeree/M sheerness/S sheer/PGTYRDS sheeting/M sheetlike sheet/RDMJSG Sheetrock Sheffielder/M Sheffield/RMZ Sheffie/M Sheff/M Sheffy/M sheikdom/SM sheikh's sheik/SM Sheilah/M Sheila/M shekel/MS Shelagh/M Shela/M Shelba/M Shelbi/M Shelby/M Shelden/M Sheldon/M shelf/MDGS Shelia/M she'll shellacked shellacking/MS shellac/S shelled/U Shelley/M shellfire/SM shellfish/SM Shellie/M Shelli/M Shell/M shell/RDMGS Shelly/M Shel/MY shelter/DRMGS sheltered/U shelterer/M Shelton/M shelve/JRSDG shelver/M shelves/M shelving/M she/M Shem/M Shena/M Shenandoah/M shenanigan/SM Shenyang/M Sheol/M Shepard/M shepherd/DMSG shepherdess/S Shepherd/M Shep/M Sheppard/M Shepperd/M Sheratan/M Sheraton/M sherbet/MS sherd's Sheree/M Sheridan/M Sherie/M sheriff/SM Sherill/M Sherilyn/M Sheri/M Sherline/M Sherlocke/M sherlock/M Sherlock/M Sher/M Sherman/M Shermie/M Sherm/M Shermy/M Sherpa/SM Sherrie/M Sherri/M Sherry/M sherry/MS Sherwin/M Sherwood/M Sherwynd/M Sherye/M Sheryl/M Shetland/S Shevardnadze/M shew/GSD shewn shh shiatsu/S shibboleth/M shibboleths shielded/U shielder/M shield/MDRSG Shields/M shiftily shiftiness/SM shiftlessness/S shiftless/PY shift/RDGZS shifty/TRP Shi'ite Shiite/SM Shijiazhuang Shikoku/M shill/DJSG shillelagh/M shillelaghs shilling/M Shillong/M Shiloh/M shimmed shimmer/DGS shimmery shimming shimmy/DSMG shim/SM Shina/M shinbone/SM shindig/MS shiner/M shine/S shingle/MDRSG shingler/M shinguard shininess/MS shining/Y shinned shinning shinny/GDSM shin/SGZDRM shinsplints Shintoism/S Shintoist/MS Shinto/MS shiny/PRT shipboard/MS shipborne shipbuilder/M shipbuild/RGZJ shipload/SM shipman/M shipmate/SM shipmen shipment/AMS shipowner/MS shippable shipped/A shipper/SM shipping/MS ship's shipshape ship/SLA shipwreck/GSMD shipwright/MS shipyard/MS Shiraz/M shire/MS shirker/M shirk/RDGZS Shirlee/M Shirleen/M Shirlene/M Shirley/M Shirline/M Shirl/M Shir/M shirr/GJDS shirtfront/S shirting/M shirt/JDMSG shirtless shirtmake/R shirtmaker/M shirtsleeve/MS shirttail/S shirtwaist/SM shit/S! shitting/! shitty/RT! Shiva/M shiverer/M shiver/GDR shivery shiv/SZRM shivved shivving shlemiel's Shmuel/M shoal/SRDMGT shoat/SM shocker/M shocking/Y Shockley/M shockproof shock/SGZRD shoddily shoddiness/SM shoddy/RSTP shod/U shoehorn/GSMD shoeing shoelace/MS shoemaker/M shoemake/RZ shoe/MS shoer's shoeshine/MS shoestring/MS shoetree/MS shogunate/SM shogun/MS Shoji/M Sholom/M shone shoo/DSG shoofly shook/SM shooter/M shootout/MS shoot/SJRGZ shopkeeper/M shopkeep/RGZ shoplifter/M shoplifting/M shoplift/SRDGZ shop/MS shopped/M shopper/M shoppe/RSDGZJ shopping/M shoptalk/SM shopworn shorebird/S shore/DSRGMJ shoreline/SM Shorewood/M shoring/M shortage/MS shortbread/MS shortcake/SM shortchange/DSG shortcoming/MS shortcrust shortcut/MS shortcutting shortener/M shortening/M shorten/RDGJ shortfall/SM shorthand/DMS Shorthorn/M shorthorn/MS shortie's shortish shortlist/GD Short/M shortness/MS short/SGTXYRDNP shortsightedness/S shortsighted/YP shortstop/MS shortwave/SM shorty/SM Shoshana/M Shoshanna/M Shoshone/SM Shostakovitch/M shotgunned shotgunner shotgunning shotgun/SM shot/MS shotted shotting shoulder/GMD shouldn't should/TZR shout/SGZRDM shove/DSRG shoveler/M shovelful/MS shovel/MDRSZG shover/M showbiz showbizzes showboat/SGDM showcase/MGSD showdown/MS shower/GDM showery/TR show/GDRZJS showgirl/SM showily showiness/MS showing/M showman/M showmanship/SM showmen shown showoff/S showpiece/SM showplace/SM showroom/MS showy/RTP shpt shrank shrapnel/SM shredded shredder/MS shredding shred/MS Shreveport/M shrewdness/SM shrewd/RYTP shrew/GSMD shrewishness/M shrewish/PY shrieker/M shriek/SGDRMZ shrift/SM shrike/SM shrill/DRTGPS shrillness/MS shrilly shrimp/MDGS shrine/SDGM shrinkage/SM shrinker/M shrinking/U shrink/SRBG shrivel/GSD shriven shrive/RSDG Shropshire/M shroud/GSMD shrubbed shrubbery/SM shrubbing shrubby/TR shrub/SM shrugged shrugging shrug/S shrunk/N shtick/S shucker/M shuck/SGMRD shucks/S shudder/DSG shuddery shuffleboard/MS shuffled/A shuffle/GDSRZ shuffles/A shuffling/A Shulman/M Shu/M shunned shunning shun/S shunter/M shunt/GSRD Shurlocke/M Shurlock/M Shurwood/M shush/SDG shutdown/MS shuteye/SM shutoff/M shutout/SM shut/S shutterbug/S shutter/DMGS shuttering/M shutting shuttlecock/MDSG shuttle/MGDS shy/DRSGTZY shyer shyest Shylockian/M Shylock/M shyness/SM shyster/SM Siamese/M Siam/M Siana/M Sianna/M Sian's Sibbie/M Sibby/M Sibeal/M Sibelius/M Sibella/M Sibelle/M Sibel/M Siberia/M Siberian/S sibilance/M sibilancy/M sibilant/SY Sibilla/M Sibley/M sibling/SM Sib/M Sibylla/M Sibylle/M sibylline Sibyl/M sibyl/SM Siciliana/M Sicilian/S Sicily/M sickbay/M sickbed/S sickener/M sickening/Y sicken/JRDG sicker/Y sick/GXTYNDRSP sickie/SM sickish/PY sickle/SDGM sickliness/M sickly/TRSDPG sickness/MS sicko/S sickout/S sickroom/SM sic/S sidearm/S sideband/MS sidebar/MS sideboard/SM sideburns sidecar/MS sided/A sidedness side/ISRM sidekick/MS sidelight/SM sideline/MGDRS sidelong sideman/M sidemen sidepiece/S sidereal sider/FA sides/A sidesaddle/MS sideshow/MS sidesplitting sidestepped sidestepping sidestep/S sidestroke/GMSD sideswipe/GSDM sidetrack/SDG sidewalk/MS sidewall/MS sidewards sideway/SM sidewinder/SM siding/SM sidle/DSG Sid/M Sidnee/M Sidney/M Sidoney/M Sidonia/M Sidonnie/M SIDS siege/GMDS Siegel/M Siegfried/M Sieglinda/M Siegmund/M Siemens/M Siena/M sienna/SM Sierpinski/M sierra/SM siesta/MS sieve/GZMDS Siffre/M sifted/UA sifter/M sift/GZJSDR Sigfrid/M Sigfried/M SIGGRAPH/M sigh/DRG sigher/M sighs sighted/P sighter/M sighting/S sight/ISM sightless/Y sightliness/UM sightly/TURP sightread sightseeing/S sightsee/RZ Sigismond/M Sigismondo/M Sigismund/M Sigismundo/M Sig/M sigma/SM sigmoid Sigmund/M signal/A signaled signaler/S signaling signalization/S signalize/GSD signally signalman/M signalmen signals signal's signatory/SM signature/MS signboard/MS signed/FU signer/SC signet/SGMD sign/GARDCS significance/IMS significantly/I significant/YS signification/M signify/DRSGNX signing/S Signora/M signora/SM signore/M signori signories signorina/SM signorine Signor/M signor/SFM signpost/DMSG sign's signs/F Sigrid/M Sigurd/M Sigvard/M Sihanouk/M Sikhism/MS Sikh/MS Sikhs Sikkimese Sikkim/M Sikorsky/M silage/GMSD Silas/M Sileas/M siled Sile/M silence/MZGRSD silencer/M silentness/M silent/TSPRY Silesia/M silhouette/GMSD silica/SM silicate/SM siliceous silicide/M silicone/SM silicon/MS silicoses silicosis/M silken/DG silk/GXNDMS silkily silkiness/SM silkscreen/SM silkworm/MS silky/RSPT silliness/SM sill/MS silly/PRST silo/GSM siltation/M silt/MDGS siltstone/M silty/RT Silurian/S Silvain/M Silva/M Silvana/M Silvan/M Silvano/M Silvanus/M silverer/M silverfish/MS Silverman/M silver/RDYMGS silversmith/M silversmiths Silverstein/M silverware/SM silvery/RTP Silvester/M Silvia/M Silvie/M Silvio/M Si/M SIMD Simenon/M Simeon/M simian/S similar/EY similarity/EMS simile/SM similitude/SME Simla/M simmer/GSD Simmonds/M Simmons/M Simmonsville/M Sim/MS Simms/M Simona/M Simone/M Simonette/M simonize/SDG Simon/M Simonne/M simony/MS simpatico simper/GDS simpleminded/YP simpleness/S simple/RSDGTP simpleton/SM simplex/S simplicity/MS simplified/U simplify/ZXRSDNG simplistic simplistically simply Simpson/M simulacrum/M Simula/M SIMULA/M simulate/XENGSD simulation/ME simulative simulator/SEM simulcast/GSD simultaneity/SM simultaneousness/M simultaneous/YP Sinai/M Sinatra/M since sincere/IY sincereness/M sincerer sincerest sincerity/MIS Sinclair/M Sinclare/M Sindbad/M Sindee/M Sindhi/M sinecure/MS sinecurist/M sine/SM sinew/SGMD sinewy sinfulness/SM sinful/YP Singaporean/S Singapore/M sing/BGJZYDR Singborg/M singeing singer/M Singer/M singe/S singing/Y singlehanded/Y singleness/SM single/PSDG Singleton/M singleton/SM singletree/SM singlet/SM singsong/GSMD singularity/SM singularization/M singular/SY Sinhalese/M sinisterness/M sinister/YP sinistral/Y sinkable/U sinker/M sink/GZSDRB sinkhole/SM Sinkiang/M sinking/M sinlessness/M sinless/YP sin/MAGS sinned sinner/MS sinning sinter/DM sinuosity/MS sinuousities sinuousness/M sinuous/PY sinusitis/SM sinus/MS sinusoidal/Y sinusoid/MS Siobhan/M Siouxie/M Sioux/M siphon/DMSG siphons/U sipped sipper/SM sipping sip/S sired/C sire/MS siren/M sires/C siring/C Sirius/M sirloin/MS Sir/MS sirocco/MS sirred sirring sirup's sir/XGMNDS sisal/MS Sisely/M Sisile/M sis/S Sissie/M sissified Sissy/M sissy/TRSM sister/GDYMS sisterhood/MS sisterliness/MS sisterly/P sister's/A Sistine Sisyphean Sisyphus/M sit/AG sitarist/SM sitar/SM sitcom/SM site/DSJM sits sitter/MS sitting/SM situate/GNSDX situational/Y situationist situation/M situ/S situs/M Siusan/M Siva/M Siward/M sixfold sixgun six/MRSH sixpence/MS sixpenny sixshooter sixteen/HRSM sixteenths sixths sixth/Y sixtieths sixty/SMH sizableness/M sizable/P sized/UA size/GJDRSBMZ sizer/M sizes/A sizing/M sizzler/M sizzle/RSDG SJ Sjaelland/M SK ska/S skateboard/SJGZMDR skater/M skate/SM skat/JMDRGZ skedaddle/GSD skeet/RMS skein/MDGS skeletal/Y skeleton/MS Skell/M Skelly/M skeptical/Y skepticism/MS skeptic/SM sketchbook/SM sketcher/M sketchily sketchiness/MS sketch/MRSDZG sketchpad sketchy/PRT skew/DRSPGZ skewer/GDM skewing/M skewness/M skidded skidding skid/S skiff/GMDS skiing/M skilfully skill/DMSG skilled/U skillet/MS skillfulnesses skillfulness/MU skillful/YUP skilling/M skimmed skimmer/MS skimming/SM ski/MNJSG skimp/GDS skimpily skimpiness/MS skimpy/PRT skim/SM skincare skindive/G skinflint/MS skinhead/SM skinless skinned Skinner/M skinner/SM skinniness/MS skinning skinny/TRSP skin/SM skintight Skip/M skipped Skipper/M skipper/SGDM Skippie/M skipping Skipp/RM Skippy/M skip/S Skipton/M skirmisher/M skirmish/RSDMZG skirter/M skirting/M skirt/RDMGS skit/GSMD skitter/SDG skittishness/SM skittish/YP skittle/SM skivvy/GSDM skoal/SDG Skopje/M skulduggery/MS skulker/M skulk/SRDGZ skullcap/MS skullduggery's skull/SDM skunk/GMDS skycap/MS skydiver/SM skydiving/MS Skye/M skyhook skyjacker/M skyjack/ZSGRDJ Skylab/M skylarker/M skylark/SRDMG Skylar/M Skyler/M skylight/MS skyline/MS Sky/M sky/MDRSGZ skyrocket/GDMS skyscraper/M skyscrape/RZ skyward/S skywave skyway/M skywriter/MS skywriting/MS slabbed slabbing slab/MS slacken/DG slacker/M slackness/MS slack/SPGTZXYRDN Slade/M slagged slagging slag/MS slain slake/DSG slaked/U slalom/SGMD slammed slammer/S slamming slam/S slander/MDRZSG slanderousness/M slanderous/PY slang/SMGD slangy/TR slanting/Y slant/SDG slantwise slapdash/S slaphappy/TR slap/MS slapped slapper slapping slapstick/MS slash/GZRSD slashing/Y slater/M Slater/M slate/SM slather/SMDG slating/M slat/MDRSGZ slatted slattern/MYS slatting slaughterer/M slaughterhouse/SM slaughter/SJMRDGZ slave/DSRGZM slaveholder/SM slaver/GDM slavery/SM Slavic/M slavishness/SM slavish/YP Slav/MS Slavonic/M slaw/MS slay/RGZS sleaze/S sleazily sleaziness/SM sleazy/RTP sledded sledder/S sledding sledgehammer/MDGS sledge/SDGM sled/SM sleekness/S sleek/PYRDGTS sleeper/M sleepily sleepiness/SM sleeping/M sleeplessness/SM sleepless/YP sleepover/S sleep/RMGZS sleepwalker/M sleepwalk/JGRDZS sleepwear/M sleepyhead/MS sleepy/PTR sleet/DMSG sleety/TR sleeveless sleeve/SDGM sleeving/M sleigh/GMD sleighs sleight/SM sleken/DG slenderize/DSG slenderness/MS slender/RYTP slept Slesinger/M sleuth/GMD sleuths slew/DGS slice/DSRGZM sliced/U slicer/M slicker/M slickness/MS slick/PSYRDGTZ slider/M slide/S slid/GZDR slight/DRYPSTG slighter/M slighting/Y slightness/S slime/SM sliminess/S slimline slimmed slimmer/S slimmest slimming/S slimness/S slim/SPGYD slimy/PTR sling/GMRS slingshot/MS slings/U slink/GS slinky/RT slipcase/MS slipcover/GMDS slipknot/SM slippage/SM slipped slipper/GSMD slipperiness/S slippery/PRT slipping slipshod slip/SM slipstream/MDGS slipway/SM slither/DSG slithery slit/SM slitted slitter/S slitting sliver/GSDM slivery Sloane/M Sloan/M slobber/SDG slobbery slob/MS Slocum/M sloe/MS sloganeer/MG slogan/MS slogged slogging slog/S sloop/SM slop/DRSGZ sloped/U slope/S slopped sloppily sloppiness/SM slopping sloppy/RTP slosh/GSDM slothfulness/MS slothful/PY sloth/GDM sloths slot/MS slotted slotting slouch/DRSZG sloucher/M slouchy/RT slough/GMD sloughs Slovakia/M Slovakian/S Slovak/S Slovene/S Slovenia/M Slovenian/S slovenliness/SM slovenly/TRP sloven/YMS slowcoaches slowdown/MS slowish slowness/MS slow/PGTYDRS slowpoke/MS SLR sludge/SDGM sludgy/TR slue/MGDS sluggard/MS slugged slugger/SM slugging sluggishness/SM sluggish/YP slug/MS sluice/SDGM slumberer/M slumber/MDRGS slumberous slumlord/MS slummed slummer slumming slum/MS slummy/TR slump/DSG slung/U slunk slur/MS slurp/GSD slurred slurried/M slurring slurrying/M slurry/MGDS slushiness/SM slush/SDMG slushy/RTP slut/MS sluttish slutty/TR Sly/M slyness/MS sly/RTY smacker/M smack/SMRDGZ smallholders smallholding/MS smallish Small/M smallness/S smallpox/SM small/SGTRDP smalltalk smalltime Smallwood/M smarmy/RT smarten/GD smartness/S smartypants smart/YRDNSGTXP smasher/M smash/GZRSD smashing/Y smashup/S smattering/SM smearer/M smear/GRDS smeary/TR smeller/M smelliness/MS smell/SBRDG smelly/TRP smelter/M smelt/SRDGZ Smetana/M smidgen/MS smilax/MS smile/GMDSR smiley/M smilies smiling/UY smirch/SDG smirk/GSMD Smirnoff/M smite/GSR smiter/M smith/DMG smithereens Smithfield/M Smith/M smiths Smithsonian/M Smithson/M Smithtown/M smithy/SM smitten Smitty/M Sm/M smocking/M smock/SGMDJ smoggy/TR smog/SM smoke/GZMDSRBJ smokehouse/MS smokeless smoker/M smokescreen/S smokestack/MS Smokey/M smokiness/S smoking/M smoky/RSPT smoldering/Y smolder/SGD Smolensk/M Smollett/M smooch/SDG smoothen/DG smoother/M smoothie/SM smoothness/MS smooths smooth/TZGPRDNY smrgsbord/SM smote smother/GSD SMSA/MS SMTP Smucker/M smudge/GSD smudginess/M smudgy/TRP smugged smugger smuggest smugging smuggle/JZGSRD smuggler/M smugness/MS smug/YSP smut/SM Smuts/M smutted smuttiness/SM smutting smutty/TRP Smyrna/M snack/SGMD snaffle/GDSM snafu/DMSG snagged snagging snag/MS snail/GSDM Snake snakebird/M snakebite/MS snake/DSGM snakelike snakeroot/M snaky/TR snapback/M snapdragon/MS snapped/U snapper/SM snappily snappiness/SM snapping/U snappishness/SM snappish/PY snappy/PTR snapshot/MS snapshotted snapshotting snap/US snare/DSRGM snarer/M snarf/JSGD snarler/M snarling/Y snarl/UGSD snarly/RT snatch/DRSZG snatcher/M snazzily snazzy/TR Snead/M sneaker/MD sneakily sneakiness/SM sneaking/Y sneak/RDGZS sneaky/PRT Sneed/M sneerer/M sneer/GMRDJS sneering/Y sneeze/SRDG Snell/M snicker/GMRD snick/MRZ snideness/M Snider/M snide/YTSRP sniffer/M sniff/GZSRD sniffle/GDRS sniffler/M sniffles/M snifter/MDSG snigger's sniper/M snipe/SM snipped snipper/SM snippet/SM snipping snippy/RT snip/SGDRZ snitch/GDS snit/SM sniveler/M snivel/JSZGDR Sn/M snobbery/SM snobbishness/S snobbish/YP snobby/RT snob/MS Snodgrass/M snood/SGDM snooker/GMD snook/SMRZ snooper/M snoop/SRDGZ Snoopy/M snoopy/RT snootily snootiness/MS snoot/SDMG snooty/TRP snooze/GSD snore/DSRGZ snorkel/ZGSRDM snorter/M snort/GSZRD snot/MS snotted snottily snottiness/SM snotting snotty/TRP snout/SGDM snowball/SDMG snowbank/SM Snowbelt/SM snowbird/SM snowblower/S snowboard/GZDRJS snowbound snowcapped snowdrift/MS snowdrop/MS snowfall/MS snowfield/MS snowflake/MS snow/GDMS snowily snowiness/MS Snow/M snowman/M snowmen snowmobile/GMDRS snowplough/M snowploughs snowplow/SMGD snowshed snowshoeing snowshoe/MRS snowshoer/M snowstorm/MS snowsuit/S snowy/RTP snubbed snubber snubbing snub/SP snuffbox/SM snuffer/M snuff/GZSYRD snuffle/GDSR snuffler/M snuffly/RT snugged snugger snuggest snugging snuggle/GDS snuggly snugness/MS snug/SYP Snyder/M so SO soaker/M soak/GDRSJ soapbox/DSMG soapiness/S soap/MDRGS soapstone/MS soapsud/S soapy/RPT soar/DRJSG soarer/M soaring/Y sobbed sobbing/Y soberer/M soberness/SM sober/PGTYRD sobriety/SIM sobriquet/MS sob/SZR Soc soccer/MS sociabilities sociability/IM sociable/S sociably/IU socialism/SM socialistic socialist/SM socialite/SM sociality/M socialization/SM socialized/U socializer/M socialize/RSDG socially/U social/SY societal/Y society/MS socio sociobiology/M sociocultural/Y sociodemographic socioeconomically socioeconomic/S sociolinguistics/M sociological/MY sociologist/SM sociology/SM sociometric sociometry/M sociopath/M sociopaths socket/SMDG sock/GDMS Socorro/M Socrates/M Socratic/S soc/S soda/SM sodded sodden/DYPSG soddenness/M sodding Soddy/M sodium/MS sod/MS sodomite/MS sodomize/GDS Sodom/M sodomy/SM soever sofa/SM Sofia/M Sofie/M softball/MS softbound softener/M soften/ZGRD softhearted softie's softness/MS soft/SPXTYNR software/MS softwood/SM softy/SM soggily sogginess/S soggy/RPT Soho/M soign soiled/U soil/SGMD soire/SM sojourn/RDZGSM solace/GMSRD solacer/M solaria solarium/M solar/S solder/RDMSZG soldier/MDYSG soldiery/MS sold/RU solecism/MS soled/FA solemness solemnify/GSD solemnity/MS solemnization/SM solemnize/GSD solemnness/SM solemn/PTRY solenoid/MS soler/F soles/IFA sole/YSP sol/GSMDR solicitation/S solicited/U solicitor/MS solicitousness/S solicitous/YP solicit/SDG solicitude/MS solidarity/MS solidi solidification/M solidify/NXSDG solidity/S solidness/SM solid/STYRP solidus/M soliloquies soliloquize/DSG soliloquy/M soling/NM solipsism/MS solipsist/S Solis/M solitaire/SM solitary/SP solitude/SM Sollie/M Solly/M Sol/MY solo/DMSG soloist/SM Solomon/SM Solon/M Soloviev/M solstice/SM solubility/IMS soluble/SI solute/ENAXS solute's solution/AME solvable/UI solvating solve/ABSRDZG solved/EU solvency/IMS solvent/IS solvently solvent's solver/MEA solves/E solving/E Solzhenitsyn/M Somalia/M Somalian/S Somali/MS soma/M somatic somberness/SM somber/PY sombre sombrero/SM somebody'll somebody/SM someday somehow someone'll someone/SM someplace/M somersault/DSGM Somerset/M somerset/S somersetted somersetting Somerville/M something/S sometime/S someway/S somewhat/S somewhere/S some/Z sommelier/SM Somme/M somnambulism/SM somnambulist/SM somnolence/MS somnolent/Y Somoza/M sonar/SM sonata/MS sonatina/SM Sondheim/M Sondra/M Sonenberg/M songbag songbird/SM songbook/S songfest/MS songfulness/M songful/YP Songhai/M Songhua/M song/MS songster/MS songstress/SM songwriter/SM songwriting Sonia/M sonic/S Sonja/M Son/M sonnet/MDSG Sonnie/M Sonni/M Sonnnie/M Sonny/M sonny/SM Sonoma/M Sonora/M sonority/S sonorousness/SM sonorous/PY son/SMY Sontag/M sonuvabitch Sonya/M Sony/M soonish soon/TR soothe soother/M sooth/GZTYSRDMJ soothingness/M soothing/YP sooths soothsayer/M soothsay/JGZR soot/MGDS sooty/RT SOP Sophey/M Sophia/SM Sophie/M Sophi/M sophism/SM sophister/M sophistical sophisticatedly sophisticated/U sophisticate/XNGDS sophistication/MU sophistic/S sophist/RMS sophistry/SM Sophoclean Sophocles/M sophomore/SM sophomoric Sophronia/M soporifically soporific/SM sopped sopping/S soppy/RT soprano/SM sop/SM Sopwith/M sorbet/SM Sorbonne/M sorcerer/MS sorceress/S sorcery/MS Sorcha/M sordidness/SM sordid/PY sorehead/SM soreness/S Sorensen/M Sorenson/M sore/PYTGDRS sorghum/MS sorority/MS sorrel/SM Sorrentine/M sorrily sorriness/SM sorrower/M sorrowfulness/SM sorrowful/YP sorrow/GRDMS sorry/PTSR sorta sortable sorted/U sorter/MS sort/FSAGD sortieing sortie/MSD sort's sos SOS Sosa/M Sosanna/M Soto/M sot/SM sottish soubriquet's souffl/MS sough/DG soughs sought/U soulfulness/MS soulful/YP soulless/Y soul/MDS sound/AUD soundboard/MS sounders sounder's sounder/U soundest sounding/AY soundings sounding's soundless/Y soundly/U soundness/UMS soundproof/GSD soundproofing/M sound's sounds/A soundtrack/MS soupon/SM soup/GMDS Souphanouvong/M soupy/RT source/ASDMG sourceless sourdough sourdoughs sourish sourness/MS sourpuss/MS sour/TYDRPSG Sousa/M sousaphone/SM sous/DSG souse sou/SMH Southampton/M southbound southeastern southeaster/YM Southeast/MS southeast/RZMS southeastward/S southerly/S souther/MY southerner/M Southerner/MS southernisms southernmost southern/PZSYR Southey/M Southfield/M southing/M southland/M South/M southpaw/MS south/RDMG souths Souths southward/S southwestern southwester/YM Southwest/MS southwest/RMSZ southwestward/S souvenir/SM sou'wester sovereignty/MS sovereign/YMS soviet/MS Soviet/S sow/ADGS sowbelly/M sowens/M sower/DS Soweto/M sown/A sox's soybean/MS Soyinka/M soy/MS Soyuz/M Spaatz/M spacecraft/MS space/DSRGZMJ spaceflight/S spaceman/M spacemen spaceport/SM spacer/M spaceship/MS spacesuit/MS spacewalk/GSMD Spacewar/M spacewoman spacewomen spacey spacial spacier spaciest spaciness spacing/M spaciousness/SM spacious/PY Spackle spade/DSRGM spadeful/SM spader/M spadework/SM spadices spadix/M Spafford/M spaghetti/SM Spahn/M Spain/M spake Spalding/M Spam/M spa/MS Span spandex/MS spandrels spangle/GMDS Spanglish/S Spaniard/SM spanielled spanielling spaniel/SM Spanish/M spanker/M spanking/M spank/SRDJG span/MS spanned/U spanner/SM spanning SPARC/M SPARCstation/M spar/DRMGTS spareness/MS spare/PSY spareribs sparer/M sparing/UY sparker/M sparkle/DRSGZ sparkler/M Sparkman/M Sparks spark/SGMRD sparky/RT sparling/SM sparred sparrer sparring/U sparrow/MS sparseness/S sparse/YP sparsity/S spars/TR Spartacus/M Sparta/M spartan Spartan/S spasm/GSDM spasmodic spasmodically spastic/S spate/SM spathe/MS spatiality/M spatial/Y spat/MS spatted spatter/DGS spatterdock/M spatting spatula/SM spavin/DMS spawner/M spawn/MRDSG spay/DGS SPCA speakable/U speakeasy/SM speaker/M Speaker's speakership/M speaking/U speak/RBGZJS spearer/M spearfish/SDMG spearhead/GSDM spearmint/MS spear/MRDGS Spears spec'd specialism/MS specialist/MS specialization/SM specialized/U specialize/GZDSR specializing/U special/SRYP specialty/MS specie/MS specif specifiability specifiable specifiably specifically specification/SM specificity/S specific/SP specified/U specifier/SM specifies specify/AD specifying specimen/SM spec'ing speciousness/SM specious/YP speck/GMDS speckle/GMDS spec/SM spectacle/MSD spectacular/SY spectator/SM specter/DMS specter's/A spectralness/M spectral/YP spectra/M spectrogram/MS spectrographically spectrograph/M spectrography/M spectrometer/MS spectrometric spectrometry/M spectrophotometer/SM spectrophotometric spectrophotometry/M spectroscope/SM spectroscopic spectroscopically spectroscopy/SM spectrum/M specularity specular/Y speculate/VNGSDX speculation/M speculative/Y speculator/SM sped speech/GMDS speechlessness/SM speechless/YP speedboat/GSRM speedboating/M speeder/M speedily speediness/SM speedometer/MS speed/RMJGZS speedster/SM speedup/MS speedway/SM speedwell/MS speedy/PTR speer/M speleological speleologist/S speleology/MS spellbinder/M spellbind/SRGZ spellbound spelldown/MS spelled/A speller/M spelling/M spell/RDSJGZ spells/A spelunker/MS spelunking/S Spencerian Spencer/M Spence/RM spender/M spend/SBJRGZ spendthrift/MS Spenglerian Spengler/M Spense/MR Spenserian Spenser/M spent/U spermatophyte/M spermatozoa spermatozoon/M spermicidal spermicide/MS sperm/SM Sperry/M spew/DRGZJS spewer/M SPF sphagnum/SM sphere/SDGM spherical/Y spheric/S spherics/M spheroidal/Y spheroid/SM spherule/MS sphincter/SM Sphinx/M sphinx/MS Spica/M spic/DGM spicebush/M spice/SM spicily spiciness/SM spicule/MS spicy/PTR spider/SM spiderweb/S spiderwort/M spidery/TR Spiegel/M Spielberg/M spiel/GDMS spier/M spiffy/TDRSG spigot/MS spike/GMDSR Spike/M spiker/M spikiness/SM spiky/PTR spillage/SM Spillane/M spillover/SM spill/RDSG spillway/SM spinach/MS spinal/YS spindle/JGMDRS spindly/RT spinelessness/M spineless/YP spine/MS spinet/SM spininess/M spinnability/M spinnaker/SM spinneret/MS spinner/SM spinning/SM Spinoza/M spin/S spinsterhood/SM spinsterish spinster/MS spiny/PRT spiracle/SM spiraea's spiral/YDSG spire/AIDSGF spirea/MS spire's spiritedness/M spirited/PY spirit/GMDS spiritless spirits/I spiritualism/SM spiritualistic spiritualist/SM spirituality/SM spiritual/SYP spirituous spirochete/SM Spiro/M spiry/TR spitball/SM spite/CSDAG spitefuller spitefullest spitefulness/MS spiteful/PY spite's/A spitfire/SM spit/SGD spitted spitting spittle/SM spittoon/SM Spitz/M splashdown/MS splasher/M splash/GZDRS splashily splashiness/MS splashy/RTP splat/SM splatted splatter/DSG splatting splayfeet splayfoot/MD splay/SDG spleen/SM splendidness/M splendid/YRPT splendorous splendor/SM splenetic/S splicer/M splice/RSDGZJ spline/MSD splinter/GMD splintery splint/SGZMDR splits/M split/SM splittable splitter/MS splitting/S splodge/SM splotch/MSDG splotchy/RT splurge/GMDS splutterer/M splutter/RDSG Sp/M Spock/M spoilables spoilage/SM spoil/CSZGDR spoiled/U spoiler/MC spoilsport/SM Spokane/M spoke/DSG spoken/U spokeshave/MS spokesman/M spokesmen spokespeople spokesperson/S spokeswoman/M spokeswomen spoliation/MCS spongecake sponge/GMZRSD sponger/M sponginess/S spongy/TRP sponsor/DGMS sponsorship/S spontaneity/SM spontaneousness/M spontaneous/PY spoof/SMDG spookiness/MS spook/SMDG spooky/PRT spool/SRDMGZ spoonbill/SM spoonerism/SM spoonful/MS spoon/GSMD spoor/GSMD sporadically sporadic/Y spore/DSGM sporran/MS sportiness/SM sporting/Y sportiveness/M sportive/PY sportscast/RSGZM sportsmanlike/U sportsman/MY sportsmanship/MS sportsmen sportswear/M sportswoman/M sportswomen sportswriter/S sport/VGSRDM sporty/PRT Sposato/M spotlessness/MS spotless/YP spotlight/GDMS spotlit spot/MSC spotted/U spotter/MS spottily spottiness/SM spotting/M spotty/RTP spousal/MS spouse/GMSD spouter/M spout/SGRD sprain/SGD sprang/S sprat/SM sprawl/GSD sprayed/UA sprayer/M spray/GZSRDM sprays/A spreadeagled spreader/M spread/RSJGZB spreadsheet/S spreeing spree/MDS sprigged sprigging sprightliness/MS sprightly/PRT sprig/MS springboard/MS springbok/MS springeing springer/M Springfield/M springily springiness/SM springing/M springlike spring/SGZR Springsteen/M springtime/MS springy/TRP sprinkle/DRSJZG sprinkler/DM sprinkling/M Sprint/M sprint/SGZMDR sprite/SM spritz/GZDSR sprocket/DMGS sprocketed/U Sproul/M sprout/GSD spruce/GMTYRSDP spruceness/SM sprue/M sprung/U spryness/S spry/TRY SPSS spudded spudding spud/MS Spuds/M spume/DSGM spumone's spumoni/S spumy/TR spun spunk/GSMD spunky/SRT spurge/MS spuriousness/SM spurious/PY spur/MS spurn/RDSG spurred spurring spurt/SGD sputa Sputnik sputnik/MS sputter/DRGS sputum/M spy/DRSGM spyglass/MS sq sqq sqrt squabbed squabber squabbest squabbing squabbler/M squabble/ZGDRS squab/SM squadded squadding squadron/MDGS squad/SM squalidness/SM squalid/PRYT squaller/M squall/GMRDS squally/RT squalor/SM squamous/Y squander/GSRD Squanto square/GMTYRSDP squareness/SM squarer/M Squaresville/M squarish squash/GSRD squashiness/M squashy/RTP squatness/MS squat/SPY squatted squatter/SMDG squattest squatting squawker/M squawk/GRDMZS squaw/SM squeaker/M squeakily squeakiness/S squeak/RDMGZS squeaky/RPT squealer/M squeal/MRDSGZ squeamishness/SM squeamish/YP squeegee/DSM squeegeeing squeeze/GZSRDB squeezer/M squelcher/M squelch/GDRS squelchy/RT squibbed Squibb/GM squibbing Squibbing/M squib/SM squidded squidding squid/SM squiggle/MGDS squiggly/RT squinter/M squint/GTSRD squinting/Y squirehood squire/SDGM squirm/SGD squirmy/TR squirrel/SGYDM squirter/M squirt/GSRD squish/GSD squishy/RTP Sr Srinagar/M SRO S's SS SSA SSE ssh s's/KI SSS SST SSW ST stabbed stabber/S stabbing/S stability/ISM stabilizability stabilization/CS stabilization's stabilize/CGSD stabilizer/MS stableman/M stablemate stablemen stableness/UM stable/RSDGMTP stabler/U stable's/F stables/F stablest/U stabling/M stably/U stab/YS staccato/S Stacee/M Stace/M Stacey/M Stacia/M Stacie/M Staci/M stackable stacker/M stack's stack/USDG Stacy/M stadias stadia's stadium/MS Stael/M Stafani/M staff/ADSG Staffard/M staffer/MS Stafford/M Staffordshire/M staffroom staff's Staford/M stag/DRMJSGZ stagecoach/MS stagecraft/MS stagehand/MS stager/M stage/SM stagestruck stagflation/SM stagged staggerer/M stagger/GSJDR staggering/Y staggers/M stagging staginess/M staging/M stagnancy/SM stagnant/Y stagnate/NGDSX stagnation/M stagy/PTR Stahl/M staidness/MS staid/YRTP stained/U stainer/M stainless/YS stain/SGRD staircase/SM stair/MS stairway/SM stairwell/MS stake/DSGM stakeholder/S stakeout/SM stalactite/SM stalag/M stalagmite/SM stalemate/SDMG staleness/MS stale/PGYTDSR Staley/M Stalingrad/M Stalinist Stalin/SM stalker/M stalk/MRDSGZJ stall/DMSJG stalled/I stallholders stallion/SM Stallone/M stalls/I stalwartness/M stalwart/PYS Sta/M stamen/MS Stamford/M stamina/SM staminate stammer/DRSZG stammerer/M stammering/Y stampede/MGDRS stampeder/M stamped/U stamper/M stamp/RDSGZJ stance/MIS stancher/M stanch/GDRST stanchion/SGMD standalone standardization/AMS standardized/U standardize/GZDSR standardizer/M standardizes/A standard/YMS standby standbys standee/MS Standford/M standing/M Standish/M standoffish standoff/SM standout/MS standpipe/MS standpoint/SM stand/SJGZR standstill/SM Stanfield/M Stanford/M Stanislas/M Stanislaus/M Stanislavsky/M Stanislaw/M stank/S Stanleigh/M Stanley/M Stanly/M stannic stannous Stanton/M Stanwood/M Stan/YMS stanza/MS staph/M staphs staphylococcal staphylococci staphylococcus/M stapled/U stapler/M Stapleton/M staple/ZRSDGM starboard/SDMG starchily starchiness/MS starch/MDSG starchy/TRP stardom/MS star/DRMGZS stardust/MS stare/S starfish/SM Stargate/M stargaze/ZGDRS staring/U Starkey/M Stark/M starkness/MS stark/SPGTYRD Starla/M Starlene/M starless starlet/MS starlight/MS starling/MS Starlin/M starlit Star/M starred starring Starr/M starry/TR starship starstruck start/ASGDR starter/MS startle/GDS startling/PY startup/SM starvation/MS starveling/M starver/M starve/RSDG stash/GSD stasis/M stat/DRSGV statecraft/MS stated/U statehood/MS statehouse/S Statehouse's state/IGASD statelessness/MS stateless/P stateliness/MS stately/PRT statement/MSA Staten/M stater/M stateroom/SM stateside state's/K states/K statesmanlike statesman/MY statesmanship/SM statesmen stateswoman stateswomen statewide statical/Y static/S statics/M stationarity stationary/S stationer/M stationery/MS stationmaster/M station/SZGMDR statistical/Y statistician/MS statistic/MS Statler/M stator/SM statuary/SM statue/MSD statuesque/YP statuette/MS stature/MS status/SM statute/SM statutorily statutory/P Stauffer/M staunchness/S staunch/PDRSYTG stave/DGM Stavro/MS stay/DRGZS stayer/M std STD stdio steadfastness/MS steadfast/PY steadily/U steadiness's steadiness/US steading/M stead/SGDM steady/DRSUTGP steakhouse/SM steak/SM stealer/M stealing/M steal/SRHG stealthily stealthiness/MS stealth/M stealths stealthy/PTR steamboat/MS steamer/MDG steamfitter/S steamfitting/S steamily steaminess/SM steamroller/DMG steamroll/GZRDS steam/SGZRDMJ steamship/SM steamy/RSTP Stearne/M Stearn/SM steed/SM Steele/M steeliness/SM steelmaker/M steel/SDMGZ steelworker/M steelwork/ZSMR steelyard/MS steely/TPRS Steen/M steepen/GD steeper/M steeplebush/M steeplechase/GMSD steeplejack/MS steeple/MS steepness/S steep/SYRNDPGTX steerage/MS steerer/M steer/SGBRDJ steersman/M steersmen steeves Stefa/M Stefania/M Stefanie/M Stefan/M Stefano/M Steffane/M Steffen/M Steffie/M Steffi/M stegosauri stegosaurus/S Steinbeck/SM Steinberg/M Steinem/M Steiner/M Steinmetz/M Stein/RM stein/SGZMRD Steinway/M Stella/M stellar stellated Ste/M stemless stemmed/U stemming stem/MS stemware/MS stench/GMDS stenciler/M stencil/GDRMSZ stencillings Stendhal/M Stendler/M Stengel/M stenographer/SM stenographic stenography/SM steno/SM stenotype/M stentorian stepbrother/MS stepchild/M stepchildren stepdaughter/MS stepfather/SM Stepha/M Stephana/M Stephanie/M Stephani/M Stephan/M Stephannie/M Stephanus/M Stephenie/M Stephen/MS Stephenson/M Stephie/M Stephi/M Stephine/M stepladder/SM step/MIS stepmother/SM stepparent/SM stepper/M steppe/RSDGMZ steppingstone/S stepsister/SM stepson/SM stepwise stereographic stereography/M stereo/GSDM stereophonic stereoscope/MS stereoscopic stereoscopically stereoscopy/M stereotype/GMZDRS stereotypic stereotypical/Y sterile sterility/SM sterilization/SM sterilized/U sterilize/RSDGZ sterilizes/A Sterling/M sterling/MPYS sterlingness/M sternal Sternberg/M Sterne/M Stern/M sternness/S Sterno stern/SYRDPGT sternum/SM steroidal steroid/MS stertorous Stesha/M stethoscope/SM stet/MS stetson/MS Stetson/SM stetted stetting Steuben/M Stevana/M stevedore/GMSD Steve/M Stevena/M Steven/MS Stevenson/M Stevie/M Stevy/M steward/DMSG stewardess/SM Steward/M stewardship/MS Stewart/M stew/GDMS st/GBJ sticker/M stickily stickiness/SM stickleback/MS stickle/GZDR stickler/M stick/MRDSGZ stickpin/SM stickup/SM sticky/GPTDRS Stieglitz/M stiffen/JZRDG stiff/GTXPSYRND stiffness/MS stifle/GJRSD stifler/M stifling/Y stigma/MS stigmata stigmatic/S stigmatization/C stigmatizations stigmatization's stigmatize/DSG stigmatized/U stile/GMDS stiletto/MDSG stillbirth/M stillbirths stillborn/S stiller/MI stillest Stillman/M Stillmann/M stillness/MS still/RDIGS Stillwell/M stilted/PY stilt/GDMS Stilton/MS Stimson/M stimulant/MS stimulated/U stimulate/SDVGNX stimulation/M stimulative/S stimulator/M stimulatory stimuli/M stimulus/MS Stine/M stinger/M sting/GZR stingily stinginess/MS stinging/Y stingray/MS stingy/RTP stinkbug/S stinker/M stink/GZRJS stinking/Y stinkpot/M Stinky/M stinky/RT stinter/M stinting/U stint/JGRDMS stipendiary stipend/MS stipple/JDRSG stippler/M stipulate/XNGSD stipulation/M Stirling/M stirred/U stirrer/SM stirring/YS stirrup/SM stir/S stitch/ASDG stitcher/M stitchery/S stitching/MS stitch's St/M stoat/SM stochastic stochastically stochasticity stockade/SDMG stockbreeder/SM stockbroker/MS stockbroking/S stocker/SM Stockhausen/M stockholder/SM Stockholm/M stockily stockiness/SM stockinet's stockinette/S stocking/MDS stockist/MS stockpile/GRSD stockpiler/M stockpot/MS stockroom/MS stock's stock/SGAD stocktaking/MS Stockton/M stockyard/SM stocky/PRT Stoddard/M stodge/M stodgily stodginess/S stodgy/TRP stogy/SM stoical/Y stoichiometric stoichiometry/M stoicism/SM Stoicism/SM stoic/MS Stoic/MS stoke/DSRGZ stoker/M stokes/M Stokes/M STOL stole/MDS stolen stolidity/S stolidness/S stolid/PTYR stolon/SM stomachache/MS stomacher/M stomach/RSDMZG stomachs stomp/DSG stonecutter/SM stone/DSRGM Stonehenge/M stoneless Stone/M stonemason/MS stoner/M stonewall/GDS stoneware/MS stonewashed stonework/SM stonewort/M stonily stoniness/MS stony/TPR stood stooge/SDGM stool/SDMG stoop/SDG stopcock/MS stopgap/SM stoplight/SM stopover/MS stoppable/U stoppage/MS Stoppard/M stopped/U stopper/GMDS stopping/M stopple/GDSM stop's stops/M stop/US stopwatch/SM storage/SM store/ADSRG storefront/SM storehouse/MS storekeeper/M storekeep/ZR storeroom/SM store's stork/SM stormbound stormer/M Stormie/M stormily Stormi/M storminess/S Storm/M storm/SRDMGZ stormtroopers Stormy/M stormy/PTR storyboard/MDSG storybook/MS story/GSDM storyline storyteller/SM storytelling/MS Stouffer/M stoup/SM stouten/DG stouthearted Stout/M stoutness/MS stout/STYRNP stove/DSRGM stovepipe/SM stover/M stowage/SM stowaway/MS Stowe/M stow/GDS Strabo/M straddler/M straddle/ZDRSG Stradivari/SM Stradivarius/M strafe/GRSD strafer/M straggle/GDRSZ straggly/RT straightaway/S straightedge/MS straightener/M straighten/ZGDR straightforwardness/MS straightforward/SYP straightjacket's straightness/MS straight/RNDYSTXGP straightway/S strain/ASGZDR strained/UF strainer/MA straining/F strains/F straiten/DG straitjacket/GDMS straitlaced straitness/M strait/XTPSMGYDNR stranded/P strand/SDRG strangeness/SM strange/PYZTR stranger/GMD stranglehold/MS strangle/JDRSZG strangles/M strangulate/NGSDX strangulation/M strapless/S strapped/U strapping/S strap's strap/US Strasbourg/M stratagem/SM strata/MS strategical/Y strategic/S strategics/M strategist/SM strategy/SM Stratford/M strati stratification/M stratified/U stratify/NSDGX stratigraphic stratigraphical stratigraphy/M stratosphere/SM stratospheric stratospherically stratum/M stratus/M Strauss Stravinsky/M strawberry/SM strawflower/SM straw/SMDG strayer/M stray/GSRDM streak/DRMSGZ streaker/M streaky/TR streamed/U streamer/M stream/GZSMDR streaming/M streamline/SRDGM streetcar/MS streetlight/SM street/SMZ streetwalker/MS streetwise Streisand/M strengthen/AGDS strengthener/MS strength/NMX strengths strenuousness/SM strenuous/PY strep/MS streptococcal streptococci streptococcus/M streptomycin/SM stress/DSMG stressed/U stressful/YP stretchability/M stretchable/U stretch/BDRSZG stretcher/DMG stretchy/TRP strew/GDHS strewn striae stria/M striate/DSXGN striated/U striation/M stricken Strickland/M strict/AF stricter strictest strictly strictness/S stricture/SM stridden stridency/S strident/Y strider/M stride/RSGM strife/SM strikebreaker/M strikebreaking/M strikebreak/ZGR strikeout/S striker/M strike/RSGZJ striking/Y Strindberg/M stringed stringency/S stringent/Y stringer/MS stringiness/SM stringing/M string's string/SAG stringy/RTP striper/M stripe/SM strip/GRDMS stripling/M stripped/U stripper/MS stripping stripteaser/M striptease/SRDGZM stripy/RT strive/JRSG striven striver/M strobe/SDGM stroboscope/SM stroboscopic strode stroke/ZRSDGM stroking/M stroller/M stroll/GZSDR Stromberg/M Stromboli/M Strom/M strongbow strongbox/MS Strongheart/M stronghold/SM strongish Strong/M strongman/M strongmen strongroom/MS strong/YRT strontium/SM strophe/MS strophic stropped stropping strop/SM strove struck structuralism/M structuralist/SM structural/Y structured/AU structureless structures/A structure/SRDMG structuring/A strudel/MS struggle/GDRS struggler/M strummed strumming strumpet/GSDM strum/S strung/UA strut/S strutted strutter/M strutting strychnine/MS Stuart/MS stubbed/M stubbing Stubblefield/MS stubble/SM stubbly/RT stubbornness/SM stubborn/SGTYRDP stubby/SRT stub/MS stuccoes stucco/GDM stuck/U studbook/SM studded studding/SM Studebaker/M studentship/MS student/SM studiedness/M studied/PY studier/SM studio/MS studiousness/SM studious/PY stud/MS study/AGDS stuffily stuffiness/SM stuffing/M stuff/JGSRD stuffy/TRP stultify/NXGSD Stu/M stumble/GZDSR stumbling/Y stumpage/M stumper/M stump/RDMSG stumpy/RT stung stunk stunned stunner/M stunning/Y stun/S stunted/P stunt/GSDM stupefaction/SM stupefy/DSG stupendousness/M stupendous/PY stupidity/SM stupidness/M stupid/PTYRS stupor/MS sturdily sturdiness/SM sturdy/SRPT sturgeon/SM Sturm/M stutter/DRSZG Stuttgart/M Stuyvesant/M sty/DSGM Stygian styled/A style/GZMDSR styles/A styli styling/A stylishness/S stylish/PY stylistically stylistic/S stylist/MS stylites stylization/MS stylize/DSG stylos stylus/SM stymieing stymie/SD stymy's styptic/S styrene/MS Styrofoam/S Styx/M suable Suarez/M suasion/EMS suaveness/S suave/PRYT suavity/SM subaltern/SM subarctic/S subareas Subaru/M subassembly/M subatomic/S subbasement/SM subbed subbing subbranch/S subcaste/M subcategorizing subcategory/SM subchain subclassifications subclass/MS subclauses subcommand/S subcommittee/SM subcompact/S subcomponent/MS subcomputation/MS subconcept subconsciousness/SM subconscious/PSY subconstituent subcontinental subcontinent/MS subcontractor/SM subcontract/SMDG subcultural subculture/GMDS subcutaneous/Y subdirectory/S subdistrict/M subdivide/SRDG subdivision/SM subdued/Y subdue/GRSD subduer/M subexpression/MS subfamily/SM subfield/MS subfile/SM subfreezing subgoal/SM subgraph subgraphs subgroup/SGM subharmonic/S subheading/M subhead/MGJS subhuman/S subindex/M subinterval/MS subj subject/GVDMS subjection/SM subjectiveness/M subjective/PSY subjectivist/S subjectivity/SM subjoin/DSG subjugate/NGXSD subjugation/M subjunctive/S sublayer sublease/DSMG sublet/S subletting sublimate/GNSDX sublimation/M sublime/GRSDTYP sublimeness/M sublimer/M subliminal/Y sublimity/SM sublist/SM subliterary sublunary submachine submarginal submarine/MZGSRD submariner/M submerge/DSG submergence/SM submerse/XNGDS submersible/S submersion/M submicroscopic submission/SAM submissiveness/MS submissive/PY submit/SA submittable submittal submitted/A submitter/S submitting/A submode/S submodule/MS sub/MS subnational subnet/SM subnetwork/SM subnormal/SY suboptimal suborbital suborder/MS subordinately/I subordinates/I subordinate/YVNGXPSD subordination/IMS subordinator subornation/SM suborn/GSD subpage subparagraph/M subpart/MS subplot/MS subpoena/GSDM subpopulation/MS subproblem/SM subprocess/SM subprofessional/S subprogram/SM subproject subproof/SM subquestion/MS subrange/SM subregional/Y subregion/MS subrogation/M subroutine/SM subsample/MS subschema/MS subscribe/ASDG subscriber/SM subscripted/U subscription/MS subscript/SGD subsection/SM subsegment/SM subsentence subsequence/MS subsequent/SYP subservience/SM subservient/SY subset/MS subsidence/MS subside/SDG subsidiarity subsidiary/MS subsidization/MS subsidized/U subsidizer/M subsidize/ZRSDG subsidy/MS subsistence/MS subsistent subsist/SGD subsocietal subsoil/DRMSG subsonic subspace/MS subspecies/M substance/MS substandard substantially/IU substantialness/M substantial/PYS substantiated/U substantiate/VGNSDX substantiation/MFS substantiveness/M substantive/PSYM substantivity substation/MS substerilization substitutability substituted/U substitute/NGVBXDRS substitutionary substitution/M substitutive/Y substrata substrate/MS substratum/M substring/S substructure/SM subsume/SDG subsurface/S subsystem/MS subtable/S subtask/SM subteen/SM subtenancy/MS subtenant/SM subtend/DS subterfuge/SM subterranean/SY subtest subtext/SM subtitle/DSMG subtleness/M subtle/RPT subtlety/MS subtly/U subtopic/SM subtotal/GSDM subtracter/M subtraction/MS subtract/SRDZVG subtrahend/SM subtree/SM subtropical subtropic/S subtype/MS subunit/SM suburbanite/MS suburbanization/MS suburbanized suburbanizing suburban/S suburbia/SM suburb/MS subvention/MS subversion/SM subversiveness/MS subversive/SPY subverter/M subvert/SGDR subway/MDGS subzero succeeder/M succeed/GDRS successfulness/M successful/UY succession/SM successiveness/M successive/YP success/MSV successor/MS successorship succinctness/SM succinct/RYPT succored/U succorer/M succor/SGZRDM succotash/SM succubus/M succulence/SM succulency/MS succulent/S succumb/SDG such suchlike sucker/DMG suck/GZSDRB suckle/SDJG suckling/M Sucre/M sucrose/MS suction/SMGD Sudanese/M Sudanic/M Sudan/M suddenness/SM sudden/YPS Sudetenland/M sud/S suds/DSRG sudsy/TR sued/DG suede/SM Suellen/M Sue/M suer/M suet/MS Suetonius/M suety sue/ZGDRS Suez/M sufferance/SM sufferer/M suffering/M suffer/SJRDGZ suffice/GRSD sufficiency/SIM sufficient/IY suffixation/S suffixed/U suffix/GMRSD suffocate/XSDVGN suffocating/Y Suffolk/M suffragan/S suffrage/MS suffragette/MS suffragist/SM suffuse/VNGSDX suffusion/M Sufi/M Sufism/M sugarcane/S sugarcoat/GDS sugarless sugarplum/MS sugar/SJGMD sugary/TR suggest/DRZGVS suggester/M suggestibility/SM suggestible suggestion/MS suggestiveness/MS suggestive/PY sugillate Suharto/M suicidal/Y suicide/GSDM Sui/M suitability/SU suitableness/S suitable/P suitably/U suitcase/MS suited/U suite/SM suiting/M suit/MDGZBJS suitor/SM Sukarno/M Sukey/M Suki/M sukiyaki/SM Sukkoth's Sukkot/S Sula/M Sulawesi/M Suleiman/M sulfaquinoxaline sulfa/S sulfate/MSDG sulfide/S sulfite/M sulfonamide/SM sulfur/DMSG sulfuric sulfurousness/M sulfurous/YP sulk/GDS sulkily sulkiness/S sulky/RSPT Sulla/M sullenness/MS sullen/TYRP sullied/U Sullivan/M sully/GSD Sully/M sulphate/SM sulphide/MS sulphuric sultana/SM sultanate/MS sultan/SM sultrily sultriness/SM sultry/PRT Sulzberger/M sumach's sumac/SM Sumatra/M Sumatran/S sumer/F Sumeria/M Sumerian/M summability/M summable summand/MS summarily summarization/MS summarized/U summarize/GSRDZ summarizer/M summary/MS summation/FMS summed Summerdale/M summerhouse/MS summer/SGDM Summer/SM summertime/MS summery/TR summing summit/GMDS summitry/MS summoner/M summon/JSRDGZ summons/MSDG sum/MRS Sumner/M sumo/SM sump/SM sumptuousness/SM sumptuous/PY Sumter/M Sun sunbaked sunbathe sunbather/M sunbathing/M sunbaths sunbath/ZRSDG sunbeam/MS Sunbelt/M sunblock/S sunbonnet/MS sunburn/GSMD sunburst/MS suncream sundae/MS Sundanese/M Sundas Sunday/MS sunder/SDG sundial/MS sundowner/M sundown/MRDSZG sundris sundry/S sunfish/SM sunflower/MS sunglass/MS Sung/M sung/U sunk/SN sunlamp/S sunless sunlight/MS sunlit sun/MS sunned Sunni/MS sunniness/SM sunning Sunnite/SM Sunny/M sunny/RSTP Sunnyvale/M sunrise/GMS sunroof/S sunscreen/S sunset/MS sunsetting sunshade/MS Sunshine/M sunshine/MS sunshiny sunspot/SM sunstroke/MS suntanned suntanning suntan/SM sunup/MS superabundance/MS superabundant superannuate/GNXSD superannuation/M superbness/M superb/YRPT supercargoes supercargo/M supercharger/M supercharge/SRDZG superciliousness/SM supercilious/PY supercity/S superclass/M supercomputer/MS supercomputing superconcept superconducting superconductivity/SM superconductor/SM supercooled supercooling supercritical superdense super/DG superego/SM supererogation/MS supererogatory superficiality/S superficial/SPY superfine superfix/M superfluity/MS superfluousness/S superfluous/YP superheat/D superheroes superhero/SM superhighway/MS superhumanness/M superhuman/YP superimpose/SDG superimposition/MS superintendence/S superintendency/SM superintendent/SM superintend/GSD superiority/MS Superior/M superior/SMY superlativeness/M superlative/PYS superlunary supermachine superman/M Superman/M supermarket/SM supermen supermodel supermom/S supernal supernatant supernaturalism/M supernaturalness/M supernatural/SPY supernormal/Y supernovae supernova/MS supernumerary/S superordinate superpose/BSDG superposition/MS superpower/MS superpredicate supersaturate/XNGDS supersaturation/M superscribe/GSD superscript/DGS superscription/SM superseder/M supersede/SRDG supersensitiveness/M supersensitive/P superset/MS supersonically supersonic/S supersonics/M superstar/SM superstition/SM superstitious/YP superstore/S superstructural superstructure/SM supertanker/SM supertitle/MSDG superuser/MS supervene/GSD supervention/S supervised/U supervise/SDGNX supervision/M supervisor/SM supervisory superwoman/M superwomen supineness/M supine/PSY supper/DMG supplanter/M supplant/SGRD supplemental/S supplementary/S supplementation/S supplementer/M supplement/SMDRG suppleness/SM supple/SPLY suppliant/S supplicant/MS supplicate/NGXSD supplication/M supplier/AM suppl/RDGT supply/MAZGSRD supportability/M supportable/UI supported/U supporter/M supporting/Y supportive/Y support/ZGVSBDR supposed/Y suppose/SRDBJG supposition/MS suppository/MS suppressant/S suppressed/U suppressible/I suppression/SM suppressive/P suppressor/S suppress/VGSD suppurate/NGXSD suppuration/M supp/YDRGZ supra supranational supranationalism/M suprasegmental supremacist/SM supremacy/SM supremal supremeness/M supreme/PSRTY supremo/M sup/RSZ supt Supt/M Surabaya/M Surat/M surcease/DSMG surcharge/MGSD surcingle/MGSD surd/M sured/I surefire surefooted surely sureness/MS sureness's/U sure/PU surer/I surest surety/SM surfaced/UA surface/GSRDPZM surfacer/AMS surfaces/A surfacing/A surfactant/SM surfboard/MDSG surfeit/SDRMG surfer/M surfing/M surf/SJDRGMZ surged/A surge/GYMDS surgeon/MS surgery/MS surges/A surgical/Y Suriname Surinamese Surinam's surliness/SM surly/TPR surmiser/M surmise/SRDG surmountable/IU surmount/DBSG surname/GSDM surpassed/U surpass/GDS surpassing/Y surplice/SM surplus/MS surplussed surplussing surprised/U surprise/MGDRSJ surpriser/M surprising/YU surrealism/MS surrealistic surrealistically surrealist/S surreality surreal/S surrender/DRSG surrenderer/M surreptitiousness/S surreptitious/PY surrey/SM surrogacy/S surrogate/SDMNG surrogation/M surrounding/M surround/JGSD surtax/SDGM surveillance/SM surveillant surveyed/A surveying/M survey/JDSG surveyor/MS surveys/A survivability/M survivable/U survivalist/S survival/MS survive/SRDBG survivor/MS survivorship/M Surya/M Sus Susana/M Susanetta/M Susan/M Susannah/M Susanna/M Susanne/M Susann/M susceptibilities susceptibility/IM susceptible/I Susette/M sushi/SM Susie/M Susi/M suspected/U suspecter/M suspect/GSDR suspecting/U suspend/DRZGS suspended/UA suspender/M suspenseful suspense/MXNVS suspension/AM suspensive/Y suspensor/M suspicion/GSMD suspiciousness/M suspicious/YP Susquehanna/M Sussex/M sustainability sustainable/U sustain/DRGLBS sustainer/M sustainment/M sustenance/MS Susy/M Sutherland/M Sutherlan/M sutler/MS Sutton/M suture/GMSD SUV Suva/M Suwanee/M Suzanna/M Suzanne/M Suzann/M suzerain/SM suzerainty/MS Suzette/M Suzhou/M Suzie/M Suzi/M Suzuki/M Suzy/M Svalbard/M svelte/RPTY Svend/M Svengali Sven/M Sverdlovsk/M Svetlana/M SW swabbed swabbing swabby/S Swabian/SM swab/MS swaddle/SDG swagged swagger/GSDR swagging swag/GMS Swahili/MS swain/SM SWAK swallower/M swallow/GDRS swallowtail/SM swam swami/SM swamper/M swampland/MS swamp/SRDMG swampy/RPT Swanee/M swankily swankiness/MS swank/RDSGT swanky/PTRS swanlike swan/MS swanned swanning Swansea/M Swanson/M swappable/U swapped swapper/SM swapping swap/S sward/MSGD swarmer/M swarm/GSRDM swarthiness/M Swarthmore/M swarthy/RTP swart/P Swartz/M swashbuckler/SM swashbuckling/S swash/GSRD swastika/SM SWAT swatch/MS swathe swather/M swaths swath/SRDMGJ swat/S swatted swatter/MDSG swatting swayback/SD sway/DRGS swayer/M Swaziland/M Swazi/SM swearer/M swear/SGZR swearword/SM sweatband/MS sweater/M sweatily sweatiness/M sweatpants sweat/SGZRM sweatshirt/S sweatshop/MS sweaty/TRP Swedenborg/M Sweden/M swede/SM Swede/SM Swedish Swed/MN Sweeney/SM sweeper/M sweepingness/M sweeping/PY sweep/SBRJGZ sweeps/M sweepstakes sweepstake's sweetbread/SM sweetbrier/SM sweetcorn sweetened/U sweetener/M sweetening/M sweeten/ZDRGJ sweetheart/MS sweetie/MS sweeting/M sweetish/Y Sweet/M sweetmeat/MS sweetness/MS sweetshop sweet/TXSYRNPG swellhead/DS swelling/M swell/SJRDGT swelter/DJGS sweltering/Y Swen/M Swenson/M swept sweptback swerve/GSD swerving/U swifter/M swift/GTYRDPS Swift/M swiftness/MS swigged swigging swig/SM swill/SDG swimmer/MS swimming/MYS swim/S swimsuit/MS Swinburne/M swindle/GZRSD swindler/M swineherd/MS swine/SM swingeing swinger/M swinging/Y swing/SGRZJB swingy/R swinishness/M swinish/PY Swink/M swipe/DSG swirling/Y swirl/SGRD swirly/TR swish/GSRD swishy/R swiss Swiss/S switchback/GDMS switchblade/SM switchboard/MS switcher/M switch/GBZMRSDJ switchgear switchman/M switchmen/M switchover/M Switzerland/M Switzer/M Switz/MR swivel/GMDS swizzle/RDGM swob's swollen swoon/GSRD swooning/Y swoop/RDSG swoosh/GSD swop's sword/DMSG swordfish/SM swordplayer/M swordplay/RMS swordsman/M swordsmanship/SM swordsmen swordtail/M swore sworn swot/S swum swung s/XJBG sybarite/MS sybaritic Sybila/M Sybilla/M Sybille/M Sybil/M Sybyl/M sycamore/SM sycophancy/S sycophantic sycophantically sycophant/SYM Sydelle/M Sydel/M Syd/M Sydney/M Sykes/M Sylas/M syllabicate/GNDSX syllabication/M syllabicity syllabic/S syllabification/M syllabify/GSDXN syllabi's syllable/SDMG syllabub/M syllabus/MS syllabusss syllogism/MS syllogistic Sylow/M sylphic sylphlike sylph/M sylphs Sylvania/M Sylvan/M sylvan/S Sylvester/M Sylvia/M Sylvie/M Syman/M symbiont/M symbioses symbiosis/M symbiotic symbol/GMDS symbolical/Y symbolics/M symbolic/SM symbolism/MS symbolist/MS symbolization/MAS symbolized/U symbolize/GZRSD symbolizes/A Symington/M symmetric symmetrically/U symmetricalness/M symmetrical/PY symmetrization/M symmetrizing symmetry/MS Symon/M sympathetically/U sympathetic/S sympathized/U sympathizer/M sympathize/SRDJGZ sympathizing/MYUS sympathy/MS symphonic symphonists symphony/MS symposium/MS symptomatic symptomatically symptomatology/M symptom/MS syn synagogal synagogue/SM synapse/SDGM synaptic synchronism/M synchronization's synchronization/SA synchronize/AGCDS synchronized/U synchronizer/MS synchronousness/M synchronous/YP synchrony synchrotron/M syncopate/VNGXSD syncopation/M syncope/MS sync/SGD syndicalist syndicate/XSDGNM syndic/SM syndrome/SM synergism/SM synergistic synergy/MS synfuel/S Synge/M synod/SM synonymic synonymous/Y synonym/SM synonymy/MS synopses synopsis/M synopsized synopsizes synopsizing synoptic/S syntactical/Y syntactics/M syntactic/SY syntax/MS syntheses synthesis/M synthesized/U synthesize/GZSRD synthesizer/M synthesizes/A synthetically synthetic/S syphilis/MS syphilitic/S syphilized syphilizing Syracuse/M Syriac/M Syria/M Syrian/SM syringe/GMSD syrup/DMSG syrupy sys systematical/Y systematics/M systematic/SP systematization/SM systematized/U systematizer/M systematize/ZDRSG systematizing/U systemically systemic/S systemization/SM system/MS systole/MS systolic Szilard/M Szymborska/M TA Tabasco/MS Tabatha/M Tabbatha/M tabbed Tabbie/M Tabbi/M tabbing Tabbitha/M Tabb/M tabbouleh tabboulehs tabby/GSD Tabby/M Taber/M Tabernacle/S tabernacle/SDGM Tabina/M Tabitha/M tabla/MS tableau/M tableaux tablecloth/M tablecloths table/GMSD tableland/SM tablespoonful/MS tablespoon/SM tablet/MDGS tabletop/MS tableware/SM tabling/M tabloid/MS Tab/MR taboo/GSMD Tabor/M tabor/MDGS Tabriz/SM tab/SM tabula tabular/Y tabulate/XNGDS tabulation/M tabulator/MS tachometer/SM tachometry tachycardia/MS tachyon/SM tacitness/MS taciturnity/MS taciturn/Y Tacitus/M tacit/YP tacker/M tack/GZRDMS tackiness/MS tackler/M tackle/RSDMZG tackling/M tacky/RSTP Tacoma/M taco/MS tact/FSM tactfulness/S tactful/YP tactical/Y tactician/MS tactic/SM tactile/Y tactility/S tactlessness/SM tactless/PY tactual/Y Taddeo/M Taddeusz/M Tadd/M Tadeas/M Tadeo/M Tades Tadio/M Tad/M tadpole/MS tad/SM Tadzhikistan's Tadzhikstan/M Taegu/M Taejon/M taffeta/MS taffrail/SM Taffy/M taffy/SM Taft/M Tagalog/SM tagged/U tagger/S tagging Tagore/M tag/SM Tagus/M Tahitian/S Tahiti/M Tahoe/M Taichung/M taiga/MS tailback/MS tail/CMRDGAS tailcoat/S tailer/AM tailgate/MGRSD tailgater/M tailing/MS taillessness/M tailless/P taillight/MS tailor/DMJSGB Tailor/M tailpipe/SM tailspin/MS tailwind/SM Tainan/M Taine/M taint/DGS tainted/U Taipei/M Taite/M Tait/M Taiwanese Taiwan/M Taiyuan/M Tajikistan takeaway/S taken/A takeoff/SM takeout/S takeover/SM taker/M take/RSHZGJ takes/IA taking/IA Taklamakan/M Talbert/M Talbot/M talcked talcking talc/SM talcum/S talebearer/SM talented/M talentless talent/SMD taler/M tale/RSMN tali Talia/M Taliesin/M talion/M talismanic talisman/SM talkativeness/MS talkative/YP talker/M talk/GZSRD talkie/M talky/RST Talladega/M Tallahassee/M Tallahatchie/M Tallahoosa/M tallboy/MS Tallchief/M Talley/M Talleyrand/M Tallia/M Tallie/M Tallinn/M tallish tallness/MS Tallou/M tallow/DMSG tallowy tall/TPR Tallulah/M tally/GRSDZ tallyho/DMSG Tally/M Talmudic Talmudist/MS Talmud/MS talon/SMD talus/MS Talyah/M Talya/M Ta/M tamable/M tamale/SM tamarack/SM Tamarah/M Tamara/M tamarind/MS Tamar/M Tamarra/M Tamas tambourine/MS tamed/U Tameka/M tameness/S Tamera/M Tamerlane/M tame/SYP Tamika/M Tamiko/M Tamil/MS Tami/M Tam/M Tamma/M Tammany/M Tammara/M tam/MDRSTZGB Tammie/M Tammi/M Tammy/M Tampa/M Tampax/M tampered/U tamperer/M tamper/ZGRD tampon/DMSG tamp/SGZRD Tamqrah/M Tamra/M tanager/MS Tanaka/M Tana/M Tananarive/M tanbark/SM Tancred/M tandem/SM Tandie/M Tandi/M tandoori/S Tandy/M Taney/M T'ang Tanganyika/M tangelo/SM tangency/M tangential/Y tangent/SM tangerine/MS tang/GSYDM tangibility/MIS tangible/IPS tangibleness's/I tangibleness/SM tangibly/I Tangier/M tangle's tangle/UDSG tango/MDSG Tangshan/M tangy/RST Tanhya/M Tania/M Tani/M Tanisha/M Tanitansy/M tankard/MS tanker/M tankful/MS tank/GZSRDM Tan/M tan/MS tanned/U Tannenbaum/M Tanner/M tanner/SM tannery/MS tannest Tanney/M Tannhuser/M Tannie/M tanning/SM tannin/SM Tann/RM Tanny/M Tansy/M tansy/SM tantalization/SM tantalized/U tantalize/GZSRD tantalizingly/S tantalizingness/S tantalizing/YP tantalum/MS Tantalus/M tantamount tantra/S tantrum/SM Tanya/M Tanzania/M Tanzanian/S taoism Taoism/MS Taoist/MS taoist/S Tao/M tao/S Tapdance/M taped/U tapeline/S taperer/M taper/GRD tape/SM tapestry/GMSD tapeworm/MS tapioca/MS tapir/MS tap/MSDRJZG tapped/U tapper/MS tappet/MS tapping/M taproom/MS taproot/SM taps/M Tarah/M Tara/M tarantella/MS tarantula/MS Tarawa/M Tarazed/M Tarbell/M tardily tardiness/S tardy/TPRS tare/MS target/GSMD tar/GSMD tariff/DMSG Tarim/M Tarkington/M tarmacked tarmacking tarmac/S tarnished/U tarnish/GDS tarn/MS taro/MS tarot/MS tarpapered tarpaulin/MS tarp/MS tarpon/MS tarragon/SM Tarrah/M Tarra/M Tarrance/M tarred/M tarring/M tarry/TGRSD Tarrytown/M tarsal/S tarsi tarsus/M tartan/MS tartaric Tartar's tartar/SM Tartary/M tartness/MS tart/PMYRDGTS Tartuffe/M Taryn/M Tarzan/M Tasha/M Tashkent/M Tasia/M task/GSDM taskmaster/SM taskmistress/MS Tasmania/M Tasmanian/S tassellings tassel/MDGS Tass/M tasted/EU tastefulness/SME tasteful/PEY taste/GZMJSRD tastelessness/SM tasteless/YP taster/M taste's/E tastes/E tastily tastiness/MS tasting/E tasty/RTP tatami/MS Tatar/SM Tate/M tater/M Tatiana/M Tatiania/M tat/SRZ tatted tatterdemalion/SM tattered/M tatter/GDS tatting/SM tattler/M tattle/RSDZG tattletale/SM tattooer/M tattooist/MS tattoo/ZRDMGS tatty/R Tatum/M taught/AU taunter/M taunting/Y taunt/ZGRDS taupe/SM Taurus/SM tau/SM tauten/GD tautness/S tautological/Y tautologous tautology/SM taut/PGTXYRDNS taverner/M tavern/RMS tawdrily tawdriness/SM tawdry/SRTP Tawney/M Tawnya/M tawny/RSMPT Tawsha/M taxable/S taxably taxation/MS taxed/U taxicab/MS taxidermist/SM taxidermy/MS taxi/MDGS taximeter/SM taxing/Y taxiway/MS taxonomic taxonomically taxonomist/SM taxonomy/SM taxpayer/MS taxpaying/M tax/ZGJMDRSB Taylor/SM Tb TB TBA Tbilisi/M tbs tbsp Tchaikovsky/M Tc/M TCP TD TDD Te teabag/S teacake/MS teacart/M teachable/P teach/AGS teacher/MS teaching/SM teacloth teacupful/MS teacup/MS Teador/M teahouse/SM teakettle/SM teak/SM teakwood/M tealeaves teal/MS tea/MDGS teammate/MS team/MRDGS teamster/MS teamwork/SM teapot/MS tearaway teardrop/MS tearer/M tearfulness/M tearful/YP teargas/S teargassed teargassing tearjerker/S tearoom/MS tear/RDMSG teary/RT Teasdale/M tease/KS teasel/DGSM teaser/M teashop/SM teasing/Y teaspoonful/MS teaspoon/MS teas/SRDGZ teatime/MS teat/MDS tech/D technetium/SM technicality/MS technicalness/M technical/YSP technician/MS Technicolor/MS Technion/M technique/SM technocracy/MS technocratic technocrat/S technological/Y technologist/MS technology/MS technophobia technophobic techs tectonically tectonic/S tectonics/M Tecumseh/M Tedda/M Teddie/M Teddi/M Tedd/M Teddy/M teddy/SM Tedie/M Tedi/M tediousness/SM tedious/YP tedium/MS Ted/M Tedman/M Tedmund/M Tedra/M tee/DRSMH teeing teem/GSD teemingness/M teeming/PY teenager/M teenage/RZ Teena/M teen/SR teenybopper/SM teeny/RT teepee's teeshirt/S teeter/GDS teethe teether/M teething/M teethmarks teeth/RSDJMG teetotaler/M teetotalism/MS teetotal/SRDGZ TEFL Teflon/MS Tegucigalpa/M Teheran's Tehran TEirtza/M tektite/SM Tektronix/M telecast/SRGZ telecommunicate/NX telecommunication/M telecommute/SRDZGJ telecoms teleconference/GMJSD Teledyne/M Telefunken/M telegenic telegrammed telegramming telegram/MS telegraphic telegraphically telegraphist/MS telegraph/MRDGZ telegraphs telegraphy/MS telekineses telekinesis/M telekinetic Telemachus/M Telemann/M telemarketer/S telemarketing/S telemeter/DMSG telemetric telemetry/MS teleological/Y teleology/M telepathic telepathically telepathy/SM telephone/SRDGMZ telephonic telephonist/SM telephony/MS telephotography/MS telephoto/S teleprinter/MS teleprocessing/S teleprompter TelePrompter/M TelePrompTer/S telescope/GSDM telescopic telescopically teletext/S telethon/MS teletype/SM Teletype/SM teletypewriter/SM televangelism/S televangelist/S televise/SDXNG television/M televisor/MS televisual telex/GSDM Telex/M tell/AGS Teller/M teller/SDMG telling/YS Tell/MR telltale/MS tellurium/SM telly/SM Telnet/M TELNET/M telnet/S telomeric tel/SY Telugu/M temblor/SM temerity/MS Tempe/M temperamental/Y temperament/SM temperance/IMS tempera/SLM temperately/I temperateness's/I temperateness/SM temperate/SDGPY temperature/MS tempered/UE temper/GRDM tempering/E temper's/E tempers/E tempest/DMSG tempestuousness/SM tempestuous/PY template/FS template's Temple/M Templeman/M temple/SDM Templeton/M Temp/M tempoes tempo/MS temporal/YS temporarily temporarinesses temporariness/FM temporary/SFP temporize/GJZRSD temporizer/M temporizings/U temporizing/YM temp/SGZTMRD temptation/MS tempted tempter/S tempt/FS tempting/YS temptress/MS tempura/SM tenabilities tenability/UM tenableness/M tenable/P tenably tenaciousness/S tenacious/YP tenacity/S tenancy/MS tenanted/U tenant/MDSG tenantry/MS tench/M tended/UE tendency/MS tendentiousness/SM tendentious/PY tendered tenderer tenderest tenderfoot/MS tender/FS tenderheartedness/MS tenderhearted/YP tendering tenderizer/M tenderize/SRDGZ tenderloin/SM tenderly tenderness/SM tending/E tendinitis/S tend/ISFRDG tendon/MS tendril/SM tends/E tenebrous tenement/MS tenet/SM Tenex/M TENEX/M tenfold/S ten/MHB Tenneco/M tenner Tennessean/S Tennessee/M Tenney/M tennis/SM Tenn/M Tennyson/M Tenochtitlan/M tenon/GSMD tenor/MS tenpin/SM tense/IPYTNVR tenseness's/I tenseness/SM tensile tensional/I tension/GMRDS tensionless tensions/E tension's/I tensity/IMS tensorial tensor/MS tenspot tens/SRDVGT tentacle/MSD tentativeness/S tentative/SPY tented/UF tenterhook/MS tenter/M tent/FSIM tenths tenth/SY tenting/F tenuity/S tenuousness/SM tenuous/YP tenure/SDM Teodoor/M Teodora/M Teodorico/M Teodor/M Teodoro/M tepee/MS tepidity/S tepidness/S tepid/YP tequila/SM Tera/M teratogenic teratology/MS terbium/SM tercel/M tercentenary/S tercentennial/S Terence/M Terencio/M Teresa/M Terese/M Tereshkova/M Teresina/M Teresita/M Teressa/M Teriann/M Teri/M Terkel/M termagant/SM termcap termer/M terminable/CPI terminableness/IMC terminal/SYM terminate/CXNV terminated/U terminates terminating termination/MC terminative/YC terminator/SM termini terminological/Y terminology/MS terminus/M termite/SM term/MYRDGS ternary/S tern/GIDS tern's terpsichorean Terpsichore/M terrace/MGSD terracing/M terracotta terrain/MS Terra/M terramycin Terrance/M Terran/M terrapin/MS terrarium/MS terrazzo/SM Terrell/M Terrel/M Terre/M Terrence/M terrestrial/YMS terribleness/SM terrible/P terribly Terrie/M terrier/M terrifically terrific/Y terrify/GDS terrifying/Y Terrijo/M Terrill/M Terri/M terrine/M territoriality/M Territorial/SM territorial/SY Territory's territory/SM terrorism/MS terroristic terrorist/MS terrorized/U terrorizer/M terrorize/RSDZG terror/MS terr/S terrycloth Terrye/M Terry/M terry/ZMRS terseness/SM terse/RTYP Tersina/M tertian Tertiary tertiary/S Terza/M TESL Tesla/M TESOL Tessa/M tessellate/XDSNG tessellation/M tesseral Tessie/M Tessi/M Tess/M Tessy/M testability/M testable/U testamentary testament/SM testate/IS testator/MS testatrices testatrix testbed/S testcard tested/AKU tester/MFCKS testes/M testicle/SM testicular testifier/M testify/GZDRS testily testimonial/SM testimony/SM testiness/S testing/S testis/M testosterone/SM test/RDBFZGSC tests/AK test's/AKF testy/RTP tetanus/MS tetchy/TR tether/DMSG tethered/U Tethys/M Tetons tetrachloride/M tetracycline/SM tetrafluoride tetragonal/Y tetrahalides tetrahedral/Y tetrahedron/SM tetrameron tetrameter/SM tetra/MS tetrasodium tetravalent Teutonic Teuton/SM Texaco/M Texan/S Texas/MS Tex/M TeX/M textbook/SM text/FSM textile/SM Textron/M textual/FY textural/Y textured/U texture/MGSD T/G Thacher/M Thackeray/M Thaddeus/M Thaddus/M Thadeus/M Thad/M Thailand/M Thaine/M Thain/M Thai/S thalami thalamus/M Thales/M Thalia/M thalidomide/MS thallium/SM thallophyte/M Thames than Thane/M thane/SM Thanh/M thanker/M thankfuller thankfullest thankfulness/SM thankful/YP thanklessness/SM thankless/PY thanksgiving/MS Thanksgiving/S thank/SRDG Thant/M Thar/M Thatcher/M thatching/M thatch/JMDRSZG Thatch/MR that'd that'll that/MS thaumaturge/M thaw/DGS Thaxter/M Thayer/M Thayne/M THC the Theadora/M Thea/M theatergoer/MS theatergoing/MS theater/SM theatricality/SM theatrical/YS theatric/S theatrics/M Thebault/M Thebes Theda/M Thedrick/M Thedric/M thee/DS theeing theft/MS Theiler/M their/MS theism/SM theistic theist/SM Thekla/M Thelma/M themas thematically thematics thematic/U theme/MS them/GD Themistocles/M themselves thence thenceforth thenceforward/S Theobald/M theocracy/SM theocratic Theocritus/M theodolite/MS Theodora/M Theodore/M Theodoric/M Theodor/M Theodosia/M Theodosian Theodosius/M theologian/SM theological/Y theologists theology/MS Theo/M theorem/MS theoretical/Y theoretician/MS theoretic/S theoretics/M theorist/SM theorization/SM theorize/ZGDRS theory/MS theosophic theosophical theosophist/MS Theosophy theosophy/SM therapeutically therapeutic/S therapeutics/M therapist/MS therapy/MS Theravada/M thereabout/S thereafter thereat thereby there'd therefor therefore therefrom therein there'll there/MS thereof thereon Theresa/M Therese/M Theresina/M Theresita/M Theressa/M thereto theretofore thereunder thereunto thereupon therewith Therine/M thermal/YS thermionic/S thermionics/M thermistor/MS therm/MS thermocouple/MS thermodynamical/Y thermodynamic/S thermodynamics/M thermoelastic thermoelectric thermoformed thermoforming thermogravimetric thermoluminescence/M thermometer/MS thermometric thermometry/M thermonuclear thermopile/M thermoplastic/S thermopower thermo/S thermosetting thermos/S Thermos/SM thermostable thermostatically thermostatic/S thermostatics/M thermostat/SM thermostatted thermostatting Theron/M thesauri thesaurus/MS these/S Theseus/M thesis/M thespian/S Thespian/S Thespis/M Thessalonian Thessalonki/M Thessaly/M theta/MS thew/SM they they'd they'll they're they've th/GNJX Thia/M thiamine/MS Thibaud/M Thibaut/M thickener/M thickening/M thicken/RDJZG thicket/SMD thickheaded/M thickish thickness/MS thickset/S thick/TXPSRNY thief/M Thiensville/M Thieu/M thievery/MS thieve/SDJG thievishness/M thievish/P thighbone/SM thigh/DM thighs thimble/DSMG thimbleful/MS Thimbu/M Thimphu thine thingamabob/MS thingamajig/SM thing/MP thinkableness/M thinkable/U thinkably/U think/AGRS thinker/MS thinkingly/U thinking/SMYP thinned thinner/MS thinness/MS thinnest thinning thinnish thin/STPYR thiocyanate/M thiouracil/M third/DYGS thirster/M thirst/GSMDR thirstily thirstiness/S thirsty/TPR thirteen/MHS thirteenths thirtieths thirty/HMS this this'll thistledown/MS thistle/SM thither Th/M tho thole/GMSD Thomasa/M Thomasina/M Thomasine/M Thomasin/M Thoma/SM Thomism/M Thomistic Thom/M Thompson/M Thomson/M thong/SMD thoracic thorax/MS Thorazine Thoreau/M thoriate/D Thorin/M thorium/MS Thor/M Thornburg/M Thorndike/M Thornie/M thorniness/S Thorn/M thorn/SMDG Thornton/M Thorny/M thorny/PTR thoroughbred/S thoroughfare/MS thoroughgoing thoroughness/SM thorough/PTYR Thorpe/M Thorstein/M Thorsten/M Thorvald/M those Thoth/M thou/DSG though thoughtfully thoughtfulness/S thoughtful/U thoughtlessness/MS thoughtless/YP thought/MS thousandfold thousand/SHM thousandths Thrace/M Thracian/M thralldom/S thrall/GSMD thrash/DSRZGJ thrasher/M thrashing/M threadbare/P threader/M threading/A threadlike thread/MZDRGS thready/RT threatener/M threaten/GJRD threatening/Y threat/MDNSXG threefold three/MS threepence/M threepenny threescore/S threesome/SM threnody/SM thresh/DSRZG thresher/M threshold/MDGS threw thrice thriftily thriftiness/S thriftless thrift/SM thrifty/PTR thriller/M thrilling/Y thrill/ZMGDRS thriver/M thrive/RSDJG thriving/Y throatily throatiness/MS throat/MDSG throaty/PRT throbbed throbbing throb/S throeing throe/SDM thrombi thromboses thrombosis/M thrombotic thrombus/M Throneberry/M throne/CGSD throne's throng/GDSM throttle/DRSZMG throttler/M throughout throughput/SM throughway's through/Y throwaway/SM throwback/MS thrower/M thrown throwout throw/SZGR thrummed thrumming thrum/S thrush/MS thruster/M thrust/ZGSR Thruway/MS thruway/SM Thunderbird/M Thu Thucydides/M thudded thudding thud/MS thuggee/M thuggery/SM thuggish thug/MS Thule/M thulium/SM thumbnail/MS thumbscrew/SM thumb/SMDG thumbtack/GMDS thump/RDMSG thunderbolt/MS thunderclap/SM thundercloud/SM thunderer/M thunderhead/SM thundering/Y thunderous/Y thundershower/MS thunderstorm/MS thunderstruck thundery thunder/ZGJDRMS thunk Thurber/M Thurman/M Thur/MS Thursday/SM Thurstan/M Thurston/M thus/Y thwack/DRSZG thwacker/M thwarter/M thwart/GSDRY thy thyme/SM thymine/MS thymus/SM thyratron/M thyristor/MS thyroglobulin thyroidal thyroid/S thyronine thyrotoxic thyrotrophic thyrotrophin thyrotropic thyrotropin/M thyroxine/M thyself Tia/M Tianjin tiara/MS Tiberius/M Tiber/M Tibetan/S Tibet/M tibiae tibial tibia/M Tibold/M Tiburon/M ticker/M ticket/SGMD tick/GZJRDMS ticking/M tickler/M tickle/RSDZG ticklishness/MS ticklish/PY ticktacktoe/S ticktock/SMDG tic/MS Ticonderoga/M tidal/Y tidbit/MS tiddlywinks/M tide/GJDS tideland/MS tidewater/SM tideway/SM tidily/U tidiness/USM tidying/M tidy/UGDSRPT tie/AUDS tieback/MS Tiebold/M Tiebout/M tiebreaker/SM Tieck/M Tiena/M Tienanmen/M Tientsin's tier/DGM Tierney/M Tiertza/M Tiffanie/M Tiffani/M tiffany/M Tiffany/M tiff/GDMS Tiffie/M Tiffi/M Tiff/M Tiffy/M tigerish tiger/SM tightener/M tighten/JZGDR tightfisted tightness/MS tightrope/SM tight/STXPRNY tightwad/MS tigress/SM Tigris/M Tijuana/M tike's Tilda/M tilde/MS Tildie/M Tildi/M Tildy/M tile/DRSJMZG tiled/UE Tiler/M tiles/U tiling/M tillable tillage/SM till/EGSZDR tiller/GDM tiller's/E Tillich/M Tillie/M Tillman/M Tilly/M tilth/M tilt/RDSGZ Ti/M timber/DMSG timbering/M timberland/SM timberline/S timbrel/SM timbre/MS Timbuktu/M ti/MDRZ timebase time/DRSJMYZG timekeeper/MS timekeeping/SM timelessness/S timeless/PY timeliness/SMU timely/UTRP timeout/S timepiece/MS timer/M timescale/S timeserver/MS timeserving/S timeshare/SDG timespan timestamped timestamps timetable/GMSD timeworn Timex/M timezone/S timidity/SM timidness/MS timid/RYTP Timi/M timing/M Timmie/M Timmi/M Tim/MS Timmy/M Timofei/M Timon/M timorousness/MS timorous/YP Timoteo/M Timothea/M Timothee/M Timotheus/M Timothy/M timothy/MS timpani timpanist/S Timur/M Tina/M tincture/SDMG tinderbox/MS tinder/MS Tine/M tine/SM tinfoil/MS tingeing tinge/S ting/GYDM tingle/SDG tingling/Y tingly/TR Ting/M tinily tininess/MS tinker/SRDMZG Tinkertoy tinkle/SDG tinkling/M tinkly tin/MDGS tinned tinner/M tinnily tinniness/SM tinning/M tinnitus/MS tinny/RSTP tinplate/S tinsel/GMDYS Tinseltown/M tinsmith/M tinsmiths tinter/M tintinnabulation/MS Tintoretto/M tint/SGMRDB tintype/SM tinware/MS tiny/RPT Tioga/M Tiphanie/M Tiphani/M Tiphany/M tipi's tip/MS tipoff Tippecanoe/M tipped Tipperary/M tipper/MS tippet/MS tipping tippler/M tipple/ZGRSD tippy/R tipsily tipsiness/SM tipster/SM tipsy/TPR tiptoeing tiptoe/SD tiptop/S tirade/SM Tirana's Tirane tired/AYP tireder tiredest tiredness/S tirelessness/SM tireless/PY tire/MGDSJ tires/A Tiresias/M tiresomeness/S tiresome/PY tiring/AU Tirolean/S Tirol/M tiro's Tirrell/M tis Tisha/M Tish/M tissue/MGSD titanate/M Titania/M titanic titanically Titanic/M titanium/SM titan/SM Titan/SM titbit's titer/M tither/M tithe/SRDGZM tithing/M Titian/M titian/S Titicaca/M titillate/XSDVNG titillating/Y titillation/M titivate/NGDSX titivation/M titled/AU title/GMSRD titleholder/SM titling/A titmice titmouse/M tit/MRZS Tito/SM titrate/SDGN titration/M titted titter/GDS titting tittle/SDMG titular/SY Titus/M tizzy/SM TKO Tlaloc/M TLC Tlingit/M Tl/M TM Tm/M tn TN tnpk TNT toad/SM toadstool/SM toady/GSDM toadyism/M toaster/M toastmaster/MS toastmistress/S toast/SZGRDM toasty/TRS tobacconist/SM tobacco/SM tobaggon/SM Tobago/M Tobe/M Tobey/M Tobiah/M Tobias/M Tobie/M Tobi/M Tobin/M Tobit/M toboggan/MRDSZG Tobye/M Toby/M Tocantins/M toccata/M Tocqueville tocsin/MS to/D today'll today/SM Toddie/M toddler/M toddle/ZGSRD Todd/M Toddy/M toddy/SM Tod/M toecap/SM toeclip/S TOEFL toehold/MS toeing toe/MS toenail/DMGS toffee/SM tofu/S toga/SMD toge togetherness/MS together/P togged togging toggle/SDMG Togolese/M Togo/M tog/SMG Toiboid/M toilet/GMDS toiletry/MS toilette/SM toil/SGZMRD toilsomeness/M toilsome/PY Toinette/M Tojo/M tokamak Tokay/M toke/GDS tokenism/SM tokenized token/SMDG Tokugawa/M Tokyoite/MS Tokyo/M Toland/M told/AU Toledo/SM tole/MGDS tolerability/IM tolerable/I tolerably/I tolerance/SIM tolerant/IY tolerate/XVNGSD toleration/M Tolkien tollbooth/M tollbooths toll/DGS Tolley/M tollgate/MS tollhouse/M tollway/S Tolstoy/M toluene/MS Tolyatti/M tomahawk/SGMD Tomasina/M Tomasine/M Toma/SM Tomaso/M tomatoes tomato/M Tombaugh/M tomb/GSDM Tombigbee/M tomblike tombola/M tomboyish tomboy/MS tombstone/MS tomcat/SM tomcatted tomcatting Tome/M tome/SM tomfoolery/MS tomfool/M Tomi/M Tomkin/M Tomlin/M Tom/M tommed Tommie/M Tommi/M tomming tommy/M Tommy/M tomographic tomography/MS tomorrow/MS Tompkins/M Tomsk/M tom/SM tomtit/SM tonality/MS tonal/Y tonearm/S tone/ISRDZG tonelessness/M toneless/YP toner/IM tone's Tonga/M Tongan/SM tong/GRDS tongueless tongue/SDMG tonguing/M Tonia/M tonic/SM Tonie/M tonight/MS Toni/M Tonio/M tonk/MS tonnage/SM tonne/MS Tonnie/M tonsillectomy/MS tonsillitis/SM tonsil/SM ton/SKM tonsorial tonsure/SDGM Tonto/M Tonya/M Tonye/M Tony/M tony/RT toodle too/H took/A tool/AGDS toolbox/SM tooler/SM tooling/M toolkit/SM toolmaker/M toolmake/ZRG toolmaking/M tool's toolsmith Toomey/M tooter/M toot/GRDZS toothache/SM toothbrush/MSG tooth/DMG toothily toothless toothmarks toothpaste/SM toothpick/MS tooths toothsome toothy/TR tootle/SRDG tootsie Tootsie/M toots/M tootsy/MS topaz/MS topcoat/MS topdressing/S Topeka/M toper/M topflight topgallant/M topiary/S topicality/MS topical/Y topic/MS topknot/MS topless topmast/MS topmost topnotch/R topocentric topographer/SM topographic topographical/Y topography/MS topological/Y topologist/MS topology/MS topped topper/MS topping/MS topple/GSD topsail/MS topside/SRM top/SMDRG topsoil/GDMS topspin/MS Topsy/M toque/MS Torah/M Torahs torchbearer/SM torchlight/S torch/SDMG toreador/SM Tore/M tore/S Torey/M Torie/M tori/M Tori/M Torin/M torment/GSD tormenting/Y tormentor/MS torn tornadoes tornado/M toroidal/Y toroid/MS Toronto/M torpedoes torpedo/GMD torpidity/S torpid/SY torpor/MS Torquemada/M torque/MZGSRD Torrance/M Torre/MS torrence Torrence/M Torrens/M torrential torrent/MS Torrey/M Torricelli/M torridity/SM torridness/SM torrid/RYTP Torrie/M Torrin/M Torr/XM Torry/M torsional/Y torsion/IAM torsions torsi's tor/SLM torso/SM tors/S tort/ASFE tortellini/MS torte/MS torten tortilla/MS tortoiseshell/SM tortoise/SM Tortola/M tortoni/MS tort's Tortuga/M tortuousness/MS tortuous/PY torture/ZGSRD torturous torus/MS Tory/SM Tosca/M Toscanini/M Toshiba/M toss/SRDGZ tossup/MS totaler/M totalistic totalitarianism/SM totalitarian/S totality/MS totalizator/S totalizing total/ZGSRDYM totemic totem/MS toter/M tote/S toting/M tot/MDRSG Toto/M totted totterer/M tottering/Y totter/ZGRDS totting toucan/MS touchable/U touch/ASDG touchdown/SM touch touched/U toucher/M touchily touchiness/SM touching/SY touchline/M touchscreen touchstone/SM touchy/TPR toughen/DRZG toughener/M toughness/SM toughs tough/TXGRDNYP Toulouse/M toupee/SM toured/CF tourer/M tour/GZSRDM touring/F tourism/SM touristic tourist/SM touristy tourmaline/SM tournament/MS tourney/GDMS tourniquet/MS tour's/CF tours/CF tousle/GSD touter/M tout/SGRD Tova/M Tove/M towardliness/M towardly/P towards toward/YU towboat/MS tow/DRSZG towelette/S towel/GJDMS toweling/M tower/GMD towering/Y towhead/MSD towhee/SM towline/MS towner/M Townes Towney/M townhouse/S Townie/M townie/S Townley/M Town/M Townsend/M townsfolk township/MS townsman/M townsmen townspeople/M town/SRM townswoman/M townswomen Towny/M towpath/M towpaths towrope/MS Towsley/M toxemia/MS toxicity/MS toxicological toxicologist/SM toxicology/MS toxic/S toxin/MS toyer/M toymaker toy/MDRSG Toynbee/M Toyoda/M Toyota/M toyshop tr traceability/M traceableness/M traceable/P trace/ASDG traceback/MS traced/U Tracee/M traceless/Y Trace/M tracepoint/SM tracer/MS tracery/MDS trace's Tracey/M tracheae tracheal/M trachea/M tracheotomy/SM Tracie/M Traci/M tracing/SM trackage trackball/S trackbed tracked/U tracker/M trackless tracksuit/SM track/SZGMRD tractability/SI tractable/I tractably/I tract/ABS Tractarians traction/KSCEMAF tractive/KFE tractor/FKMASC tract's tracts/CEFK Tracy/M trademark/GSMD trader/M tradesman/M tradesmen tradespeople tradespersons trade/SRDGZM tradeswoman/M tradeswomen traditionalism/MS traditionalistic traditionalist/MS traditionalized traditionally traditional/U tradition/SM traduce/DRSGZ Trafalgar/M trafficked trafficker/MS trafficking/S traffic/SM tragedian/SM tragedienne/MS tragedy/MS tragically tragicomedy/SM tragicomic tragic/S trailblazer/MS trailblazing/S trailer/GDM trails/F trailside trail/SZGJRD trainable train/ASDG trained/U trainee/MS traineeships trainer/MS training/SM trainman/M trainmen trainspotter/S traipse/DSG trait/MS traitorous/Y traitor/SM Trajan/M trajectory/MS trammed trammeled/U trammel/GSD tramming tram/MS trample/DGRSZ trampler/M trampoline/GMSD tramp/RDSZG tramway/M trance/MGSD tranche/SM Tran/M tranquility/S tranquilized/U tranquilize/JGZDSR tranquilizer/M tranquilizes/A tranquilizing/YM tranquillize/GRSDZ tranquillizer/M tranquilness/M tranquil/PTRY transact/GSD transactional transaction/MS transactor/SM transalpine transaminase transatlantic Transcaucasia/M transceiver/SM transcendence/MS transcendentalism/SM transcendentalist/SM transcendental/YS transcendent/Y transcend/SDG transconductance transcontinental transcribe/DSRGZ transcriber/M transcription/SM transcript/SM transcultural transducer/SM transduction/M transect/DSG transept/SM transferability/M transferal/MS transfer/BSMD transferee/M transference/SM transferor/MS transferral/SM transferred transferrer/SM transferring transfiguration/SM transfigure/SDG transfinite/Y transfix/SDG transformational transformation/MS transform/DRZBSG transformed/U transformer/M transfuse/XSDGNB transfusion/M transgression/SM transgressor/S transgress/VGSD trans/I transience/SM transiency/S transient/YS transistorize/GDS transistor/SM Transite/M transitional/Y transition/MDGS transitivenesses transitiveness/IM transitive/PIY transitivity/MS transitoriness/M transitory/P transit/SGVMD transl translatability/M translatable/U translated/AU translate/VGNXSDB translational translation/M translator/SM transliterate/XNGSD translucence/SM translucency/MS translucent/Y transmigrate/XNGSD transmissible transmission/MSA transmissive transmit/AS transmittable transmittal/SM transmittance/MS transmitted/A transmitter/SM transmitting/A transmogrification/M transmogrify/GXDSN transmutation/SM transmute/GBSD transnational/S transoceanic transom/SM transonic transpacific transparency/MS transparentness/M transparent/YP transpiration/SM transpire/GSD transplantation/S transplant/GRDBS transpolar transponder/MS transportability transportable/U transportation/SM transport/BGZSDR transpose/BGSD transposed/U transposition/SM Transputer/M transsexualism/MS transsexual/SM transship/LS transshipment/SM transshipped transshipping transubstantiation/MS Transvaal/M transversal/YM transverse/GYDS transvestism/SM transvestite/SM transvestitism Transylvania/M trapdoor/S trapeze/DSGM trapezium/MS trapezoidal trapezoid/MS trap/MS trappable/U trapped trapper/SM trapping/S Trappist/MS trapshooting/SM trashcan/SM trashiness/SM trash/SRDMG trashy/TRP Trastevere/M trauma/MS traumatic traumatically traumatize/SDG travail/SMDG traveled/U traveler/M travelog's travelogue/S travel/SDRGZJ Traver/MS traversal/SM traverse/GBDRS traverser/M travertine/M travesty/SDGM Travis/M Travus/M trawler/M trawl/RDMSZG tray/SM treacherousness/SM treacherous/PY treachery/SM treacle/DSGM treacly treader/M treadle/GDSM treadmill/MS tread/SAGD Treadwell/M treas treason/BMS treasonous treasure/DRSZMG treasurer/M treasurership treasury/SM Treasury/SM treatable treated/U treater/S treatise/MS treatment/MS treat's treat/SAGDR treaty/MS treble/SDG Treblinka/M treeing treeless treelike tree/MDS treetop/SM trefoil/SM Trefor/M trekked trekker/MS Trekkie/M trekking trek/MS trellis/GDSM Tremaine/M Tremain/M trematode/SM Tremayne/M tremble/JDRSG trembler/M trembles/M trembly tremendousness/M tremendous/YP tremolo/MS tremor/MS tremulousness/SM tremulous/YP trenchancy/MS trenchant/Y trencherman/M trenchermen trencher/SM trench/GASD trench's trendily trendiness/S trend/SDMG trendy/PTRS Trenna/M Trent/M Trenton/M trepanned trepidation/MS Tresa/M Trescha/M trespasser/M trespass/ZRSDG Tressa/M tressed/E tresses/E tressing/E tress/MSDG trestle/MS Trevar/M Trevelyan/M Trever/M Trevino/M Trevor/M Trev/RM Trey/M trey/MS triableness/M triable/P triadic triad/MS triage/SDMG trial/ASM trialization trialled trialling triamcinolone triangle/SM triangulable triangularization/S triangular/Y triangulate/YGNXSD triangulation/M Triangulum/M Trianon/M Triassic triathlon/S triatomic tribalism/MS tribal/Y tribe/MS tribesman/M tribesmen tribeswoman tribeswomen tribulate/NX tribulation/M tribunal/MS tribune/SM tributary/MS tribute/EGSF tribute's trice/GSDM tricentennial/S triceps/SM triceratops/M trichinae trichina/M trichinoses trichinosis/M trichloroacetic trichloroethane trichotomy/M trichromatic Tricia/M trickery/MS trick/GMSRD trickily trickiness/SM trickle/DSG trickster/MS tricky/RPT tricolor/SMD tricycle/SDMG trident/SM tridiagonal tried/UA triennial/SY trier/AS trier's tries/A Trieste/M triffid/S trifle/MZGJSRD trifler/M trifluoride/M trifocals trigged trigger/GSDM triggest trigging triglyceride/MS trigonal/Y trigonometric trigonometrical trigonometry/MS trigram/S trig/S trihedral trike/GMSD trilateral/S trilby/SM trilingual trillion/SMH trillionth/M trillionths trillium/SM trill/RDMGS trilobite/MS trilogy/MS trimaran/MS Trimble/M trimer/M trimester/MS trimmed/U trimmer/MS trimmest trimming/MS trimness/S trimodal trimonthly trim/PSYR Trimurti/M Trina/M Trinidad/M trinitarian/S trinitrotoluene/SM trinity/MS Trinity/MS trinketer/M trinket/MRDSG triode/MS trio/SM trioxide/M tripartite/N tripartition/M tripe/MS triphenylarsine triphenylphosphine triphenylstibine triphosphopyridine triple/GSD triplet/SM triplex/S triplicate/SDG triplication/M triply/GDSN Trip/M tripodal tripod/MS tripoli/M Tripoli/M tripolyphosphate tripos/SM tripped Trippe/M tripper/MS tripping/Y Tripp/M trip/SMY triptych/M triptychs tripwire/MS trireme/SM Tris trisect/GSD trisection/S trisector Trisha/M Trish/M trisodium Trista/M Tristam/M Tristan/M tristate trisyllable/M tritely/F triteness/SF trite/SRPTY tritium/MS triton/M Triton/M triumphal triumphalism triumphant/Y triumph/GMD triumphs triumvirate/MS triumvir/MS triune trivalent trivet/SM trivia triviality/MS trivialization/MS trivialize/DSG trivial/Y trivium/M Trixie/M Trixi/M Trix/M Trixy/M Trobriand/M trochaic/S trochee/SM trod/AU trodden/UA trodes troff/MR troglodyte/MS troika/SM Trojan/MS troll/DMSG trolled/F trolleybus/S trolley/SGMD trolling/F trollish Trollope/M trollop/GSMD trolly's trombone/MS trombonist/SM tromp/DSG Trondheim/M trooper/M troopship/SM troop/SRDMZG trope/SM Tropez/M trophic trophy/MGDS tropical/SY tropic/MS tropism/SM tropocollagen troposphere/MS tropospheric troth/GDM troths trot/S Trotsky/M trotted trotter/SM trotting troubadour/SM troubled/U trouble/GDRSM troublemaker/MS troubler/M troubleshooter/M troubleshoot/SRDZG troubleshot troublesomeness/M troublesome/YP trough/M troughs trounce/GZDRS trouncer/M troupe/MZGSRD trouper/M trouser/DMGS trousseau/M trousseaux Troutman/M trout/SM trove/SM troweler/M trowel/SMDRGZ trow/SGD Troyes Troy/M troy/S Trstram/M truancy/MS truant/SMDG truce/SDGM Truckee/M trucker/M trucking/M truckle/GDS truckload/MS truck/SZGMRDJ truculence/SM truculent/Y Truda/M Trudeau/M Trude/M Trudey/M trudge/SRDG Trudie/M Trudi/M Trudy/M true/DRSPTG truelove/MS Trueman/M trueness/M truer/U truest/U truffle/MS truism/SM Trujillo/M Trula/M truly/U Trumaine/M Truman/M Trumann/M Trumbull/M trump/DMSG trumpery/SM trumpeter/M trumpet/MDRZGS Trump/M truncate/NGDSX truncation/M truncheon/MDSG trundle/GZDSR trundler/M trunk/GSMD trunnion/SM trusser/M trussing/M truss/SRDG trusted/EU trusteeing trustee/MDS trusteeship/SM truster/M trustful/EY trustfulness/SM trustiness/M trusting/Y trust/RDMSG trusts/E trustworthier trustworthiest trustworthiness/MS trustworthy/UP trusty/PTMSR Truth truthfulness/US truthful/UYP truths/U truth/UM TRW trying/Y try/JGDRSZ tryout/MS trypsin/M tryst/GDMS ts T's tsarevich tsarina's tsarism/M tsarist tsetse/S Tsimshian/M Tsiolkovsky/M Tsitsihar/M tsp tsunami/MS Tsunematsu/M Tswana/M TTL tty/M ttys Tuamotu/M Tuareg/M tubae tubal tuba/SM tubbed tubbing tubby/TR tubeless tubercle/MS tubercular/S tuberculin/MS tuberculoses tuberculosis/M tuberculous tuber/M tuberose/SM tuberous tube/SM tubing/M tub/JMDRSZG Tubman/M tubular/Y tubule/SM tucker/GDM Tucker/M tuck/GZSRD Tuckie/M Tuck/RM Tucky/M Tucson/M Tucuman/M Tudor/MS Tue/S Tuesday/SM tufter/M tuft/GZSMRD tufting/M tugboat/MS tugged tugging tug/S tuition/ISM Tulane/M tularemia/S tulip/SM tulle/SM Tulley/M Tull/M Tully/M Tulsa/M tum tumbledown tumbler/M tumbleweed/MS tumble/ZGRSDJ tumbrel/SM tumescence/S tumescent tumidity/MS tumid/Y tummy/SM tumor/MDS tumorous Tums/M tumult/SGMD tumultuousness/M tumultuous/PY tumulus/M tunableness/M tunable/P tuna/SM tundra/SM tun/DRJZGBS tune/CSDG tunefulness/MS tuneful/YP tuneless/Y tuner/M tune's tuneup/S tung tungstate/M tungsten/SM Tunguska/M Tungus/M tunic/MS tuning/A tuning's Tunisia/M Tunisian/S Tunis/M tunned tunneler/M tunnel/MRDSJGZ tunning tunny/SM tupelo/M Tupi/M tuple/SM tuppence/M Tupperware Tupungato/M turban/SDM turbid turbidity/SM turbinate/SD turbine/SM turbocharged turbocharger/SM turbofan/MS turbojet/MS turboprop/MS turbo/SM turbot/MS turbulence/SM turbulent/Y turd/MS tureen/MS turf/DGSM turfy/RT Turgenev/M turgidity/SM turgidness/M turgid/PY Turing/M Turin/M Turkestan/M Turkey/M turkey/SM Turkic/SM Turkish Turkmenistan/M turk/S Turk/SM turmeric/MS turmoil/SDMG turnabout/SM turnaround/MS turn/AZGRDBS turnbuckle/SM turncoat/SM turned/U turner/M Turner/M turning/MS turnip/SMDG turnkey/MS turnoff/MS turnout/MS turnover/SM turnpike/MS turnround/MS turnstile/SM turnstone/M turntable/SM turpentine/GMSD Turpin/M turpitude/SM turquoise/SM turret/SMD turtleback/MS turtledove/MS turtleneck/SDM turtle/SDMG turves's turvy Tuscaloosa/M Tuscan Tuscany/M Tuscarora/M Tuscon/M tush/SDG Tuskegee/M tusker/M tusk/GZRDMS tussle/GSD tussock/MS tussocky Tussuad/M Tutankhamen/M tutelage/MS tutelary/S Tut/M tutored/U tutorial/MS tutor/MDGS tutorship/S tut/S Tutsi tutted tutting tutti/S Tuttle/M tutu/SM Tuvalu tuxedo/SDM tux/S TVA TV/M TVs twaddle/GZMRSD twaddler/M Twain/M twain/S TWA/M twang/MDSG twangy/TR twas tweak/SGRD tweediness/M Tweedledee/M Tweedledum/M Tweed/M twee/DP tweed/SM tweedy/PTR tween tweeter/M tweet/ZSGRD tweezer/M tweeze/ZGRD twelfth twelfths twelvemonth/M twelvemonths twelve/MS twentieths twenty/MSH twerp/MS twice/R twiddle/GRSD twiddler/M twiddly/RT twigged twigging twiggy/RT twig/SM Twila/M twilight/MS twilit twill/SGD twiner/M twine/SM twinge/SDMG Twinkie twinkler/M twinkle/RSDG twinkling/M twinkly twinned twinning twin/RDMGZS twirler/M twirling/Y twirl/SZGRD twirly/TR twisted/U twister/M twists/U twist/SZGRD twisty twitch/GRSD twitchy/TR twit/S twitted twitterer/M twitter/SGRD twittery twitting twixt twofer/MS twofold/S two/MS twopence/SM twopenny/S twosome/MS twp Twp TWX Twyla/M TX t/XTJBG Tybalt/M Tybie/M Tybi/M tycoon/MS tyeing Tye/M tying/UA tyke/SM Tylenol/M Tyler/M Ty/M Tymon/M Tymothy/M tympani tympanist/SM tympanum/SM Tynan/M Tyndale/M Tyndall/M Tyne/M typeahead typecast/SG typed/AU typedef/S typeface/MS typeless type/MGDRSJ types/A typescript/SM typeset/S typesetter/MS typesetting/SM typewriter/M typewrite/SRJZG typewriting/M typewritten typewrote typhoid/SM Typhon/M typhoon/SM typhus/SM typicality/MS typically typicalness/M typical/U typification/M typify/SDNXG typing/A typist/MS typographer/SM typographic typographical/Y typography/MS typological/Y typology/MS typo/MS tyrannic tyrannicalness/M tyrannical/PY tyrannicide/M tyrannizer/M tyrannize/ZGJRSD tyrannizing/YM tyrannosaur/MS tyrannosaurus/S tyrannous tyranny/MS tyrant/MS Tyree/M tyreo Tyrolean/S Tyrol's Tyrone/M tyrosine/M tyro/SM Tyrus/M Tyson/M tzarina's tzar's Tzeltal/M u U UAR UART UAW Ubangi/M ubiquitous/YP ubiquity/S Ucayali/M Uccello/M UCLA/M Udale/M Udall/M udder/SM Udell/M Ufa/M ufologist/S ufology/MS UFO/S Uganda/M Ugandan/S ugh ughs uglification ugliness/MS uglis ugly/PTGSRD Ugo/M uh UHF Uighur Ujungpandang/M UK ukase/SM Ukraine/M Ukrainian/S ukulele/SM UL Ula/M Ulberto/M ulcerate/NGVXDS ulceration/M ulcer/MDGS ulcerous Ulick/M Ulises/M Ulla/M Ullman/M ulnae ulna/M ulnar Ulrica/M Ulrich/M Ulrick/M Ulric/M Ulrika/M Ulrikaumeko/M Ulrike/M Ulster/M ulster/MS ult ulterior/Y ultimas ultimate/DSYPG ultimateness/M ultimatum/MS ultimo ultracentrifugally ultracentrifugation ultracentrifuge/M ultraconservative/S ultrafast ultrahigh ultralight/S ultramarine/SM ultramodern ultramontane ultra/S ultrashort ultrasonically ultrasonic/S ultrasonics/M ultrasound/SM ultrastructure/M Ultrasuede ultraviolet/SM Ultrix/M ULTRIX/M ululate/DSXGN ululation/M Ulyanovsk/M Ulysses/M um umbel/MS umber/GMDS Umberto/M umbilical/S umbilici umbilicus/M umbrage/MGSD umbrageous umbra/MS umbrella/GDMS Umbriel/M Umeko/M umiak/MS umlaut/GMDS umpire/MGSD ump/MDSG umpteen/H UN unabated/Y unabridged/S unacceptability unacceptable unaccepted unaccommodating unaccountability unaccustomed/Y unadapted unadulterated/Y unadventurous unalienability unalterableness/M unalterable/P unalterably Una/M unambiguity unambiguous unambitious unamused unanimity/SM unanimous/Y unanticipated/Y unapologetic unapologizing/M unappeasable unappeasably unappreciative unary unassailableness/M unassailable/P unassertive unassumingness/M unassuming/PY unauthorized/PY unavailing/PY unaware/SPY unbalanced/P unbar unbarring unbecoming/P unbeknown unbelieving/Y unbiased/P unbid unbind/G unblessed unblinking/Y unbodied unbolt/G unbreakability unbred unbroken unbuckle unbudging/Y unburnt uncap uncapping uncatalogued uncauterized/MS unceasing/Y uncelebrated uncertain/P unchallengeable unchangingness/M unchanging/PY uncharacteristic uncharismatic unchastity unchristian uncial/S uncivilized/Y unclassified uncle/MSD unclouded/Y uncodable uncollected uncoloredness/M uncolored/PY uncombable uncommunicative uncompetitive uncomplicated uncomprehending/Y uncompromisable unconcerned/P unconcern/M unconfirmed unconfused unconscionableness/M unconscionable/P unconscionably unconstitutional unconsumed uncontentious uncontrollability unconvertible uncool uncooperative uncork/G uncouple/G uncouthness/M uncouth/YP uncreate/V uncritical uncross/GB uncrowded unction/IM unctions unctuousness/MS unctuous/PY uncustomary uncut undated/I undaunted/Y undeceive undecided/S undedicated undefinability undefinedness/M undefined/P undelete undeliverability undeniableness/M undeniable/P undeniably undependable underachiever/M underachieve/SRDGZ underact/GDS underadjusting underage/S underarm/DGS underbedding underbelly/MS underbidding underbid/S underbracing underbrush/MSDG undercarriage/MS undercharge/GSD underclassman underclassmen underclass/S underclothes underclothing/MS undercoating/M undercoat/JMDGS underconsumption/M undercooked undercount/S undercover undercurrent/SM undercut/S undercutting underdeveloped underdevelopment/MS underdog/MS underdone undereducated underemphasis underemployed underemployment/SM underenumerated underenumeration underestimate/NGXSD underexploited underexpose/SDG underexposure/SM underfed underfeed/SG underfloor underflow/GDMS underfoot underfund/DG underfur/MS undergarment/SM undergirding undergoes undergo/G undergone undergrad/MS undergraduate/MS underground/RMS undergrowth/M undergrowths underhand/D underhandedness/MS underhanded/YP underheat underinvestment underlaid underlain/S underlay/GS underlie underline/GSDJ underling/MS underlip/SM underloaded underly/GS undermanned undermentioned undermine/SDG undermost underneath underneaths undernourished undernourishment/SM underpaid underpants underpart/MS underpass/SM underpay/GSL underpayment/SM underperformed underpinned underpinning/MS underpin/S underplay/SGD underpopulated underpopulation/M underpowered underpricing underprivileged underproduction/MS underrate/GSD underregistration/M underreported underreporting underrepresentation/M underrepresented underscore/SDG undersealed undersea/S undersecretary/SM undersell/SG undersexed undershirt/SM undershoot/SG undershorts undershot underside/SM undersigned/M undersign/SGD undersized undersizes undersizing underskirt/MS undersold underspecification underspecified underspend/G understaffed understandability/M understandably understanding/YM understand/RGSJB understate/GSDL understatement/MS understocked understood understrength understructure/SM understudy/GMSD undertaken undertaker/M undertake/SRGZJ undertaking/M underthings undertone/SM undertook undertow/MS underused underusing underutilization/M underutilized undervaluation/S undervalue/SDG underwater/S underway underwear/M underweight/S underwent underwhelm/DGS underwood/M Underwood/M underworld/MS underwrite/GZSR underwriter/M underwritten underwrote under/Y undeserving undesigned undeviating/Y undialyzed/SM undiplomatic undiscerning undiscriminating undo/GJ undoubted/Y undramatic undramatized/SM undress/G undrinkability undrinkable undroppable undue undulant undulate/XDSNG undulation/M unearthliness/S unearthly/P unearth/YG unease uneconomic uneducated unemployed/S unencroachable unending/Y unendurable/P unenergized/MS unenforced unenterprising UNESCO unethical uneulogized/SM unexacting unexceptionably unexcited unexpectedness/MS unfading/Y unfailingness/M unfailing/P unfamiliar unfashionable unfathomably unfavored unfeeling unfeigned/Y unfelt unfeminine unfertile unfetchable unflagging unflappability/S unflappable unflappably unflinching/Y unfold/LG unfoldment/M unforced unforgeable unfossilized/MS unfraternizing/SM unfrozen unfulfillable unfunny unfussy ungainliness/MS ungainly/PRT Ungava/M ungenerous ungentle unglamorous ungrammaticality ungrudging unguent/MS ungulate/MS unharmonious unharness/G unhistorical unholy/TP unhook/DG unhydrolyzed/SM unhygienic Unibus/M unicameral UNICEF unicellular Unicode/M unicorn/SM unicycle/MGSD unicyclist/MS unideal unidimensional unidiomatic unidirectionality unidirectional/Y unidolized/MS unifiable unification/MA unifier/MS unifilar uniformity/MS uniformness/M uniform/TGSRDYMP unify/AXDSNG unilateralism/M unilateralist unilateral/Y unimodal unimpeachably unimportance unimportant unimpressive unindustrialized/MS uninhibited/YP uninominal uninsured unintellectual unintended uninteresting uninterruptedness/M uninterrupted/YP unintuitive uninviting union/AEMS unionism/SM unionist/SM Unionist/SM unionize Union/MS UniPlus/M unipolar uniprocessor/SM uniqueness/S unique/TYSRP Uniroyal/M unisex/S UniSoft/M unison/MS Unisys/M unitarianism/M Unitarianism/SM unitarian/MS Unitarian/MS unitary unite/AEDSG united/Y uniter/M unitize/GDS unit/VGRD unity/SEM univ Univac/M univalent/S univalve/MS univariate universalism/M universalistic universality/SM universalize/DSRZG universalizer/M universal/YSP universe/MS university/MS Unix/M UNIX/M unjam unkempt unkind/TP unkink unknightly unknowable/S unknowing unlabored unlace/G unlearn/G unlikeable unlikeliness/S unlimber/G unlimited unlit unliterary unloose/G unlucky/TP unmagnetized/MS unmanageably unmannered/Y unmask/G unmeaning unmeasured unmeetable unmelodious unmemorable unmemorialized/MS unmentionable/S unmerciful unmeritorious unmethodical unmineralized/MS unmissable unmistakably unmitigated/YP unmnemonic unmobilized/SM unmoral unmount/B unmovable unmoving unnaturalness/M unnavigable unnerving/Y unobliging unoffensive unofficial unorganized/YP unorthodox unpack/G unpaintable unpalatability unpalatable unpartizan unpatronizing unpeople unperceptive unperson unperturbed/Y unphysical unpick/G unpicturesque unpinning unpleasing unploughed unpolarized/SM unpopular unpractical unprecedented/Y unpredictable/S unpreemphasized unpremeditated unpretentiousness/M unprincipled/P unproblematic unproductive unpropitious unprovable unproven unprovocative unpunctual unquestionable unraisable unravellings unreadability unread/B unreal unrealizable unreasoning/Y unreceptive unrecordable unreflective unrelenting/Y unremitting/Y unrepeatability unrepeated unrepentant unreported unrepresentative unreproducible unrest/G unrestrained/P unrewarding unriddle unripe/P unromantic unruliness/SM unruly/PTR unsaleable unsanitary unsavored/YP unsavoriness/M unseal/GB unsearchable unseasonal unseeing/Y unseen/S unselfconsciousness/M unselfconscious/P unselfishness/M unsellable unsentimental unset unsettledness/M unsettled/P unsettling/Y unshapely unshaven unshorn unsighted unsightliness/S unskilful unsociability unsociable/P unsocial unsound/PT unspeakably unspecific unspectacular unspoilt unspoke unsporting unstable/P unstigmatized/SM unstilted unstinting/Y unstopping unstrapping unstudied unstuffy unsubdued unsubstantial unsubtle unsuitable unsuspecting/Y unswerving/Y unsymmetrical unsympathetic unsystematic unsystematized/Y untactful untalented untaxing unteach/B untellable untenable unthinking until/G untiring/Y unto untouchable/MS untowardness/M untoward/P untraceable untrue untruthfulness/M untwist/G Unukalhai/M unusualness/M unutterable unutterably unvocalized/MS unvulcanized/SM unwaivering unwarrantable unwarrantably unwashed/PS unwearable unwearied/Y unwed unwedge unwelcome unwell/M unwieldiness/MS unwieldy/TPR unwind/B unwomanly unworkable/S unworried unwrap unwrapping unyielding/Y unyoke unzip up Upanishads uparrow upbeat/SM upbraid/GDRS upbringing/M upbring/JG UPC upchuck/SDG upcome/G upcountry/S updatability updater/M update/RSDG Updike/M updraft/SM upend/SDG upfield upfront upgradeable upgrade/DSJG upheaval/MS upheld uphill/S upholder/M uphold/RSGZ upholster/ADGS upholsterer/SM upholstery/MS UPI upkeep/SM uplander/M upland/MRS uplifter/M uplift/SJDRG upload/GSD upmarket upon upped uppercase/GSD upperclassman/M upperclassmen uppercut/S uppercutting uppermost upper/S upping uppish uppity upraise/GDS uprated uprating uprear/DSG upright/DYGSP uprightness/S uprise/RGJ uprising/M upriver/S uproariousness/M uproarious/PY uproar/MS uproot/DRGS uprooter/M ups UPS upscale/GDS upset/S upsetting/MS upshot/SM upside/MS upsilon/MS upslope upstage/DSRG upstairs upstandingness/M upstanding/P upstart/MDGS upstate/SR upstream/DSG upstroke/MS upsurge/DSG upswing/GMS upswung uptake/SM upthrust/GMS uptight uptime Upton/M uptown/RS uptrend/M upturn/GDS upwardness/M upward/SYP upwelling upwind/S uracil/MS Ural/MS Urania/M uranium/MS Uranus/M uranyl/M Urbain/M Urbana/M urbane/Y urbanism/M urbanite/SM urbanity/SM urbanization/MS urbanize/DSG Urban/M urbanologist/S urbanology/S Urbano/M urban/RT Urbanus/M urchin/SM Urdu/M urea/SM uremia/MS uremic ureter/MS urethane/MS urethrae urethral urethra/M urethritis/M Urey/M urge/GDRSJ urgency/SM urgent/Y urger/M Uriah/M uric Uriel/M urinal/MS urinalyses urinalysis/M urinary/MS urinate/XDSNG urination/M urine/MS Uri/SM URL Ur/M urning/M urn/MDGS urogenital urological urologist/S urology/MS Urquhart/M Ursala/M Ursa/M ursine Ursola/M Urson/M Ursula/M Ursulina/M Ursuline/M urticaria/MS Uruguayan/S Uruguay/M Urumqi US USA usability/S usable/U usably/U USAF usage/SM USART USCG USC/M USDA us/DRSBZG used/U use/ESDAG usefulness/SM useful/YP uselessness/MS useless/PY Usenet/M Usenix/M user/M USG/M usherette/SM usher/SGMD USIA USMC USN USO USP USPS USS USSR Ustinov/M usu usuals usual/UPY usurer/SM usuriousness/M usurious/PY usurpation/MS usurper/M usurp/RDZSG usury/SM UT Utahan/SM Utah/M Uta/M Ute/M utensil/SM uteri uterine uterus/M Utica/M utile/I utilitarianism/MS utilitarian/S utility/MS utilization/MS utilization's/A utilize/GZDRS utilizer/M utilizes/A utmost/S Utopia/MS utopianism/M utopian's Utopian/S utopia/S Utrecht/M Utrillo/M utterance/MS uttered/U utterer/M uttermost/S utter/TRDYGS uucp/M UV uvula/MS uvular/S uxorious Uzbekistan Uzbek/M Uzi/M V VA vacancy/MS vacantness/M vacant/PY vacate/NGXSD vacationist/SM vacationland vacation/MRDZG vaccinate/NGSDX vaccination/M vaccine/SM vaccinial vaccinia/M Vachel/M vacillate/XNGSD vacillating/Y vacillation/M vacillator/SM Vaclav/M vacua's vacuity/MS vacuo vacuolated/U vacuolate/SDGN vacuole/SM vacuolization/SM vacuousness/MS vacuous/PY vacuum/GSMD Vader/M Vaduz/M vagabondage/MS vagabond/DMSG vagarious vagary/MS vaginae vaginal/Y vagina/M vagrancy/MS vagrant/SMY vagueing vagueness/MS vague/TYSRDP Vail/M vaingloriousness/M vainglorious/YP vainglory/MS vain/TYRP val valance/SDMG Valaree/M Valaria/M Valarie/M Valdemar/M Valdez/M Valeda/M valediction/MS valedictorian/MS valedictory/MS Vale/M valence/SM Valencia/MS valency/MS Valene/M Valenka/M Valentia/M Valentijn/M Valentina/M Valentine/M valentine/SM Valentin/M Valentino/M Valenzuela/M Valera/M Valeria/M Valerian/M Valerie/M Valerye/M Valry/M vale/SM valet/GDMS valetudinarianism/MS valetudinarian/MS Valhalla/M valiance/S valiantness/M valiant/SPY Valida/M validated/AU validate/INGSDX validates/A validation/AMI validity/IMS validnesses validness/MI valid/PIY Valina/M valise/MS Valium/S Valkyrie/SM Vallejo Valle/M Valletta/M valley/SM Vallie/M Valli/M Vally/M Valma/M Val/MY Valois/M valor/MS valorous/Y Valparaiso/M Valry/M valuable/IP valuableness/IM valuables valuably/I valuate/NGXSD valuation/CSAM valuator/SM value/CGASD valued/U valuelessness/M valueless/P valuer/SM value's values/E valve/GMSD valveless valvular Va/M vamoose/GSD vamp/ADSG vamper vampire/MGSD vamp's vanadium/MS Vance/M Vancouver/M vandalism/MS vandalize/GSD vandal/MS Vandal/MS Vanda/M Vandenberg/M Vanderbilt/M Vanderburgh/M Vanderpoel/M Vandyke/SM vane/MS Vanessa/M Vang/M vanguard/MS Vania/M vanilla/MS vanisher/M vanish/GRSDJ vanishing/Y vanity/SM Van/M Vanna/M vanned Vannie/M Vanni/M vanning Vanny/M vanquisher/M vanquish/RSDGZ van/SMD vantage/MS Vanuatu Vanya/M Vanzetti/M vapidity/MS vapidness/SM vapid/PY vaporer/M vaporing/MY vaporisation vaporise/DSG vaporization/AMS vaporize/DRSZG vaporizer/M vapor/MRDJGZS vaporous vapory vaquero/SM VAR Varanasi/M Varese/M Vargas/M variability/IMS variableness/IM variable/PMS variables/I variably/I variance/I variances variance's Varian/M variant/ISY variate/MGNSDX variational variation/M varicolored/MS varicose/S variedly varied/U variegate/NGXSD variegation/M varier/M varietal/S variety/MS various/PY varistor/M Varityping/M varlet/MS varmint/SM varnished/U varnisher/M varnish/ZGMDRS var/S varsity/MS varying/UY vary/SRDJG vascular vasectomy/SM Vaseline/DSMG vase/SM Vasili/MS Vasily/M vasomotor Vasquez/M vassalage/MS vassal/GSMD Vassar/M Vassili/M Vassily/M vastness/MS vast/PTSYR v/ASV VAT Vatican/M vat/SM vatted vatting vaudeville/SM vaudevillian/SM Vaudois Vaughan/M Vaughn/M vaulter/M vaulting/M vault/ZSRDMGJ vaunter/M vaunt/GRDS VAXes Vax/M VAX/M Vazquez/M vb VCR VD VDT VDU vealed/A vealer/MA veal/MRDGS veals/A Veblen/M vectorial vectorization vectorized vectorizing vector's/F vector/SGDM Veda/MS Vedanta/M veejay/S veep/S veer/DSG veering/Y vegan/SM Vega/SM Vegemite/M veges vegetable/MS vegetarianism/MS vegetarian/SM vegetate/DSNGVX vegetation/M vegetative/PY vegged veggie/S vegging veg/M vehemence/MS vehemency/S vehement/Y vehicle/SM vehicular veiling/MU veil's veil/UGSD vein/GSRDM veining/M vela/M Vela/M velarize/SDG velar/S Velsquez/M Velzquez Velcro/SM veld/SM veldt's Velez/M Vella/M vellum/MS Velma/M velocipede/SM velocity/SM velor/S velour's velum/M Velveeta/M velveteen/MS velvet/GSMD Velvet/M velvety/RT venality/MS venal/Y venation/SM vend/DSG vender's/K vendetta/MS vendible/S vendor/MS veneerer/M veneer/GSRDM veneering/M venerability/S venerable/P venerate/XNGSD veneration/M venereal venetian Venetian/SM Venezuela/M Venezuelan/S vengeance/MS vengeful/APY vengefulness/AM venialness/M venial/YP Venice/M venireman/M veniremen venison/SM Venita/M Venn/M venomousness/M venomous/YP venom/SGDM venous/Y venter/M ventilated/U ventilate/XSDVGN ventilation/M ventilator/MS vent/ISGFD ventral/YS ventricle/MS ventricular ventriloquies ventriloquism/MS ventriloquist/MS ventriloquy vent's/F Ventura/M venture/RSDJZG venturesomeness/SM venturesome/YP venturi/S venturousness/MS venturous/YP venue/MAS Venusian/S Venus/S veraciousness/M veracious/YP veracities veracity/IM Veracruz/M Veradis Vera/M verandahed veranda/SDM verbalization/MS verbalized/U verbalizer/M verbalize/ZGRSD verballed verballing verbal/SY verbatim verbena/MS verbiage/SM verb/KSM verbose/YP verbosity/SM verboten verdant/Y Verde/M Verderer/M verdict/SM verdigris/GSDM Verdi/M verdure/SDM Vere/M Verena/M Verene/M verge/FGSD Verge/M verger/SM verge's Vergil's veridical/Y Veriee/M verifiability/M verifiableness/M verifiable/U verification/S verified/U verifier/MS verify/GASD Verile/M verily Verina/M Verine/M verisimilitude/SM veritableness/M veritable/P veritably verity/MS Verlag/M Verlaine/M Verla/M Vermeer/M vermicelli/MS vermiculite/MS vermiform vermilion/MS vermin/M verminous Vermonter/M Vermont/ZRM vermouth/M vermouths vernacular/YS vernal/Y Verna/M Verne/M Vernen/M Verney/M Vernice/M vernier/SM Vern/NM Vernon/M Vernor/M Verona/M Veronese/M Veronica/M veronica/SM Veronika/M Veronike/M Veronique/M verrucae verruca/MS versa Versailles/M Versatec/M versatileness/M versatile/YP versatility/SM versed/UI verse's verses/I verse/XSRDAGNF versicle/M versification/M versifier/M versify/GDRSZXN versing/I version/MFISA verso/SM versus vertebrae vertebral/Y vertebra/M vertebrate/IMS vertebration/M vertex/SM vertical/YPS vertices's vertiginous vertigoes vertigo/M verve/SM very/RT Vesalius/M vesicle/SM vesicular/Y vesiculate/GSD Vespasian/M vesper/SM Vespucci/M vessel/MS vestal/YS Vesta/M vest/DIGSL vestibular vestibule/SDM vestige/SM vestigial/Y vesting/SM vestment/ISM vestryman/M vestrymen vestry/MS vest's vesture/SDMG Vesuvius/M vetch/SM veteran/SM veterinarian/MS veterinary/S veter/M veto/DMG vetoes vet/SMR vetted vetting/A Vevay/M vexation/SM vexatiousness/M vexatious/PY vexed/Y vex/GFSD VF VFW VG VGA vhf VHF VHS VI via viability/SM viable/I viably viaduct/MS Viagra/M vial/MDGS viand/SM vibe/S vibraharp/MS vibrancy/MS vibrant/YS vibraphone/MS vibraphonist/SM vibrate/XNGSD vibrational/Y vibration/M vibrato/MS vibrator/SM vibratory vibrio/M vibrionic viburnum/SM vicarage/SM vicariousness/MS vicarious/YP vicar/SM vice/CMS viced vicegerent/MS vicennial Vicente/M viceregal viceroy/SM Vichy/M vichyssoise/MS vicing vicinity/MS viciousness/S vicious/YP vicissitude/MS Vickers/M Vickie/M Vicki/M Vicksburg/M Vicky/M Vick/ZM Vic/M victimization/SM victimized/U victimizer/M victimize/SRDZG victim/SM Victoir/M Victoria/M Victorianism/S Victorian/S victoriousness/M victorious/YP Victor/M victor/SM victory/MS Victrola/SM victualer/M victual/ZGSDR vicua/S Vidal/M Vida/M videlicet videocassette/S videoconferencing videodisc/S videodisk/SM video/GSMD videophone/SM videotape/SDGM Vidovic/M Vidovik/M Vienna/M Viennese/M Vientiane/M vier/M vie/S Vietcong/M Viet/M Vietminh/M Vietnamese/M Vietnam/M viewed/A viewer/AS viewer's viewfinder/MS viewgraph/SM viewing/M viewless/Y view/MBGZJSRD viewpoint/SM views/A vigesimal vigilance/MS vigilante/SM vigilantism/MS vigilantist vigilant/Y vigil/SM vignette/MGDRS vignetter/M vignetting/M vignettist/MS vigor/MS vigorousness/M vigorous/YP vii viii Vijayawada/M Viki/M Viking/MS viking/S Vikki/M Vikky/M Vikram/M Vila vile/AR vilely vileness/MS vilest Vilhelmina/M vilification/M vilifier/M vilify/GNXRSD villager/M village/RSMZ villainousness/M villainous/YP villain/SM villainy/MS Villa/M villa/MS Villarreal/M ville villeinage/SM villein/MS villi Villon/M villus/M Vilma/M Vilnius/M Vilyui/M Vi/M vi/MDR vim/MS vinaigrette/MS Vina/M Vince/M Vincent/MS Vincenty/M Vincenz/M vincible/I Vinci/M Vindemiatrix/M vindicate/XSDVGN vindication/M vindicator/SM vindictiveness/MS vindictive/PY vinegar/DMSG vinegary vine/MGDS vineyard/SM Vinita/M Vin/M Vinnie/M Vinni/M Vinny/M vino/MS vinous Vinson/M vintage/MRSDG vintager/M vintner/MS vinyl/SM violable/I Viola/M Violante/M viola/SM violate/VNGXSD violator/MS Viole/M violence/SM violent/Y Violet/M violet/SM Violetta/M Violette/M violinist/SM violin/MS violist/MS viol/MSB violoncellist/S violoncello/MS viper/MS viperous VIP/S viragoes virago/M viral/Y vireo/SM Virge/M Virgie/M Virgilio/M Virgil/M virginal/YS Virgina/M Virginia/M Virginian/S Virginie/M virginity/SM virgin/SM Virgo/MS virgule/MS virile virility/MS virologist/S virology/SM virtual/Y virtue/SM virtuosity/MS virtuosoes virtuoso/MS virtuousness/SM virtuous/PY virulence/SM virulent/Y virus/MS visage/MSD Visakhapatnam's Visa/M visa/SGMD Visayans viscera visceral/Y viscid/Y viscoelastic viscoelasticity viscometer/SM viscose/MS viscosity/MS viscountcy/MS viscountess/SM viscount/MS viscousness/M viscous/PY viscus/M vise/CAXNGSD viselike vise's Vishnu/M visibility/ISM visible/PI visibly/I Visigoth/M Visigoths visionariness/M visionary/PS vision/KMDGS vision's/A visitable/U visitant/SM visitation/SM visited/U visit/GASD visitor/MS vis/MDSGV visor/SMDG VISTA vista/GSDM Vistula/M visualization/AMS visualized/U visualizer/M visualizes/A visualize/SRDZG visual/SY vitae vitality/MS vitalization/AMS vitalize/ASDGC vital/SY vita/M Vita/M vitamin/SM Vite/M Vitia/M vitiate/XGNSD vitiation/M viticulture/SM viticulturist/S Vitim/M Vito/M Vitoria/M vitreous/YSP vitrifaction/S vitrification/M vitrify/XDSNG vitrine/SM vitriolic vitriol/MDSG vitro vittles Vittoria/M Vittorio/M vituperate/SDXVGN vituperation/M vituperative/Y Vitus/M vivace/S vivaciousness/MS vivacious/YP vivacity/SM viva/DGS Vivaldi Viva/M vivaria vivarium/MS vivaxes Vivekananda/M vive/Z Vivia/M Viviana/M Vivian/M Vivianna/M Vivianne/M vividness/SM vivid/PTYR Vivie/M Viviene/M Vivien/M Vivienne/M vivifier vivify/NGASD Vivi/MN viviparous vivisect/DGS vivisectional vivisectionist/SM vivisection/MS Viviyan/M Viv/M vivo Vivyan/M Vivyanne/M vixenish/Y vixen/SM viz vizier/MS vizor's VJ Vladamir/M Vladimir/M Vladivostok/M Vlad/M VLF VLSI VMS/M VOA vocable/SM vocab/S vocabularian vocabularianism vocabulary/MS vocalic/S vocalise's vocalism/M vocalist/MS vocalization/SM vocalized/U vocalizer/M vocalize/ZGDRS vocal/SY vocation/AKMISF vocational/Y vocative/KYS vociferate/NGXSD vociferation/M vociferousness/MS vociferous/YP vocoded vocoder vodka/MS voe/S Vogel/M vogue/GMSRD vogueing voguish voiceband voiced/CU voice/IMGDS voicelessness/SM voiceless/YP voicer/S voices/C voicing/C voidable void/C voided voider/M voiding voidness/M voids voil voile/MS volar volatileness/M volatile/PS volatility/MS volatilization/MS volatilize/SDG volcanically volcanic/S volcanism/M volcanoes volcano/M vole/MS Volga/M Volgograd/M vol/GSD volitionality volitional/Y volition/MS Volkswagen/SM volleyball/MS volleyer/M volley/SMRDG Vol/M Volstead/M voltage/SM voltaic Voltaire/M Volta/M volt/AMS Volterra/M voltmeter/MS volubility/S voluble/P volubly volume/SDGM volumetric volumetrically voluminousness/MS voluminous/PY voluntarily/I voluntariness/MI voluntarism/MS voluntary/PS volunteer/DMSG voluptuary/SM voluptuousness/S voluptuous/YP volute/S Volvo/M vomit/GRDS Vonda/M Von/M Vonnegut/M Vonnie/M Vonni/M Vonny/M voodoo/GDMS voodooism/S voraciousness/MS voracious/YP voracity/MS Voronezh/M Vorster/M vortex/SM vortices's vorticity/M votary/MS vote/CSDG voter/SM vote's votive/YP voucher/GMD vouchsafe/SDG vouch/SRDGZ vowelled vowelling vowel/MS vower/M vow/SMDRG voyage/GMZJSRD voyager/M voyageur/SM voyeurism/MS voyeuristic voyeur/MS VP vs V's VT Vt/M VTOL vulcanization/SM vulcanized/U vulcanize/SDG Vulcan/M vulgarian/MS vulgarism/MS vulgarity/MS vulgarization/S vulgarize/GZSRD vulgar/TSYR Vulgate/SM Vulg/M vulnerability/SI vulnerable/IP vulnerably/I vulpine vulturelike vulture/SM vulturous vulvae vulva/M vying Vyky/M WA Waals Wabash/M WAC Wacke/M wackes wackiness/MS wacko/MS wacky/RTP Waco/M Wac/S wadded wadding/SM waddle/GRSD Wade/M wader/M wade/S wadi/SM wad/MDRZGS Wadsworth/M wafer/GSMD waffle/GMZRSD Wafs wafter/M waft/SGRD wag/DRZGS waged/U wager/GZMRD wage/SM wagged waggery/MS wagging waggishness/SM waggish/YP waggle/SDG waggly Wagnerian Wagner/M wagoner/M wagon/SGZMRD wagtail/SM Wahl/M waif/SGDM Waikiki/M wailer/M wail/SGZRD wain/GSDM Wain/M wainscot/SGJD Wainwright/M wainwright/SM waistband/MS waistcoat/GDMS waister/M waist/GSRDM waistline/MS Waite/M waiter/DMG Waiter/M wait/GSZJRD Wait/MR waitpeople waitperson/S waitress/GMSD waiver/MB waive/SRDGZ Wakefield/M wakefulness/MS wakeful/PY Wake/M wake/MGDRSJ waken/SMRDG waker/M wakeup Waksman/M Walbridge/M Walcott/M Waldemar/M Walden/M Waldensian Waldheim/M Wald/MN Waldo/M Waldon/M Waldorf/M wale/DRSMG Wales Walesa/M Walford/M Walgreen/M waling/M walkabout/M walkaway/SM walker/M Walker/M walk/GZSBJRD walkie Walkman/S walkout/SM walkover/SM walkway/MS wallaby/MS Wallace/M Wallache/M wallah/M Wallas/M wallboard/MS Wallenstein/M Waller/M wallet/SM walleye/MSD wallflower/MS Wallie/M Wallis Walliw/M Walloon/SM walloper/M walloping/M wallop/RDSJG wallower/M wallow/RDSG wallpaper/DMGS wall/SGMRD Wall/SMR Wally/M wally/S walnut/SM Walpole/M Walpurgisnacht walrus/SM Walsh/M Walter/M Walther/M Walton/M waltzer/M Walt/ZMR waltz/MRSDGZ Walworth/M Waly/M wampum/SM Wanamaker/M Wanda/M wanderer/M wander/JZGRD wanderlust/SM Wandie/M Wandis/M wand/MRSZ wane/S Waneta/M wangler/M wangle/RSDGZ Wang/M Wanids/M Wankel/M wanna wannabe/S wanned wanner wanness/S wannest wanning wan/PGSDY Wansee/M Wansley/M wanted/U wanter/M want/GRDSJ wantonness/S wanton/PGSRDY wapiti/MS warble/GZRSD warbler/M warbonnet/S ward/AGMRDS Warde/M warden/DMGS Warden/M warder/DMGS Ward/MN wardrobe/MDSG wardroom/MS wardship/M wards/I warehouseman/M warehouse/MGSRD Ware/MG ware/MS warfare/SM Warfield/M war/GSMD warhead/MS Warhol/M warhorse/SM warily/U warinesses/U wariness/MS Waring/M warless warlike warlock/SM warlord/MS warmblooded warmed/A warmer/M warmheartedness/SM warmhearted/PY warmish warmness/MS warmongering/M warmonger/JGSM warms/A warmth/M warmths warm/YRDHPGZTS warned/U warner/M Warner/M warn/GRDJS warning/YM Warnock/M warpaint warpath/M warpaths warper/M warplane/MS warp/MRDGS warranted/U warranter/M warrant/GSMDR warranty/SDGM warred/M warrener/M Warren/M warren/SZRM warring/M warrior/MS Warsaw/M wars/C warship/MS warthog/S wartime/SM wart/MDS warty/RT Warwick/M wary/URPT Wasatch/M washable/S wash/AGSD washbasin/SM washboard/SM washbowl/SM Washburn/M washcloth/M washcloths washday/M washed/U washer/GDMS washerwoman/M washerwomen washing/SM Washingtonian/S Washington/M Wash/M Washoe/M washout/SM washrag/SM washroom/MS washstand/SM washtub/MS washy/RT wasn't WASP waspishness/SM waspish/PY Wasp's wasp/SM was/S wassail/GMDS Wasserman/M Wassermann/M wastage/SM wastebasket/SM wastefulness/S wasteful/YP wasteland/MS wastepaper/MS waster/DG waste/S wastewater wast/GZSRD wasting/Y wastrel/MS Watanabe/M watchable/U watchband/SM watchdogged watchdogging watchdog/SM watched/U watcher/M watchfulness/MS watchful/PY watch/JRSDGZB watchmake/JRGZ watchmaker/M watchman/M watchmen watchpoints watchtower/MS watchword/MS waterbird/S waterborne Waterbury/M watercolor/DMGS watercolorist/SM watercourse/SM watercraft/M watercress/SM waterer/M waterfall/SM waterfowl/M waterfront/SM Watergate/M waterhole/S Waterhouse/M wateriness/SM watering/M water/JGSMRD waterless waterlily/S waterline/S waterlogged waterloo Waterloo/SM waterman/M watermark/GSDM watermelon/SM watermill/S waterproof/PGRDSJ watershed/SM waterside/MSR watersider/M Waters/M waterspout/MS watertightness/M watertight/P Watertown/M waterway/MS waterwheel/S waterworks/M watery/PRT Watkins WATS Watson/M wattage/SM Watteau/M Wattenberg/M Watterson/M wattle/SDGM Watt/MS watt/TMRS Watusi/M Wat/ZM Waugh/M Waukesha/M Waunona/M Waupaca/M Waupun/M Wausau/M Wauwatosa/M waveband/MS waveform/SM wavefront/MS waveguide/MS Waveland/M wavelength/M wavelengths wavelet/SM wavelike wavenumber waver/GZRD wavering/YU Waverley/M Waverly/M Wave/S wave/ZGDRS wavily waviness/MS wavy/SRTP waxer/M waxiness/MS wax/MNDRSZG waxwing/MS waxwork/MS waxy/PRT wayfarer/MS wayfaring/S waylaid Wayland/M Waylan/M waylayer/M waylay/GRSZ wayleave/MS Waylen/M Waylin/M Waylon/M Way/M waymarked way/MS Wayne/M Waynesboro/M wayside/MS waywardness/S wayward/YP WC we weakener/M weaken/ZGRD weakfish/SM weakish weakliness/M weakling/SM weakly/RTP weakness/MS weak/TXPYRN weal/MHS wealthiness/MS wealth/M wealths wealthy/PTR weaner/M weanling/M wean/RDGS weapon/GDMS weaponless weaponry/MS wearable/S wearer/M wearied/U wearily weariness/MS wearing/Y wearisomeness/M wearisome/YP wear/RBSJGZ wearying/Y weary/TGPRSD weasel/SGMDY weatherbeaten weathercock/SDMG weatherer/M Weatherford/M weathering/M weatherize/GSD weatherman/M weather/MDRYJGS weathermen weatherperson/S weatherproof/SGPD weatherstripped weatherstripping/S weatherstrip/S weaver/M Weaver/M weaves/A weave/SRDGZ weaving/A webbed Webber/M webbing/MS Webb/RM weber/M Weber/M Webern/M webfeet webfoot/M Web/MR website/S web/SMR Webster/MS Websterville/M we'd wedded/A Weddell/M wedder wedding/SM wedge/SDGM wedgie/RST Wedgwood/M wedlock/SM Wed/M Wednesday/SM wed/SA weeder/M weediness/M weedkiller/M weedless wee/DRST weed/SGMRDZ weedy/TRP weeing weekday/MS weekender/M weekend/SDRMG weekly/S weeknight/SM Weeks/M week/SYM weenie/M ween/SGD weeny/RSMT weeper/M weep/SGZJRD weepy/RST weevil/MS weft/SGMD Wehr/M Weibull/M Weidar/M Weider/M Weidman/M Weierstrass/M weighed/UA weigher/M weigh/RDJG weighs/A weighted/U weighter/M weightily weightiness/SM weighting/M weight/JMSRDG weightlessness/SM weightless/YP weightlifter/S weightlifting/MS weighty/TPR Weill/M Wei/M Weinberg/M Weiner/M Weinstein/M weirdie/SM weirdness/MS weirdo/SM weird/YRDPGTS weir/SDMG Weisenheimer/M Weiss/M Weissman/M Weissmuller/M Weizmann/M Welbie/M Welby/M Welcher/M Welches welcomeness/M welcome/PRSDYG welcoming/U welder/M Weldon/M weld/SBJGZRD Weldwood/M welfare/SM welkin/SM we'll Welland/M wellbeing/M Weller/M Wellesley/M Welles/M wellhead/SM Wellington/MS wellington/S Wellman/M wellness/MS well/SGPD Wells/M wellspring/SM Wellsville/M Welmers/M Welsh welsher/M Welshman/M Welshmen welsh/RSDGZ Welshwoman/M Welshwomen welter/GD welterweight/MS welt/GZSMRD wencher/M wench/GRSDM Wendall/M Wenda/M wend/DSG Wendeline/M Wendell/M Wendel/M Wendie/M Wendi/M Wendye/M Wendy/M wen/M Wenonah/M Wenona/M went Wentworth/M wept/U were we're weren't werewolf/M werewolves Werner/M Wernher/M Werther/M werwolf's Wes Wesleyan Wesley/M Wessex/M Wesson/M westbound Westbrooke/M Westbrook/M Westchester/M wester/DYG westerly/S westerner/M westernization/MS westernize/GSD westernmost Western/ZRS western/ZSR Westfield/M Westhampton/M Westinghouse/M westing/M Westleigh/M Westley/M Westminster/M Westmore/M West/MS Weston/M Westphalia/M Westport/M west/RDGSM westward/S Westwood/M wetback/MS wetland/S wetness/MS wet/SPY wettable wetter/S wettest wetting we've Weyden/M Weyerhauser/M Weylin/M Wezen/M WFF whacker/M whack/GZRDS whaleboat/MS whalebone/SM whale/GSRDZM Whalen/M whaler/M whaling/M whammed whamming/M wham/MS whammy/S wharf/SGMD Wharton/M wharves whatchamacallit/MS what'd whatever what/MS whatnot/MS what're whatsoever wheal/MS wheatgerm Wheaties/M Wheatland/M wheat/NMXS Wheaton/M Wheatstone/M wheedle/ZDRSG wheelbarrow/GSDM wheelbase/MS wheelchair/MS wheeler/M Wheeler/M wheelhouse/SM wheelie/MS wheeling/M Wheeling/M Wheelock/M wheel/RDMJSGZ wheelwright/MS whee/S wheeze/SDG wheezily wheeziness/SM wheezy/PRT Whelan/M whelk/MDS Wheller/M whelm/DGS whelp/DMGS whence/S whenever when/S whensoever whereabout/S whereas/S whereat whereby where'd wherefore/MS wherein where/MS whereof whereon where're wheresoever whereto whereupon wherever wherewith wherewithal/SM wherry/DSGM whether whet/S whetstone/MS whetted whetting whew/GSD whey/MS which whichever whiff/GSMD whiffle/DRSG whiffler/M whiffletree/SM whig/S Whig/SM while/GSD whilom whilst whimmed whimming whimper/DSG whimsey's whimsicality/MS whimsical/YP whim/SM whimsy/TMDRS whine/GZMSRD whining/Y whinny/GTDRS whiny/RT whipcord/SM whiplash/SDMG Whippany/M whipped whipper/MS whippersnapper/MS whippet/MS whipping/SM Whipple/M whippletree/SM whippoorwill/SM whipsaw/GDMS whips/M whip/SM whirligig/MS whirlpool/MS whirl/RDGS whirlwind/MS whirlybird/MS whirly/MS whirred whirring whir/SY whisker/DM whiskery whiskey/SM whisk/GZRDS whisperer/M whisper/GRDJZS whispering/YM whist/GDMS whistleable whistle/DRSZG whistler/M Whistler/M whistling/M Whitaker/M Whitby/M Whitcomb/M whitebait/M whitecap/MS whiteface/M Whitefield/M whitefish/SM Whitehall/M Whitehead/M whitehead/S Whitehorse/M Whiteleaf/M Whiteley/M White/MS whitener/M whiteness/MS whitening/M whiten/JZDRG whiteout/S white/PYS whitespace whitetail/S whitewall/SM whitewash/GRSDM whitewater Whitewater/M whitey/MS Whitfield/M whither/DGS whitier whitiest whiting/M whitish Whitley/M Whitlock/M Whit/M Whitman/M Whitney/M whit/SJGTXMRND Whitsunday/MS Whittaker/M whitter Whittier whittle/JDRSZG whittler/M whiz whizkid whizzbang/S whizzed whizzes whizzing WHO whoa/S who'd whodunit/SM whoever wholegrain wholeheartedness/MS wholehearted/PY wholemeal wholeness/S wholesale/GZMSRD wholesaler/M wholesomeness/USM wholesome/UYP whole/SP wholewheat who'll wholly whom who/M whomever whomsoever whoopee/S whooper/M whoop/SRDGZ whoosh/DSGM whop whopper/MS whopping/S who're whorehouse/SM whoreish whore/SDGM whorish whorl/SDM whose whoso whosoever who've why whys WI Wiatt/M Wichita/M wickedness/MS wicked/RYPT wicker/M wickerwork/MS wicketkeeper/SM wicket/SM wick/GZRDMS wicking/M widemouthed widener/M wideness/S widen/SGZRD wide/RSYTP widespread widgeon's widget/SM widower/M widowhood/S widow/MRDSGZ width/M widths widthwise Wieland/M wielder/M wield/GZRDS Wiemar/M wiener/SM wienie/SM Wier/M Wiesel/M wife/DSMYG wifeless wifely/RPT wigeon/MS wigged wigging/M Wiggins wiggler/M wiggle/RSDGZ wiggly/RT wight/SGDM wiglet/S wigmaker wig/MS Wigner/M wigwagged wigwagging wigwag/S wigwam/MS Wilberforce/M Wilbert/M Wilbur/M Wilburn/M Wilburt/M Wilcox/M Wilda/M wildcat/SM wildcatted wildcatter/MS wildcatting wildebeest/SM Wilde/MR Wilden/M Wilder/M wilderness/SM wilder/P wildfire/MS wildflower/S wildfowl/M wilding/M wildlife/M wildness/MS Wildon/M wild/SPGTYRD wile/DSMG Wileen/M Wilek/M Wiley/M Wilford/M Wilfred/M Wilfredo/M Wilfrid/M wilfulness's Wilhelmina/M Wilhelmine/M Wilhelm/M Wilie/M wilily wiliness/MS Wilkerson/M Wilkes/M Wilkins/M Wilkinson/M Willabella/M Willa/M Willamette/M Willamina/M Willard/M Willcox/M Willdon/M willed/U Willem/M Willemstad/M willer/M Willetta/M Willette/M Willey/M willfulness/S willful/YP Williamsburg/M William/SM Williamson/M Willied/M Willie/M willies Willi/MS willinger willingest willingness's willingness/US willing/UYP Willisson/M williwaw/MS Will/M Willoughby/M willower/M Willow/M willow/RDMSG willowy/TR willpower/MS will/SGJRD Willy/SDM Willyt/M Wilma/M Wilmar/M Wilmer/M Wilmette/M Wilmington/M Wilona/M Wilone/M Wilow/M Wilshire/M Wilsonian Wilson/M wilt/DGS Wilt/M Wilton/M wily/PTR Wimbledon/M wimp/GSMD wimpish wimple/SDGM wimpy/RT wince/SDG Winchell/M wincher/M winchester/M Winchester/MS winch/GRSDM windbag/SM windblown windbreak/MZSR windburn/GSMD winded winder/UM windfall/SM windflower/MS Windham/M Windhoek/M windily windiness/SM winding/MS windjammer/SM windlass/GMSD windless/YP windmill/GDMS window/DMGS windowless windowpane/SM Windows windowsill/SM windpipe/SM windproof windrow/GDMS wind's winds/A windscreen/MS windshield/SM windsock/MS Windsor/MS windstorm/MS windsurf/GZJSRD windswept windup/MS wind/USRZG Windward/M windward/SY Windy/M windy/TPR wineglass/SM winegrower/SM Winehead/M winemake winemaster wine/MS winery/MS Winesap/M wineskin/M Winfield/M Winfred/M Winfrey/M wingback/M wingding/MS wingeing winger/M wing/GZRDM wingless winglike wingman wingmen wingspan/SM wingspread/MS wingtip/S Winifield/M Winifred/M Wini/M winker/M wink/GZRDS winking/U Winkle/M winkle/SDGM winless Win/M winnable Winnah/M Winna/M Winnebago/M Winne/M winner/MS Winnetka/M Winnie/M Winnifred/M Winni/M winning/SY Winnipeg/M Winn/M winnow/SZGRD Winny/M Winograd/M wino/MS Winonah/M Winona/M Winooski/M Winsborough/M Winsett/M Winslow/M winsomeness/SM winsome/PRTY Winston/M winterer/M wintergreen/SM winterize/GSD Winters winter/SGRDYM wintertime/MS Winthrop/M wintriness/M wintry/TPR winy/RT win/ZGDRS wipe/DRSZG wiper/M wirehair/MS wireless/MSDG wireman/M wiremen wirer/M wire's wires/A wiretap/MS wiretapped wiretapper/SM wiretapping wire/UDA wiriness/S wiring/SM wiry/RTP Wisc Wisconsinite/SM Wisconsin/M wisdoms wisdom/UM wiseacre/MS wisecrack/GMRDS wised wisely/TR Wise/M wiseness wisenheimer/M Wisenheimer/M wises wise/URTY wishbone/MS wishfulness/M wishful/PY wish/GZSRD wishy wising Wis/M wisp/MDGS wispy/RT wist/DGS wisteria/SM wistfulness/MS wistful/PY witchcraft/SM witchdoctor/S witchery/MS witch/SDMG withal withdrawal/MS withdrawer/M withdrawnness/M withdrawn/P withdraw/RGS withdrew withe/M wither/GDJ withering/Y Witherspoon/M with/GSRDZ withheld withholder/M withhold/SJGZR within/S without/S withs withstand/SG withstood witlessness/MS witless/PY Wit/M witness/DSMG witnessed/U wit/PSM witted witter/G Wittgenstein/M witticism/MS Wittie/M wittily wittiness/SM wittings witting/UY Witt/M Witty/M witty/RTP Witwatersrand/M wive/GDS wives/M wizard/MYS wizardry/MS wizen/D wiz's wk/Y Wm/M WNW woad/MS wobble/GSRD wobbler/M wobbliness/S wobbly/PRST Wodehouse/M woebegone/P woefuller woefullest woefulness/SM woeful/PY woe/PSM woke wok/SMN Wolcott/M wold/MS Wolfe/M wolfer/M Wolff/M Wolfgang/M wolfhound/MS Wolfie/M wolfishness/M wolfish/YP Wolf/M wolfram/MS wolf/RDMGS Wolfy/M Wollongong/M Wollstonecraft/M Wolsey/M Wolverhampton/M wolverine/SM Wolverton/M wolves/M woman/GSMYD womanhood/MS womanish womanized/U womanizer/M womanize/RSDZG womanizes/U womankind/M womanlike womanliness/SM womanly/PRT wombat/MS womb/SDM womenfolk/MS women/MS wonderer/M wonderfulness/SM wonderful/PY wonder/GLRDMS wondering/Y wonderland/SM wonderment/SM wondrousness/M wondrous/YP Wong/M wonk/S wonky/RT wonned wonning won/SG won't wontedness/MU wonted/PUY wont/SGMD Woodard/M Woodberry/M woodbine/SM woodblock/S Woodbury/M woodcarver/S woodcarving/MS woodchopper/SM woodchuck/MS woodcock/MS woodcraft/MS woodcut/SM woodcutter/MS woodcutting/MS woodenness/SM wooden/TPRY woodgrain/G woodhen Woodhull/M Woodie/M woodiness/MS woodland/SRM Woodlawn/M woodlice woodlot/S woodlouse/M woodman/M Woodman/M woodmen woodpecker/SM woodpile/SM Woodrow/M woodruff/M woo/DRZGS woodshedded woodshedding woodshed/SM woodside Wood/SM woodsman/M woodsmen wood/SMNDG woodsmoke woods/R Woodstock/M woodsy/TRP Woodward/MS woodwind/S woodworker/M woodworking/M woodwork/SMRGZJ woodworm/M woodyard Woody/M woody/TPSR woofer/M woof/SRDMGZ Woolf/M woolgatherer/M woolgathering/M woolgather/RGJ woolliness/MS woolly/RSPT Woolongong/M wool/SMYNDX Woolworth/M Woonsocket/M Wooster/M Wooten/M woozily wooziness/MS woozy/RTP wop/MS! Worcestershire/M Worcester/SM wordage/SM word/AGSJD wordbook/MS Worden/M wordily wordiness/SM wording/AM wordless/Y wordplay/SM word's Wordsworth/M wordy/TPR wore workability's workability/U workableness/M workable/U workably workaday workaholic/S workaround/SM workbench/MS workbook/SM workday/SM worked/A worker/M workfare/S workforce/S work/GZJSRDMB workhorse/MS workhouse/SM working/M workingman/M workingmen workingwoman/M workingwomen workload/SM workmanlike Workman/M workman/MY workmanship/MS workmate/S workmen/M workout/SM workpiece/SM workplace/SM workroom/MS works/A worksheet/S workshop/MS workspace/S workstation/MS worktable/SM worktop/S workup/S workweek/SM worldlier worldliest worldliness/USM worldly/UP worldwide world/ZSYM wormer/M wormhole/SM worm/SGMRD Worms/M wormwood/SM wormy/RT worn/U worried/Y worrier/M worriment/MS worrisome/YP worrying/Y worrywart/SM worry/ZGSRD worsen/GSD worse/SR worshiper/M worshipfulness/M worshipful/YP worship/ZDRGS worsted/MS worst/SGD worth/DG worthily/U worthinesses/U worthiness/SM Worthington/M worthlessness/SM worthless/PY Worth/M worths worthwhile/P Worthy/M worthy/UTSRP wort/SM wost wot Wotan/M wouldn't would/S wouldst would've wound/AU wounded/U wounder wounding wounds wound's wove/A woven/AU wovens wow/SDG Wozniak/M WP wpm wrack/SGMD wraith/M wraiths Wrangell/M wrangle/GZDRS wrangler/M wraparound/S wrap/MS wrapped/U wrapper/MS wrapping/SM wraps/U wrasse/SM wrathful/YP wrath/GDM wraths wreak/SDG wreathe wreath/GMDS wreaths wreckage/MS wrecker/M wreck/GZRDS wrenching/Y wrench/MDSG wren/MS Wren/MS Wrennie/M wrester/M wrestle/JGZDRS wrestler/M wrestling/M wrest/SRDG wretchedness/SM wretched/TPYR wretch/MDS wriggle/DRSGZ wriggler/M wriggly/RT Wright/M wright/MS Wrigley/M wringer/M wring/GZRS wrinkled/U wrinkle/GMDS wrinkly/RST wristband/SM wrist/MS wristwatch/MS writable/U write/ASBRJG writer/MA writeup writhe/SDG writing/M writ/MRSBJGZ written/UA Wroclaw wrongdoer/MS wrongdoing/MS wronger/M wrongfulness/MS wrongful/PY wrongheadedness/MS wrongheaded/PY wrongness/MS wrong/PSGTYRD Wronskian/M wrote/A wroth wrought/I wrung wry/DSGY wryer wryest wryness/SM W's WSW wt W/T Wuhan/M Wu/M Wurlitzer/M wurst/SM wuss/S wussy/TRS WV WW WWI WWII WWW w/XTJGV WY Wyatan/M Wyatt/M Wycherley/M Wycliffe/M Wye/MH Wyeth/M Wylie/M Wylma/M Wyman/M Wyndham/M Wyn/M Wynne/M Wynnie/M Wynn/M Wynny/M Wyo/M Wyomingite/SM Wyoming/M WYSIWYG x X Xanadu Xanthippe/M Xanthus/M Xaviera/M Xavier/M Xebec/M Xe/M XEmacs/M Xenakis/M Xena/M Xenia/M Xenix/M xenon/SM xenophobe/MS xenophobia/SM xenophobic Xenophon/M Xenos xerographic xerography/MS xerox/GSD Xerox/MGSD Xerxes/M Xever/M Xhosa/M Xi'an Xian/S Xiaoping/M xii xiii xi/M Ximenes/M Ximenez/M Ximian/SM Xingu/M xis xiv xix XL Xmas/SM XML Xochipilli/M XOR X's XS xterm/M Xuzhou/M xv xvi xvii xviii xx XXL xylem/SM xylene/M Xylia/M Xylina/M xylophone/MS xylophonist/S Xymenes/M Y ya yacc/M Yacc/M yachting/M yachtsman yachtsmen yachtswoman/M yachtswomen yacht/ZGJSDM yack's Yagi/M yahoo/MS Yahweh/M Yakima/M yakked yakking yak/SM Yakut/M Yakutsk/M Yale/M Yalies/M y'all Yalonda/M Yalow/M Yalta/M Yalu/M Yamaha/M yammer/RDZGS Yamoussoukro yam/SM Yanaton/M Yance/M Yancey/M Yancy/M Yang/M Yangon yang/S Yangtze/M Yankee/SM yank/GDS Yank/MS Yaounde/M yapped yapping yap/S Yaqui/M yardage/SM yardarm/SM Yardley/M Yard/M yardman/M yardmaster/S yardmen yard/SMDG yardstick/SM yarmulke/SM yarn/SGDM Yaroslavl/M yarrow/MS Yasmeen/M Yasmin/M Yates yaw/DSG yawl/SGMD yawner/M yawn/GZSDR yawning/Y Yb/M yd Yeager/M yeah yeahs yearbook/SM yearling/M yearlong yearly/S yearner/M yearning/MY yearn/JSGRD year/YMS yea/S yeastiness/M yeast/SGDM yeasty/PTR Yeats/M yecch yegg/MS Yehudi/M Yehudit/M Yekaterinburg/M Yelena/M yell/GSDR yellowhammers yellowish Yellowknife/M yellowness/MS Yellowstone/M yellow/TGPSRDM yellowy yelper/M yelp/GSDR Yeltsin Yemeni/S Yemenite/SM Yemen/M Yenisei/M yenned yenning yen/SM Yentl/M yeomanry/MS yeoman/YM yeomen yep/S Yerevan/M Yerkes/M Yesenia/M yeshiva/SM yes/S yessed yessing yesterday/MS yesteryear/SM yet ye/T yeti/SM Yetta/M Yettie/M Yetty/M Yevette/M Yevtushenko/M yew/SM y/F Yggdrasil/M Yiddish/M yielded/U yielding/U yield/JGRDS yikes yin/S yipe/S yipped yippee/S yipping yip/S YMCA YMHA Ymir/M YMMV Ynes/M Ynez/M yo Yoda/M yodeler/M yodel/SZRDG Yoder/M yoga/MS yoghurt's yogi/MS yogurt/SM yoke/DSMG yoked/U yokel/SM yokes/U yoking/U Yoknapatawpha/M Yokohama/M Yoko/M Yolanda/M Yolande/M Yolane/M Yolanthe/M yolk/DMS yon yonder Yong/M Yonkers/M yore/MS Yorgo/MS Yorick/M Yorke/M Yorker/M yorker/SM Yorkshire/MS Yorktown/M York/ZRMS Yoruba/M Yosemite/M Yoshiko/M Yoshi/M Yost/M you'd you'll youngish Young/M youngster/MS Youngstown/M young/TRYP you're your/MS yourself yourselves you/SH youthfulness/SM youthful/YP youths youth/SM you've Yovonnda/M yow yowl/GSD Ypres/M Ypsilanti/M yr yrs Y's Ysabel/M YT ytterbium/MS yttrium/SM yuan/M Yuba/M Yucatan yucca/MS yuck/GSD yucky/RT Yugo/M Yugoslavia/M Yugoslavian/S Yugoslav/M Yuh/M Yuki/M yukked yukking Yukon/M yuk/S yule/MS Yule/MS yuletide/MS Yuletide/S Yul/M Yulma/M yum Yuma/M yummy/TRS Yunnan/M yuppie/SM yup/S Yurik/M Yuri/M yurt/SM Yves/M Yvette/M Yvon/M Yvonne/M Yvor/M YWCA YWHA Zabrina/M Zaccaria/M Zachariah/M Zacharia/SM Zacharie/M Zachary/M Zacherie/M Zachery/M Zach/M Zackariah/M Zack/M zagging Zagreb/M zag/S Zahara/M Zaire/M Zairian/S Zak/M Zambezi/M Zambia/M Zambian/S Zamboni Zamenhof/M Zamora/M Zandra/M Zane/M Zaneta/M zaniness/MS Zan/M Zanuck/M zany/PDSRTG Zanzibar/M Zapata/M Zaporozhye/M Zappa/M zapped zapper/S zapping zap/S Zarah/M Zara/M Zared/M Zaria/M Zarla/M Zealand/M zeal/MS zealot/MS zealotry/MS zealousness/SM zealous/YP Zea/M Zebadiah/M Zebedee/M Zeb/M zebra/MS Zebulen/M Zebulon/M zebu/SM Zechariah/M Zedekiah/M Zed/M Zedong/M zed/SM Zeffirelli/M Zeiss/M zeitgeist/S Zeke/M Zelda/M Zelig/M Zellerbach/M Zelma/M Zena/M Zenger/M Zenia/M zenith/M zeniths Zen/M Zennist/M Zeno/M Zephaniah/M zephyr/MS Zephyrus/M Zeppelin's zeppelin/SM Zerk/M zeroed/M zeroing/M zero/SDHMG zestfulness/MS zestful/YP zest/MDSG zesty/RT zeta/SM zeugma/M Zeus/M Zhdanov/M Zhengzhou Zhivago/M Zhukov/M Zia/M Zibo/M Ziegfeld/MS Ziegler/M zig zigged zigging Ziggy/M zigzagged zigzagger zigzagging zigzag/MS zilch/S zillion/MS Zilvia/M Zimbabwean/S Zimbabwe/M Zimmerman/M zincked zincking zinc/MS zing/GZDRM zingy/RT zinnia/SM Zionism/MS Zionist/MS Zion/SM zip/MS zipped/U zipper/GSDM zipping/U zippy/RT zips/U zirconium/MS zircon/SM Zita/M Zitella/M zither/SM zit/S zloty/SM Zn/M zodiacal zodiac/SM Zoe/M Zola/M Zollie/M Zolly/M Zomba/M zombie/SM zombi's zonal/Y Zonda/M Zondra/M zoned/A zone/MYDSRJG zones/A zoning/A zonked Zonnya/M zookeepers zoological/Y zoologist/SM zoology/MS zoom/DGS zoophyte/SM zoophytic zoo/SM Zorah/M Zora/M Zorana/M Zorina/M Zorine/M Zorn/M Zoroaster/M Zoroastrianism/MS Zoroastrian/S Zorro/M Zosma/M zounds/S Zr/M Zs Zsazsa/M Zsigmondy/M z/TGJ Zubenelgenubi/M Zubeneschamali/M zucchini/SM Zukor/M Zulema/M Zululand/M Zulu/MS Zuni/S Zrich/M Zuzana/M zwieback/MS Zwingli/M Zworykin/M Z/X zydeco/S zygote/SM zygotic zymurgy/S mudlet-2.1/src/astar.cpp0000644000175000017500000001545311513237311014570 0ustar csmallcsmall // //======================================================================= // Copyright (c) 2004 Kristopher Beevers // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= // #include #include #include #include #include #include #include #include #include #include #include // for sqrt using namespace boost; using namespace std; // auxiliary types struct location { float y, x, z; // lat, long }; typedef float cost; template class city_writer { public: city_writer(Name n, LocMap l, float _minx, float _maxx, float _minz, float _miny, float _maxy, float _maxz, unsigned int _ptx, unsigned int _pty, unsigned int _ptz ) : name(n), loc(l), minx(_minx), maxx(_maxx), miny(_miny), maxy(_maxy), minz(_minz), maxz(_maxz), ptx(_ptx), pty(_pty), ptz(_ptz) {} template void operator()(ostream& out, const Vertex& v) const { float px = 1 - (loc[v].x - minx) / (maxx - minx); float py = (loc[v].y - miny) / (maxy - miny); float pz = (loc[v].z - minz) / (maxz - minz); out << "[label=\"" << name[v] << "\", pos=\"" << static_cast(ptx * px) << "," << static_cast(pty * py) << "," << static_cast(ptz * pz) << "\", fontsize=\"11\"]"; } private: Name name; LocMap loc; float minx, maxx, miny, maxy, minz, maxz; unsigned int ptx, pty, ptz; }; template class time_writer { public: time_writer(WeightMap w) : wm(w) {} template void operator()(ostream &out, const Edge& e) const { out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]"; } private: WeightMap wm; }; // euclidean distance heuristic template class distance_heuristic : public astar_heuristic { public: typedef typename graph_traits::vertex_descriptor Vertex; distance_heuristic(LocMap l, Vertex goal) : m_location(l), m_goal(goal) {} CostType operator()(Vertex u) { CostType dx = m_location[m_goal].x - m_location[u].x; CostType dy = m_location[m_goal].y - m_location[u].y; CostType dz = m_location[m_goal].z - m_location[u].z; return ::sqrt(dx * dx + dy * dy + dz * dz); } private: LocMap m_location; Vertex m_goal; }; struct found_goal {}; // exception for termination // visitor that terminates when we find the goal template class astar_goal_visitor : public boost::default_astar_visitor { public: astar_goal_visitor(Vertex goal) : m_goal(goal) {} template void examine_vertex(Vertex u, Graph& g) { if(u == m_goal) throw found_goal(); } private: Vertex m_goal; }; int main(int argc, char **argv) { // specify some types typedef adjacency_list > mygraph_t; typedef property_map::type WeightMap; typedef mygraph_t::vertex_descriptor vertex; typedef mygraph_t::edge_descriptor edge_descriptor; typedef mygraph_t::vertex_iterator vertex_iterator; typedef std::pair edge; // specify data enum nodes { Troy, LakePlacid, Plattsburgh, Massena, Watertown, Utica, Syracuse, Rochester, Buffalo, Ithaca, Binghamton, Woodstock, NewYork, N }; const char *name[] = { "Troy", "Lake Placid", "Plattsburgh", "Massena", "Watertown", "Utica", "Syracuse", "Rochester", "Buffalo", "Ithaca", "Binghamton", "Woodstock", "New York" }; location locations[] = { // lat/long {42.73, 73.68, 12.3}, {44.28, 73.99, 15.7}, {44.70, 73.46, 194.8}, {44.93, 74.89, 5.4}, {43.97, 75.91, 942.5}, {43.10, 75.23, 28.7}, {43.04, 76.14, 93.8}, {43.17, 77.61, 17.8}, {42.89, 78.86,56.8}, {42.44, 76.50,98.1}, {42.10, 75.91,28.8}, {42.04, 74.11,9.6}, {40.67, 73.94, 17.7} }; edge edge_array[] = { edge(Troy,Utica), edge(Troy,LakePlacid), edge(Troy,Plattsburgh), edge(LakePlacid,Plattsburgh), edge(Plattsburgh,Massena), edge(LakePlacid,Massena), edge(Massena,Watertown), edge(Watertown,Utica), edge(Watertown,Syracuse), edge(Utica,Syracuse), edge(Syracuse,Rochester), edge(Rochester,Buffalo), edge(Syracuse,Ithaca), edge(Ithaca,Binghamton), edge(Ithaca,Rochester), edge(Binghamton,Troy), edge(Binghamton,Woodstock), edge(Binghamton,NewYork), edge(Syracuse,Binghamton), edge(Woodstock,Troy), edge(Woodstock,NewYork) }; unsigned int num_edges = sizeof(edge_array) / sizeof(edge); cost weights[] = { // estimated travel time (mins) 96, 134, 143, 65, 115, 133, 117, 116, 74, 56, 84, 73, 69, 70, 116, 147, 173, 183, 74, 71, 124 }; // create graph mygraph_t g(N); WeightMap weightmap = get(edge_weight, g); for(std::size_t j = 0; j < num_edges; ++j) { edge_descriptor e; bool inserted; tie(e, inserted) = add_edge(edge_array[j].first, edge_array[j].second, g); weightmap[e] = weights[j]; } // pick random start/goal mt19937 gen(time(0)); vertex start = random_vertex(g, gen); vertex goal = random_vertex(g, gen); cout << "Start vertex: " << name[start] << endl; cout << "Goal vertex: " << name[goal] << endl; ofstream dotfile; dotfile.open("test-astar-cities.dot"); write_graphviz(dotfile, g, city_writer (name, locations, 73.46, 78.86,12.76,24.8,40.67, 44.93, 480, 400,300), time_writer(weightmap)); vector p(num_vertices(g)); vector d(num_vertices(g)); try { // call astar named parameter interface astar_search (g, start, distance_heuristic (locations, goal), predecessor_map(&p[0]).distance_map(&d[0]). visitor(astar_goal_visitor(goal))); } catch(found_goal fg) { // found a path to the goal list shortest_path; for(vertex v = goal;; v = p[v]) { shortest_path.push_front(v); if(p[v] == v) break; } cout << "Shortest path from " << name[start] << " to " << name[goal] << ": "; list::iterator spi = shortest_path.begin(); cout << name[start]; for(++spi; spi != shortest_path.end(); ++spi) cout << " -> " << name[*spi]; cout << endl << "Total travel time: " << d[goal] << endl; return 0; } cout << "Didn't find a path from " << name[start] << "to" << name[goal] << "!" << endl; return 0; }mudlet-2.1/src/dlgComposer.cpp0000644000175000017500000000404711513237311015731 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn - KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "dlgComposer.h" #include #include "TDebug.h" #include "Host.h" dlgComposer::dlgComposer( Host * pH ) : mpHost( pH ) { setupUi(this); QFont f = QFont("Bitstream Vera Sans Mono", 10, QFont::Courier ); edit->setFont ( f ); connect( saveButton, SIGNAL(pressed()), this, SLOT(save())); connect( cancelButton, SIGNAL(pressed()), this, SLOT(cancel())); } void dlgComposer::cancel() { mpHost->mTelnet.atcpComposerCancel(); this->hide(); } void dlgComposer::save() { mpHost->mTelnet.atcpComposerSave( edit->toPlainText() ); this->hide(); } void dlgComposer::init( QString t, QString txt ) { titel->setText( t ); edit->setPlainText( txt ); } mudlet-2.1/src/dlgSystemMessageArea.cpp0000644000175000017500000000304711513237311017523 0ustar csmallcsmall /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "dlgSystemMessageArea.h" dlgSystemMessageArea::dlgSystemMessageArea(QWidget * pF) : QWidget(pF) { // init generated dialog setupUi(this); } mudlet-2.1/src/TriggerUnit.cpp0000644000175000017500000003541312020507607015721 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include // NULL #include #include #include #include #include "Host.h" #include "TLuaInterpreter.h" #include "TConsole.h" #include #include "TriggerUnit.h" using namespace std; void TriggerUnit::initStats() { statsTriggerTotal = 0; statsTempTriggers = 0; statsActiveTriggers = 0; statsActiveTriggersMax = 0; statsActiveTriggersMin = 0; statsActiveTriggersAverage = 0; statsTempTriggersCreated = 0; statsTempTriggersKilled = 0; statsAverageLineProcessingTime = 0; statsMaxLineProcessingTime = 0; statsMinLineProcessingTime = 0; statsRegexTriggers = 0; } void TriggerUnit::_uninstall( TTrigger * pChild, QString packageName ) { typedef list::const_iterator I; list * childrenList = pChild->mpMyChildrenList; for( I it2 = childrenList->begin(); it2 != childrenList->end(); it2++) { TTrigger * pT = *it2; _uninstall( pT, packageName ); uninstallList.append( pT ); } } void TriggerUnit::uninstall( QString packageName ) { typedef std::list::iterator IT; for( IT it = mTriggerRootNodeList.begin(); it != mTriggerRootNodeList.end(); it ++ ) { TTrigger * pT = *it; if( pT->mPackageName == packageName ) { _uninstall( pT, packageName ); uninstallList.append( pT ); } } for( int i=0; i::const_iterator I; for( I it = mTriggerRootNodeList.begin(); it != mTriggerRootNodeList.end(); it++) { TTrigger * pChild = *it; if( pChild->isTempTrigger() ) { pChild->setIsActive( false ); markCleanup( pChild ); } } } void TriggerUnit::addTriggerRootNode( TTrigger * pT, int parentPosition, int childPosition, bool moveTrigger ) { if( ! pT ) return; if( ! pT->getID() ) { pT->setID( getNewID() ); } if( ( parentPosition == -1 ) || ( childPosition >= static_cast(mTriggerRootNodeList.size()) ) ) { mTriggerRootNodeList.push_back( pT ); } else { // insert item at proper position int cnt = 0; typedef std::list::iterator IT; for( IT it = mTriggerRootNodeList.begin(); it != mTriggerRootNodeList.end(); it ++ ) { if( cnt >= childPosition ) { mTriggerRootNodeList.insert( it, pT ); break; } cnt++; } } if( ! moveTrigger ) { mTriggerMap.insert( pT->getID(), pT ); } } void TriggerUnit::reParentTrigger( int childID, int oldParentID, int newParentID, int parentPosition, int childPosition ) { TTrigger * pOldParent = getTriggerPrivate( oldParentID ); TTrigger * pNewParent = getTriggerPrivate( newParentID ); TTrigger * pChild = getTriggerPrivate( childID ); if( ! pChild ) { return; } if( pOldParent ) { pOldParent->popChild( pChild ); } else { mTriggerRootNodeList.remove( pChild ); } if( pNewParent ) { pNewParent->addChild( pChild, parentPosition, childPosition ); if( pChild ) pChild->setParent( pNewParent ); //cout << "dumping family of newParent:"<Dump(); } else { pChild->Tree::setParent( 0 ); addTriggerRootNode( pChild, parentPosition, childPosition, true ); } } void TriggerUnit::removeTriggerRootNode( TTrigger * pT ) { if( ! pT ) return; if( ! pT->mIsTempTrigger ) { mLookupTable.remove( pT->mName, pT ); } else { mLookupTable.remove( pT->getName() ); } mTriggerMap.remove( pT->getID() ); mTriggerRootNodeList.remove( pT ); } TTrigger * TriggerUnit::getTrigger( int id ) { QMutexLocker locker(& mTriggerUnitLock); if( mTriggerMap.find( id ) != mTriggerMap.end() ) { return mTriggerMap.value( id ); } else { return 0; } } TTrigger * TriggerUnit::getTriggerPrivate( int id ) { if( mTriggerMap.find( id ) != mTriggerMap.end() ) { return mTriggerMap.value( id ); } else { return 0; } } bool TriggerUnit::registerTrigger( TTrigger * pT ) { if( ! pT ) return false; if( pT->getParent() ) { addTrigger( pT ); return true; } else { addTriggerRootNode( pT ); return true; } } void TriggerUnit::unregisterTrigger( TTrigger * pT ) { if( ! pT ) return; if( pT->getParent() ) { removeTrigger( pT ); return; } else { removeTriggerRootNode( pT ); return; } } void TriggerUnit::addTrigger( TTrigger * pT ) { if( ! pT ) return; if( ! pT->getID() ) { pT->setID( getNewID() ); } mTriggerMap.insert( pT->getID(), pT ); } void TriggerUnit::removeTrigger( TTrigger * pT ) { if( ! pT ) return; if( ! pT->mIsTempTrigger ) { mLookupTable.remove( pT->mName, pT ); } else mLookupTable.remove( pT->getName() ); mTriggerMap.remove(pT->getID()); } qint64 TriggerUnit::getNewID() { return ++mMaxID; } void TriggerUnit::processDataStream( QString & data, int line ) { if( data.size() > 0 ) { char * subject = (char *) malloc( strlen( data.toLocal8Bit().data() ) + 1 ); strcpy( subject, data.toLocal8Bit().data() ); typedef list::const_iterator I; for( I it = mTriggerRootNodeList.begin(); it != mTriggerRootNodeList.end(); it++) { TTrigger * pChild = *it; //QFuture future = QtConcurrent::run( pChild, &TTrigger::match, subject, data, line, 0 ); //future.waitForFinished(); pChild->match( subject, data, line ); } free( subject ); for( I it = mCleanupList.begin(); it != mCleanupList.end(); it++ ) { delete *it; } mCleanupList.clear(); } } void TriggerUnit::compileAll() { typedef list::const_iterator I; for( I it = mTriggerRootNodeList.begin(); it != mTriggerRootNodeList.end(); it++) { TTrigger * pChild = *it; if( pChild->isActive() ) { pChild->compileAll(); } } } void TriggerUnit::stopAllTriggers() { typedef list::const_iterator I; for( I it = mTriggerRootNodeList.begin(); it != mTriggerRootNodeList.end(); it++) { TTrigger * pChild = *it; QString name = pChild->getName(); pChild->disableFamily(); } } void TriggerUnit::reenableAllTriggers() { typedef list::const_iterator I; for( I it = mTriggerRootNodeList.begin(); it != mTriggerRootNodeList.end(); it++) { TTrigger * pChild = *it; pChild->enableFamily(); } } bool TriggerUnit::serialize( QDataStream & ofs ) { bool ret = true; ofs << (qint64)mMaxID; ofs << (qint64)mTriggerRootNodeList.size(); typedef list::const_iterator I; for( I it = mTriggerRootNodeList.begin(); it != mTriggerRootNodeList.end(); it++) { TTrigger * pChild = *it; ret = pChild->serialize( ofs ); } return ret; } bool TriggerUnit::restore( QDataStream & ifs, bool initMode ) { ifs >> mMaxID; qint64 children; ifs >> children; //if( initMode ) qDebug()<<"TriggerUnit::restore() mMaxID="<::iterator I; for( I it = mCleanupList.begin(); it != mCleanupList.end(); it++) { delete *it; } mCleanupList.clear(); } void TriggerUnit::markCleanup( TTrigger * pT ) { typedef list::iterator I; for( I it = mCleanupList.begin(); it != mCleanupList.end(); it++) { if( *it == pT ) { return; } } mCleanupList.push_back( pT ); } mudlet-2.1/src/Mudlet_Programming_Reference.txt0000755000175000017500000001331411513237311021262 0ustar csmallcsmall (= manages all mud sessions) +-------------+ +-----------------+ | HostManager | <--- | HostManagerView | +------+------+ +-----------------+ | +----+-----+ | HostPool | (= one mud session) +----+-----+ (= html conversion) | +------------------+ +--------------------+ +---+--------+ +----------+ | Browser Display | <--- | OutputPreprocessor +---+ Host | <--- | HostView | +------------------+ +--------------------+ +---+----+---+ +----------+ | | | | | | +--------------------+ | +-----------+ (= host session scripts) | | | (= manages stand alone scripts) +--------------------+-------+ +-------+----+ +-----+----------+ +----------------+ | Host ScriptingModule | | DataPool ####### JobManager | <--- | JobManagerView + +--------+-------------------+ +--+--#--+---+ +-+------------+-+ +----------------+ | | # | | | | +-------------+ # | +----+----+ +--+-------------+ +-------------+------+ | Telnet | # | | JobPool | | JobProcessor | | Scripting engines | +-------------+ # | +---------+ +-----+----------+ +--------------------+ # | | * +-----#--+-----------+ +------+--------------+ * | DataProcessingUnit | | Job ScriptingModule | * +--+---------+-------+ +--------+------------+ * | | | * +-------------+------+ +------------+ +------+-----------+ ******** | TriggerUnit | | | FilterUnit | | Scripting engine | * +-------------+ | +------------+ +------------------+ * | * /\ * +-----------+------+ * \ ********** | AliasUnit | * \ +--------------------------+ * +-----------+ * \| Filter/Trigger/AliasView | * * +--------------------------+ ******************************************* Data Flow Chart =============== Input Stream: ------------- Server => Telnet +---> JobManager ----------------------------------------+ | | (stand alone scripts have direct access | | | to both original Input and direct output, i.e. they | | | can exec or call Javascript functions/code in | +---> DataPool the display browser, but more often will use | | the OutputPreprocessor for convenience. | | | +---> DataProcessingUnit | | | | | +--- >FilterUnit | | | | +-----------+ +---> TriggerUnit | | | | | | | | +---> OutputPreprocessor | | | | | +---> TConsole (Display) Output Stream ------------- User Actions/Input => stand alone Scripts => AliasUnit -> Telnet => Server Trigger Scripts => mudlet-2.1/src/ctelnet.h0000644000175000017500000001460512076170616014570 0ustar csmallcsmall/*************************************************************************** copyright (C) 2002-2005 by Tomas Mecir (kmuddy@kmuddy.com) copyright (c) 2008-2009 by Heiko Koehn (koehnheiko@googlemail.com) *************************************************************************** * * * 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. * * * ***************************************************************************/ #ifndef CTELNET_H #define CTELNET_H #include #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dlgComposer.h" #include #include const char TN_SE = 240; const char TN_NOP = 241; const char TN_DM = 242; const char TN_B = 243; const char TN_IP = 244; const char TN_AO = 245; const char TN_AYT = 246; const char TN_EC = 247; const char TN_EL = 248; const char TN_GA = 249; const char TN_SB = 250; const char TN_WILL = 251; const char TN_WONT = 252; const char TN_DO = 253; const char TN_DONT = 254; const char TN_IAC = 255; const char GMCP = 201; /* GMCP */ const char MXP = 91; //MXP const char OPT_ECHO = 1; const char OPT_SUPPRESS_GA = 3; const char OPT_STATUS = 5; const char OPT_TIMING_MARK = 6; const char OPT_TERMINAL_TYPE = 24; const char OPT_NAWS = 31; const char OPT_COMPRESS = 85; const char OPT_COMPRESS2 = 86; const char OPT_MSP = 90; const char OPT_MXP = 91; const char TNSB_IS = 0; const char TNSB_SEND = 1; class mudlet; class Host; //class dlgComposer; class cTelnet : public QObject { Q_OBJECT public: cTelnet( Host * pH ); ~cTelnet(); void connectIt(const QString &address, int port); void disconnect(); bool sendData ( QString & data ); void setCommandEcho( bool cmdEcho ); void setATCPVariables( QString & _msg ); void setGMCPVariables( QString & _msg ); void atcpComposerCancel(); void atcpComposerSave( QString ); void setLPMudStyle ( bool lpmustyle ); void setNegotiateOnStartup( bool startupneg ); void setDisplayDimensions(); void encodingChanged(QString encoding); void set_USE_IRE_DRIVER_BUGFIX( bool b ){ mUSE_IRE_DRIVER_BUGFIX=b; } void set_LF_ON_GA( bool b ){ mLF_ON_GA=b; } void recordReplay(); void loadReplay( QString & ); void _loadReplay(); void setChannel102Variables( QString & ); bool socketOutRaw(std::string & data); QMap supportedTelnetOptions; bool mResponseProcessed; double networkLatency; QTime networkLatencyTime; bool mAlertOnNewData; bool mGA_Driver; bool mFORCE_GA_OFF; dlgComposer * mpComposer; QNetworkAccessManager * mpDownloader; QProgressDialog * mpProgressDialog; QString mServerPackage; public slots: void setDownloadProgress( qint64, qint64 ); void replyFinished( QNetworkReply * ); void readPipe(); void handle_socket_signal_hostFound(QHostInfo); void handle_socket_signal_connected(); void handle_socket_signal_disconnected(); void handle_socket_signal_readyRead(); void handle_socket_signal_error(); void slot_timerPosting(); void slot_send_login(); void slot_send_pass(); private: cTelnet(){;} void initStreamDecompressor(); int decompressBuffer( char * dirtyBuffer, int length ); void postMessage( QString msg ); void reset(); void connectionFailed(); void processTelnetCommand (const std::string &command); void sendTelnetOption( char type, char option); //string getCurrentTime(); //NOTE: not w32 compatible void gotRest( std::string & ); void gotPrompt( std::string & ); void postData(); Host * mpHost; QTcpSocket socket; QHostAddress mHostAddress; QTextCodec * incomingDataCodec; QTextCodec * outgoingDataCodec; QTextDecoder * incomingDataDecoder; QTextEncoder * outgoingDataDecoder; QString hostName; int hostPort; QDataStream mOfs; double networkLatencyMin; double networkLatencyMax; bool mWaitingForResponse; std::queue mCommandQueue; z_stream mZstream; bool mNeedDecompression; bool mWaitingForCompressedStreamToStart; std::string command; bool iac, iac2, insb; bool myOptionState[256], hisOptionState[256]; bool announcedState[256]; bool heAnnouncedState[256]; bool triedToEnable[256]; bool recvdGA; int curX, curY; QString termType; QString encoding; QTimer * mpPostingTimer; bool mUSE_IRE_DRIVER_BUGFIX; bool mLF_ON_GA; int mCommands; bool mMCCP_version_1; bool mMCCP_version_2; std::string mMudData; bool mIsTimerPosting; QTimer * mTimerLogin; QTimer * mTimerPass; QTime timeOffset; QTime mConnectionTime; int lastTimeOffset; bool enableATCP; bool enableGMCP; bool enableChannel102; }; #endif mudlet-2.1/src/XMLimport.cpp0000644000175000017500000014436012070466512015357 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn ( KoehnHeiko@googlemail.com ) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "XMLimport.h" #include "mudlet.h" #include #include int maxRooms; int maxAreas; QMap areaMap; //int module = 0; XMLimport::XMLimport( Host * pH ) : mpHost( pH ) { } bool XMLimport::importPackage( QIODevice * device, QString packName, int moduleFlag) { mPackageName = packName; setDevice( device ); gotTrigger = false; gotTimer = false; gotAlias = false; gotKey = false; gotAction = false; gotScript = false; module = moduleFlag; qDebug()<<"module flag:"<mModuleMasterFolder=true; mpKey->mModuleMember=true; } mpKey->setPackageName( mPackageName ); mpKey->setIsActive( true ); mpKey->setName( mPackageName ); mpKey->setIsFolder( true ); mpTrigger = new TTrigger( 0, mpHost ); if (module){ mpTrigger->mModuleMasterFolder=true; mpTrigger->mModuleMember=true; } mpTrigger->setPackageName( mPackageName ); mpTrigger->setIsActive( true ); mpTrigger->setName( mPackageName ); mpTrigger->setIsFolder( true ); mpTimer = new TTimer( 0, mpHost ); mpTimer->setIsFolder( true ); if (module){ mpTimer->mModuleMasterFolder=true; mpTimer->mModuleMember=true; } mpTimer->setPackageName( mPackageName ); mpTimer->setName( mPackageName ); mpTimer->setIsActive( true ); mpAlias = new TAlias( 0, mpHost ); if (module){ mpAlias->mModuleMasterFolder=true; mpAlias->mModuleMember=true; } mpAlias->setPackageName( mPackageName ); mpAlias->setName( mPackageName ); mpAlias->setIsFolder( true ); QString _nothing = ""; mpAlias->setScript(_nothing); mpAlias->setRegexCode(""); mpAlias->setIsActive( true ); mpAction = new TAction( 0, mpHost ); if (module){ mpAction->mModuleMasterFolder=true; mpAction->mModuleMember=true; } mpAction->setPackageName( mPackageName ); mpAction->setIsActive( true ); mpAction->setName( mPackageName ); mpAction->setIsFolder( true ); mpScript = new TScript( 0, mpHost ); if (module){ mpScript->mModuleMasterFolder=true; mpScript->mModuleMember=true; } mpScript->setPackageName( mPackageName ); mpScript->setIsActive( true ); mpScript->setName( mPackageName ); mpScript->setIsFolder( true ); mpHost->getTriggerUnit()->registerTrigger( mpTrigger ); mpHost->getTimerUnit()->registerTimer( mpTimer ); mpHost->getAliasUnit()->registerAlias( mpAlias ); mpHost->getActionUnit()->registerAction( mpAction ); mpHost->getKeyUnit()->registerKey( mpKey ); mpHost->getScriptUnit()->registerScript( mpScript ); } while( ! atEnd() ) { readNext(); if( isStartElement() ) { if( name() == "MudletPackage" )// && attributes().value("version") == "1.0") { readPackage(); } else if( name() == "map" ) { maxAreas = 0; maxRooms = 0; areaMap.clear(); readMap(); mpHost->mpMap->init(mpHost); } else { qDebug()<<"ERROR:name="<setIsActive( true ); mpTimer->enableTimer( mpTimer->getID() ); } if( gotAlias && ! packName.isEmpty() ) { mpAlias->setIsActive( true ); } if( gotAction && ! packName.isEmpty() ) { mpHost->getActionUnit()->updateToolbar(); } if( ! packName.isEmpty()) { if( ! gotTrigger ) mpHost->getTriggerUnit()->unregisterTrigger( mpTrigger ); if( ! gotTimer ) mpHost->getTimerUnit()->unregisterTimer( mpTimer ); if( ! gotAlias ) mpHost->getAliasUnit()->unregisterAlias( mpAlias ); if( ! gotAction ) mpHost->getActionUnit()->unregisterAction( mpAction ); if( ! gotKey ) mpHost->getKeyUnit()->unregisterKey( mpKey ); if( ! gotScript ) mpHost->getScriptUnit()->unregisterScript( mpScript ); } return ! error(); } void XMLimport::readMap() { while( ! atEnd() ) { readNext(); if( isStartElement() ) { if( name() == "areas" ) { mpHost->mpMap->areaNamesMap.clear(); readAreas(); } else if( name() == "rooms" ) { readRooms(); } else if( name() == "environments" ) { readEnvColors(); } } } } void XMLimport::readEnvColors() { while( ! atEnd() ) { readNext(); if( name() == "environment" ) { readEnvColor(); } /*else { readUnknownMapElement(); }*/ } } void XMLimport::readEnvColor() { int id = attributes().value("id").toString().toInt(); int color = attributes().value("color").toString().toInt(); mpHost->mpMap->envColors[id] = color; } void XMLimport::readAreas() { while( ! atEnd() ) { readNext(); if( name() == "areas") { break; } if( name() == "area" ) { readAreaNames(); } } } void XMLimport::readAreaNames() { int id = attributes().value("id").toString().toInt(); QString name = attributes().value("name").toString(); mpHost->mpMap->areaNamesMap[id] = name; } void XMLimport::readRooms() { while( ! atEnd() ) { readNext(); if( isEndElement() ) { break; } if( isStartElement() ) { if( name() == "room" ) { readRoom(); } else { readUnknownMapElement(); } } } } void XMLimport::readRoom() { TRoom * pT = new TRoom; pT->id = attributes().value("id").toString().toInt(); pT->area = attributes().value("area").toString().toInt(); pT->name = attributes().value("title").toString(); pT->environment = attributes().value("environment").toString().toInt(); while( ! atEnd() ) { readNext(); if( name() == "" ) continue; if( name() == "coord" ) { if( attributes().value("x").toString() == "" ) continue; pT->x = attributes().value("x").toString().toInt(); pT->y = attributes().value("y").toString().toInt(); pT->z = attributes().value("z").toString().toInt(); continue; } else if( name() == "exit") { QString dir = attributes().value("direction").toString(); int e = attributes().value("target").toString().toInt(); if( dir == "" ) continue; if( dir == "north" ) { pT->north = e; } if( dir == "south" ) { pT->south = e; } if( dir == "northwest" ) { pT->northwest = e; } if( dir == "southwest" ) { pT->southwest = e; } if( dir == "northeast" ) { pT->northeast = e; } if( dir == "southeast" ) { pT->southeast = e; } if( dir == "west" ) { pT->west = e; } if( dir == "east" ) { pT->east = e; } if( dir == "up" ) { pT->up = e; } if( dir == "down" ) { pT->down = e; } if( dir == "in" ) { pT->in = e; } if( dir == "out" ) { pT->out = e; } continue; } if( isEndElement() ) { break; } } if( pT->id != 0 ) { mpHost->mpMap->rooms[pT->id] = pT; maxRooms++; } else delete pT; } void XMLimport::readUnknownMapElement() { while( ! atEnd() ) { readNext(); if( isEndElement() ) { break; } if( isStartElement() ) { readMap(); } } } void XMLimport::readUnknownRoomElement() { while( ! atEnd() ) { readNext(); qDebug()<<"[ERROR]: UNKNOWN room element:name="<moduleHelp[mPackageName].insert("helpURL", contents); continue; } } } } void XMLimport::readUnknownPackage() { while( ! atEnd() ) { readNext(); qDebug()<<"[ERROR]: UNKNOWN readUnknownPackage() Package Element:"<mAutoClearCommandLineAfterSend = ( attributes().value("autoClearCommandLineAfterSend") == "yes" ); pT->mDisableAutoCompletion = ( attributes().value("disableAutoCompletion") == "yes" ); pT->mPrintCommand = ( attributes().value("printCommand") == "yes" ); pT->set_USE_IRE_DRIVER_BUGFIX( attributes().value("USE_IRE_DRIVER_BUGFIX") == "yes" ); pT->mUSE_FORCE_LF_AFTER_PROMPT = ( attributes().value("mUSE_FORCE_LF_AFTER_PROMPT") == "yes" ); pT->mUSE_UNIX_EOL = ( attributes().value("mUSE_UNIX_EOL") == "yes" ); pT->mNoAntiAlias = ( attributes().value("mNoAntiAlias") == "yes" ); pT->mRawStreamDump = ( attributes().value("mRawStreamDump") == "yes" ); pT->mAlertOnNewData = ( attributes().value("mAlertOnNewData") == "yes" ); pT->mFORCE_NO_COMPRESSION = ( attributes().value("mFORCE_NO_COMPRESSION") == "yes" ); pT->mFORCE_GA_OFF = ( attributes().value("mFORCE_GA_OFF") == "yes" ); pT->mFORCE_SAVE_ON_EXIT = ( attributes().value("mFORCE_SAVE_ON_EXIT") == "yes" ); pT->mEnableGMCP = ( attributes().value("mEnableGMCP") == "yes" ); pT->mMapStrongHighlight = ( attributes().value("mMapStrongHighlight") == "yes" ); pT->mLogStatus = ( attributes().value("mLogStatus") == "yes" ); pT->mEnableSpellCheck = ( attributes().value("mEnableSpellCheck") == "yes" ); pT->mShowInfo = ( attributes().value("mShowInfo") == "yes" ); pT->mAcceptServerGUI = ( attributes().value("mAcceptServerGUI") == "yes" ); pT->mMapperUseAntiAlias = ( attributes().value("mMapperUseAntiAlias") == "yes" ); pT->mFORCE_MXP_NEGOTIATION_OFF = ( attributes().value("mFORCE_MXP_NEGOTIATION_OFF") == "yes" ); pT->mRoomSize = attributes().value("mRoomSize").toString().toInt(); if (!pT->mRoomSize) pT->mRoomSize=3; pT->mLineSize = attributes().value("mLineSize").toString().toInt(); if (!pT->mLineSize) pT->mLineSize=1; pT->mBubbleMode = ( attributes().value("mBubbleMode") == "yes" ); pT->mShowRoomID = ( attributes().value("mShowRoomIDs") == "yes" ); pT->mShowPanel = ( attributes().value("mShowPanel") == "yes" ); pT->mHaveMapperScript = ( attributes().value("mHaveMapperScript") == "yes"); while( ! atEnd() ) { readNext(); if( isEndElement() ) break; if( isStartElement() ) { if( name() == "name" ) { pT->mHostName = readElementText(); continue; } else if( name() == "mInstalledModules") { QMap entry; readMapList(entry); QMapIterator it(entry); while (it.hasNext()){ it.next(); QStringList moduleList; QStringList entryList = it.value(); moduleList << entryList[0]; moduleList << entryList[1]; pT->mInstalledModules[it.key()] = moduleList; pT->mModulePriorities[it.key()] = entryList[2].toInt(); } //readMapList( pT->mInstalledModules ); continue; } else if( name() == "mInstalledPackages") { readStringList( pT->mInstalledPackages ); continue; } else if( name() =="url" ) { pT->mUrl = readElementText(); continue; } else if( name() =="serverPackageName" ) { pT->mServerGUI_Package_name = readElementText(); continue; } else if( name() == "serverPackageVersion") { pT->mServerGUI_Package_version = readElementText().toInt(); continue; } else if( name() == "port") { pT->mPort = readElementText().toInt(); continue; } else if( name() == "borderTopHeight") { pT->mBorderTopHeight = readElementText().toInt(); continue; } else if( name() == "commandLineMinimumHeight") { pT->commandLineMinimumHeight = readElementText().toInt(); continue; } else if( name() == "borderBottomHeight") { pT->mBorderBottomHeight = readElementText().toInt(); continue; } else if( name() == "borderLeftWidth") { pT->mBorderLeftWidth = readElementText().toInt(); continue; } else if( name() == "borderRightWidth") { pT->mBorderRightWidth = readElementText().toInt(); continue; } else if( name() == "wrapAt") { pT->mWrapAt = readElementText().toInt(); continue; } else if( name() == "wrapIndentCount" ) { pT->mWrapIndentCount = readElementText().toInt(); continue; } else if( name() == "mCommandSeparator" ) { pT->mCommandSeparator = readElementText(); continue; } else if( name() == "mCommandLineFgColor") { pT->mCommandLineFgColor.setNamedColor( readElementText() ); continue; } else if( name() == "mCommandLineBgColor") { pT->mCommandLineBgColor.setNamedColor( readElementText() ); continue; } else if( name() == "mFgColor") { pT->mFgColor.setNamedColor( readElementText() ); continue; } else if( name() == "mBgColor") { pT->mBgColor.setNamedColor( readElementText() ); continue; } else if( name() == "mCommandFgColor") { pT->mCommandFgColor.setNamedColor( readElementText() ); continue; } else if( name() == "mCommandBgColor") { pT->mCommandBgColor.setNamedColor( readElementText() ); continue; } else if( name() == "mBlack") { pT->mBlack.setNamedColor( readElementText() ); continue; } else if( name() == "mLightBlack") { pT->mLightBlack.setNamedColor( readElementText() ); continue; } else if( name() == "mRed") { pT->mRed.setNamedColor( readElementText() ); continue; } else if( name() == "mLightRed") { pT->mLightRed.setNamedColor( readElementText() ); continue; } else if( name() == "mBlue") { pT->mBlue.setNamedColor( readElementText() ); continue; } else if( name() == "mLightBlue") { pT->mLightBlue.setNamedColor( readElementText() ); continue; } else if( name() == "mGreen") { pT->mGreen.setNamedColor( readElementText() ); continue; } else if( name() == "mLightGreen") { pT->mLightGreen.setNamedColor( readElementText() ); continue; } else if( name() == "mYellow") { pT->mYellow.setNamedColor( readElementText() ); continue; } else if( name() == "mLightYellow") { pT->mLightYellow.setNamedColor( readElementText() ); continue; } else if( name() == "mCyan") { pT->mCyan.setNamedColor( readElementText() ); continue; } else if( name() == "mLightCyan") { pT->mLightCyan.setNamedColor( readElementText() ); continue; } else if( name() == "mMagenta") { pT->mMagenta.setNamedColor( readElementText() ); continue; } else if( name() == "mLightMagenta") { pT->mLightMagenta.setNamedColor( readElementText() ); continue; } else if( name() == "mWhite") { pT->mWhite.setNamedColor( readElementText() ); continue; } else if( name() == "mLightWhite") { pT->mLightWhite.setNamedColor( readElementText() ); continue; } else if( name() == "mDisplayFont") { pT->mDisplayFont.fromString( readElementText() ); pT->mDisplayFont.setFixedPitch( true ); // pT->mDisplayFont.setWordSpacing( 0 ); // pT->mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, 0 ); continue; } else if( name() == "mCommandLineFont") { pT->mCommandLineFont.fromString( readElementText() ); continue; } else if( name() == "mFgColor2") { pT->mFgColor_2.setNamedColor( readElementText() ); continue; } else if( name() == "mBgColor2") { pT->mBgColor_2.setNamedColor( readElementText() ); continue; } else if( name() == "mBlack2") { pT->mBlack_2.setNamedColor( readElementText() ); continue; } else if( name() == "mLightBlack2") { pT->mLightBlack_2.setNamedColor( readElementText() ); continue; } else if( name() == "mRed2") { pT->mRed_2.setNamedColor( readElementText() ); continue; } else if( name() == "mLightRed2") { pT->mLightRed_2.setNamedColor( readElementText() ); continue; } else if( name() == "mBlue2") { pT->mBlue_2.setNamedColor( readElementText() ); continue; } else if( name() == "mLightBlue2") { pT->mLightBlue_2.setNamedColor( readElementText() ); continue; } else if( name() == "mGreen2") { pT->mGreen_2.setNamedColor( readElementText() ); continue; } else if( name() == "mLightGreen2") { pT->mLightGreen_2.setNamedColor( readElementText() ); continue; } else if( name() == "mYellow2") { pT->mYellow_2.setNamedColor( readElementText() ); continue; } else if( name() == "mLightYellow2") { pT->mLightYellow_2.setNamedColor( readElementText() ); continue; } else if( name() == "mCyan2") { pT->mCyan_2.setNamedColor( readElementText() ); continue; } else if( name() == "mLightCyan2") { pT->mLightCyan_2.setNamedColor( readElementText() ); continue; } else if( name() == "mMagenta2") { pT->mMagenta_2.setNamedColor( readElementText() ); continue; } else if( name() == "mLightMagenta2") { pT->mLightMagenta_2.setNamedColor( readElementText() ); continue; } else if( name() == "mWhite2") { pT->mWhite_2.setNamedColor( readElementText() ); continue; } else if( name() == "mLightWhite2") { pT->mLightWhite_2.setNamedColor( readElementText() ); continue; } else if( name() == "mSpellDic") { pT->mSpellDic = readElementText(); continue; } else if( name() == "mRoomSize" ) { pT->mRoomSize = readElementText().toDouble(); } else if( name() == "mLineSize" ) { pT->mLineSize = readElementText().toDouble(); } else { readUnknownHostElement(); } } } } void XMLimport::readTriggerGroup( TTrigger * pParent ) { TTrigger * pT; if( pParent ) { pT = new TTrigger( pParent, mpHost ); } else { pT = new TTrigger( 0, mpHost ); } if (module){ pT->mModuleMember = true; } mpHost->getTriggerUnit()->registerTrigger( pT ); pT->setIsActive( (attributes().value("isActive") == "yes" ) ); pT->mIsFolder = ( attributes().value("isFolder") == "yes" ); pT->mIsTempTrigger = ( attributes().value("isTempTrigger") == "yes" ); pT->mIsMultiline = ( attributes().value("isMultiline") == "yes" ); pT->mPerlSlashGOption = ( attributes().value("isPerlSlashGOption") == "yes" ); pT->mIsColorizerTrigger = ( attributes().value("isColorizerTrigger") == "yes" ); pT->mFilterTrigger = ( attributes().value("isFilterTrigger") == "yes" ); pT->mSoundTrigger = ( attributes().value("isSoundTrigger") == "yes" ); pT->mColorTrigger = ( attributes().value("isColorTrigger") == "yes" ); pT->mColorTriggerBg = ( attributes().value("isColorTriggerBg") == "yes" ); pT->mColorTriggerFg = ( attributes().value("isColorTriggerFg") == "yes" ); while( ! atEnd() ) { readNext(); //qDebug()<<"[INFO] element:"<setName( readElementText() ); continue; } else if( name() == "script") { pT->mScript = readElementText(); continue; } else if( name() == "packageName") { pT->mPackageName = readElementText(); continue; } else if( name() == "triggerType" ) { pT->mTriggerType = readElementText().toInt(); continue; } else if( name() == "conditonLineDelta" ) { pT->mConditionLineDelta = readElementText().toInt(); continue; } else if( name() == "mStayOpen" ) { pT->mStayOpen = readElementText().toInt(); continue; } else if( name() == "mCommand" ) { pT->mCommand = readElementText(); continue; } else if( name() == "mFgColor") { pT->mFgColor.setNamedColor( readElementText() ); continue; } else if( name() == "mBgColor") { pT->mBgColor.setNamedColor( readElementText() ); continue; } else if( name() == "colorTriggerFgColor") { pT->mColorTriggerFgColor.setNamedColor( readElementText() ); continue; } else if( name() == "colorTriggerBgColor") { pT->mColorTriggerBgColor.setNamedColor( readElementText() ); continue; } else if( name() == "mSoundFile" ) { pT->mSoundFile = readElementText(); continue; } else if( name() == "regexCodeList") { readStringList( pT->mRegexCodeList ); continue; } else if( name() == "regexCodePropertyList" ) { readIntegerList( pT->mRegexCodePropertyList ); continue; } else if( name() == "TriggerGroup" ) { readTriggerGroup( pT ); } else if( name() == "Trigger" ) { readTriggerGroup( pT ); } else { readUnknownTriggerElement(); } } } if( ! pT->setRegexCodeList( pT->mRegexCodeList, pT->mRegexCodePropertyList ) ) { qDebug()<<"IMPORT: ERROR: cant initialize pattern list for trigger "<getName(); } QString script = pT->mScript; if( ! pT->setScript( script ) ) { qDebug()<<"IMPORT: ERROR: trigger script "<< pT->getName()<<" does not compile"; } } void XMLimport::readTimerPackage() { while( ! atEnd() ) { readNext(); if( isEndElement() ) { break; } if( isStartElement() ) { if( name() == "TimerGroup" ) { gotTimer = true; if( mPackageName.isEmpty() ) readTimerGroup(0); else readTimerGroup(mpTimer); } else if( name() == "Timer" ) { gotTimer = true; if( mPackageName.isEmpty() ) readTimerGroup(0); else readTimerGroup(mpTimer); } else { readUnknownTimerElement(); } } } } void XMLimport::readTimerGroup( TTimer * pParent ) { TTimer * pT; QTime _time(10,0,0,0); if( pParent ) { pT = new TTimer( pParent, mpHost ); } else { pT = new TTimer( 0, mpHost ); } pT->mIsFolder = ( attributes().value("isFolder") == "yes" ); pT->mIsTempTimer = ( attributes().value("isTempTimer") == "yes" ); mpHost->getTimerUnit()->registerTimer( pT ); pT->setShouldBeActive( ( attributes().value("isActive") == "yes" ) ); bool isOffsetTimer = ( attributes().value("isOffsetTimer") == "yes" ); if (module) pT->mModuleMember = true; while( ! atEnd() ) { readNext(); if( isEndElement() ) break; if( isStartElement() ) { if( name() == "name" ) { pT->setName( readElementText() ); continue; } else if( name() == "packageName") { pT->mPackageName = readElementText(); continue; } else if( name() == "script") { QString script = readElementText(); pT->setScript( script ); continue; } else if( name() == "command") { pT->mCommand = readElementText(); continue; } else if( name() == "time") { QString timeString = readElementText(); QTime time = QTime::fromString( timeString, "hh:mm:ss.zzz" ); pT->setTime( time ); continue; } else if( name() == "TimerGroup" ) { readTimerGroup( pT ); } else if( name() == "Timer" ) { readTimerGroup( pT ); } else { readUnknownTimerElement(); } } } mudlet::self()->registerTimer( pT, pT->mpTimer ); //if( ( ! isOffsetTimer ) && ( ! pT->isFolder() ) && ( pT->shouldBeActive() ) ) if( ! pT->mpParent && pT->shouldBeActive() ) { qDebug()<<"regular Timer enabling name:"<getName(); pT->setIsActive( true ); pT->enableTimer( pT->getID() ); // if( pT->canBeUnlocked( 0 ) ) // { // if( pT->activate() ) // { // pT->mpTimer->start(); // } // else // { // pT->deactivate(); // pT->mpTimer->stop(); // } // } } else { qDebug()<<"NOT enabling Timer name:"<getName(); //pT->disableTimer( pT->getID() ); //pT->deactivate(); //pT->mpTimer->stop(); //pT->setIsActive( pT->shouldBeActive() ); } } void XMLimport::readAliasPackage() { while( ! atEnd() ) { readNext(); if( isEndElement() ) { break; } if( isStartElement() ) { if( name() == "AliasGroup" ) { gotAlias = true; if( mPackageName.isEmpty() ) readAliasGroup(0); else readAliasGroup(mpAlias); } else if( name() == "Alias" ) { gotAlias = true; if( mPackageName.isEmpty() ) readAliasGroup(0); else readAliasGroup(mpAlias); } else { readUnknownAliasElement(); } } } } void XMLimport::readAliasGroup( TAlias * pParent ) { TAlias * pT; if( pParent ) { pT = new TAlias( pParent, mpHost ); } else { pT = new TAlias( 0, mpHost ); } mpHost->getAliasUnit()->registerAlias( pT ); pT->setIsActive( ( attributes().value("isActive") == "yes" ) ); pT->mIsFolder = ( attributes().value("isFolder") == "yes" ); if (module) pT->mModuleMember = true; while( ! atEnd() ) { readNext(); if( isEndElement() ) break; if( isStartElement() ) { if( name() == "name" ) { pT->setName( readElementText() ); continue; } else if( name() == "packageName") { pT->mPackageName = readElementText(); continue; } else if( name() == "script") { QString script = readElementText(); pT->setScript( script ); continue; } else if( name() == "command") { pT->mCommand = readElementText(); continue; } else if( name() == "regex") { pT->setRegexCode( readElementText() ); continue; } else if( name() == "AliasGroup" ) { readAliasGroup( pT ); } else if( name() == "Alias" ) { readAliasGroup( pT ); } else { readUnknownAliasElement(); } } } } void XMLimport::readActionPackage() { while( ! atEnd() ) { readNext(); if( isEndElement() ) { break; } if( isStartElement() ) { if( name() == "ActionGroup" ) { gotAction = true; if( mPackageName.isEmpty() ) readActionGroup(0); else readActionGroup(mpAction); } else if( name() == "Action" ) { gotAction = true; if( mPackageName.isEmpty() ) readActionGroup(0); else readActionGroup(mpAction); } else { readUnknownActionElement(); } } } } void XMLimport::readActionGroup( TAction * pParent ) { TAction * pT; if( pParent ) { pT = new TAction( pParent, mpHost ); } else { pT = new TAction( 0, mpHost ); } mpHost->getActionUnit()->registerAction( pT ); pT->setIsActive( ( attributes().value("isActive") == "yes" ) ); pT->mIsFolder = ( attributes().value("isFolder") == "yes" ); pT->mIsPushDownButton = ( attributes().value("isPushButton") == "yes" ); pT->mButtonFlat = ( attributes().value("isFlatButton") == "yes" ); pT->mUseCustomLayout = ( attributes().value("useCustomLayout") == "yes" ); if (module) pT->mModuleMember = true; while( ! atEnd() ) { readNext(); if( isEndElement() ) break; if( isStartElement() ) { if( name() == "name" ) { pT->mName = readElementText(); continue; } else if( name() == "packageName") { pT->mPackageName = readElementText(); continue; } else if( name() == "script") { QString script = readElementText(); pT->setScript( script ); continue; } else if( name() == "css") { pT->css = readElementText(); continue; } else if( name() == "commandButtonUp") { pT->mCommandButtonUp = readElementText(); continue; } else if( name() == "commandButtonDown") { pT->mCommandButtonDown = readElementText(); continue; } else if( name() == "icon") { pT->mIcon = readElementText(); continue; } else if( name() == "orientation") { pT->mOrientation = readElementText().toInt(); continue; } else if( name() == "location") { pT->mLocation = readElementText().toInt(); continue; } else if( name() == "buttonRotation") { pT->mButtonRotation = readElementText().toInt(); continue; } else if( name() == "sizeX") { pT->mSizeX = readElementText().toInt(); continue; } else if( name() == "sizeY") { pT->mSizeY = readElementText().toInt(); continue; } else if( name() == "mButtonState") { pT->mButtonState = readElementText().toInt(); continue; } else if( name() == "buttonColor") { pT->mButtonColor.setNamedColor( readElementText() ); continue; } else if( name() == "buttonColumn") { pT->mButtonColumns = readElementText().toInt(); continue; } else if( name() == "posX") { pT->mPosX = readElementText().toInt(); continue; } else if( name() == "posY") { pT->mPosY = readElementText().toInt(); continue; } else if( name() == "ActionGroup" ) { readActionGroup( pT ); } else if( name() == "Action" ) { readActionGroup( pT ); } else { readUnknownActionElement(); } } } } void XMLimport::readScriptPackage() { while( ! atEnd() ) { readNext(); if( isEndElement() ) { break; } if( isStartElement() ) { if( name() == "ScriptGroup" ) { gotScript = true; if( mPackageName.isEmpty() ) readScriptGroup(0); else readScriptGroup(mpScript); } else if( name() == "Script" ) { gotScript = true; if( mPackageName.isEmpty() ) readScriptGroup(0); else readScriptGroup(mpScript); } else { readUnknownScriptElement(); } } } } void XMLimport::readScriptGroup( TScript * pParent ) { TScript * pT; if( pParent ) { pT = new TScript( pParent, mpHost ); } else { pT = new TScript( 0, mpHost ); } mpHost->getScriptUnit()->registerScript( pT ); pT->setIsActive( ( attributes().value("isActive") == "yes" ) ); pT->mIsFolder = ( attributes().value("isFolder") == "yes" ); if (module) pT->mModuleMember = true; while( ! atEnd() ) { readNext(); if( isEndElement() ) break; if( isStartElement() ) { if( name() == "name" ) { pT->mName = readElementText(); continue; } else if( name() == "packageName") { pT->mPackageName = readElementText(); continue; } else if( name() == "script") { QString script = readElementText(); pT->setScript( script ); continue; } else if( name() == "eventHandlerList") { readStringList( pT->mEventHandlerList ); pT->setEventHandlerList( pT->mEventHandlerList ); continue; } else if( name() == "ScriptGroup" ) { readScriptGroup( pT ); } else if( name() == "Script" ) { readScriptGroup( pT ); } else { readUnknownScriptElement(); } } } } void XMLimport::readKeyPackage() { while( ! atEnd() ) { readNext(); if( isEndElement() ) { break; } if( isStartElement() ) { if( name() == "KeyGroup" ) { gotKey = true; if( mPackageName.isEmpty() ) readKeyGroup(0); else readKeyGroup(mpKey); } else if( name() == "Key" ) { gotKey = true; if( mPackageName.isEmpty() ) readKeyGroup(0); else readKeyGroup(mpKey); } else { readUnknownKeyElement(); } } } } void XMLimport::readKeyGroup( TKey * pParent ) { TKey * pT; if( pParent ) { pT = new TKey( pParent, mpHost ); } else { pT = new TKey( 0, mpHost ); } mpHost->getKeyUnit()->registerKey( pT ); pT->setIsActive( ( attributes().value("isActive") == "yes" ) ); pT->mIsFolder = ( attributes().value("isFolder") == "yes" ); if (module) pT->mModuleMember = true; while( ! atEnd() ) { readNext(); if( isEndElement() ) break; if( isStartElement() ) { if( name() == "name" ) { pT->mName = readElementText(); continue; } else if( name() == "packageName") { pT->mPackageName = readElementText(); continue; } else if( name() == "script") { QString script = readElementText(); pT->setScript( script ); continue; } else if( name() == "command") { pT->mCommand = readElementText(); continue; } else if( name() == "keyCode" ) { pT->mKeyCode = readElementText().toInt(); continue; } else if( name() == "keyModifier" ) { pT->mKeyModifier = readElementText().toInt(); continue; } else if( name() == "KeyGroup" ) { readKeyGroup( pT ); } else if( name() == "Key" ) { readKeyGroup( pT ); } else { readUnknownKeyElement(); } } } } void XMLimport::readMapList( QMap & map) { QString key; QStringList entry; while( ! atEnd() ) { readNext(); if( isEndElement() ) break; if( isStartElement() ) { if( name() == "key") { key = readElementText(); } else if (name() == "filepath"){ entry << readElementText(); //map[key] = readElementText(); //qDebug()<<"key:"< & list ) { while( ! atEnd() ) { readNext(); if( isEndElement() ) break; if( isStartElement() ) { if( name() == "integer") { bool ok = false; int num; num = readElementText().toInt( &ok, 10 ); if( ok ) { list << num; } else { qFatal("FATAL ERROR: reading package property list contained invalid elements"); } } else { readUnknownTriggerElement(); } } } } mudlet-2.1/src/dlgIRC.h0000644000175000017500000000126111624306130014216 0ustar csmallcsmall#ifndef DLGIRC_H #define DLGIRC_H #include #include "ui_irc.h" #ifdef Q_CC_MSVC #define IRC_SHARED #include #else #include "irc/include/ircsession.h" #endif class dlgIRC : public QMainWindow, public Ui::irc_dlg { Q_OBJECT public: dlgIRC(); Irc::Session* session; QString mNick; public slots: void irc_gotMsg( QString, QString, QString ); void irc_gotMsg2( QString a, QStringList c ); void irc_gotMsg3( QString a, uint code, QStringList c ); void anchorClicked(const QUrl& link); void slot_joined(QString, QString); void slot_parted(QString, QString, QString); void sendMsg(); }; #endif // DLGIRC_H mudlet-2.1/src/deleteOldProfiles.xml0000644000175000017500000000650212070466512017102 0ustar csmallcsmall delete old profiles ^delete old (profiles|maps)(?: (\d+))?$ mudlet-2.1/src/EAction.cpp0000644000175000017500000000377011513237311014777 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "EAction.h" #include "TFlipButton.h" #include EAction::EAction( QIcon & icon, QString & name, mudlet * parent ) : QAction( icon, name, parent ) { setText( name ); setObjectName( name ); setIcon( icon ); connect(this, SIGNAL(triggered(bool)), this, SLOT(slot_execute(bool))); } void EAction::slot_execute(bool checked) { if( checked ) { mpHost->getActionUnit()->getAction( mID )->mButtonState = 2; } else { mpHost->getActionUnit()->getAction( mID )->mButtonState = 1; } QStringList sL; mpHost->getActionUnit()->getAction( mID )->_execute( sL ); } mudlet-2.1/src/TSplitterHandle.cpp0000644000175000017500000000156711513237311016525 0ustar csmallcsmall#include "TSplitterHandle.h" #include "TSplitter.h" #include #include #include TSplitterHandle::TSplitterHandle( Qt::Orientation orientation, TSplitter * parent ) : QSplitterHandle( orientation, (QSplitter*) parent ) { } void TSplitterHandle::paintEvent( QPaintEvent * event ) { QPainter painter( this ); QLinearGradient gradient(QPointF(100, 100), QPointF(200, 200)); gradient.setColorAt(0, Qt::black); gradient.setColorAt(1, Qt::white); if(orientation() == Qt::Horizontal) { gradient.setStart(rect().left(), rect().height()/2); gradient.setFinalStop(rect().right(), rect().height()/2); } else { gradient.setStart(rect().width()/2, rect().top()); gradient.setFinalStop(rect().width()/2, rect().bottom()); } painter.fillRect(event->rect(), QBrush(gradient)); } mudlet-2.1/src/TAlias.h0000644000175000017500000000707012070466512014302 0ustar csmallcsmall #ifndef _TALIAS_H_ #define _TALIAS_H_ /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "Tree.h" #include #include "Host.h" #include class TLuaInterpreter; class TAlias : public Tree { friend class XMLexport; friend class XMLimport; public: virtual ~TAlias(); TAlias( TAlias * parent, Host * pHost ); TAlias( QString name, Host * pHost ); TAlias& clone(const TAlias& ); void compileAll(); QString getName() { return mName; } void setName( QString name ); void compile(); bool compileScript(); void execute(); QString getScript() { return mScript; } bool setScript( QString & script ); QString getRegexCode() { return mRegexCode; } void setRegexCode( QString ); void setCommand( QString command ) { mCommand = command; } QString getCommand() { return mCommand; } bool isFolder() { return mIsFolder; } void setIsFolder( bool b ) { mIsFolder = b; } bool match( QString & toMatch ); bool registerAlias(); bool isClone(TAlias &b) const; bool isTempAlias() { return mIsTempAlias; } void setIsTempAlias( bool b ) { mIsTempAlias = b; } TAlias(){}; QString mName; QString mCommand; QString mRegexCode; pcre * mpRegex; QString mScript; bool mIsFolder; Host * mpHost; bool mNeedsToBeCompiled; bool mIsTempAlias; bool mModuleMember; bool mModuleMasterFolder; QString mFuncName; bool exportItem; }; #endif mudlet-2.1/src/TriggerUnit.h0000644000175000017500000001140111647202526015363 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _TRIGGER_UNIT_H #define _TRIGGER_UNIT_H #include "TTrigger.h" #include #include #include #include #include class TTrigger; class Host; class TriggerUnit { friend class XMLexport; friend class XMLimport; public: TriggerUnit( Host * pHost ) : mpHost(pHost), mMaxID(0) { initStats();} std::list getTriggerRootNodeList() { QMutexLocker locker(& mTriggerUnitLock); return mTriggerRootNodeList; } TTrigger * getTrigger( int id ); void removeAllTempTriggers(); TTrigger * findTrigger( QString & ); bool enableTrigger( QString & ); bool disableTrigger( QString & ); bool killTrigger( QString & name ); bool registerTrigger( TTrigger * pT ); void unregisterTrigger( TTrigger * pT ); bool serialize( QDataStream & ); bool restore( QDataStream &, bool ); void reParentTrigger( int childID, int oldParentID, int newParentID, int parentPosition = -1, int childPosition = -1 ); void processDataStream( QString &, int ); void dump(); void compileAll(); void setTriggerStayOpen( QString, int ); void stopAllTriggers(); void reenableAllTriggers(); QString assembleReport(); std::list mCleanupList; qint64 getNewID(); QMultiMap mLookupTable; QMutex mTriggerUnitLock; void markCleanup( TTrigger * pT ); void doCleanup(); void uninstall( QString ); void _uninstall( TTrigger * pChild, QString packageName ); int statsTriggerTotal; int statsTempTriggers; int statsPatterns; int statsActiveTriggers; int statsActiveTriggersMax; int statsActiveTriggersMin; int statsActiveTriggersAverage; int statsTempTriggersCreated; int statsTempTriggersKilled; int statsAverageLineProcessingTime; int statsMaxLineProcessingTime; int statsMinLineProcessingTime; int statsRegexTriggers; QList uninstallList; private: TriggerUnit(){;} void initStats(); void _assembleReport( TTrigger * ); TTrigger * getTriggerPrivate( int id ); void addTriggerRootNode( TTrigger * pT, int parentPosition = -1, int childPosition = -1, bool moveTrigger = false ); void addTrigger( TTrigger * pT ); void removeTriggerRootNode( TTrigger * pT ); void removeTrigger( TTrigger *); Host * mpHost; QMap mTriggerMap; std::list mTriggerRootNodeList; qint64 mMaxID; bool mModuleMember; }; #endif mudlet-2.1/src/TAstar.h0000644000175000017500000000540511624306130014314 0ustar csmallcsmall#ifndef TASTAR_H #define TASTAR_H #include #include #include #include #include //#include #include #include #include #include #include // for sqrt using namespace boost; using namespace std; // auxiliary types struct location { float y, x, z; // lat, long }; typedef float cost; template class city_writer { public: city_writer(Name n, LocMap l, float _minx, float _maxx, float _minz, float _miny, float _maxy, float _maxz, unsigned int _ptx, unsigned int _pty, unsigned int _ptz ) : name(n), loc(l), minx(_minx), maxx(_maxx), miny(_miny), maxy(_maxy), minz(_minz), maxz(_maxz), ptx(_ptx), pty(_pty), ptz(_ptz) {} template void operator()(ostream& out, const Vertex& v) const { float px = 1 - (loc[v].x - minx) / (maxx - minx); float py = (loc[v].y - miny) / (maxy - miny); float pz = (loc[v].z - minz) / (maxz - minz); out << "[label=\"" << name[v] << "\", pos=\"" << static_cast(ptx * px) << "," << static_cast(pty * py) << "," << static_cast(ptz * pz) << "\", fontsize=\"11\"]"; } private: Name name; LocMap loc; float minx, maxx, miny, maxy, minz, maxz; unsigned int ptx, pty, ptz; }; template class time_writer { public: time_writer(WeightMap w) : wm(w) {} template void operator()(ostream &out, const Edge& e) const { out << "[label=\"" << wm[e] << "\", fontsize=\"11\"]"; } private: WeightMap wm; }; // euclidean distance heuristic template class distance_heuristic : public astar_heuristic { public: typedef typename graph_traits::vertex_descriptor Vertex; distance_heuristic(LocMap l, Vertex goal) : m_location(l), m_goal(goal) {} CostType operator()(Vertex u) { // CostType dx = m_location[m_goal].x - m_location[u].x; // CostType dy = m_location[m_goal].y - m_location[u].y; // CostType dz = m_location[m_goal].z - m_location[u].z; return 1; //return ::sqrt(dx * dx + dy * dy + dz * dz); } private: LocMap m_location; Vertex m_goal; }; struct found_goal {}; // exception for termination // visitor that terminates when we find the goal template class astar_goal_visitor : public boost::default_astar_visitor { public: astar_goal_visitor(Vertex goal) : m_goal(goal) {} template void examine_vertex(Vertex u, Graph& g) { if(u == m_goal) throw found_goal(); } private: Vertex m_goal; }; #endif // TASTAR_H mudlet-2.1/src/3k-mapper.xml0000644000175000017500000030227312070466512015300 0ustar csmallcsmall 3k Mapper 0 99 0 3k Mapper #ff0000 #ffff00 #000000 #000000 3k Mapper 0 0 0 #ff0000 #ffff00 #000000 #000000 3k Room Description 0 0 0 #ff0000 #ffff00 #000000 #000000 roomexits 0 1 0 #ff0000 #ffff00 #000000 #000000 (((\s+There (are|is) \w+ obvious exit.?:) (.+))|No obvious exits.¡?) 1 roomdescription 0 1 1 #ff0000 #ffff00 #808000 #000000 FG8BG2 ^(.+)$ 6 1 roomname 0 11 0 #00fff7 #000000 #00ff00 #000000 3?s?>?`?(.+)(\s+)?¡ 1 spacer 0 3 0 #ff0000 #ffff00 #000000 #000000 ^$ 1 multipleRoomExits 0 0 0 #ff0000 #ffff00 #000000 #000000 [\s]{10,}(.*) 1 WimpyNoDir 0 0 0 #ff0000 #ffff00 #000000 #000000 Your legs run away with you! 0 Can't go trigger 0 0 0 #ff0000 #ffff00 #000000 #000000 You cannot go 0 Too dark 0 99 0 #ff0000 #ffff00 #000000 #000000 It is too dark 1 Follower 0 99 0 #ff0000 #ffff00 #000000 #000000 (.+) leaves (.+). 1 Wimpy 0 99 0 #ff0000 #ffff00 #000000 #000000 Your legs run away with you (.+). 1 3k Mapper 3k Mapper 3k Mapper Purge exit queue ^tmap dirclear$ firstroom ^tmap firstroom$ Set Location ^tmap setroom (\d+)$ Room walker ^tmap walk (.+)$ Map toggle ^tmap mapon\s?(.+)?$ Show Exits ^tmap showexits$ Set Room Size ^tmap setroomsize (\d+)$ Mouse Set Location ^tmap setloc$ Delete Room ^tmap delroom\s?(.+)?$ Map Follow Toggle ^tmap follow$ Map Special Exit ^>([^>]+)>(\w+)$ Find Me ^tmap findme\s?(\w+)?$ Stop Special Exits ^tmap stopspecial$ No HM Portals ^tmap portalsoff\s?(.+)$ Set Room Cost ^tmap setrcost (\d+)$ Show Room Script ^tmap showscript$ Delete Selected Rooms ^tmap doDelete$ Color Room ^tmap croom (\w+)$ show color ^tmap scolor$ Show room weight ^tmap sweight$ Block room ^tmap broom$ Move Player on Map ^tmap move (.+)$ Move room to new area ^tmap movenewarea (.*)$ move room to existing area ^tmap movetoarea\s(.*)$ Setup Mapper Ansi ^tmap mapSetup$ Delete rooms from an entire area ^tmap clearArea\s(.*)$ Make a brand new area ^tmap newarea\s(.*)$ Add Favorite ^tmap addFav\s(.*)$ search Mode ^tmap searchMode\s?(.+)?$ show room scripts ^tmap showScripts$ set room script ^tmap setScript (.*)$ clear room script ^tmap clearScript$ Set room lua script ^tmap luascript (.+)$ Add Exit Script ^tmap exitscript \"(.+)\" (.+)$ Show Room Lua Scripts ^tmap showluascripts$ Clear room lua script ^tmap clearluascript$ show exit scripts ^tmap showescript$ Update Room Description ^tmap updateRoom$ Delete Temporary Rooms ^tmap delTemp$ Player Follow ^tmap follow (.+)$ Show Room Info ^tmap roominfo$ General Help ^tmap$ Room exit trigger setup ^tmap automove "(.+)" .+$ clear room exit script ^tmap clearexit (.+)$ Pause speedwalk ^tmap pauseUntil "(.+)" (.+)$ Create a looping exit ^tmap loopexit (.+)$ Move a label ^tmap movelabel\s?(.+)?$ Rename a label ^tmap renamelabel\s?(.+)?$ Delete a label ^tmap deletelabel\s?(.+)?$ Make a label ^tmap addlabel\s(.+)$ Exit Alias ^tmap addalias "(.+)" (.+)$ 3k Mapper 3k Mapper 3k Mapper sysDataSendRequest gmcp.Room RoomNum setPlayerLocation sysLoadEvent sysExitEvent enableMapper clearDirQueue tempMapper followMapper findme searchMode mapOpenEvent https://github.com/Chris7/3k-Scripts/wiki mudlet-2.1/src/TMatchState.h0000644000175000017500000000616311513237311015302 0ustar csmallcsmall #ifndef _TMatchState_H_ #define _TMatchState_H_ /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ class TMatchState { public: TMatchState( int NumberOfConditions, int delta ) { mNumberOfConditions = NumberOfConditions; mNextCondition = 1; // first condition was true when the state was created mDelta = delta; mLineCount = 1; mSpacer = 0; } TMatchState( const TMatchState &ms ) { mNumberOfConditions = ms.mNumberOfConditions; mNextCondition = ms.mNextCondition; mDelta = ms.mDelta; mLineCount = ms.mLineCount; } int nextCondition() { return mNextCondition; } void conditionMatched(){ mNextCondition++; } bool isComplete() { if( mNextCondition >= mNumberOfConditions ) { return true; } else { return false; } } void newLineArrived(){ mLineCount++; } bool newLine() { if( mLineCount > mDelta ) { return false; } else { return true; } } bool lineSpacerMatch( int lines ) { if( mSpacer >= lines ) { mSpacer = 0; return true; } else { mSpacer++; return false; } } int mSpacer; std::list< std::list > multiCaptureList; std::list< std::list > multiCapturePosList; int mNumberOfConditions; int mNextCondition; int mLineCount; int mDelta; }; #endif mudlet-2.1/src/dlgRoomExits.cpp0000644000175000017500000003023512020507607016073 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn - KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "Host.h" #include "TMap.h" #include "dlgRoomExits.h" dlgRoomExits::dlgRoomExits( Host * pH, QWidget * pW ) : mpHost( pH ) , mpEditItem( 0 ) , QDialog( pW ) { setupUi(this); connect( saveButton, SIGNAL(pressed()), this, SLOT(save())); connect( addSpecialExit,SIGNAL(pressed()), this, SLOT(slot_addSpecialExit())); connect( specialExits,SIGNAL(itemClicked ( QTreeWidgetItem *, int)), this, SLOT(slot_editItem(QTreeWidgetItem*,int))); } void dlgRoomExits::slot_editItem(QTreeWidgetItem * pI, int column ) { if( column == 0 || !pI ) { if( mpEditItem ) specialExits->closePersistentEditor( mpEditItem, mEditColumn ); mpEditItem = 0; mEditColumn = 0; return; } if( mpEditItem != 0 ) { specialExits->closePersistentEditor( mpEditItem, mEditColumn ); mpEditItem = 0; } mpEditItem = pI; mEditColumn = column; specialExits->openPersistentEditor(pI, column); specialExits->editItem(pI, column); } void dlgRoomExits::slot_addSpecialExit() { QStringList sL; QTreeWidgetItem * pI = new QTreeWidgetItem(specialExits);// pI->setCheckState( 0, Qt::Unchecked ); pI->setText(1, ""); pI->setText(2, ""); specialExits->addTopLevelItem(pI); } void dlgRoomExits::save() { if( !mpHost->mpMap->rooms.contains(mRoomID) ) return; mpHost->mpMap->mMapGraphNeedsUpdate = true; mpHost->mpMap->rooms[mRoomID]->other.clear(); for( int i=0; itopLevelItemCount(); i++ ) { QTreeWidgetItem * pI = specialExits->topLevelItem(i); int key = pI->text(1).toInt(); QString value = pI->text(2); //qDebug()<<"key="<"; if( value != "" && key != 0 ) { if( pI->checkState( 0 ) == Qt::Unchecked ) value = value.prepend( '0' ); else value = value.prepend( '1' ); //qDebug()<<"setting: key="< #include "dlgTriggersMainArea.h" dlgTriggersMainArea::dlgTriggersMainArea(QWidget * pF) : QWidget(pF) { // init generated dialog setupUi(this); } mudlet-2.1/src/dlgTimersMainArea.h0000644000175000017500000000331711513237311016447 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DLG_Timersmainarea_H #define DLG_Timersmainarea_H #include "ui_timers_main_area.h" #include #include "TTimer.h" class dlgTimersMainArea : public QWidget , public Ui::timers_main_area { Q_OBJECT public: dlgTimersMainArea(QWidget*); signals: public slots: }; #endif mudlet-2.1/src/dlgAliasMainArea.h0000644000175000017500000000327111513237311016234 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef dlg_aliasesmainarea_h #define dlg_aliasesmainarea_h #include "ui_aliases_main_area.h" #include class dlgAliasMainArea : public QWidget , public Ui::aliases_main_area { Q_OBJECT public: dlgAliasMainArea(QWidget*); signals: public slots: }; #endif mudlet-2.1/src/mudlet-mapper.xml0000644000175000017500000113630712070466512016261 0ustar csmallcsmall Mudlet Mapper 0 0 0 #ff0000 #ffff00 #000000 #000000 Have to swim 0 0 0 #ff0000 #ffff00 #000000 #000000 There's water ahead of you. You'll have to swim in that direction to make it through. There's water ahead of you. You'll have to swim in that direction to make it There's water ahead of you. You'll have to SWIM You'll have to swim to make it through the water in that direction. The water is too deep for you to walk that way, you must swim. 3 3 2 3 3 Rubble at the exit 0 0 0 #ff0000 #ffff00 #000000 #000000 You begin to slowly clamber over the rubble that blocks your way. You begin to slowly clamber over a pile of rubble that blocks your way. 3 3 Too quick 0 99 0 #ff0000 #ffff00 #000000 #000000 Now now, don't be so hasty! You can not move that fast! 3 3 Hobbling 0 0 0 #ff0000 #ffff00 #000000 #000000 You slowly hobble 2 Frozen 0 0 0 #ff0000 #ffff00 #000000 #000000 You begin moving your frozen body slowly 2 People here 0 1 0 #ff0000 #ffff00 #000000 #000000 You see the following people here: 1 3 5 Person 0 0 0 #aaff00 #ffff00 #000000 #000000 ([A-Z][a-z]+) 1 Retardation/aeon walk delay 0 0 0 #ff0000 #ffff00 #000000 #000000 You move sluggishly into action. 3 Scent (Achaea+Imperian) 0 0 0 #ff0000 #ffff00 #000000 #000000 ^You detect traces of scent from (.+)\.$ 1 Alertness (Achaea+Imperian) 0 0 0 #ff0000 #ffff00 #000000 #000000 ^Your enhanced senses inform you that (\w+) has entered (.+?)(?: nearby)?\.$ 1 Mudlet Mapper prompt trigger 0 0 0 #ff0000 #ffff00 #000000 #000000 return isPrompt() 4 Wormhole 0 0 0 #ff0000 #ffff00 #000000 #000000 You hurl yourself forwards through the air, and sure enough a swirling vortex of colours springs into existence to swallow you. You reach out with the vibrating stick to probe for a wormhole, and as it connects with one, you are sucked through. 3 3 Achaea 0 0 0 #ff0000 #ffff00 #000000 #000000 Login 0 0 0 #ff0000 #ffff00 #000000 #000000 Password correct. Welcome to Achaea. 3 Local area farsee 0 0 0 #ff0000 #ffff00 #000000 #000000 You see that ^You see that (\w+) is at (.+)\.$ 2 1 Entering wilderness 0 99 0 #ff0000 #ffff00 #000000 #000000 You begin to look for that place to enter the wilderness. It's around here somewhere! 3 Icon enter/leave 0 1 0 #ff0000 #ffff00 #000000 #000000 You reach out and touch a powerful Icon. For a moment, nothing happens, but soon you feel a humming deep inside you. 3 Underworld root 0 0 0 #ff0000 #ffff00 #000000 #000000 As you touch a huge grey root, you feel dark energies coursing up your hand and throughout your body. 3 Mindsense 0 0 0 #ff0000 #ffff00 #000000 #000000 You seek out the mind of ^You seek out the mind of \w+ and an image of (.+) appears in your mind\.$ 2 1 Destroyed room 0 0 0 #ff0000 #ffff00 #000000 #000000 Your movement is slowed as you move through the decimated remains. 3 Underworld entry 0 0 0 #ff0000 #ffff00 #000000 #000000 A huge grey root numbs your fingertips as you reach out to touch it. 3 Angel sense 0 0 100 #ff0000 #ffff00 #000000 #000000 Your guardian angel senses ^Your guardian angel senses .+? at (.+?), 2 1 Each person 0 0 0 #ff0000 #ffff00 #000000 #000000 is with (\w+)\.$ 1 Stop 0 99 0 #ff0000 #ffff00 #000000 #000000 return isPrompt() 4 Dragonsense 0 1 0 #ff0000 #ffff00 #000000 #000000 Tapping into the unfathomable depths of your power, you sense that Tapping into the unfathomable depths of your power, you sense that (\w+) is at (.+?), in (.+)\.$ 2 1 Defilement 0 0 0 #ff0000 #ffff00 #000000 #000000 (Order): ^\(Order\): \w+'s Herald says, "A shrine is being defiled at (.+)!"$ 2 1 Defiled 0 0 0 #ff0000 #ffff00 #000000 #000000 (Order): ^\(Order\): \w+'s Herald says, "A shrine has been destroyed at (.+)!"$ 2 1 View 0 0 0 #ff0000 #ffff00 #000000 #000000 You see ^You see (\w+) at (.+)\.$ 2 1 Elementalism scry 0 0 0 #ff0000 #ffff00 #000000 #000000 You create a pool of water in the air in front of you, and look through it, sensing You create a pool of water in the air in front of you, and look through it, sensing \w+ at (.+)\.$ 2 1 Parse wholist 0 99 0 #ff0000 #ffff00 #000000 #000000 ^(\w+) +\((.+)\)$ 1 Piety on astralform 0 0 0 #ff0000 #ffff00 #000000 #000000 A rite of piety slows your movement as it pulls at your ephemeral body. 3 Angel presences 0 0 100 #ff0000 #ffff00 #000000 #000000 You bid your guardian angel to seek out life presences nearby. 3 Each person 0 0 0 #ff0000 #ffff00 #000000 #000000 ^Your guardian angel senses (\w+) at (.+?), 1 Stop (angel presences 0 0 0 #ff0000 #ffff00 #000000 #000000 return isPrompt() 4 Annwyn circle 0 0 0 #ff0000 #ffff00 #000000 #000000 The melody of a strange song rises unbidden to your lips as you skip around the circle of mushrooms. 2 Scrying bowl 0 1 0 #ff0000 #ffff00 #000000 #000000 You dip your fingers into the cool water of the bowl, willing it to reveal the location of ^You dip your fingers into the cool water of the bowl, willing it to reveal the location of (\w+)\.$ ^An image of .+? appears reflected within the bowl, shifting with the rippling water to display (.+)\.$ 2 1 1 Occultist entities 0 0 1000 #ff0000 #ffff00 #000000 #000000 The following entities reside on the Prime Material plane: 3 Each doppleganger 0 0 0 #ff0000 #ffff00 #000000 #000000 ^(\w+) is at (.+)\.$ 1 Stop 0 0 0 #ff0000 #ffff00 #000000 #000000 return isPrompt() 4 Party traces/locaters 0 0 0 #ff0000 #ffff00 #000000 #000000 (Party): 2 regex (party locate) 0 0 0 #ff0000 #ffff00 #000000 #000000 ^\(Party\): \w+ says, "(\w+) moved to (.+)\."$ ^\(Party\): \w+ says, "(\w+) is at (.+), in .+\." ^\(Party\): \w+ says, "Trace: (\w+) moved to (.+)\." 1 1 1 Arena event (Achaea) 0 3 1000 #ff0000 #ffff00 #000000 #000000 Current event Player Location ---------------------------------------------------------------------- 2 3 3 Each person 0 0 0 #ff0000 #ffff00 #000000 #000000 ^(\w+) +(.+)$ 1 Stop (arena event) 0 0 0 #ff0000 #ffff00 #000000 #000000 return isPrompt() 4 Angel trace 0 0 0 #ff0000 #ffff00 #000000 #000000 Your guardian angel reports that ^Your guardian angel reports that (\w+) has moved to (.+)\.$ 2 1 KoTH (mudlet mapper) 0 5 1000 #ff0000 #ffff00 #000000 #000000 Current event: King of the Hill 5 3 5 Each person 0 0 0 #ff0000 #ffff00 #000000 #000000 ^(\w+) .+? ([A-Z][a-z ]+?)$ 1 Stop (koth) 0 0 0 #ff0000 #ffff00 #000000 #000000 return isPrompt() 4 Fullsense (mudlet mapper) 0 0 100 #ff0000 #ffff00 #000000 #000000 You seek out all mental presences within your reach: 3 Each person 0 0 0 #ff0000 #ffff00 #000000 #000000 ^You sense (\w+) at (.+)\.$ 1 Stop 0 0 0 #ff0000 #ffff00 #000000 #000000 return isPrompt() 4 Aetolia 0 1 0 #ff0000 #ffff00 #000000 #000000 Login 0 99 0 #ff0000 #ffff00 #000000 #000000 Password correct. Welcome to Aetolia. 3 Lusternia 0 0 0 #ff0000 #ffff00 #000000 #000000 Login 0 5 0 #ff0000 #ffff00 #000000 #000000 .____ __ .__ | | __ __ _______/ |_ ____ _______ ____ |__|_____ | | | | \ / ___/\ __\_/ __ \ \_ __ \ / \ | |\__ \ | |___ | | / \___ \ | | \ ___/ | | \/| | \| | / __ \_ |_______ \|____/ /____ > |__| \___ > |__| |___| /|__|(____ / \/ \/ \/ \/ \/ 3 3 3 3 3 3 mmp Lusternia Scent 0 99 100 #ff0000 #ffff00 #000000 #000000 You scent at the air, your skilled nose picking up the faint traces of others in the surrounding area. You snort and snuffle at the air, sensing through a ridiculous pig nose upon your face the faint traces of others in the surrounding area. 3 3 Got line 0 0 0 #ff0000 #ffff00 #000000 #000000 ^You make out the scent of (\w+) coming from (.+)\.$ 1 Stop capturing 0 0 0 #ff0000 #ffff00 #000000 #000000 return isPrompt() 4 Deathsight 0 0 0 #ff0000 #ffff00 #000000 #000000 You see the death occur at ^You see the death occur at (.+)\.$ 2 1 Wildnodes nodes 0 99 0 #ff0000 #ffff00 #000000 #000000 ^\(Planted\) Node \d+ - (.*)\.$ ^ +Node \d+ - (.*)\.$ 1 1 Window search 0 39 0 #ff0000 #ffff00 #000000 #000000 ^You open up a window in the cosmic fabric and search out (\w+). Through the cosmic window, you see (\w+) at (.+?)(?: \(.*\))?\. 1 Scry search 0 1 0 #ff0000 #ffff00 #000000 #000000 ^You rub .* and it begins to glow with a pulsating light\.$ Within the enchanted item, an image forms of (\w+) at (.+?)(?: \(.*\))?\. 1 1 Map artefact 0 3 0 #ff0000 #ffff00 #000000 #000000 As you inscribe the name of ^As you inscribe the name of \w+ with a flourish, lines crawl across the surface of the map, centered upon (.*)\.$ You see the following in detail: v(\d+) 2 1 3 1 map scry 0 0 0 #ff0000 #ffff00 #000000 #000000 As you inscribe the name of ^As you inscribe the name of (\w+) with a flourish, lines crawl across the surface of the map, centered upon (.*)\. 2 1 World events 0 0 0 #ff0000 #ffff00 #000000 #000000 ^The Staff of Ascension is at (.*)\.$ ^The Purple Hamster of Chaos is at (.*)\.$ 1 1 Seeing stone 0 3 0 #ff0000 #ffff00 #000000 #000000 You gaze into a seeing stone. 1 ^(.*)\.$ 3 5 1 Birdseye 0 0 0 #ff0000 #ffff00 #000000 #000000 From your vantage point in the sky, your crow senses perceive that ^From your vantage point in the sky, your crow senses perceive that (\w+) is (.*) within the vicinity of (.*)\.$ 2 1 Bond look 0 3 0 #ff0000 #ffff00 #000000 #000000 ^You look through the mind of (.*)\:$ 1 ^(.*)\.$ 1 5 1 Pyramid probe # 0 0 0 #ff0000 #ffff00 #000000 #000000 You lightly caress a button on a paradox puzzle pyramid and suddenly a hazy image of ^You lightly caress a button on a paradox puzzle pyramid and suddenly a hazy image of (.*) flashes momentarily in front of you\.$ 2 1 Pentagon probe # 0 0 0 #ff0000 #ffff00 #000000 #000000 You lightly caress a button on a paradox puzzle pentagon and suddenly a hazy image of ^You lightly caress a button on a paradox puzzle pentagon and suddenly a hazy image of (.+) \(room \#\d+\) flashes momentarily in front of you\.$ 2 1 Pyramid port 0 0 0 #ff0000 #ffff00 #000000 #000000 Your hands become a blur as you twist and turn a paradox puzzle pyramid until each side is made up of the same colour, solving the puzzle in mere moments. Suddenly the image of ^Your hands become a blur as you twist and turn a paradox puzzle pyramid until each side is made up of the same colour, solving the puzzle in mere moments. Suddenly the image of (.*) appears in the back of your mind and you feel drawn towards it\.$ 2 1 Pyramid probe 0 99 4 #ff0000 #ffff00 #000000 #000000 You lightly caress a few buttons on a paradox puzzle pyramid and suddenly a series of hazy images flashes momentarily in front of you. 3 Each location 0 0 0 #ff0000 #ffff00 #000000 #000000 ^Puzzle point \d+ is set to (.+) \( 1 Astrology scry 0 0 0 #ff0000 #ffff00 #000000 #000000 Gazing up at the sky, you bring the image of ^Gazing up at the sky, you bring the image of (\w+) into your mind's eye and overlay it on the constellations\. The power of the stars manifests as an image of (.+?) forms before your eyes\.$ 2 1 Tierstone 0 1 0 #ff0000 #ffff00 #000000 #000000 You gaze into a glittering tierstone. ^\w+ is at (.+?) in (.*)\.$ 3 1 Quicksand 0 0 0 #ff0000 #ffff00 #000000 #000000 You struggle slowly through the quicksand as you move 2 Gravity 0 0 0 #ff0000 #ffff00 #000000 #000000 The dragging force of a war shrine of 2 Crow spy 0 0 0 #ff0000 #ffff00 #000000 #000000 An image of ^An image of \w+ (?:entering|leaving) (.+?) appears in the centre of the nest\.$ 2 1 Crow spy remote 0 0 0 #ff0000 #ffff00 #000000 #000000 Your nest projects into your head an image ^Your nest projects into your head an image of \w+ (?:entering|exiting) (.+)\.$ 2 1 Imperian 0 99 0 #ff0000 #ffff00 #000000 #000000 Login 0 0 0 #ff0000 #ffff00 #000000 #000000 Password correct. Welcome to Imperian. 3 Wormholes 0 0 0 #ff0000 #ffff00 #000000 #000000 You sense a stable wormhole between ^You sense a stable wormhole between (.+?) and (.+)\.$ 2 1 Personal wormholes 0 0 0 #ff0000 #ffff00 #000000 #000000 You sense a personal wormhole at ^You sense a personal wormhole at (.+). It is attached to (.+)\.$ 2 1 Parse wholist 0 0 0 #ff0000 #ffff00 #000000 #000000 .+( \- [A-Z].+?\s*?) \- (.+) 1 Trap went off 0 0 0 #ff0000 #ffff00 #000000 #000000 Your alarm at ^Your alarm at \'(.+)\' has been set off by (\w+)\!$ 2 1 Trap List 0 0 0 #ff0000 #ffff00 #000000 #000000 ^ (\w+) \((\w+)\) at (.+)$ 2 1 Scout 0 0 0 #ff0000 #ffff00 #000000 #000000 ^ .+ at (.+)$ 2 1 Hunt 0 0 0 #ff0000 #ffff00 #000000 #000000 ^You sense that (\w+) has entered (.+)\, (.+)\.$ 1 Sewer grate 0 0 0 #ff0000 #ffff00 #000000 #000000 A sewer grate prevents you from moving down into the sewers. 3 Caravan 0 0 0 #ff0000 #ffff00 #000000 #000000 You begin leading a caravan 2 Midkemia Online 0 99 0 #ff0000 #ffff00 #000000 #000000 Login 0 0 0 #ff0000 #ffff00 #000000 #000000 Password correct. Welcome to Midkemia Online. 3 Fording 0 0 0 #ff0000 #ffff00 #000000 #000000 You ford the water towards the 2 Lithmeria 0 0 0 #ff0000 #ffff00 #000000 #000000 Login 0 0 0 #ff0000 #ffff00 #000000 #000000 Welcome to your account! 3 Wall 0 0 0 #ff0000 #ffff00 #000000 #000000 A wall blocks your way. 3 Doors 0 0 0 #ff0000 #ffff00 #000000 #000000 Closing doors 0 1 1 #ff0000 #ffff00 #000000 #000000 You open the door to the 2 Lack of piety 0 0 0 #ff0000 #ffff00 #000000 #000000 ^You try to open the door to the (\w+) but find it slams closed in your face, symbolic of your lack of piety\.$ 1 Slam Shut 0 1 0 #ff0000 #ffff00 #000000 #000000 The door slams shut! 3 Denied entry 0 0 0 #ff0000 #ffff00 #000000 #000000 The door suddenly slams shut, denying you entry. 3 CIJ 0 0 0 #ff0000 #ffff00 #000000 #000000 A section of the door slides aside, and a rubber-gloved fist on a spring pops out and punches you in the nose! 3 Springs back 0 0 0 #ff0000 #ffff00 #000000 #000000 The door budges, and then springs immediately back into place. 3 Bolted 0 0 0 #ff0000 #ffff00 #000000 #000000 ^The door to the (\w+) is closed forcefully fromthe other side and the sound of a bolt being slammed home makes your lack of admittance clear\.$ 1 Mhaldor council room 0 0 0 #ff0000 #ffff00 #000000 #000000 The door closes swiftly with a loud 'BANG'! 3 Door closed 0 2 0 #ff0000 #ffff00 #000000 #000000 You open the door to the return isPrompt() ^The door to the \w+ closes with a click\.$ 2 4 1 Failed to open Door 0 0 0 #ff0000 #ffff00 #000000 #000000 You are not carrying a key for this door. This door has been magically locked shut. Not recognising you as cast or crew, stagehands firmly close the door on you. 3 3 3 Door Locked 0 0 0 #ff0000 #ffff00 #000000 #000000 The door is locked. 3 Door in the way 0 0 0 #ff0000 #ffff00 #000000 #000000 There is a door in the way, to the There is a door in the way. 2 3 Wormholes 0 0 0 #ff0000 #ffff00 #000000 #000000 Worm Sources 0 0 0 #ff0000 #ffff00 #000000 #000000 You sense a connection between ^You sense a connection between (.*) and (.*).$ 2 1 Worm seek 0 0 0 #ff0000 #ffff00 #000000 #000000 You sense a wormhole leading to ^You sense a wormhole leading to (.*).$ 2 1 Mudlet Mapper Check for updates periodically Mudlet Mapper Go to ID or area ^goto (.+)$ View roomID or area ^mmap ?(.+)?$ Toggle pause ^mpp(?:\s?(on|off))?$ Stop walking ^mstop$ Option ^mconfig( (\w+) (.*))?$ Display area for lock/unlock ^arealock(?: (.*))?$ Add a room label ^room label (.+)$ View/delete area labels ^area labels ?(.+)?$ Room find ^(?:rf|room find) (.+)$ Room look ^(?:rl|room look)(?: (.+))?$ Room list ^room list(?: (.+))?$ Area list ^area list$ mm Mapping Manually set the room coordinates ^(?:rc|room coords) (?:v(\d+) )?(.+)$ Add a special exit ^(?:spe|exit special) (\w+) (.+)$ List special exits ^spe list(?: (.+))?$ Clear all special exits ^(?:spe clear|exit special clear) ?(\w+)?$ Create a room ^(?:rlc|room create) (.+)?$ Create a link between two rooms ^(?:rlk|room link) ?(\d+)? (\w+)( one)?$ Delete a room ^(?:rld|room delete) ?(\w+)?$ Delete a link ^(?:urlk|room unlink) (\w+)$ Move room to another area ^room area (?:v(\d+) )?(.+)$ Set a room character ^rcc ([^ ]+)(?: (\w+))?$ Set room weight ^rw(?: (\w+))? (\d+)$ -- (area functions) Create an area ^area add (.+)$ Delete an area ^area delete (.+)$ Rename an area ^area rename (.+)$ List continents ^(?:acl|area continents)$ Add area to continent ^ac ([\w']+)(?: (.+))?$ -- (dangerous functions) Clear the map completely ^map delete all$ Delete shop stockroom exits ^delete known stockrooms$ Clear continent data ^clear continent data$ Delete suffixed periods ^delete suffixed periods$ Find single exits ^find single exits$ Show char marks ^show char marks$ Toggle mapping mode ^(?:mc|map create) ?(on|off)?$ Save a map ^map save(?: (.+))?$ Load a map ^map load(?: (.+))?$ Get dirs ^showpath(?: (\d+))?(?: (\d+))?$ Check wholist ^who b$ Add Room Mark ^room mark (\w+) (\w+)$ Remove Room Mark ^room unmark (\w+)$ Display Room Marks ^room marks$ Mudlet Mapper RoomNum gmcp.Room.Info gmcp.Room mm Mapping gmcp.Room.Info RoomNum sysDataSendRequest sysExitEvent sysLoadEvent mmp areas changed sys2DMapLoad sys3DMapLoad sysMapLoad Game-specific mmp logged in mmapper went outside mmp logged in mmp logged in mmp logged in mmp logged in mmp logged in Test / one-time things gmcp.Room.Info Check for map updates sysDownloadDone mmp logged in sysDownloadError mudlet-2.1/src/HostManager.h0000644000175000017500000000534311624306130015327 0ustar csmallcsmall#ifndef _HOSTMANAGER_H_ #define _HOSTMANAGER_H_ /*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include "HostPool.h" #include "Host.h" class HostManager { public: static HostManager * self(); Host * getHost( QString hostname ); Host * getHost( std::string hostname ); QStringList getHostList() { return mHostPool.getHostList(); } QList getHostNameList() { return mHostPool.getHostNameList(); } Host * getFirstHost(){ return mHostPool.getFirstHost(); } Host * getNextHost( QString LastHost ){ return mHostPool.getNextHost(LastHost); } //get next host key by providing a LastHost bool addHost( QString name, QString port, QString login, QString pass ); bool deleteHost( QString ); bool renameHost( QString ); Host * getHostFromHostID( int id ){ return mHostPool.getHostFromHostID( id ); } bool serialize(); void postIrcMessage(QString, QString, QString ); private: HostManager(){;} void init(); static HostManager * _self; HostPool mHostPool; QMutex mLock; Host * mpActiveHost; }; #endif mudlet-2.1/src/en_US.aff0000644000175000017500000000574511513237311014444 0ustar csmallcsmallSET ISO8859-1 TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ' NOSUGGEST ! # ordinal numbers COMPOUNDMIN 1 # only in compounds: 1th, 2th, 3th ONLYINCOMPOUND c # compound rules: # 1. [0-9]*1[0-9]th (10th, 11th, 12th, 56714th, etc.) # 2. [0-9]*[02-9](1st|2nd|3rd|[4-9]th) (21st, 22nd, 123rd, 1234th, etc.) COMPOUNDRULE 2 COMPOUNDRULE n*1t COMPOUNDRULE n*mp WORDCHARS 0123456789 PFX A Y 1 PFX A 0 re . PFX I Y 1 PFX I 0 in . PFX U Y 1 PFX U 0 un . PFX C Y 1 PFX C 0 de . PFX E Y 1 PFX E 0 dis . PFX F Y 1 PFX F 0 con . PFX K Y 1 PFX K 0 pro . SFX V N 2 SFX V e ive e SFX V 0 ive [^e] SFX N Y 3 SFX N e ion e SFX N y ication y SFX N 0 en [^ey] SFX X Y 3 SFX X e ions e SFX X y ications y SFX X 0 ens [^ey] SFX H N 2 SFX H y ieth y SFX H 0 th [^y] SFX Y Y 1 SFX Y 0 ly . SFX G Y 2 SFX G e ing e SFX G 0 ing [^e] SFX J Y 2 SFX J e ings e SFX J 0 ings [^e] SFX D Y 4 SFX D 0 d e SFX D y ied [^aeiou]y SFX D 0 ed [^ey] SFX D 0 ed [aeiou]y SFX T N 4 SFX T 0 st e SFX T y iest [^aeiou]y SFX T 0 est [aeiou]y SFX T 0 est [^ey] SFX R Y 4 SFX R 0 r e SFX R y ier [^aeiou]y SFX R 0 er [aeiou]y SFX R 0 er [^ey] SFX Z Y 4 SFX Z 0 rs e SFX Z y iers [^aeiou]y SFX Z 0 ers [aeiou]y SFX Z 0 ers [^ey] SFX S Y 4 SFX S y ies [^aeiou]y SFX S 0 s [aeiou]y SFX S 0 es [sxzh] SFX S 0 s [^sxzhy] SFX P Y 3 SFX P y iness [^aeiou]y SFX P 0 ness [aeiou]y SFX P 0 ness [^y] SFX M Y 1 SFX M 0 's . SFX B Y 3 SFX B 0 able [^aeiou] SFX B 0 able ee SFX B e able [^aeiou]e SFX L Y 1 SFX L 0 ment . REP 88 REP a ei REP ei a REP a ey REP ey a REP ai ie REP ie ai REP are air REP are ear REP are eir REP air are REP air ere REP ere air REP ere ear REP ere eir REP ear are REP ear air REP ear ere REP eir are REP eir ere REP ch te REP te ch REP ch ti REP ti ch REP ch tu REP tu ch REP ch s REP s ch REP ch k REP k ch REP f ph REP ph f REP gh f REP f gh REP i igh REP igh i REP i uy REP uy i REP i ee REP ee i REP j di REP di j REP j gg REP gg j REP j ge REP ge j REP s ti REP ti s REP s ci REP ci s REP k cc REP cc k REP k qu REP qu k REP kw qu REP o eau REP eau o REP o ew REP ew o REP oo ew REP ew oo REP ew ui REP ui ew REP oo ui REP ui oo REP ew u REP u ew REP oo u REP u oo REP u oe REP oe u REP u ieu REP ieu u REP ue ew REP ew ue REP uff ough REP oo ieu REP ieu oo REP ier ear REP ear ier REP ear air REP air ear REP w qu REP qu w REP z ss REP ss z REP shun tion REP shun sion REP shun cion mudlet-2.1/src/dlgOptionsAreaScripts.h0000644000175000017500000000334311513237311017401 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _dlgOptionsAreaScripts_h #define _dlgOptionsAreaScripts_h #include "ui_options_area_scripts.h" #include #include "TScript.h" class dlgOptionsAreaScripts: public QWidget , public Ui::options_area_scripts { Q_OBJECT public: dlgOptionsAreaScripts(QWidget *); signals: public slots: }; #endif mudlet-2.1/src/ActionUnit.h0000644000175000017500000001011011647202526015171 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _ACTION_UNIT_H #define _ACTION_UNIT_H #include "TAction.h" #include #include #include #include #include "TToolBar.h" #include "TEasyButtonBar.h" #include class TToolBar; class TEasyButtonBar; class TAction; class Host; class ActionUnit { friend class XMLexport; friend class XMLimport; public: ActionUnit( Host * pHost ) : mpHost(pHost), mMaxID(0) {;} std::list getActionRootNodeList() { QMutexLocker locker(& mActionUnitLock); return mActionRootNodeList; } TAction * getAction( int id ); TAction * findAction( QString & ); void compileAll(); bool registerAction( TAction * pT ); void unregisterAction( TAction * pT ); bool serialize( QDataStream & ); bool restore( QDataStream &, bool ); void reParentAction( int childID, int oldParentID, int newParentID, int parentPostion = -1, int childPosition = -1 ); qint64 getNewID(); void uninstall( QString ); void _uninstall( TAction * pChild, QString packageName ); void updateToolbar(); std::list getToolBarList(); std::list getEasyButtonBarList(); TAction * getHeadAction( TToolBar * ); TAction * getHeadAction( TEasyButtonBar * ); void processDataStream( QString & ); void constructToolbar( TAction *, mudlet * pMainWindow, TToolBar * pTB ); void constructToolbar( TAction *, mudlet * pMainWindow, TEasyButtonBar * pTB ); void showToolBar( QString & ); void hideToolBar( QString & ); QMutex mActionUnitLock; QList uninstallList; private: ActionUnit(){;} TAction * getActionPrivate( int id ); void addActionRootNode( TAction * pT, int parentPosition = -1, int childPosition = -1 ); void addAction( TAction * pT ); void removeActionRootNode( TAction * pT ); void removeAction( TAction *); Host * mpHost; QMap mActionMap; std::list mActionRootNodeList; qint64 mMaxID; TToolBar * mpToolBar; TEasyButtonBar * mpEasyButtonBar; bool mModuleMember; std::list mToolBarList; std::list mEasyButtonBarList; }; #endif mudlet-2.1/src/dlgActionMainArea.h0000644000175000017500000000327311513237311016422 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef dlg_actionsmainarea_h #define dlg_actionsmainarea_h #include "ui_actions_main_area.h" #include class dlgActionMainArea : public QWidget , public Ui::actions_main_area { Q_OBJECT public: dlgActionMainArea(QWidget*); signals: public slots: }; #endif mudlet-2.1/src/EActionGroup.cpp0000644000175000017500000000340411513237311016006 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "EActionGroup.h" #include EActionGroup::EActionGroup(QObject* parent, QString name) : QAction(parent) { qDebug() << "MyAction::MyAction()"; setText(name); setObjectName(name); } void EActionGroup::triggered() { qDebug()<<"FUUUUUUUUUUUUUUk triggered"; } void EActionGroup::trigger() { ; qDebug()<<"####################EAction::triggered is called!!!!"; } mudlet-2.1/src/HostPool.cpp0000644000175000017500000001553411624306130015224 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include "HostPool.h" #include "Host.h" #include #include bool HostPool::deleteHost(QString hostname) { QMutexLocker locker(& mPoolLock); std::cout << "---> trying to delete host <"< from host pool."<mIsGoingDown = true; pH->mTelnet.disconnect(); std::cout << "[OK] Host deleted removing pool entry ..."<::iterator it; if( ++it != mHostPool.end() ) { Host * pHost = mHostPool[it.key()]; return pHost; } } else { return 0; } Host * pHost = mHostPool[mHostPool.begin().key()]; return pHost; } bool HostPool::serialize( QString directory ) { QMutexLocker locker(& mPoolLock); QString filename = directory + "/HostPool.dat"; QDir dir; if( ! dir.exists( directory ) ) { dir.mkpath( directory ); } QFile file( filename ); file.open(QIODevice::WriteOnly); QDataStream ofs(&file); ofs << mHostPool.size(); typedef QMap::iterator IT; for( IT it=mHostPool.begin(); it!=mHostPool.end(); it++ ) { ofs << it.key(); //host pool selbst serialisen QString host_directory = directory + it.key(); if( ! it.value()->serialize() ) { file.close(); qDebug() << "ERROR: can't serialize " << it.key() << endl; return false; } } file.close(); return true; } mudlet-2.1/src/Host.cpp0000644000175000017500000011374512076170616014407 0ustar csmallcsmall /*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn KoehnHeiko@googlemail.com * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _HOST_CPP_ #define _HOST_CPP_ #include #include "Host.h" #include "ctelnet.h" #include #include #include #include #include "XMLexport.h" #include "XMLimport.h" #include "mudlet.h" #include "TEvent.h" #include #include "dlgNotepad.h" extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" } Host::Host( int port, QString hostname, QString login, QString pass, int id ) : mTelnet( this ) , mpConsole( 0 ) , mLuaInterpreter ( this, id ) , mTriggerUnit ( this ) , mTimerUnit ( this ) , mScriptUnit ( this ) , mAliasUnit ( this ) , mActionUnit ( this ) , mKeyUnit ( this ) , commandLineMinimumHeight( 30 ) , mAlertOnNewData( true ) , mAllowToSendCommand( true ) , mAutoClearCommandLineAfterSend( false ) , mBlockScriptCompile( true ) , mBorderBottomHeight( 0 ) , mBorderLeftWidth( 0 ) , mBorderRightWidth( 0 ) , mBorderTopHeight( 0 ) , mCodeCompletion( true ) , mCommandLineFont ( QFont("Bitstream Vera Sans Mono", 10, QFont::Courier ) )//( QFont("Monospace", 10, QFont::Courier) ) , mCommandSeparator ( QString(";") ) , mCommandSeperator ( QString(";") ) , mDisableAutoCompletion( false ) , mDisplayFont ( QFont("Bitstream Vera Sans Mono", 10, QFont::Courier ) )//, mDisplayFont ( QFont("Bitstream Vera Sans Mono", 10, QFont:://( QFont("Monospace", 10, QFont::Courier) ), mPort ( port ) , mEnableGMCP( false ) , mFORCE_GA_OFF( false ) , mFORCE_NO_COMPRESSION( false ) , mFORCE_SAVE_ON_EXIT( false ) , mHostID( id ) , mHostName( hostname ) , mInsertedMissingLF( false ) , mIsGoingDown( false ) , mLF_ON_GA( true ) , mLogin( login ) , mMainIconSize( 3 ) , mNoAntiAlias( false ) , mPass( pass ) , mpEditorDialog(0) , mpMap( new TMap( this ) ) , mpNotePad( 0 ) , mPort(port) , mPrintCommand( true ) , mRawStreamDump( false ) , mResetProfile( false ) , mRetries( 5 ) , mSaveProfileOnExit( false ) , mScreenHeight( 25 ) , mScreenWidth( 90 ) , mTEFolderIconSize( 3 ) , mTimeout( 60 ) , mUSE_FORCE_LF_AFTER_PROMPT( false ) , mUSE_IRE_DRIVER_BUGFIX( true ) , mUSE_UNIX_EOL( false ) , mWrapAt( 100 ) , mWrapIndentCount( 0 ) , mCommandLineBgColor( QColor( 0, 0, 0) ) , mCommandLineFgColor( QColor(128,128,128) ) , mBlack ( QColor( 0, 0, 0) ) , mLightBlack ( QColor(128,128,128) ) , mRed ( QColor(128, 0, 0) ) , mLightRed ( QColor(255, 0, 0) ) , mLightGreen ( QColor( 0,255, 0) ) , mGreen ( QColor( 0,179, 0) ) , mLightBlue ( QColor( 0, 0,255) ) , mBlue ( QColor( 0, 0,128) ) , mLightYellow ( QColor(255,255, 0) ) , mYellow ( QColor(128,128, 0) ) , mLightCyan ( QColor( 0,255,255) ) , mCyan ( QColor( 0,128,128) ) , mLightMagenta ( QColor(255, 0,255) ) , mMagenta ( QColor(128, 0,128) ) , mLightWhite ( QColor(255,255,255) ) , mWhite ( QColor(192,192,192) ) , mFgColor ( QColor(192,192,192) ) , mBgColor ( QColor( 0, 0, 0) ) , mCommandBgColor ( QColor( 0, 0, 0) ) , mCommandFgColor ( QColor(113,113, 0) ) , mBlack_2 ( QColor( 36, 36, 36, 255) ) , mLightBlack_2 ( QColor(128,128,128, 255) ) , mRed_2 ( QColor(128, 0, 0, 255) ) , mLightRed_2 ( QColor(255, 0, 0, 255) ) , mLightGreen_2 ( QColor( 0,255, 0, 255) ) , mGreen_2 ( QColor( 0,179, 0, 255) ) , mLightBlue_2 ( QColor( 0, 0, 255, 255) ) , mBlue_2 ( QColor( 0, 0, 128, 255) ) , mLightYellow_2 ( QColor(255,255, 0, 255) ) , mYellow_2 ( QColor(128,128, 0, 255) ) , mLightCyan_2 ( QColor( 0,255,255, 255) ) , mCyan_2 ( QColor( 0,128,128, 255) ) , mLightMagenta_2 ( QColor(255, 0,255, 255) ) , mMagenta_2 ( QColor(128, 0,128, 255) ) , mLightWhite_2 ( QColor(255,255,255, 255) ) , mWhite_2 ( QColor(192,192,192, 255) ) , mFgColor_2 ( QColor(192,192,192, 255) ) , mBgColor_2 ( QColor( 0, 0, 0, 255) ) , mSpellDic ( "en_US" ) , mLogStatus ( false ) , mEnableSpellCheck ( true ) , mpUnzipDialog ( 0 ) , mRoomSize ( 0.5 ) , mLineSize ( 5.0 ) , mServerGUI_Package_version( -1 ) , mServerGUI_Package_name( "nothing" ) , mAcceptServerGUI ( true ) , mModuleSaveBlock(false) , mFORCE_MXP_NEGOTIATION_OFF( false ) , mHaveMapperScript( false ) { // mLogStatus = mudlet::self()->mAutolog; QString directoryLogFile = QDir::homePath()+"/.config/mudlet/profiles/"; directoryLogFile.append(mHostName); directoryLogFile.append("/log"); QString logFileName = directoryLogFile + "/errors.txt"; QDir dirLogFile; if( ! dirLogFile.exists( directoryLogFile ) ) { dirLogFile.mkpath( directoryLogFile ); } mErrorLogFile.setFileName( logFileName ); mErrorLogFile.open( QIODevice::Append ); mErrorLogStream.setDevice( &mErrorLogFile ); mpMap->restore(""); mpMap->init( this ); mMapStrongHighlight = false; mGMCP_merge_table_keys.append("Char.Status"); } Host::Host() : mTelnet( this ) , mpConsole( 0 ) , mLuaInterpreter ( this, 0 ) , mTriggerUnit ( this ) , mTimerUnit ( this ) , mScriptUnit ( this ) , mAliasUnit ( this ) , mActionUnit ( this ) , mKeyUnit ( this ) , commandLineMinimumHeight( 30 ) , mAlertOnNewData( true ) , mAllowToSendCommand( true ) , mAutoClearCommandLineAfterSend( false ) , mBlockScriptCompile( true ) , mBorderBottomHeight( 0 ) , mBorderLeftWidth( 0 ) , mBorderRightWidth( 0 ) , mBorderTopHeight( 0 ) , mCodeCompletion( true ) , mCommandLineFont ( QFont("Bitstream Vera Sans Mono", 10, QFont::Courier ) )//( QFont("Monospace", 10, QFont::Courier) ) , mCommandSeparator ( QString(";") ) , mCommandSeperator ( QString(";") ) , mDisableAutoCompletion( false ) , mDisplayFont ( QFont("Bitstream Vera Sans Mono", 10, QFont::Courier ) )//, mDisplayFont ( QFont("Bitstream Vera Sans Mono", 10, QFont:://( QFont("Monospace", 10, QFont::Courier) ), mPort ( port ) , mEnableGMCP( false ) , mFORCE_GA_OFF( false ) , mFORCE_NO_COMPRESSION( false ) , mFORCE_SAVE_ON_EXIT( false ) , mHostID( 0 ) , mHostName( "default-host" ) , mInsertedMissingLF( false ) , mIsGoingDown( false ) , mLF_ON_GA( true ) , mLogin( "" ) , mMainIconSize( 3 ) , mNoAntiAlias( false ) , mPass( "" ) , mpEditorDialog(0) , mpMap( new TMap( this ) ) , mpNotePad( 0 ) , mPort(23) , mPrintCommand( true ) , mRawStreamDump( false ) , mResetProfile( false ) , mRetries( 5 ) , mSaveProfileOnExit( false ) , mScreenHeight( 25 ) , mScreenWidth( 90 ) , mTEFolderIconSize( 3 ) , mTimeout( 60 ) , mUSE_FORCE_LF_AFTER_PROMPT( false ) , mUSE_IRE_DRIVER_BUGFIX( true ) , mUSE_UNIX_EOL( false ) , mWrapAt( 100 ) , mWrapIndentCount( 0 ) , mModuleSaveBlock(false) , mCommandLineBgColor( QColor( 0, 0, 0) ) , mCommandLineFgColor( QColor(128,128,128) ) , mBlack ( QColor( 0, 0, 0) ) , mLightBlack ( QColor(128,128,128) ) , mRed ( QColor(128, 0, 0) ) , mLightRed ( QColor(255, 0, 0) ) , mLightGreen ( QColor( 0,255, 0) ) , mGreen ( QColor( 0,179, 0) ) , mLightBlue ( QColor( 0, 0,255) ) , mBlue ( QColor( 0, 0,128) ) , mLightYellow ( QColor(255,255, 0) ) , mYellow ( QColor(128,128, 0) ) , mLightCyan ( QColor( 0,255,255) ) , mCyan ( QColor( 0,128,128) ) , mLightMagenta ( QColor(255, 0,255) ) , mMagenta ( QColor(128, 0,128) ) , mLightWhite ( QColor(255,255,255) ) , mWhite ( QColor(192,192,192) ) , mFgColor ( QColor(192,192,192) ) , mBgColor ( QColor( 0, 0, 0) ) , mCommandBgColor ( QColor( 0, 0, 0) ) , mCommandFgColor ( QColor(113,113, 0) ) , mBlack_2 ( QColor( 36, 36, 36, 255) ) , mLightBlack_2 ( QColor(128,128,128, 255) ) , mRed_2 ( QColor(128, 0, 0, 255) ) , mLightRed_2 ( QColor(255, 0, 0, 255) ) , mLightGreen_2 ( QColor( 0,255, 0, 255) ) , mGreen_2 ( QColor( 0,179, 0, 255) ) , mLightBlue_2 ( QColor( 0, 0, 255, 255) ) , mBlue_2 ( QColor( 0, 0, 128, 255) ) , mLightYellow_2 ( QColor(255,255, 0, 255) ) , mYellow_2 ( QColor(128,128, 0, 255) ) , mLightCyan_2 ( QColor( 0,255,255, 255) ) , mCyan_2 ( QColor( 0,128,128, 255) ) , mLightMagenta_2 ( QColor(255, 0,255, 255) ) , mMagenta_2 ( QColor(128, 0,128, 255) ) , mLightWhite_2 ( QColor(255,255,255, 255) ) , mWhite_2 ( QColor(192,192,192, 255) ) , mFgColor_2 ( QColor(192,192,192, 255) ) , mBgColor_2 ( QColor( 0, 0, 0, 255) ) , mSpellDic ( "en_US" ) , mLogStatus ( false ) , mEnableSpellCheck ( true ) , mpUnzipDialog ( 0 ) , mRoomSize ( 0.5 ) , mLineSize ( 5.0 ) , mShowInfo ( true ) , mServerGUI_Package_version( -1 ) , mServerGUI_Package_name( "nothing" ) , mAcceptServerGUI ( true ) , mFORCE_MXP_NEGOTIATION_OFF( false ) , mHaveMapperScript( false ) { QString directoryLogFile = QDir::homePath()+"/.config/mudlet/profiles/"; directoryLogFile.append(mHostName); directoryLogFile.append("/log"); QString logFileName = directoryLogFile + "/errors.txt"; QDir dirLogFile; if( ! dirLogFile.exists( directoryLogFile ) ) { dirLogFile.mkpath( directoryLogFile ); } mErrorLogFile.setFileName( logFileName ); mErrorLogFile.open( QIODevice::Append ); mErrorLogStream.setDevice( &mErrorLogFile ); mpMap->restore(""); mpMap->init( this ); mMapStrongHighlight = false; mGMCP_merge_table_keys.append("Char.Status"); } Host::~Host() { mErrorLogStream.flush(); mErrorLogFile.close(); } void Host::saveModules(int sync){ if (mModuleSaveBlock){ qDebug()<<"MODULES SAVING DISABLED UNTIL RELOAD"; return; } qDebug()<<"DONE MAIN WRITING, DOING MODULES NOW"; QMapIterator it(modulesToWrite); QStringList modulesToSync; QString dirName = QDir::homePath()+"/.config/mudlet/moduleBackups/"; QDir savePath = QDir(dirName); if (!savePath.exists()) savePath.mkpath(dirName); while(it.hasNext()){ it.next(); QStringList entry = it.value(); QString filename_xml = entry[0]; QString time = QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss"); //move the old file, use the key (module name) as the file savePath.rename(filename_xml,dirName+it.key()+time); QFile file_xml( filename_xml ); qDebug()<<"writing module xml for:"< activeSessions = mudlet::self()->mConsoleMap; QMapIterator it2(activeSessions); while (it2.hasNext()){ it2.next(); Host * host = it2.key(); if (host->mHostName == mHostName) continue; QMap installedModules = host->mInstalledModules; QMap modulePri = host->mModulePriorities; QMapIterator it3(modulePri); QMap moduleOrder; while( it3.hasNext() ){ it3.next(); //QStringList moduleEntry = moduleOrder[it3.value()]; //moduleEntry.append(it3.key()); moduleOrder[it3.value()].append(it3.key());// = moduleEntry; } QMapIterator it4(moduleOrder); while(it4.hasNext()){ it4.next(); //qDebug()<<"On priority "<mHostName; host->reloadModule(moduleName); } } } } } } void Host::reloadModule(QString moduleName){ QMap installedModules = mInstalledModules; QMapIterator it(installedModules); while(it.hasNext()){ it.next(); QStringList entry = it.value(); if (it.key() == moduleName){ uninstallPackage(it.key(),2); installPackage(entry[0],1); } } //iterate through mInstalledModules again and reset the entry flag to be correct. //both the installedModules and mInstalled should be in the same order now as well QMapIterator it2(mInstalledModules); while(it2.hasNext()){ it2.next(); QStringList entry = installedModules[it2.key()]; mInstalledModules[it2.key()] = entry; } } void Host::resetProfile() { getTimerUnit()->stopAllTriggers(); mudlet::self()->mTimerMap.clear(); getTimerUnit()->removeAllTempTimers(); getTriggerUnit()->removeAllTempTriggers(); mTimerUnit.doCleanup(); mTriggerUnit.doCleanup(); mpConsole->resetMainConsole(); mEventHandlerMap.clear(); mEventMap.clear(); mLuaInterpreter.initLuaGlobals(); mLuaInterpreter.loadGlobal(); mBlockScriptCompile = false; getTriggerUnit()->compileAll(); getAliasUnit()->compileAll(); getActionUnit()->compileAll(); getKeyUnit()->compileAll(); getScriptUnit()->compileAll(); //getTimerUnit()->compileAll(); mResetProfile = false; mTimerUnit.reenableAllTriggers(); TEvent event; event.mArgumentList.append( "sysLoadEvent" ); event.mArgumentTypeList.append(ARGUMENT_TYPE_STRING); raiseEvent( & event ); qDebug()<<"resetProfile() DONE"; } void Host::assemblePath() { QStringList list; for( int i=0; imPathList.size(); i++ ) { QString n = QString::number( mpMap->mPathList[i]); list.append( n ); } QStringList list2; for( int i=0; imDirList.size(); i++ ) { QString n = mpMap->mDirList[i]; list2.append( n ); } QString t1 = "speedWalkPath"; mLuaInterpreter.set_lua_table( t1, list ); QString t2 = "speedWalkDir"; mLuaInterpreter.set_lua_table( t2, list2 ); } int Host::check_for_mappingscript() { // the mapper script reminder is only shown once // because it is too difficult and error prone (->proper script sequence) // to disable this message bool ret = (mLuaInterpreter.check_for_mappingscript() || mHaveMapperScript); mHaveMapperScript = true; return ret; } void Host::startSpeedWalk() { QStringList list; for( int i=0; imPathList.size(); i++ ) { QString n = QString::number( mpMap->mPathList[i]); list.append( n ); } QStringList list2; for( int i=0; imDirList.size(); i++ ) { QString n = mpMap->mDirList[i]; list2.append( n ); } QString t1 = "speedWalkPath"; mLuaInterpreter.set_lua_table( t1, list ); QString t2 = "speedWalkDir"; mLuaInterpreter.set_lua_table( t2, list2 ); QString f = "doSpeedWalk"; QString n = ""; mLuaInterpreter.call( f, n ); } void Host::adjustNAWS() { mTelnet.setDisplayDimensions(); } void Host::setReplacementCommand( QString s ) { mReplacementCommand = s; } void Host::stopAllTriggers() { mTriggerUnit.stopAllTriggers(); mAliasUnit.stopAllTriggers(); mTimerUnit.stopAllTriggers(); } void Host::reenableAllTriggers() { mTriggerUnit.reenableAllTriggers(); mAliasUnit.reenableAllTriggers(); mTimerUnit.reenableAllTriggers(); } void Host::send( QString cmd, bool wantPrint, bool dontExpandAliases ) { if( wantPrint && mPrintCommand ) { mInsertedMissingLF = true; if( (cmd == "") && ( mUSE_IRE_DRIVER_BUGFIX ) && ( ! mUSE_FORCE_LF_AFTER_PROMPT ) ) { ; } else { mpConsole->printCommand( cmd ); // used to print the terminal that terminates a telnet command // this is important to get the cursor position right } mpConsole->update(); } QStringList commandList = cmd.split( QString( mCommandSeparator ), QString::SkipEmptyParts ); if( ! dontExpandAliases ) { if( commandList.size() == 0 ) { sendRaw( "\n" );//NOTE: damit leerprompt moeglich sind return; } } for( int i=0; i 0 ) { mTelnet.sendData( mReplacementCommand ); } else { mTelnet.sendData( command ); } } } } void Host::sendRaw( QString command ) { mTelnet.sendData( command ); } /*QStringList Host::getBufferTable( int from, int to ) { QStringList bufList; if( (mTextBufferList.size()-1-to<0) || (mTextBufferList.size()-1-from<0) || (mTextBufferList.size()-1-from>=mTextBufferList.size()) || mTextBufferList.size()-1-to>=mTextBufferList.size() ) { return bufList << QString("ERROR: buffer out of range"); } for( int i=mTextBufferList.size()-1-from; i>=0; i-- ) { if( i < mTextBufferList.size()-1-to ) break; bufList << mTextBufferList[i]; } return bufList; } QString Host::getBufferLine( int line ) { QString text; if( (line < 0) || (mTextBufferList.size()-1-line>=mTextBufferList.size()) ) { text = "ERROR: buffer out of range"; return text; } text = mTextBufferList[mTextBufferList.size()-1-line]; return text; } */ int Host::createStopWatch() { int newWatchID = mStopWatchMap.size()+1; mStopWatchMap[newWatchID] = QTime(0,0,0,0); return newWatchID; } double Host::getStopWatchTime( int watchID ) { if( mStopWatchMap.contains( watchID ) ) { return static_cast(mStopWatchMap[watchID].elapsed())/1000; } else { return -1.0; } } bool Host::startStopWatch( int watchID ) { if( mStopWatchMap.contains( watchID ) ) { mStopWatchMap[watchID].start(); return true; } else return false; } double Host::stopStopWatch( int watchID ) { if( mStopWatchMap.contains( watchID ) ) { return static_cast(mStopWatchMap[watchID].elapsed())/1000; } else { return -1.0; } } bool Host::resetStopWatch( int watchID ) { if( mStopWatchMap.contains( watchID ) ) { mStopWatchMap[watchID].setHMS(0,0,0,0); return true; } else return false; } void Host::callEventHandlers() { } void Host::incomingStreamProcessor( QString & data, int line ) { mTriggerUnit.processDataStream( data, line ); mTimerUnit.doCleanup(); if( mResetProfile ) { resetProfile(); } } void Host::registerEventHandler( QString name, TScript * pScript ) { if( mEventHandlerMap.contains( name ) ) { if( ! mEventHandlerMap[name].contains( pScript ) ) { mEventHandlerMap[name].append( pScript ); } } else { QList scriptList; scriptList.append( pScript ); mEventHandlerMap.insert( name, scriptList ); } } void Host::registerAnonymousEventHandler( QString name, QString fun ) { if( mAnonymousEventHandlerFunctions.contains( name ) ) { if( ! mAnonymousEventHandlerFunctions[name].contains( fun ) ) { mAnonymousEventHandlerFunctions[name].push_back( fun ); } } else { QStringList newList; newList << fun; mAnonymousEventHandlerFunctions[name] = newList; } } void Host::unregisterEventHandler( QString name, TScript * pScript ) { if( mEventHandlerMap.contains( name ) ) { mEventHandlerMap[name].removeAll( pScript ); } } void Host::raiseEvent( TEvent * pE ) { if( pE->mArgumentList.size() < 1 ) return; if( mEventHandlerMap.contains( pE->mArgumentList[0] ) ) { qDebug()<<"event:"<mArgumentList; QList scriptList = mEventHandlerMap[pE->mArgumentList[0]]; for( int i=0; icallEventHandler( pE ); } } if( mAnonymousEventHandlerFunctions.contains( pE->mArgumentList[0] ) ) { qDebug()<<"event:"<mArgumentList; QStringList funList = mAnonymousEventHandlerFunctions[pE->mArgumentList[0]]; for( int i=0; i calling anonymous handler:"<mArgumentList << "sysIrcMessage"; pE->mArgumentList << a << b << c; pE->mArgumentTypeList << ARGUMENT_TYPE_STRING << ARGUMENT_TYPE_STRING << ARGUMENT_TYPE_STRING << ARGUMENT_TYPE_STRING; raiseEvent( pE ); } void Host::enableTimer( QString & name ) { mTimerUnit.enableTimer( name ); } void Host::disableTimer( QString & name ) { mTimerUnit.disableTimer( name ); } bool Host::killTimer( QString & name ) { return mTimerUnit.killTimer( name ); } void Host::enableKey( QString & name ) { mKeyUnit.enableKey( name ); } void Host::disableKey( QString & name ) { mKeyUnit.disableKey( name ); } void Host::enableTrigger( QString & name ) { mTriggerUnit.enableTrigger( name ); } void Host::disableTrigger( QString & name ) { mTriggerUnit.disableTrigger( name ); } bool Host::killTrigger( QString & name ) { return mTriggerUnit.killTrigger( name ); } void Host::connectToServer() { mTelnet.connectIt( mUrl, mPort ); } bool Host::serialize() { return false; if( ! mSaveProfileOnExit ) { return true; } QString directory_xml = QDir::homePath()+"/.config/mudlet/profiles/"+mHostName+"/current"; QString filename_xml = directory_xml + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss")+".xml"; QDir dir_xml; if( ! dir_xml.exists( directory_xml ) ) { dir_xml.mkpath( directory_xml ); } QDir dir_map; QString directory_map = QDir::homePath()+"/.config/mudlet/profiles/"+mHostName+"/map"; QString filename_map = directory_map + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss")+"map.dat"; if( ! dir_map.exists( directory_map ) ) { dir_map.mkpath( directory_map ); } QFile file_xml( filename_xml ); if ( file_xml.open( QIODevice::WriteOnly ) ) { modulesToWrite.clear(); XMLexport writer( this ); writer.exportHost( & file_xml ); file_xml.close(); saveModules(0); } else { QMessageBox::critical( 0, "Profile Save Failed", "Failed to save "+mHostName+" to location "+filename_xml+" because of the following error: "+file_xml.errorString() ); } if( mpMap->rooms.size() > 10 ) { QFile file_map( filename_map ); if ( file_map.open( QIODevice::WriteOnly ) ) { QDataStream out( & file_map ); mpMap->serialize( out ); file_map.close(); } else { QMessageBox::critical( 0, "Profile Save Failed", "Failed to save "+mHostName+" to location "+filename_xml+" because of the following error: "+file_xml.errorString() ); } } return true; } bool Host::closingDown() { QMutexLocker locker(& mLock); bool shutdown = mIsClosingDown; return shutdown; } void Host::orderShutDown() { QMutexLocker locker(& mLock); mIsClosingDown = true; } // this is called by the Lua function unzip() defined in LuaGlobal.lua void Host::showUnpackingProgress( QString txt ) { return; if( ! mpUnzipDialog ) return; QStringList l; l << txt; packageList->addItems( l ); packageList->scrollToBottom(); packageList->update(); QApplication::sendPostedEvents(); } #include #ifdef Q_OS_WIN #include "quazip.h" #include "JlCompress.h" #endif bool Host::installPackage( QString fileName, int module ) { if( fileName.isEmpty() ) return false; QFile file(fileName); if( ! file.open(QFile::ReadOnly | QFile::Text) ) { return false; } QString packageName = fileName.section("/", -1); packageName.replace( ".zip" , "" ); packageName.replace( "trigger", "" ); packageName.replace( "xml", "" ); packageName.replace( ".mpackage" , "" ); packageName.replace( '/' , "" ); packageName.replace( '\\' , "" ); packageName.replace( '.' , "" ); if (module){ if( mActiveModules.contains( packageName ) ){ uninstallPackage(packageName, 2); } } else{ if( mInstalledPackages.contains( packageName ) ) { return false; } } if( mpEditorDialog ) { mpEditorDialog->doCleanReset(); } QFile file2; if( fileName.endsWith(".zip") || fileName.endsWith(".mpackage") ) { QString _home = QDir::homePath(); _home.append( "/.config/mudlet/profiles/" ); _home.append( getName() ); QString _dest = QString( "%1/%2/").arg( _home ).arg( packageName ); QDir _tmpDir; _tmpDir.mkpath(_dest); QUiLoader loader; QFile file(":/ui/package_manager_unpack.ui"); file.open(QFile::ReadOnly); mpUnzipDialog = dynamic_cast(loader.load( &file, 0 ) ); file.close(); if( ! mpUnzipDialog ) return false; QString _title = QString("Unpacking package: %1").arg(fileName); mpUnzipDialog->setWindowTitle( _title ); mpUnzipDialog->show(); mpUnzipDialog->raise(); QApplication::sendPostedEvents(); // At the moment, QuaZip is for Windows only - OSX and Linux use LuaZip as it is more commonly available // In the future, QuaZip will be the preferred option with LuaZip as a fallback #ifndef Q_OS_WIN QString _script = QString( "unzip([[%1]], [[%2]])" ).arg( fileName ).arg( _dest ); mLuaInterpreter.compileAndExecuteScript( _script ); #else JlCompress::extractDir(fileName, _dest ); #endif mpUnzipDialog->close(); mpUnzipDialog = 0; // requirements for zip packages: // - packages must be compressed in zip format // - file extension should be .mpackage (though .zip is accepted) // - there can only be a single xml file per package // - the xml file must be located in the root directory of the zip package. example: myPack.zip contains: the folder images and the file myPack.xml QDir _dir( _dest ); // before we start importing xmls in, see if the config.lua manifest file exists // - if it does, update the packageName from it if (_dir.exists("config.lua")) { // read in the new packageName from Lua. Should be expanded in future to whatever else config.lua will have readPackageConfig(_dir.absoluteFilePath("config.lua"), packageName); // now that the packageName changed, redo relevant checks to make sure it's still valid if (module) { if( mActiveModules.contains( packageName ) ) { uninstallPackage(packageName, 2); } } else { if( mInstalledPackages.contains( packageName ) ) { // cleanup and quit if already installed removeDir( _dir.absolutePath(),_dir.absolutePath() ); return false; } } // continuing, so update the folder name on disk QString newpath(QString( "%1/%2/").arg( _home ).arg( packageName )); _dir.rename(_dir.absolutePath(), newpath); _dir = QDir( newpath ); } QStringList _filterList; _filterList << "*.xml" << "*.trigger"; QFileInfoList entries = _dir.entryInfoList( _filterList, QDir::Files ); for( int i=0; idoCleanReset(); } if (!module){ QString directory_xml = QDir::homePath()+"/.config/mudlet/profiles/"+getName()+"/current"; QString filename_xml = directory_xml + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss")+".xml"; QDir dir_xml; if( ! dir_xml.exists( directory_xml ) ) { dir_xml.mkpath( directory_xml ); } QFile file_xml( filename_xml ); if ( file_xml.open( QIODevice::WriteOnly ) ) { XMLexport writer( this ); writer.exportHost( & file_xml ); file_xml.close(); } } return true; } // credit: http://john.nachtimwald.com/2010/06/08/qt-remove-directory-and-its-contents/ bool Host::removeDir( const QString dirName, QString originalPath ) { bool result = true; QDir dir(dirName); if( dir.exists( dirName ) ) { Q_FOREACH( QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) { // prevent recursion outside of the original branch if( info.isDir() && info.absoluteFilePath().startsWith( originalPath ) ) { result = removeDir( info.absoluteFilePath(), originalPath ); } else { result = QFile::remove( info.absoluteFilePath() ); } if( !result ) { return result; } } result = dir.rmdir( dirName ); } return result; } bool Host::uninstallPackage( QString packageName, int module) { if (module){ if( ! mInstalledModules.contains( packageName ) ) return false; } else{ if( ! mInstalledPackages.contains( packageName ) ) return false; } int dualInstallations=0; if (mInstalledModules.contains(packageName) && mInstalledPackages.contains(packageName)) dualInstallations=1; if( mpEditorDialog ) { mpEditorDialog->doCleanReset(); } mTriggerUnit.uninstall( packageName ); mTimerUnit.uninstall( packageName ); mAliasUnit.uninstall( packageName ); mActionUnit.uninstall( packageName ); mScriptUnit.uninstall( packageName ); mKeyUnit.uninstall( packageName ); if (module==2){ //if module == 2, this is a temporary uninstall for reloading so we exit here mInstalledModules.remove( packageName ); mActiveModules.removeAll(packageName); return true; } else if (module==1){ //if module == 1, we actually uninstall it. QStringList entry = mInstalledModules[packageName]; qDebug()<<"removing"<doCleanReset(); } getActionUnit()->updateToolbar(); QString _home = QDir::homePath(); _home.append( "/.config/mudlet/profiles/" ); _home.append( getName() ); QString _dest = QString( "%1/%2/").arg( _home ).arg( packageName ); removeDir( _dest, _dest ); QString directory_xml = QDir::homePath()+"/.config/mudlet/profiles/"+getName()+"/current"; QString filename_xml = directory_xml + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss")+".xml"; QDir dir_xml; if( ! dir_xml.exists( directory_xml ) ) { dir_xml.mkpath( directory_xml ); } QFile file_xml( filename_xml ); if ( file_xml.open( QIODevice::WriteOnly ) ) { XMLexport writer( this ); writer.exportHost( & file_xml ); file_xml.close(); } return true; } void Host::readPackageConfig( QString luaConfig, QString & packageName ) { QFile configFile(luaConfig); QStringList strings; if (configFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&configFile); while (!in.atEnd()) { strings += in.readLine(); } } lua_State *L = luaL_newstate(); luaL_openlibs(L); int error = luaL_loadstring(L, strings.join("\n").toLatin1().data()); if( !error ) error = lua_pcall(L, 0,0,0); if( !error ) { // for now, only read the mpackage parameter // would be nice to read author, save & version too later lua_getglobal(L, "mpackage"); if (lua_isstring(L, -1)) { packageName = QString(lua_tostring(L, -1)); } lua_pop(L, -1); lua_close(L); return; } else // error { string e = "no error message available from Lua"; e = lua_tostring( L, -1 ); string reason; switch (error) { case 4: reason = "Out of memory"; break; case 3: reason = "Syntax error"; break; case 2: reason = "Runtime error"; break; case 1: reason = "Yield error"; break; default: reason = "Unknown error"; break; } if( mudlet::debugMode ) qDebug()<< reason.c_str() <<" in config.lua:"<printSystemMessage(msg); lua_pop(L, -1); lua_close(L); } } #endif mudlet-2.1/src/TScript.cpp0000644000175000017500000001236512070466512015053 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include "TScript.h" #include "Host.h" #include "HostManager.h" #include "mudlet.h" #include "TDebug.h" using namespace std; TScript::TScript( TScript * parent, Host * pHost ) : Tree( parent ) , mpHost( pHost ) , mModuleMember(false) , mModuleMasterFolder(false) , mNeedsToBeCompiled( true ) , exportItem(true) { } TScript::TScript( QString name, Host * pHost ) : Tree(0) , mName( name ) , mpHost( pHost ) , mModuleMember(false) , mModuleMasterFolder(false) , mNeedsToBeCompiled( true ) , exportItem(true) { } TScript::~TScript() { if( ! mpHost ) { return; } for( int i=0; iunregisterEventHandler( mEventHandlerList[i], this ); } mpHost->getScriptUnit()->unregisterScript( this ); } bool TScript::registerScript() { if( ! mpHost ) { return false; } return mpHost->getScriptUnit()->registerScript(this); } void TScript::setEventHandlerList( QStringList handlerList ) { for( int i=0; iunregisterEventHandler( mEventHandlerList[i], this ); } mEventHandlerList.clear(); for( int i=0; iregisterEventHandler( handlerList[i], this ); } } void TScript::compileAll() { compile(); typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TScript * pChild = *it; pChild->compileAll(); } } void TScript::callEventHandler( TEvent * pE ) { // Only call this event handler if this script and all its ancestors are active: if(isActive() && ancestorsActive()) { qDebug()<<"-->calling:"<mLuaInterpreter.callEventHandler( mName, pE ); } } void TScript::compile() { if( mNeedsToBeCompiled || mpHost->mResetProfile ) { if( ! compileScript() ) { if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::red))<<"ERROR: Lua compile error. compiling script of script:"<>0;} mOK_code = false; } } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TScript * pChild = *it; pChild->compile(); } } bool TScript::setScript( QString & script ) { mScript = script; mNeedsToBeCompiled = true; if( ! mpHost->blockScripts() ) mOK_code = compileScript(); return mOK_code; } bool TScript::compileScript() { QString error; if( mpHost->mLuaInterpreter.compile( mScript, error ) ) { mNeedsToBeCompiled = false; mOK_code = true; return true; } else { mOK_code = false; setError( error ); return false; } } void TScript::execute() { if( mNeedsToBeCompiled ) { if( ! compileScript() ) { return; } } mpHost->mLuaInterpreter.call( mFuncName, mName ); } TScript& TScript::clone(const TScript& b) { mName = b.mName; mScript = b.mScript; mIsFolder = b.mIsFolder; mpHost = b.mpHost; mNeedsToBeCompiled = b.mNeedsToBeCompiled; mEventHandlerList = b.mEventHandlerList; return *this; } bool TScript::isClone(TScript &b) const { return ( mName == b.mName && mScript == b.mScript && mIsFolder == b.mIsFolder && mpHost == b.mpHost && mNeedsToBeCompiled == b.mNeedsToBeCompiled && mEventHandlerList == b.mEventHandlerList ); } mudlet-2.1/src/TDebug.cpp0000644000175000017500000000751511513237311014630 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include "mudlet.h" #include "TDebug.h" TDebug::TDebug(QColor c, QColor d) { fgColor = c; bgColor = d; msg = ""; } TDebug & TDebug::operator>>( const int code) { mudlet::mpDebugConsole->printDebug( fgColor, bgColor, msg ); return *this; } TDebug::~TDebug() { } TDebug & TDebug::operator<<( const QString & t ) { msg += t; return *this; } TDebug & TDebug::operator<<( const int & t ) { msg += QString::number(t); return *this; } TDebug & TDebug::operator<<( QString & t ) { msg += t; return *this; } TDebug & TDebug::operator<<( const QMap &map ) { for( QMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) { msg += "("; msg += it.key(); msg += ", "; msg += it.value(); msg += ")"; } msg += "), "; return *this; } TDebug & TDebug::operator<<( const QMap &map ) { for( QMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) { msg += "("; msg += it.key(); msg += ", "; msg += QString::number(it.value()); msg += ")"; } msg += "), "; return *this; } TDebug & TDebug::operator<<( const QMap &map ) { for( QMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) { msg += "("; msg += QString::number(it.key()); msg += ", "; msg += it.value(); msg += ")"; } msg += "), "; return *this; } TDebug & TDebug::operator<<( const QMap &map ) { for( QMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) { msg += "("; msg += QString::number(it.key()); msg += ", "; msg += QString::number(it.value()); msg += ")"; } msg += "), "; return *this; } TDebug & TDebug::operator<<( const QList &list ) { for( QList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) { msg += (*it); msg += ", "; } msg += ")"; return *this; } TDebug & TDebug::operator<<( const QList &list ) { for( QList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) { msg += QString::number(*it); msg += ", "; } msg += "), "; return *this; } mudlet-2.1/src/dlgConnectionProfiles.h0000644000175000017500000000663511624306130017416 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DLGCONNECTION_PROFILES_H #define DLGCONNECTION_PROFILES_H #include #include #include "ui_connection_profiles.h" class dlgConnectionProfiles : public QDialog , public Ui::profile_dialog { Q_OBJECT public: dlgConnectionProfiles(QWidget * parent = 0); void fillout_form(); void copy_profile( QString ); void writeProfileData( QString, QString, QString ); QString readProfileData( QString, QString ); QStringList readProfileHistory( QString, QString ); void accept(); signals: void signal_establish_connection( QString profile_name, int historyVersion ); void update(); public slots: void slot_chose_history(); void slot_update_name( const QString ) ; void slot_save_name() ; void slot_update_url( const QString ) ; void slot_update_port( const QString ) ; void slot_update_login( const QString ); void slot_update_pass( const QString ); void slot_update_website( const QString ); void slot_deleteprofile_check (const QString); void slot_update_description(); void slot_item_clicked( QListWidgetItem * ); void slot_update(); void slot_addProfile(); void slot_deleteProfile(); void slot_reallyDeleteProfile(); void slot_update_autologin( int state ); void slot_connectToServer(); void slot_cancel(); void slot_copy_profile(); private: bool removeDir( QString dirName, QString originalPath ); void copyFolder(QString sourceFolder, QString destFolder); bool validName; bool validUrl; bool validPort; bool validateConnect(); QString mOrigin; QString mUnsavedProfileName; QStringList mProfileList; bool mEditOK; QPalette mRegularPalette; QPalette mOKPalette; QPalette mErrorPalette; QPalette mReadOnlyPalette; QString mCurrentProfileEditName; QPushButton * connect_button; QLineEdit * delete_profile_lineedit; QPushButton * delete_button; }; #endif mudlet-2.1/src/TTimer.h0000644000175000017500000001026012070466512014324 0ustar csmallcsmall #ifndef _TIMER_H_ #define _TIMER_H_ /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "Tree.h" #include #include "Host.h" #include #include class TTimer : public Tree { friend class TimerUnit; friend class XMLexport; friend class XMLimport; public: ~TTimer(); TTimer( TTimer * parent, Host * pHost ); TTimer( QString name, QTime time, Host * pHost ); TTimer& clone(const TTimer& ); void compileAll(); QString & getName() { return mName; } void setName( QString name ); QTime & getTime() { return mTime; } void compile(); bool checkRestart(); bool compileScript(); void execute(); void setTime( QTime time ); QString getCommand() { return mCommand; } void setCommand( QString & cmd ) { mCommand = cmd; } QString getScript() { return mScript; } bool setScript( QString & script ); bool canBeUnlocked( TTimer * ); bool isFolder() { return mIsFolder; } void setIsTempTimer( bool b ) { mIsTempTimer = b; } bool isTempTimer() { return mIsTempTimer; } void setIsFolder( bool b ) { mIsFolder = b; } bool registerTimer(); bool setIsActive( bool ); void stop(); void start(); void enableTimer(); void disableTimer(); void enableTimer( QString & ); void disableTimer( QString & ); void enableTimer( qint64 ); void disableTimer( qint64 ); void killTimer(); bool isClone(TTimer &b) const; bool isOffsetTimer(); bool mRegisteredAnonymousLuaFunction; bool exportItem; private: TTimer(){}; QString mName; QString mScript; QTime mTime; QString mCommand; QString mFuncName; bool mIsFolder; Host * mpHost; bool mNeedsToBeCompiled; bool mIsTempTimer; QMutex mLock; QTimer * mpTimer; bool mModuleMember; bool mModuleMasterFolder; //TLuaInterpreter * mpLua; }; #endif mudlet-2.1/src/TForkedProcess.cpp0000644000175000017500000001613611513237311016352 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2009 by Benjamin Lerman * * mudlet@ambre.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "TForkedProcess.h" #include TForkedProcess::~TForkedProcess() { if (callBackFunctionRef != -1 ) { luaL_unref(interpreter->pGlobalLua, LUA_REGISTRYINDEX, callBackFunctionRef); } } TForkedProcess::TForkedProcess( TLuaInterpreter * interpreter, lua_State * L ) :QProcess() { this->interpreter = interpreter; int n = lua_gettop(L); callBackFunctionRef = -1; if(n < 2) { lua_pushstring(L, "Need read function and process name as parameters."); lua_error(L); } if(!lua_isfunction(L, 1)) { lua_pushstring(L, "Need read function as first parameter."); lua_error(L); } lua_pushvalue( L, 1); callBackFunctionRef = luaL_ref(L, LUA_REGISTRYINDEX); QString prog = QString((char*)luaL_checkstring(L, 2)); QStringList args; for(int i = 3; i <= n; i++) { args << ((char*)luaL_checkstring(L, i)); } connect(this, SIGNAL(finished(int)), interpreter, SLOT(slotDeleteSender())); connect(this, SIGNAL(finished(int)), this, SLOT(slotFinish())); connect(this, SIGNAL(readyReadStandardOutput ()), this, SLOT(slotReceivedData())); setReadChannelMode(QProcess::MergedChannels); start(prog, args, QIODevice::ReadWrite); waitForStarted(); running = true; } void TForkedProcess::slotFinish() { running = false; } void TForkedProcess::slotReceivedData() { if(canReadLine ()) { QByteArray line = readLine(); // Call lua function by stored Reference lua_rawgeti(interpreter->pGlobalLua, LUA_REGISTRYINDEX, callBackFunctionRef); lua_pushstring(interpreter->pGlobalLua, line.data()); lua_pcall(interpreter->pGlobalLua, 1, 0, 0); } } int TForkedProcess::sendMessage( lua_State * L ) { QPointer * forkedProcess = *((QPointer **) lua_topointer(L, lua_upvalueindex(1))); if(forkedProcess == 0 || forkedProcess->isNull() || !(*forkedProcess)->running) { lua_pushstring(L, "Unable to send data to process. Process has ended."); lua_error(L); } size_t stringLength = 0; const char *toWrite = lua_tolstring (L, 1, &stringLength); if(toWrite == 0) { lua_pushstring(L, "Unable to get data to send."); lua_error(L); } size_t writedBytes = 0; while(stringLength > writedBytes) { int res = (*forkedProcess)->write(toWrite + writedBytes, stringLength - writedBytes); if(res == -1) { lua_pushstring(L, "Unable to send data to process."); lua_error(L); } writedBytes += res; } return 0; } int TForkedProcess::isProcessRunning ( lua_State * L ) { QPointer * forkedProcess = *((QPointer **) lua_topointer(L, lua_upvalueindex(1))); bool running = (forkedProcess != 0 && !forkedProcess->isNull() && (*forkedProcess)->running); lua_pushboolean(L, running); return 1; } int TForkedProcess::closeInputOfProcess ( lua_State * L ) { QPointer * forkedProcess = *((QPointer **) lua_topointer(L, lua_upvalueindex(1))); if(forkedProcess == 0 || forkedProcess->isNull() || !(*forkedProcess)->running) { // Process is already finished. Nothing to do. return 0; } (*forkedProcess)->closeWriteChannel (); return 0; } static int qPointerGC ( lua_State * L ) { QPointer * forkedProcessPointer = *((QPointer **) lua_topointer(L, 1)); delete forkedProcessPointer; lua_pushboolean(L, true); return 1; } int TForkedProcess::startProcess( TLuaInterpreter * interpreter, lua_State * L ) { TForkedProcess * process = new TForkedProcess(interpreter, L); // The userdata for the closures. QPointer ** luaMemory = (QPointer **)lua_newuserdata (L, sizeof(QPointer *)); int userDataIndex = lua_gettop(L); if(lua_getmetatable (L, userDataIndex) != 0) { lua_pushstring(L, "Error: new user data should not have any metatable."); lua_error(L); } else { if(luaL_newmetatable(L, "qPointerGCMetatable") == 1) { // First time one call this method. One must register the garbage collection method. int tableIndex = lua_gettop(L); lua_pushstring(L, "__gc"); lua_pushcfunction(L, qPointerGC); lua_settable(L, tableIndex); } lua_setmetatable(L, userDataIndex); } *luaMemory = new QPointer(process); // One must return a table with the following function: // send( a ) -> () : to send a to the process // close() -> () : to close the input of the process // isRunning() -> bool : to know if the process is still running. lua_newtable( L ); int tableIndex = lua_gettop(L); // The name of the send function lua_pushstring(L, "send"); // The metadatcontaining the process lua_pushvalue(L, userDataIndex); // The send function lua_pushcclosure(L, TForkedProcess::sendMessage, 1); // Set the table for the send function. lua_settable(L, tableIndex); // The name of the close function lua_pushstring(L, "close"); // The metadatcontaining the process lua_pushvalue(L, userDataIndex); // The close function lua_pushcclosure(L, TForkedProcess::closeInputOfProcess, 1); // Set the table for the close function. lua_settable(L, tableIndex); lua_pushstring(L, "isRunning"); // The metadatcontaining the function lua_pushvalue(L, userDataIndex); // The isRunning function lua_pushcclosure(L, TForkedProcess::isProcessRunning, 1); // Set the table for the isRunning function. lua_settable(L, tableIndex); return 1; } mudlet-2.1/src/echo.xml0000644000175000017500000000075012070466512014412 0ustar csmallcsmall `echo `echo (.+) mudlet-2.1/src/ui/0000755000175000017500000000000012076170616013370 5ustar csmallcsmallmudlet-2.1/src/ui/help_dialog.ui0000755000175000017500000000107011513237311016166 0ustar csmallcsmall helpDialog 0 0 800 600 Mudlet Documentation mudlet-2.1/src/ui/notes_editor.ui0000755000175000017500000000236311513237311016423 0ustar csmallcsmall NotesEditor 0 0 800 600 Note Pad 0 21 800 558 0 0 0 0 800 21 0 579 800 21 mudlet-2.1/src/ui/module_manager.ui0000644000175000017500000001544112070466513016711 0ustar csmallcsmall packageDialog 0 0 652 508 Dialog 0 0 0 0 true QAbstractItemView::SingleSelection true 0 4 false true false 0 0 7 QFrame::Box QFrame::Sunken <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:7pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Modules are a way to utilize a common package across many sessions - unlike packages, which are installed per-profile.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Modules are loaded in ascending priority (1 will get loaded first, 2 second). Modules with the same priority will be loaded in alphabetical order.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The 'save &amp; sync' option, if it is enabled, will save the module to disk, and then reload the module for all open sessions which also are using that module. To make several profiles use the same module, install it in each profile through the module manager. Zip and mpackage modules are currently unable to be synced, only .xml packages are able to be synchronized across profiles at the moment.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For each save operation, modules are backed up to a directory, </span><span style=" font-size:10pt; font-style:italic;">moduleBackups</span><span style=" font-size:10pt;">, within your Mudlet profile directory.</span></p></body></html> 0 0 Qt::RightToLeft 0 0 Uninstall 0 0 Install Module Help mudlet-2.1/src/ui/package_manager_unpack.ui0000644000175000017500000000164611624306130020352 0ustar csmallcsmall Dialog 0 0 312 52 Dialog 14 75 true unpacking please wait ... true Qt::AlignCenter mudlet-2.1/src/ui/system_message_area.ui0000755000175000017500000023440211561116467017761 0ustar csmallcsmall systemMessageArea 0 0 485 88 0 0 0 75 16777215 88 Form 0 0 0 70 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 254 215 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 254 215 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 16 PreferAntialias ArrowCursor false QFrame#notificationArea { border: 3px solid; border-radius: 6px; background-color: rgb(255, 254, 215); } 0 0 0 0 0 0 10 0 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 true :/icons/dialog-warning.png false Qt::AlignCenter true 5 Qt::NoTextInteraction 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 true :/icons/dialog-error.png false Qt::AlignCenter true 5 Qt::NoTextInteraction 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 true :/icons/dialog-information.png false Qt::AlignCenter true 5 Qt::NoTextInteraction 0 0 0 0 0 0 0 0 0 0 16777215 16777215 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 9 true Qt::RichText true Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 0 true 0 0 16 0 16 16777215 0 0 16 16 16 16 Sans Serif 9 Qt::NoFocus ... :/icons/application-exit.png:/icons/application-exit.png true Qt::Vertical 20 40 mudlet-2.1/src/ui/trigger_editor.ui0000755000175000017500000012237111561116467016753 0ustar csmallcsmall trigger_editor 0 0 636 688 0 0 Script editor 0 0 0 0 0 0 0 0 0 0 0 3 0 3 0 0 0 0 0 0 0 QFrame::NoFrame 0 5 Qt::Horizontal true 5 0 0 0 0 0 0 QFrame::NoFrame QFrame::Plain 1 0 0 QFrame::NoFrame 4 QAbstractItemView::InternalMove false 32 32 true true false false false 1 QFrame::NoFrame 4 QAbstractItemView::InternalMove false 32 32 true false true true false false false 1 QFrame::NoFrame 4 QAbstractItemView::InternalMove false 32 32 true true true false false false 1 QFrame::NoFrame 4 QAbstractItemView::InternalMove false 32 32 true true true false false false 1 QFrame::NoFrame 4 QAbstractItemView::InternalMove false 32 32 true true true false false false 1 QFrame::NoFrame 4 QAbstractItemView::InternalMove false 32 32 true false true true false false false 1 0 0 0 0 16777215 30 255 255 255 255 234 218 255 255 255 255 234 218 255 234 218 255 234 218 true 0 0 0 0 0 0 60 0 Search: 0 0 50 20 16777215 28 true QComboBox::InsertAtTop true false Qt::Horizontal QSizePolicy::Fixed 10 13 0 0 16 0 16 16777215 0 0 16 16 16 16 Sans Serif 9 Qt::NoFocus ... :/icons/application-exit.png:/icons/application-exit.png true Qt::Vertical 20 40 QFrame::NoFrame 4 false 16 16 Qt::ElideRight true true true true false 3 true 80 20 80 true 20 1 2 3 1 0 0 0 PreferAntialias QFrame::NoFrame QFrame::Plain 1 0 0 0 0 0 0 16777215 16777215 PreferAntialias QFrame::NoFrame 9 Qt::Vertical 5 true 0 0 0 0 0 0 false QFrame::NoFrame QFrame::Plain 0 0 0 0 false true 0 0 0 0 16777215 175 QFrame::NoFrame QFrame::Plain 4 0 0 0 0 0 0 16777215 16777215 PreferAntialias false 0 0 16777215 0 Alias Trigger Variable Alias Trigger Variable Group Group true Aliases true Triggers true Variables true Script options true Search results Expert mode TTreeWidget QTreeWidget
TTreeWidget.h
mudlet-2.1/src/ui/about_dialog.ui0000755000175000017500000013410212076170616016364 0ustar csmallcsmall about_dialog 0 0 781 380 0 0 0 380 800 380 255 254 215 188 170 145 255 254 215 188 170 145 188 170 145 188 170 145 About Mudlet true 9 9 0 0 :/Mudlet_splashscreen_main.png false 0 0 0 255 255 255 255 255 255 255 255 255 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 255 255 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 255 255 255 255 255 255 255 255 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 255 255 255 255 255 0 0 0 255 254 215 255 255 220 0 0 0 0 About Mudlet 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 true QFrame::NoFrame <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> <tr> <td style="border: none;"> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:600; text-decoration: underline; color:#005500;">Mudlet 2.1</span></p> <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:10pt; font-weight:600; text-decoration: underline; color:#005500;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:600; color:#000000;">homepage and forum at: </span><a href="http://mudlet.sourceforge.net"><span style=" font-family:'Sans Serif'; font-size:9pt; text-decoration: underline; color:#0000ff;">mudlet.sourceforge.net</span></a></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:600; color:#000000;">latest version can be found at:</span><span style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:600; color:#00007f;"> </span><a href="http://mudlet.sourceforge.net"><span style=" font-family:'Sans Serif'; font-size:9pt; text-decoration: underline; color:#0000ff;">mudlet.sourceforge.net</span></a><span style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:600; color:#00007f;">/</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">documentation and Help:</span><span style=" font-family:'Sans Serif'; font-size:9pt;"> </span><a href="http://mudlet.sourceforge.net/wordpress/?page_id=40"><span style=" font-family:'Sans Serif'; font-size:9pt; text-decoration: underline; color:#0000ff;">Manual, Help and FAQs</span></a></p> <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:600;">Author: </span><span style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:600; text-decoration: underline; color:#bc8942;">Heiko Köhn</span><span style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:600;"> ( </span><span style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:600; color:#0000ff;">KoehnHeiko@googlemail.com </span><span style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:600;">) </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:6pt;"> </span></p> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600;">Credits:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Vadim Peretokin</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; text-decoration: underline; color:#000000;"> </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">(</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#0000ff;">vadim.peretokin@mudlet.org</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">) </span><span style=" font-family:'Sans Serif'; font-size:9pt;">GUI design and initial feature planning. He is responsible for the project homepage and the user manual. Maintainer of the Ubuntu packages. Project management, public relations &amp; user help. He has been with the project from the very beginning and is an official spokesman of the project.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:6pt; color:#000000;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Stephen Hansen</span><span style=" font-family:'DejaVu Sans'; font-size:7pt; color:#000000;"> ( </span><span style=" font-family:'Bitstream Vera Sans'; font-size:8pt; text-decoration: underline; color:#5500ff;">me+</span><a href="mailto:mudlet@ixokai.io"><span style=" font-family:'Bitstream Vera Sans'; font-size:8pt; text-decoration: underline; color:#5500ff;">mudlet@ixokai.io</span></a><span style=" font-family:'Sans Serif'; font-size:9pt; color:#0000ff;"> </span><span style=" font-family:'Sans Serif'; font-size:9pt;">) has developed the current improved MAC OSX installer. He is the current maintainer of the MAC version of Mudlet and he has contributed the database Lua api.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Chris Mitchell</span><span style=" font-family:'DejaVu Sans'; font-size:7pt; color:#000000;"> ( </span><span style=" font-family:'DejaVu Sans'; font-size:7pt; text-decoration: underline; color:#0000ff;">chrismudlet@gmail.com</span><span style=" font-family:'Sans Serif'; font-size:9pt; color:#0000ff;"> </span><span style=" font-family:'Sans Serif'; font-size:9pt;">) has developed a shared module system that allows script packages to be shared among profiles and he has contributed some patches for the mapper.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Bruno Bigras</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; color:#000000;"> </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">( </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#0000ff;">bruno@burnbox.net</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"> ) </span><span style=" font-family:'Sans Serif'; font-size:9pt;">has developed our cross platform cmake build script and he has committed a number of patches.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Damian Monogue</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"> (</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#0000ff;">demonnic@gmail.com)</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"> Former maintainer of the early Windows and Apple OSX packages. He also administers our server and helps the project in many ways. </span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Thorsten Wilms</span><span style=" font-family:'DejaVu Sans'; font-size:8pt;"> (</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#0000ff;">t_w_@freenet.de). </span><span style=" font-family:'Sans Serif'; font-size:9pt;">has designed our beautiful logo, our splash screen, the about dialog, our website, several icons and badges. Visit his homepage at </span><a href="http://thorwil.wordpress.com"><span style=" font-family:'Sans Serif'; font-size:9pt; text-decoration: underline; color:#0000ff;">thorwil.wordpress.com</span></a><span style=" font-family:'Sans Serif'; font-size:9pt;">.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt; color:#0000ff;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Leigh Stillard</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#bc8942;"> </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">( </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#0000ff;">leigh.stillard@gmail.com</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"> ) is the author of our windows installer. </span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Ben Carlsen</span><span style=" font-family:'DejaVu Sans'; font-size:7pt; color:#000000;"> ( </span><a href="mailto:arkholt@gmail.com"><span style=" font-family:'Sans Serif'; font-size:8pt; text-decoration: underline; color:#0000ff;">arkholt@gmail.com</span></a><span style=" font-family:'Sans Serif'; font-size:9pt; color:#0000ff;"> </span><span style=" font-family:'Sans Serif'; font-size:9pt;">) has developed the first version of our MAC OSX installer. He is the former maintainer of the MAC version of Mudlet. </span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">John Dahlström</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; color:#000000;"> </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">( </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#0000ff;">email@johndahlstrom.se </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">) helped develop and debug the Lua API. </span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Carter Dewey</span><span style=" font-family:'Sans Serif'; font-size:9pt;"> (</span><span style=" font-family:'Sans Serif'; font-size:9pt; color:#0000ff;">eldarerathis@gmail.com</span><span style=" font-family:'Sans Serif'; font-size:9pt;">) has submitted 3 small patches so far. Hopefully, we'll see more in the future.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600; text-decoration: underline; color:#bc8942;">Blaine von Roeder</span><span style=" font-family:'Sans Serif'; font-size:9pt;"> () joined in December 2009. So far he has contributed to the Lua API, submitted small bugfix patches and has helped with release management of 1.0.5.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600; text-decoration: underline; color:#bc8942;">Ben Smith</span><span style=" font-family:'Sans Serif'; font-size:9pt;"> () joined in December 2009 though he's been around much longer. Promising contributions to the Lua API. He is the current Maintainer of the Lua API.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600; color:#bc8942;">James Younquist</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"> (daemacles@yahoo.com) contributed the Geyser layout manager for Mudlet in March 2010. It is written in Lua and aims at simplifying user GUI scripting. </span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Bitstream Vera Sans'; font-size:9pt; color:#000000;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600; color:#bc8942;">Karsten Bock</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"> contributed several improvements and new features for Geyser. He is the current maintainer of Geyser.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Maksym V. Grinenko</span><span style=" font-family:'DejaVu Sans'; font-size:7pt; color:#000000;"> (</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#0055ff;">maksym.grinenko@gmail.com</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">) work on the manual, forum help and helps with GUI design and documentation.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">Most icons are taken from the </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">KDE4 oxygen icon theme</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"> at </span><a href="www.oxygen-icons.org or www.kde.org"><span style=" font-family:'Sans Serif'; font-size:9pt; text-decoration: underline; color:#0000ff;">www.oxygen-icons.org or www.kde.org</span></a><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#00aa00;">.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">The rest is from Thorsten Wilms.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">Special thanks to </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; color:#0000ff;">Brett Duzevich</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"> and </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; color:#0000ff;">Ronny Ho</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">. They have contributed many good ideas and thus helped improve the scripting framework substantially.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">Thanks to </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Tomas Mecir</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"> (</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#0000ff;">kmuddy@kmuddy.com</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">) who brought us all together and inspired us with his KMuddy project. Mudlet is using some of the telnet code he wrote for his KMuddy project (</span><a href="www.kmuddy.com"><span style=" font-family:'Sans Serif'; font-size:9pt; text-decoration: underline; color:#0000ff;">www.kmuddy.com</span></a><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">).</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">Special thanks to </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#bc8942;">Nick Gammon</span><span style=" font-family:'DejaVu Sans'; font-size:8pt; font-weight:600; text-decoration: underline; color:#000000;"> </span><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;"> (</span><a href="http://www.gammon.com.au/mushclient/mushclient.htm"><span style=" font-family:'Sans Serif'; font-size:9pt; text-decoration: underline; color:#0000ff;">http://www.gammon.com.au/mushclient/mushclient.htm</span></a><span style=" font-family:'DejaVu Sans'; font-size:8pt; color:#000000;">) for giving us some valued pieces of advice.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:6pt; color:#000000;"> </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:6pt; color:#000000;"> </span></p> <p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p></td></tr></table></body></html> true License 0 0 QFrame::NoFrame <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> <tr> <td style="border: none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:12pt;">Mudlet has been written by Heiko Köhn, KoehnHeiko@googlemail.com.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:12pt; color:#000000;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:12pt; color:#000000;">Mudlet is published under the GPL License version 3 </span></p> <p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:9pt; color:#000000;"></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:600; color:#000000;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Version 3, 29 June 2007 </span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Copyright © 2007 Free Software Foundation, Inc. http://fsf.org/</span></p></td></tr></table></body></html> mudlet-2.1/src/ui/options_area_scripts.ui0000755000175000017500000000151611513237311020156 0ustar csmallcsmall options_area_scripts 0 0 200 29 0 0 0 0 16777215 16777215 Form mudlet-2.1/src/ui/actions_main_area.ui0000755000175000017500000004156012070466513017372 0ustar csmallcsmall actions_main_area 0 0 900 351 0 0 0 0 Form 3 0 0 0 9 6 0 0 0 Button name: Command on button down: 0 0 6 0 6 0 0 0 Button stylesheet: true 0 0 Bitstream Vera Sans Mono 8 false false false 0 0 9 21 80 27 0 0 Choose Icon false 9 66 80 27 0 0 Color false 0 0 0 0 16777215 131 9 0 0 0 0 0 16777215 16777215 Button Bar 0 0 Orientation Horizontal Orientation Vertical 0 0 Number of columns or rows: 0 0 8 0 0 Dock Area Top Dock Area Left Dock Area Right Floating Toolbar 0 0 0 0 Button Appearance Button Rotation: 0 0 no rotation 90° rotation to the left 90° rotation to the right 0 0 Push down button true false 0 0 0 0 Command on button up: true true 0 0 0 0 0 0 16777215 16777215 false Use custom layout true false 0 0 5 Size X: 8 Size Y: 8 Position X: 8 Position Y: 8 lineEdit_action_icon optionsArea widget widget_2 mudlet-2.1/src/ui/mapper_room_color.ui0000644000175000017500000000463011520630027017436 0ustar csmallcsmall Dialog 0 0 468 300 Dialog 30 240 341 32 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok 40 20 256 192 300 30 120 80 10 10 105 24 New Color 10 40 105 24 New Image buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 mudlet-2.1/src/ui/options_area_filters.ui0000755000175000017500000001132211513237311020133 0ustar csmallcsmall Form 0 0 534 433 Form 0 50 0 Options Filter enabled Show whitespace QFrame::StyledPanel QFrame::Raised Filter name: Qt::Vertical 20 254 Test area 0 0 0 0 true QComboBox::InsertAtTop 0 0 Result: listWidget 0 0 0 50 0 0 Sample text: comboBox mudlet-2.1/src/ui/composer.ui0000755000175000017500000001105711647202526015564 0ustar csmallcsmall composer 0 0 567 412 News & Message Composer 5 5 255 241 199 255 241 199 255 255 255 true Qt::AlignCenter true 0 0 0 30 Qt::Horizontal 375 20 0 0 Cancel 0 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Save (<span style=" color:#565656;">Shift+Tab</span>)</p></body></html> Save edit saveButton cancelButton titel mudlet-2.1/src/ui/filters_main_area.ui0000755000175000017500000021472111513237311017374 0ustar csmallcsmall trigger_main_area 0 0 433 562 0 0 Form 0 0 0 70 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 Arial Black 16 PreferAntialias ArrowCursor true QFrame::Box QFrame::Plain 3 3 0 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 true :/dialog-warning.png false Qt::AlignCenter true 5 Qt::NoTextInteraction 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 true :/dialog-error.png false Qt::AlignCenter true 5 Qt::NoTextInteraction 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 true :/dialog-information.png false Qt::AlignCenter true 5 Qt::NoTextInteraction 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 Arial 14 true Note: A trigger needs to have a name to work properly. true Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 5 0 0 0 0 50 0 Pattern: 0 0 0 50 16777215 50 Andale Mono 16 true true 0 0 0 0 Script: script_scintilla 0 0 0 0 QsciScintilla QFrame
Qsci/qsciscintilla.h
script_scintilla
mudlet-2.1/src/ui/options_area_aliases.ui0000755000175000017500000000056111513237311020107 0ustar csmallcsmall options_area_aliases 0 0 230 48 Form mudlet-2.1/src/ui/options_area_timers.ui0000755000175000017500000000141511513237311017770 0ustar csmallcsmall options_area_timers 0 0 453 16 0 0 0 0 16777215 16 Form mudlet-2.1/src/ui/timers_main_area.ui0000755000175000017500000004451712076170616017244 0ustar csmallcsmall timers_main_area 0 0 656 115 0 0 0 115 16777215 115 Form 9 0 0 0 0 Timer name: 0 0 0 61 16777215 61 0 0 0 0 0 0 80 16777215 9 50 false Time: 0 0 60 40 60 16777215 255 234 218 255 234 218 244 244 244 30 <html><head/><body><p>The <span style=" font-weight:600;">hour</span> interval that the timer will go off at</p></body></html> true false Qt::AlignCenter QAbstractSpinBox::NoButtons false 0 0 0 2000 1 1 QDateTimeEdit::HourSection h 0 0 0 0 80 16777215 40 75 true PreferAntialias : 0 0 60 40 60 16777215 255 254 215 255 254 215 244 244 244 30 <html><head/><body><p>The <span style=" font-weight:600;">minute</span> interval that the timer will go off at</p></body></html> true false Qt::AlignCenter QAbstractSpinBox::NoButtons true QDateTimeEdit::MinuteSection m 0 0 0 0 80 16777215 40 75 true PreferAntialias : 0 0 60 40 60 16777215 232 255 231 232 255 231 244 244 244 30 <html><head/><body><p>The <span style=" font-weight:600;">second</span> interval that the timer will go off at</p></body></html> true false Qt::AlignCenter QAbstractSpinBox::NoButtons true QDateTimeEdit::SecondSection s 0 0 0 0 80 16777215 40 75 true PreferAntialias . 0 0 110 40 110 16777215 255 230 232 255 230 232 244 244 244 30 <html><head/><body><p>The <span style=" font-weight:600;">milisecond</span> interval that the timer will go off at (1000 miliseconds = 1 second)</p></body></html> true false Qt::AlignCenter QAbstractSpinBox::NoButtons true QDateTimeEdit::MSecSection z <html><head/><body><p>(hours <span style=" font-weight:600;">:</span> minutes <span style=" font-weight:600;">:</span> seconds <span style=" font-weight:600;">:</span> miliseconds)</p></body></html> Qt::Horizontal 40 20 0 0 0 0 16777215 16777215 9 Command: mudlet-2.1/src/ui/custom_lines.ui0000644000175000017500000001363411624306130016430 0ustar csmallcsmall roomExits 0 0 605 442 Dialog 20 20 371 16 14 Chose start exit and line format 10 59 114 32 NW 130 59 114 32 N 250 59 114 32 NE 10 109 114 32 W 250 109 114 32 E 10 159 114 32 SW 130 159 114 32 S 250 159 114 32 SE 20 261 571 131 2 1 2 290 220 81 32 90 220 111 26 20 220 62 21 Line style: 220 220 71 21 Line color: 480 400 114 32 Cancel 390 160 71 32 IN 470 160 71 32 OUT 390 110 71 32 UP 470 110 71 32 DOWN 400 220 181 20 line ends with an arrow mudlet-2.1/src/ui/connection_profiles.ui0000755000175000017500000027736711624306130020010 0ustar csmallcsmall profile_dialog 0 0 875 561 760 0 Select a profile to connect with 0 0 0 0 0 0 0 0 0 0 0 0 9 0 9 0 0 365 0 QListView::Adjust 0 0 0 50 16777215 16777215 Qt::Horizontal 15 20 true 0 0 0 25 16777215 16777215 Remove :/icons/dialog-close.png:/icons/dialog-close.png 0 0 0 25 16777215 16777215 Copy :/icons/list-add_small.png:/icons/list-add_small.png 0 0 0 25 16777215 16777215 New :/icons/list-add_small.png:/icons/list-add_small.png 0 0 0 70 16777215 16777215 255 255 255 255 254 215 255 255 255 255 254 215 255 254 215 255 254 215 Arial Black 16 PreferAntialias ArrowCursor true QFrame::Box QFrame::Plain 3 3 0 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 true :/icons/dialog-warning.png false Qt::AlignCenter true 5 Qt::NoTextInteraction 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 true :/icons/dialog-error.png false Qt::AlignCenter true 5 Qt::NoTextInteraction 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 true :/icons/dialog-information.png false Qt::AlignCenter true 5 Qt::NoTextInteraction 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 0 0 0 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 0 0 0 255 255 255 0 0 0 255 255 255 255 254 215 0 0 0 255 254 235 255 255 220 0 0 0 127 127 107 255 254 215 255 255 255 255 254 235 127 127 107 170 169 143 127 127 107 255 255 255 127 127 107 255 254 215 255 254 215 0 0 0 255 254 215 255 255 220 0 0 0 Arial 8 true true Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true 5 true 0 0 340 0 300 16777215 12 0 12 0 0 true 0 0 0 140 16777215 16777215 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> <tr> <td style="border: none;"> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans'; font-size:10pt; font-weight:600;">Welcome to Mudlet!</span></p> <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt; font-weight:600;"></p> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans'; font-size:9pt; font-weight:600;">Click on one of the MUDs on the list below to play.</span></p> <p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:9pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans'; font-size:9pt;">If you want to play on a server that is not on the list, click on the </span><img src=":/icons/icons/list-add_small.png" /><span style=" font-family:'Sans'; font-size:9pt; color:#aa0000;"> Create New Profile</span><span style=" font-family:'Sans'; font-size:9pt;"> button on your left, create your own profile, and fill in the </span><span style=" font-family:'Sans'; font-size:9pt; font-style:italic;">Profile Name</span><span style=" font-family:'Sans'; font-size:9pt;">, </span><span style=" font-family:'Sans'; font-size:9pt; font-style:italic;">Host</span><span style=" font-family:'Sans'; font-size:9pt;">, and </span><span style=" font-family:'Sans'; font-size:9pt; font-style:italic;">Port</span><span style=" font-family:'Sans'; font-size:9pt;"> fields in the R</span><span style=" font-family:'Sans'; font-size:9pt; font-style:italic;">equired </span><span style=" font-family:'Sans'; font-size:9pt;">area. </span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:9pt;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans'; font-size:9pt; font-weight:600;">After that, click Connect to play.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:9pt; font-weight:600;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans'; font-size:9pt;">Have fun!</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:9pt; font-weight:600;"></p> <p align="right" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans'; font-size:9pt; font-weight:600;">- The Mudlet Team</span></p></td></tr></table></body></html> false 0 0 Required 9 DejaVu Sans 9 50 false Profile name: Bitstream Charter 9 false DejaVu Sans 9 false Server address: 100 0 Bitstream Charter 9 Bitstream Charter 9 Port: 40 0 50 16777215 Bitstream Charter 9 32767 QLineEdit::Normal 0 DejaVu Sans 9 Profile history: 0 0 0 0 8 load newest profile load oldest profile 0 0 0 0 Optional DejaVu Sans 9 Character name: The characters name QLineEdit::Normal DejaVu Sans 9 Password: Characters password. Note that the password isn't encrypted in storage QLineEdit::Password DejaVu Sans 10 50 false With this enabled, Mudlet will automatically start and connect on this profile when it is launched Qt::LeftToRight Auto connect this profile on startup 0 0 0 0 Informational 0 0 0 0 DejaVu Sans 9 Website: 0 25 0 0 0 0 DejaVu Sans 9 true true 0 0 16777215 16777215 MUD description false Qt::Horizontal 40 20 0 0 50 0 340 16777215 Qt::Horizontal QDialogButtonBox::Cancel false dialog_buttonbox remove_profile_button mudlet-2.1/src/ui/irc.ui0000644000175000017500000002501211652101526014475 0ustar csmallcsmall irc_dlg 0 0 621 443 0 0 PreferDefault Script editor true 0 0 0 0 0 0 0 0 0 0 0 3 0 3 0 0 0 0 0 0 0 QFrame::NoFrame 0 5 Qt::Horizontal true 5 3 0 0 0 0 0 QFrame::NoFrame QFrame::Plain 1 0 0 0 0 5 0 1 0 16777215 16777215 0 0 PreferAntialias QFrame::NoFrame QFrame::Plain 1 0 0 16777215 16777215 Alias Trigger Variable Alias Trigger Variable Group Group true Aliases true Triggers true Variables true Script options true Search results Expert mode mudlet-2.1/src/ui/aliases_main_area.ui0000755000175000017500000001073511513237311017344 0ustar csmallcsmall aliases_main_area 0 0 510 100 0 0 0 100 16777215 100 Form Alias name: 0 21 16777215 21 chose a unique name for your alias; it will show in the tree and is needed for scripting. 0 0 67 0 Pattern: 0 21 16777215 21 9 enter a perl regex pattern for your alias; alias are triggers on your input Type: false Regex Plain 0 0 50 0 Substitution: 0 21 16777215 21 9 optional, simple text substitution that is sent to the MUD if the alias pattern matches your input lineEdit_alias_name pattern_textedit substitution mudlet-2.1/src/ui/main_window.ui0000755000175000017500000001762712076170616016262 0ustar csmallcsmall MainWindow Qt::NonModal 0 0 750 502 780 590 Mudlet 1.0 - alpha 1 :/mudlet_main_16px.png:/mudlet_main_16px.png 0 0 QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks|QMainWindow::VerticalTabs 0 0 0 0 0 0 0 0 6 PreferAntialias 0 Qt::ScrollBarAsNeeded Qt::ScrollBarAsNeeded QMdiArea::TabbedView QTabWidget::Rounded QTabWidget::North 0 0 750 24 Toolbox Options Help About Games Play Alt+C Disconnect Alt+D Reconnect Alt+R Preferences Alt+P Script editor Open script editor Alt+E Notepad Alt+N API Reference Online forum About Mudlet IRC help channel Video tutorials Load replay Online forum Download latest version Help chat Get live help on IRC. If nobody answers right away, give it time Live help chat Show map Alt+M Package manager Alt+O test1 asdf Module manager Package exporter (experimental) MultiView Alt+V mudlet-2.1/src/ui/color_trigger.ui0000755000175000017500000002163211513237311016566 0ustar csmallcsmall color_trigger_dlg Qt::ApplicationModal 0 0 364 270 Dialog true 270 240 81 20 cancel 10 0 341 231 chose color to trigger on Black: Red: Green: Blue: Magenta: Cyan: White: true true true true true true true true Yellow: Light black: Light red: Light green: Light yellow: Light blue: Light magenta: Light cyan: true true true true true true true Light white: true mudlet-2.1/src/ui/mapper.ui0000755000175000017500000010377712076170616015235 0ustar csmallcsmall mapper 0 0 403 387 0 0 0 0 0 0 255 255 255 230 230 230 255 255 255 230 230 230 230 230 230 230 230 230 true 0 0 0 0 0 0 0 0 16777215 15 ^ true true 0 0 16777215 200 true 0 0 0 0 0 0 16777215 16777215 1 0 0 0 200 22 1 0 0 0 20 20 30 20 0 0 50 false true 100 1 0 0 20 20 30 20 0 0 true 100 1 0 0 20 20 30 20 0 0 true 100 1 0 0 25 20 30 20 0 0 true 100 1 25 20 25 20 30 20 0 0 75 true + 0 0 30 20 30 20 0 0 75 true - 0 0 56 20 2D/3D 0 0 16777215 20 Area: 0 0 16777215 20 QComboBox::InsertAlphabetically 0 0 0 1 2 0 0 0 Qt::Horizontal 40 20 Rooms 0 0 Qt::AlignCenter 1 11 5 Exits 0 0 Qt::AlignCenter 2 20 7 Round 0 0 50 0 Info 0 0 Qt::LeftToRight Room IDs Qt::Horizontal 40 20 0 0 0 0 0 0 0 0 0 0 2 0 0 16777215 25 -360 360 1 10 Qt::Horizontal 16777215 25 -360 360 1 5 Qt::Horizontal 16777215 25 -100 100 1 1 Qt::Horizontal 0 0 top + 1 0 0 bottom + 1 0 0 bottom -1 0 0 top - 1 0 0 1 level 0 0 16777215 16777215 default 0 0 top view 0 0 side view 0 0 all levels 16777215 25 0 1000 1 1 Qt::Horizontal GLWidget QWidget
glwidget.h
1
T2DMap QWidget
T2DMap.h
1
mudlet-2.1/src/ui/room_exits.ui0000644000175000017500000003752112020507607016120 0ustar csmallcsmall roomExits 0 0 747 486 Dialog General exits Qt::NoFocus lock true Set the number of the room that's to the northwest here NW exit... Qt::NoFocus lock true Set the number of the room that's to the north here N exit... Qt::NoFocus lock true Set the number of the room that's to the northeast here NE exit... Qt::NoFocus lock true Set the number of the room that's to the up here Up exit... Qt::NoFocus lock true Set the number of the room that's to the west here W exit... Qt::NoFocus lock true Set the number of the room that's to the east here E exit... Qt::Horizontal 40 20 Qt::NoFocus lock true Set the number of the room that's to the down here Down exit... Qt::NoFocus lock true Set the number of the room that's to the southwest here SW exit... Qt::NoFocus lock true Set the number of the room that's to the south here S exit... Qt::NoFocus lock true Set the number of the room that's to the southeast here SE exit... Qt::NoFocus lock true Set the number of the room that's to the in here In exit... Qt::NoFocus lock true Set the number of the room that's to the out here Out exit... Special exits false false 3 true Locked? Exit room ID Command or script (Lua scripts need to be prefixed with "script:") add special exit OK Cancel Qt::Horizontal 40 20 ExitsTreeWidget QTreeWidget
exitstreewidget.h
addSpecialExit saveButton pushButton_14 lnw clicked(bool) nw setDisabled(bool) 36 48 135 45 ln clicked(bool) n setDisabled(bool) 216 52 328 48 lne clicked(bool) ne setDisabled(bool) 395 47 494 47 lup clicked(bool) up setDisabled(bool) 571 46 678 47 lw clicked(bool) w setDisabled(bool) 43 73 138 76 le clicked(bool) e setDisabled(bool) 387 74 490 78 ldown clicked(bool) down setDisabled(bool) 570 71 663 71 lsw clicked(bool) sw setDisabled(bool) 39 114 145 114 ls clicked(bool) s setDisabled(bool) 211 108 306 111 lse clicked(bool) se setDisabled(bool) 399 108 494 108 lin clicked(bool) in setDisabled(bool) 575 100 666 100 lout clicked(bool) out setDisabled(bool) 571 133 679 133 pushButton_14 clicked() roomExits reject() 679 456 298 485
mudlet-2.1/src/ui/trigger_pattern_edit.ui0000755000175000017500000000650611624306130020134 0ustar csmallcsmall trigger_pattern_edit 0 0 635 34 0 0 16777206 34 Form 0 0 40 20 20 20 16777215 33 Qt::PlainText true Qt::AlignCenter 0 0 16777215 33 7 Foreground Color 0 0 16777215 33 7 Background Color 16777215 33 16777215 33 mudlet-2.1/src/ui/source_editor_area.ui0000755000175000017500000000152711513237311017564 0ustar csmallcsmall source_editor_area 0 0 795 573 0 0 Form 0 0 mudlet-2.1/src/ui/dlgPackageExporter.ui0000644000175000017500000001025412070466513017502 0ustar csmallcsmall dlgPackageExporter 0 0 655 411 Package Exporter Check items to export Triggers Aliases Timers Scripts Keys Buttons Do you want to add additional files to the package e. g. images, sounds etc. ? The add files button will bring up the file explorer. Copy all files and folders that you want to add to the package in the temporary package directory that is shown in the file explorer. When you are done click on the export button below to start package creation. true textLabel1_2 Add Files Export location: browseButton Select 8 Qt::AlignCenter true QDialogButtonBox::NoButton buttonBox accepted() dlgPackageExporter accept() 248 254 157 274 buttonBox rejected() dlgPackageExporter reject() 316 260 286 274 mudlet-2.1/src/ui/keybindings_main_area.ui0000755000175000017500000000615711513237311020234 0ustar csmallcsmall keys_main_area 0 0 402 80 0 0 0 80 16777215 80 Form 0 4 0 Name: Command: Key Binding: 225 232 255 225 232 255 244 244 244 true Grab New Key mudlet-2.1/src/ui/package_manager.ui0000644000175000017500000000613111624306130017003 0ustar csmallcsmall packageDialog 0 0 652 490 Dialog 0 0 0 0 0 0 Install 0 0 Uninstall Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() packageDialog accept() 248 254 157 274 buttonBox rejected() packageDialog reject() 316 260 286 274 mudlet-2.1/src/ui/options_area_actions.ui0000755000175000017500000000142511513237311020126 0ustar csmallcsmall options_area_actions 0 0 200 29 0 0 0 0 16777215 16777215 Form mudlet-2.1/src/ui/profile_preferences_old.ui0000755000175000017500000005525111513237311020610 0ustar csmallcsmall profile_preferences 0 0 571 550 Dialog true QTabWidget::Rounded 0 Input line false Input false Echo the text you send in the display box Show the text you sent Command separator command_separator_lineedit false Auto clear the input line after you sent text false Spell checker false Enable spellchecking false Character Set Encoding of the MUD Encoding: false UTF-8 ISO 8859-1 ISO 8859-2 ISO 8859-15 KOI8-R ROMAN8 Windows-1250 Neues Element false Input Completion false Disable input completion Qt::Vertical 20 40 Color view Select your color preferences Foreground color: true Background color: true These preferences set how do you want a particular color to be represented visually in the display box true Black: Red: Green: Blue: Magenta: Cyan: White: true true true true true true true true Yellow: Light black: Light red: Light green: Light yellow: Light blue: Light magenta: Light cyan: Light white: true true true true true true true true Reset all colors to default Qt::Vertical QSizePolicy::Minimum 20 20 Fonts && Colors Input line Chose Command Line Font Input line Chose Display Font Qt::Vertical 20 302 Qt::Horizontal QDialogButtonBox::Close show_sent_text_checkbox command_separator_lineedit enable_spellchecking_checkbox input_completion_checkbox encoding_combobox tabWidgeta buttonBox pushButton_black pushButton_red pushButton_green pushButton_yellow pushButton_blue pushButton_magenta pushButton_cyan pushButton_white pushButton_Lblack pushButton_Lred pushButton_Lgreen pushButton_Lyellow pushButton_Lblue pushButton_Lmagenta pushButton_Lcyan pushButton_Lwhite buttonBox accepted() profile_preferences accept() 257 413 157 274 buttonBox rejected() profile_preferences reject() 325 413 286 274 mudlet-2.1/src/ui/lacking_mapper_script.ui0000644000175000017500000001134011561116467020270 0ustar csmallcsmall no_mapping_script true 0 0 486 187 0 0 No mapping script found QLayout::SetMinimumSize 0 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">It seems that you don't have any <a href="http://wiki.mudlet.org/w/Mapping_script"><span style=" text-decoration: underline; color:#0000ff;">mapping scripts</span></a> installed yet - the mapper needs you to have one for your MUD, so it can track where you are and autowalk you. You can either make one yourself, or import and existing one that someone else made.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Would you like to see if any are available?</p></body></html> false true true Qt::Vertical QSizePolicy::Expanding 20 6 0 Qt::Horizontal QSizePolicy::Expanding 0 0 Close Find some scripts true close clicked() no_mapping_script reject() 296 148 238 85 find_scripts clicked() no_mapping_script accept() 405 148 238 85 mudlet-2.1/src/ui/delete_profile_confirmation.ui0000644000175000017500000000566611624306130021464 0ustar csmallcsmall delete_profile_dialog 0 0 389 180 Confirm permanent profile deletion 0 0 Are you sure that you'd like to delete this profile? Everything (aliases, triggers, backups, etc) will be gone. If you are, please type in the profile name as a confirmation: true Qt::Vertical 20 20 Delete Cancel true Qt::Horizontal 40 20 cancel_button clicked() delete_profile_dialog reject() 246 157 194 89 delete_button clicked() delete_profile_dialog accept() 337 157 194 89 mudlet-2.1/src/ui/triggers_main_area.ui0000755000175000017500000014220411624306130017545 0ustar csmallcsmall trigger_main_area 0 0 592 230 1 0 0 230 16777215 240 Form 0 0 0 0 255 255 255 225 255 254 255 255 255 225 255 254 225 255 254 225 255 254 true 6 6 2 6 2 51 0 51 16777215 name: lineEdit_trigger_name 16777215 16777215 Chose a good name for your trigger. This name will be displayed in the trigger tree. send plain text: trigger_command 0 0 Type in what command you want the trigger to send to the MUD if it fires. (optional) 0 0 0 120 1 0 0 0 true 0 0 true 0 0 483 139 0 0 255 255 255 203 239 207 255 255 255 203 239 207 203 239 207 203 239 207 true 0 1 0 0 0 0 16777215 16777215 255 255 255 255 224 192 255 255 255 255 224 192 255 224 192 255 224 192 Keep firing the script for x more lines, after the trigger or chain has matched. true fire length false false 5 5 5 0 5 0 0 Within how many lines must all condition be true to fire the trigger? 1000 0 0 more lines true true 0 0 0 0 0 16777215 16777215 play a wave sound file if the trigger fires play sound true false 0 5 5 9 5 0 0 0 11 chose file: 1 0 6 0 0 0 16 16777215 16 Qt::Vertical 20 40 0 0 0 65 16777215 65 255 255 255 239 239 239 255 255 255 239 239 239 239 239 239 239 239 239 true 0 0 0 0 1 255 255 255 255 254 215 255 255 255 255 254 215 255 254 215 255 254 215 true 1 1 0 0 0 0 16777215 16777215 255 255 255 255 254 215 255 255 255 255 254 215 255 254 215 255 254 215 The trigger will only fire if all conditions on the list have been met within the specified line margin. If this option is not set the trigger will fire if any conditon on the list has been met. Read more about the additional implications in the manual as this is a complex topic. true multiline / AND Trigger true false 0 5 9 3 9 0 0 0 25 line delta true true 0 0 0 0 15 16777215 16777215 Within how many lines must all condition be true to fire the trigger? 0 0 150 0 0 0 255 255 255 248 217 255 255 255 255 248 217 255 248 217 255 248 217 255 true 5 1 3 1 0 0 0 0 act as filter, i.e. only pass matches to its children to trigger on, instead of the original line from the MUD filter true false 5 5 1 1 0 0 0 0 16777215 16777215 Only the filtered content (=capture groups) will be passed on to child triggers, not the initial line (see manual on filters) only pass matches to children as trigger input true Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 0 255 255 255 255 206 217 255 255 255 255 206 217 255 206 217 255 206 217 true 0 5 1 5 1 0 0 Chose this option if you want to include all possible matches of the pattern in the line. Without this option, the pattern matching will stop after the first successful match. match all true false 5 5 1 1 0 0 0 0 16777215 16777215 match all occurences of the pattern in the line true Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true 0 0 0 255 255 255 220 223 255 255 255 255 220 223 255 220 223 255 220 223 255 true 5 1 5 1 0 0 0 0 16777215 16777215 highlight the capture groups if there are any otherwise highlight the entire match highlight true false 5 5 0 5 5 0 0 16777215 16777215 Lucida Grande 0 0 0 13 fg color 0 0 16777215 16777215 13 false 0 0 0 13 bg color mudlet-2.1/src/ui/options_area_triggers.ui0000755000175000017500000000222711513237311020315 0ustar csmallcsmall options_area_triggers 0 0 501 52 0 0 0 0 16777215 52 Form QFormLayout::AllNonFixedFieldsGrow 3 3 0 mudlet-2.1/src/ui/set_room_area.ui0000644000175000017500000000377311624306130016546 0ustar csmallcsmall set_room_area_dialog 0 0 377 105 Move rooms to another area Which area would you like to move the room(s) to? Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() set_room_area_dialog accept() 248 254 157 274 buttonBox rejected() set_room_area_dialog reject() 316 260 286 274 mudlet-2.1/src/ui/scripts_main_area.ui0000755000175000017500000001136111513237311017406 0ustar csmallcsmall scripts_main_area 0 0 643 92 0 0 0 80 16777215 92 Form 0 0 3 16777215 65 Script name: 0 0 200 0 Registered Event Handlers: true true 0 0 150 0 16777215 40 6 0 0 200 0 Add User Defined Event Handler: true true 15 15 15 15 add event handler to list + 15 15 15 15 11 remove event handler from list - mudlet-2.1/src/ui/extended_search_area.ui0000755000175000017500000001764611513237311020054 0ustar csmallcsmall extended_search_area 0 0 370 365 0 0 Form QTabWidget::Rounded 0 false Search Search for... Search Search results 1 Search options Search in... Script patterns Patterns Script names Names Script fields (where you write the code for your aliases/triggers and such) Scripts Status Active & inactive scripts Only active scripts Only non-active scripts Type All scripts Triggers only Aliases only Timers only Keybindings only Match type Match type: Contains Exact Regex Fires trigger pattern Fires alias pattern Rank by Rank results by: Most relevant First match mudlet-2.1/src/ui/profile_preferences.ui0000755000175000017500000020065512070466513017761 0ustar csmallcsmall profile_preferences 0 0 744 576 0 0 Profile preferences true 0 0 QTabWidget::Rounded 0 0 0 General 0 0 Icon sizes Icon size toolbars: 1 4 3 Icon size in tree views: 1 4 3 Enables the typical menu bar with drop-down menus in the main window. Requires restart to take effect Show menu bar Enables the default button bar in the main window. Requires restart to take effect Show main toolbar Misc Toolbar notification if Mudlet is minimized and new data arrives Force auto save on exit Switch log file format from HTML to raw stream dump in logfiles as sent by server. The logfile can then be can be loaded by Mudlet to test your trigger systems offline. Save log files in html format instead of text only Allow server to install scrpt packages GMCP Note: On IRE games, because Rapture is buggy, if you enable GMCP it will stop sending you ATCP Enable GMCP true 8 false Please reconnect to your game for GMCP to take effect Qt::AutoText true Qt::Vertical 20 40 IRC Nick name in mudlet IRC channel: ircNick label_58 0 0 Input line true Input 16777215 16777215 use strict UNIX line endings on commands for old UNIX servers that can't handle windows line endings correctly Strict UNIX line endings true Echo the text you send in the display box Show the text you sent true Auto clear the input line after you sent text Command separator: command_separator_lineedit true Command line minimum height in pixels: command_separator_lineedit 300 Spell check Chose spell check dictionary: Enable spell check true Qt::Vertical 20 26 0 0 Main display 0 0 Font Font: 0 0 false QFontComboBox::MonospacedFonts Size: Use anti aliasing on fonts. Smoothes fonts if you have a high screen resolution and you can use larger fonts. Note that on low resolutions and small font sizes, the font gets blurry. Enable anti-aliasing 0 0 Display Border 0 0 200 16777215 Top border height: 0 0 0 2000 0 0 0 200 16777215 Left border width: 0 0 0 2000 0 0 0 200 16777215 Bottom border height: 0 0 0 2000 0 0 0 200 16777215 Right border width: 0 0 0 2000 0 false Pick border color false Border background image 0 0 Qt::LeftToRight Word wrapping 0 0 200 16777215 Wrap lines at: 1 999999 90 characters 0 0 200 16777215 Indent wrapped lines by: 0 99999 0 characters Qt::Horizontal 40 20 Display workarounds Some MUDs (notably all IRE ones) suffer from a bug where they don't properly communicate with the client on where a newline should be. Enable this to fix text from getting appended to the previous prompt line Fix unnecessary linebreaks on GA servers Select this option for better compatability if you are using a netbook, or some other computer model that has a small screen. Use Mudlet on a netbook with a small screen Qt::Vertical 20 40 Color view Select your color preferences Command line background: Foreground: true Background: true Command line foreground: Command foreground: true Command background: true Black: Red: Green: Blue: Magenta: Cyan: White: true true true true true true true true Yellow: Light black: Light red: Light green: Light yellow: Light blue: Light magenta: Light cyan: Light white: true true true true true true true true Qt::Vertical 678 58 0 0 These preferences set how do you want a particular color to be represented visually in the main display true Reset all colors to default Mapper Map files Load another map file in: Pick map file Copy Copy map to another profile: Pick location Save your current map: 8 An action above happened Map download <html><head/><body><p>On MUDs that provide maps for download (currently IRE games only), you can press this button to get the latest map. Note that this will <span style=" font-weight:600;">overwrite</span> any changes you've done to your map, and will use the new map only</p></body></html> Download latest map provided by your MUD: <html><head/><body><p>On MUDs that provide maps for download (currently IRE games only), you can press this button to get the latest map. Note that this will <span style=" font-weight:600;">overwrite</span> any changes you've done to your map, and will use the new map only</p></body></html> Download false Map backups Delete map backups older than: true days since today, keeping newer and monthly backups Map view <html><head/><body><p>This enables anti-aliasing (AA) for tha map view, making it look smother and nicer</p></body></html> Use high quality graphics (disable on slow computers) Qt::Vertical 20 40 Mapper colors Select your color preferences for the map display Qt::Vertical 20 40 true Link color true Background color: Black: Red: Green: Blue: Magenta: Cyan: White: true true true true true true true true Yellow: Light black: Light red: Light green: Light yellow: Light blue: Light magenta: Light cyan: Light white: true true true true true true true true Reset all colors to default Special Options Qt::Vertical 20 40 Special options needed for some older MUD drivers (needs client restart to take effect) Force compression off Force telnet GA signal interpretation off This option adds a line line break <LF> or " " to your command input on empty commands. This option will rarely be necessary. Force new line on empty commands Force MXP negotiation off true 8 false Please reconnect to your game for the change to take effect Qt::AutoText true 0 0 Qt::Horizontal 447 17 0 0 Save :/icons/icons/dialog-close.png:/icons/icons/dialog-close.png show_sent_text_checkbox command_separator_lineedit mudlet-2.1/src/ui/console.ui0000755000175000017500000000305211513237311015363 0ustar csmallcsmall console 0 0 703 521 0 0 PreferAntialias Qt::StrongFocus 1 1 14 PreferAntialias Qt::NoFocus false true Qt::NoFocus mudlet-2.1/src/mudlet-lua/0000755000175000017500000000000011520630027015012 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/CONTRIBS0000644000175000017500000000022611520630027016160 0ustar csmallcsmallBlaine von Roeder (December 2009) John Dahlstrom (November 2008) Heiko Tichi (2009) Vadim Peretrokin (2009) Ryan Benjamin Smith (December 2009) Iocun mudlet-2.1/src/mudlet-lua/README0000644000175000017500000000162011520630027015671 0ustar csmallcsmall This project contains all Mudlet lua code (lua folder). This will allow us to easily maintain it and generate common documentation with LuaDoc. (We are using improved version of LuaDoc, because LuaDoc 3.0.1 is barely usable.) You can generate doc on linux box with following command (mudlet-lua-doc folder). You will need LuaDoc 3.0.1 (with custom improvements, which are in lua/luadoc folder) sh genDoc.sh Project structure: ------------------ mudlet-lua/ lua/ all Lua code luadoc/ LuaDoc extensions (this code is not loaded by Mudlet) LuaGlobal.lua loader for all Lua code used by Mudlet mudlet-lua-doc/ all generated documentation CONTRIBS genDoc.sh script for generation documentation luadoc-guide.txt guide with basic LuaDoc conventions README TODO mudlet-2.1/src/mudlet-lua/mudlet-lua-doc/0000755000175000017500000000000012070466512017635 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/mudlet-lua-doc/files/0000755000175000017500000000000012070466512020737 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/mudlet-lua-doc/files/geyser/0000755000175000017500000000000012070466512022235 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/mudlet-lua-doc/modules/0000755000175000017500000000000012070466512021305 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/mudlet-lua-doc/luadoc.css0000644000175000017500000001260511520630027021613 0ustar csmallcsmallbody { margin-left: 1em; margin-right: 1em; font-family: arial, helvetica, geneva, sans-serif; background-color:#ffffff; margin:0px; } code { font-family: "Andale Mono", monospace; } tt { font-family: "Andale Mono", monospace; } body, td, th { font-size: 11pt; } h1, h2, h3, h4 { margin-left: 0em; } textarea, pre, tt { font-size:10pt; } body, td, th { color:#000000; } small { font-size:0.85em; } h1 { font-size:1.5em; } h2 { font-size:1.25em; } h3 { font-size:1.15em; } h4 { font-size:1.06em; } pre { border:1px solid silver; background-color:#f4fff4; padding-top:0.5em; width: 80% } a:link { font-weight:bold; color: #004080; text-decoration: none; } a:visited { font-weight:bold; color: #006699; text-decoration: none; } a:link:hover { text-decoration:underline; } hr { color:#cccccc } img { border-width: 0px; } h3 { padding-top: 1em; } p { margin-left: 1em; } p.name { font-family: "Andale Mono", monospace; padding-top: 1em; margin-left: 0em; } blockquote { margin-left: 3em; } pre.example { background-color: rgb(245, 245, 245); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: silver; border-right-color: silver; border-bottom-color: silver; border-left-color: silver; padding: 1em; margin-left: 1em; margin-right: 1em; font-family: "Andale Mono", monospace; font-size: smaller; } hr { margin-left: 0em; background: #00007f; border: 0px; height: 1px; } ul { list-style-type: disc; } table.index { border: 1px #00007f; } table.index td { text-align: left; vertical-align: top; } table.index ul { padding-top: 0em; margin-top: 0em; } table { border: 1px solid black; border-collapse: collapse; margin-left: auto; margin-right: auto; } th { border: 1px solid black; padding: 0.5em; } td { border: 1px solid black; padding: 0.5em; } div.header, div.footer { margin-left: 0em; } #container { margin-left: 1em; margin-right: 1em; background-color: #f0f0f0; } #product { text-align: center; border-bottom: 1px solid #cccccc; background-color: #ffffff; } #product big { font-size: 2em; } #product_logo { } #product_name { } #product_description { } #main { background-color: #f0f0f0; border-left: 2px solid #cccccc; } #navigation { float: left; width: 18em; margin: 0; vertical-align: top; background-color: #f0f0f0; overflow:visible; position:fixed; left: 17px; top: 1px } #navigation h1 { background-color:#e7e7e7; font-size:1.1em; color:#000000; text-align:left; margin:0px; padding:0.2em; border-top:1px solid #dddddd; border-bottom:1px solid #dddddd; } #navigation ul { font-size:1em; list-style-type: none; padding: 0; margin: 1px; } #navigation li { text-indent: -1em; margin: 0em 0em 0em 0.5em; display: block; padding: 3px 0px 0px 12px; } #navigation li li a { padding: 0px 3px 0px -1em; } #content { margin-left: 18em; padding: 1em; border-left: 2px solid #cccccc; border-right: 2px solid #cccccc; background-color: #ffffff; } #about { clear: both; margin: 0; padding: 5px; border-top: 2px solid #cccccc; background-color: #ffffff; } @media print { body { font: 12pt "Times New Roman", "TimeNR", Times, serif; } a { font-weight:bold; color: #004080; text-decoration: underline; } #main { background-color: #ffffff; border-left: 0px; } #container { margin-left: 2%; margin-right: 2%; background-color: #ffffff; } #content { margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff; } #navigation { display: none; } pre.example { font-family: "Andale Mono", monospace; font-size: 10pt; page-break-inside: avoid; } } table.module_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.module_list td.name { background-color: #f0f0f0; } table.module_list td.summary { width: 100%; } table.file_list { border-width: 1px; border-style: solid; border-color: #cccccc; border-collapse: collapse; } table.file_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.file_list td.name { background-color: #f0f0f0; } table.file_list td.summary { width: 100%; } table.function_list { border-width: 1px; border-style: solid; border-color: #cccccc; border-collapse: collapse; } table.function_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.function_list td.name { background-color: #f0f0f0; } table.function_list td.summary { width: 100%; } table.table_list { border-width: 1px; border-style: solid; border-color: #cccccc; border-collapse: collapse; } table.table_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.table_list td.name { background-color: #f0f0f0; } table.table_list td.summary { width: 100%; } dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} dl.function dd {padding-bottom: 1em;} dl.function h3 {padding: 0; margin: 0; font-size: medium;} dl.table dt {border-top: 1px solid #ccc; padding-top: 1em;} dl.table dd {padding-bottom: 1em;} dl.table h3 {padding: 0; margin: 0; font-size: medium;} #TODO: make module_list, file_list, function_list, table_list inherit from a list mudlet-2.1/src/mudlet-lua/lua/0000755000175000017500000000000012076170616015605 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/lua/DB.lua0000644000175000017500000014143612070466512016603 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet DB ---------------------------------------------------------------------------------- -- TODO will be already loaded in LuaGlobal ----------------------------------------------------------------------------- -- General-purpose useful tools that were needed during development: ----------------------------------------------------------------------------- if package.loaded["rex_pcre"] then rex = require"rex_pcre" end -- TODO those funciton are already definde elsewhere -- Tests if a table is empty: this is useful in situations where you find -- yourself wanting to do 'if my_table == {}' and such. function table.is_empty(tbl) return next(tbl) == nil end function string.starts(String,Start) return string.sub(String,1,string.len(Start))==Start end function string.ends(String,End) return End=='' or string.sub(String,-string.len(End))==End end -- TODO move to StringUtils? ----------------------------------------------------------------------------- -- Some Date / Time parsing functions. ----------------------------------------------------------------------------- datetime = { _directives = { ["%b"] = "(?Pjan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)", ["%B"] = "(?Pjanuary|febuary|march|april|may|june|july|august|september|october|november|december)", ["%d"] = "(?P\\d{2})", ["%H"] = "(?P\\d{2})", ["%I"] = "(?P\\d{2})", ["%m"] = "(?P\\d{2})", ["%M"] = "(?P\\d{2})", ["%p"] = "(?Pam|pm)", ["%S"] = "(?P\\d{2})", ["%y"] = "(?P\\d{2})", ["%Y"] = "(?P\\d{4})" }, _pattern_cache = {}, _month_names = { ["january"] = 1, ["febuary"] = 2, ["march"] = 3, ["april"] = 4, ["may"] = 5, ["june"] = 6, ["july"] = 7, ["august"] = 8, ["september"] = 9, ["october"] = 10, ["november"] = 11, ["december"] = 12 }, _abbrev_month_names = { ["jan"] = 1, ["feb"] = 2, ["mar"] = 3, ["apr"] = 4, ["may"] = 5, ["jun"] = 6, ["jul"]= 7, ["aug"]= 8, ["sep"] = 9, ["oct"] = 10, ["nov"] = 11, ["dec"] = 12 } } -- NOT LUADOC -- The rex.match function does not return named patterns even if you use named capture -- groups, but the r:tfind does -- but this only operates on compiled patterns. So, -- we are caching the conversion of 'simple format' date patterns into a regex, and -- then compiling them. function datetime:_get_pattern(format) if not datetime._pattern_cache[format] then local fmt = rex.gsub(format, "(%[A-Za-z])", function(m) return datetime._directives[m] or m end ) datetime._pattern_cache[format] = rex.new(fmt, rex.flags().CASELESS) end return datetime._pattern_cache[format] end --- Parses the specified source string, according to the format if given, to return a representation of --- the date/time. The default format if not specified is: "^%Y-%m-%d %H:%M:%S$"

--- --- If as_epoch is provided and true, the return value will be a Unix epoch -- the number --- of seconds since 1970. This is a useful format for exchanging date/times with other systems. If as_epoch --- is false, then a Lua time table will be returned. Details of the time tables are provided --- in the http://www.lua.org/pil/22.1.html.

--- --- Supported Format Codes --- --- %b Abbreviated Month Name --- %B Full Month Name --- %d Day of Month --- %H Hour (24-hour format) --- %I Hour (12-hour format, requires %p as well) --- %p AM or PM --- %m 2-digit month (01-12) --- %M 2-digit minutes (00-59) --- %S 2-digit seconds (00-59) --- %y 2-digit year (00-99), will automatically prepend 20 so 10 becomes 2010 and not 1910. --- %Y 4-digit year. --- function datetime:parse(source, format, as_epoch) if not format then format = "^%Y-%m-%d %H:%M:%S$" end local fmt = datetime:_get_pattern(format) local m = {fmt:tfind(source)} if m then m = m[3] dt = {} if m.year_half then dt.year = tonumber("20"..m.year_half) elseif m.year_full then dt.year = tonumber(m.year_full) end if m.month then dt.month = tonumber(m.month) elseif m.month_name then dt.month = datetime._month_names[m.month_name:lower()] elseif m.abbrev_month_name then dt.month = datetime._abbrev_month_names[m.abbrev_month_name:lower()] end dt.day = m.day_of_month if m.hour_12 then assert(m.ampm, "You must use %p (AM|PM) with %I (12-hour time)") if m.ampm == "PM" then dt.hour = 12 + tonumber(m.hour_12) else dt.hour = tonumber(m.hour_12) end else dt.hour = tonumber(m.hour_24) end dt.min = tonumber(m.minute) dt.sec = tonumber(m.second) dt.isdst = false if as_epoch then return os.time(dt) else return dt end else return nil end end ----------------------------------------------------------------------------- -- The database wrapper library ----------------------------------------------------------------------------- if package.loaded["luasql.sqlite3"] then require "luasql.sqlite3" end db = {} db.__autocommit = {} db.__schema = {} db.__conn = {} db.debug_sql = false -- NOT LUADOC -- Converts the type of a lua object to the equivalent type in SQL function db:_sql_type(value) local t = type(value) if t == "number" then return "REAL" elseif t == "nil" then return "NULL" elseif t == "table" and value._timestamp ~= nil then return "INTEGER" else return "TEXT" end end -- NOT LUADOC -- Converts a data value in Lua to its SQL equivalent; notably it will also escape single-quotes to -- prevent inadvertant SQL injection. function db:_sql_convert(value) local t = db:_sql_type(value) if value == nil then return "NULL" elseif t == "TEXT" then return '"'..value:gsub("'", "''")..'"' elseif t == "NULL" then return "NULL" elseif t == "INTEGER" then -- With db.Timestamp's, a value of false should be interpreted as nil. if value._timestamp == false then return "NULL" end return tostring(value._timestamp) else return tostring(value) end end -- NOT LUADOC -- Given a sheet name and the details of an index, this function will return a unique index name to -- add to the database. The purpose of this is to create unique index names as indexes are tested -- for existance on each call of db:create and not only on creation. That way new indexes can be -- added after initial creation. function db:_index_name(tbl_name, params) local t = type(params) if t == "string" then return "idx_" .. tbl_name .. "_c_" .. params elseif assert(t == "table", "Indexes must be either a string or a table.") then local parts = {"idx", tbl_name, "c"} for _, v in pairs(params) do parts[#parts+1] = v end return table.concat(parts, "_") end end -- NOT LUADOC -- This function returns true if all of the columns referenced in index_columns also exist within -- the sheet_columns table array. The purpose of this is to raise an error if someone tries to index -- a column which doesn't currently exist in the schema. function db:_index_valid(sheet_columns, index_columns) if type(index_columns) == "string" then if sheet_columns[index_columns] ~= nil then return true else return false end else for _, v in ipairs(index_columns) do if sheet_columns[v] == nil then echo("\n--> Bad index "..v) return false end end end return true end -- NOT LUADOC -- The column_spec is either a string or an indexed table. This function returns either "column" or -- "column1", "column2" for use in the column specification of INSERT. function db:_sql_columns(value) local colstr = '' local t = type(value) if t == "table" then col_chunks = {} for _, v in ipairs(value) do col_chunks[#col_chunks+1] = '"'..v:lower()..'"' end colstr = table.concat(col_chunks, ',') elseif assert(t == "string", "Must specify either a table array or string for index, not "..type(value)) then colstr = '"'..value:lower()..'"' end return colstr end -- NOT LUADOC -- This serves as a very similar function to db:_sql_columns, quoting column names properly but for -- uses outside of INSERTs. function db:_sql_fields(values) local sql_fields = {} for k, v in pairs(values) do sql_fields[#sql_fields+1] = '"'..k..'"' end return "("..table.concat(sql_fields, ",")..")" end -- NOT LUADOC -- This quotes values to be passed into an INSERT or UPDATE operation in a SQL list. Meaning, it turns -- {x="this", y="that", z=1} into ('this', 'that', 1). -- It is intelligent with data-types; strings are automatically quoted (with internal single quotes -- escaped), nil turned into NULL, timestamps converted to integers, and such. function db:_sql_values(values) local sql_values = {} for k, v in pairs(values) do local t = type(v) local s = "" if t == "string" then s = "'"..v:gsub("'", "''").."'" elseif t == "nil" then s = "NULL" elseif t == "table" and t._timestamp ~= nil then if not t._timestamp then return "NULL" else s = tostring(t._timestamp) end else s = tostring(v) end sql_values[#sql_values+1] = s end return "("..table.concat(sql_values, ",")..")" end --- TODO db:safe_name(name) -- On a filesystem level, names are restricted to being alphanumeric only. So, "my_database" becomes -- "mydatabase", and "../../../../etc/passwd" becomes "etcpasswd". This prevents any possible -- security issues with database names. function db:safe_name(name) name = name:gsub("[^%ad]", "") name = name:lower() return name end --- Creates and/or modifies an existing database. This function is safe to define at a top-level of a Mudlet --- script: in fact it is reccommended you run this function at a top-level without any kind of guards. --- If the named database does not exist it will create it. If the database does exist then it will add --- any columns or indexes which didn't exist before to that database. If the database already has all the --- specified columns and indexes, it will do nothing.

--- --- The database will be called Database_.db and will be stored in the --- Mudlet configuration directory.

--- --- Database 'tables' are called 'sheets' consistently throughout this documentation, to avoid confusion --- with Lua tables.

--- --- The schema table must be a Lua table array containing table dictionaries that define the structure and --- layout of each sheet.

--- --- For sheets with unique indexes, you may specify a _violations key to indicate how the db layer handle --- cases where the unique index is violated. The options you may use are: ---
---   FAIL - the default. A hard error is thrown, cancelling the script.
---   IGNORE - The command that would add a record that violates uniqueness just fails silently.
---   REPLACE - The old record which matched the unique index is dropped, and the new one is added to replace it.
---   
--- --- @usage Example bellow will create a database with two sheets; the first is kills and is used to track every successful kill, --- with both where and when the kill happened. It has one index, a compound index tracking the combination of name and area. --- The second sheet has two indexes, but one is unique: it isn't possible to add two items to the enemies sheet with the same name. ---
---   local mydb = db:create("combat_log",
---     {
---       kills = {
---         name = "",
---         area = "",
---         killed = db:Timestamp("CURRENT_TIMESTAMP"),
---         _index = {{"name", "area"}}
---       },
---       enemies = {
---         name = "",
---         city = "",
---         reason = "",
---         enemied = db:Timestamp("CURRENT_TIMESTAMP"),
---         _index = { "city" },
---         _unique = { "name" },
---         _violations = "IGNORE"
---       }
---     }
---   )
---   
--- Note that you have to use double {{ }} if you have composite index/unique constrain. function db:create(db_name, sheets) if not db.__env then db.__env = luasql.sqlite3() end db_name = db:safe_name(db_name) if not db.__conn[db_name] then db.__conn[db_name] = db.__env:connect(getMudletHomeDir() .. "/Database_" .. db_name .. ".db") db.__conn[db_name]:setautocommit(false) db.__autocommit[db_name] = true end db.__schema[db_name] = {} -- We need to separate the actual column configuration from the meta-configuration of the desired -- sheet. {sheet={"column"}} verses {sheet={"column"}, _index={"column"}}. In the former we are -- creating a database with a single field; in the latter we are also adding an index on that -- field. The db package reserves any key that begins with an underscore to be special and syntax -- for its own use. for s_name, sht in pairs(sheets) do options = {} if sht[1] ~= nil then t = {} for k, v in pairs(sht) do t[v] = nil end sht = t else for k, v in pairs(sht) do if string.starts(k, "_") then options[k] = v sht[k] = nil end end end if not options._violations then options._violations = "FAIL" end db.__schema[db_name][s_name] = {columns=sht, options=options} db:_migrate(db_name, s_name) end return db:get_database(db_name) end -- NOT LUADOC -- The migrate function is meant to upgrade an existing database live, to maintain a consistant -- and correct set of sheets and fields, along with their indexes. It should be safe to run -- at any time, and must not cause any data loss. It simply adds to what is there: in perticular -- it is not capable of removing indexes, columns, or sheets after they have been defined. function db:_migrate(db_name, s_name) local conn = db.__conn[db_name] local schema = db.__schema[db_name][s_name] local current_columns = {} -- The PRAGMA table_info command is a query which returns all of the columns currently -- defined in the specified table. The purpose of this section is to see if any new columns -- have been added. local cur = conn:execute("PRAGMA table_info('"..s_name.."')") if cur ~= 0 then local row = cur:fetch({}, "a") while row do current_columns[row.name:lower()] = row.type row = cur:fetch({}, "a") end cur:close() end -- The SQL definition of a column is: -- "column_name" column_type NULL -- The db module does not presently support columns that are required. Everything is optional, -- everything may be NULL / nil. -- If you specify a column's type, you also specify its default value. local sql_column = ', "%s" %s NULL' local sql_column_default = sql_column..' DEFAULT %s' if table.is_empty(current_columns) then -- At this point, we know that the specified table does not exist in the database and so we -- should create it. -- Every sheet has an implicit _row_id column. It is not presently (and likely never will be) -- supported to define the primary key of any sheet. local sql_chunks = {"CREATE TABLE ", s_name, '("_row_id" INTEGER PRIMARY KEY AUTOINCREMENT'} -- We iterate over every defined column, and add a line which creates it. for key, value in pairs(schema.columns) do local sql = "" if value == nil then sql = sql_column:format(key:lower(), db:_sql_type(value)) else sql = sql_column_default:format(key:lower(), db:_sql_type(value), db:_sql_convert(value)) end sql_chunks[#sql_chunks+1] = sql end sql_chunks[#sql_chunks+1] = ")" local sql = table.concat(sql_chunks, "") db:echo_sql(sql) conn:execute(sql) else -- At this point we know that the sheet already exists, but we are concerned if the current -- definition includes columns which may be added. local sql_chunks = {} local sql_add = 'ALTER TABLE %s ADD COLUMN "%s" %s NULL DEFAULT %s' for k, v in pairs(schema.columns) do k = k:lower() t = db:_sql_type(v) v = db:_sql_convert(v) -- Here we test it a given column exists in the sheet already, and if not, we add that -- column. if not current_columns[k] then local sql = sql_add:format(s_name, k, t, v) conn:execute(sql) db:echo_sql(sql) end end end -- On every invocation of db:create we run the code that creates indexes, as that code will -- do nothing if the specific indexes already exist. This is enforced by the db:_index_name -- function creating a unique index. -- -- Note that in no situation will an existing index be deleted. db:_migrate_indexes(conn, s_name, schema, current_columns) db:echo_sql("COMMIT") conn:commit() conn:execute("VACUUM") end -- NOT LUADOC -- Creates any indexes which do not yet exist in the given database. function db:_migrate_indexes(conn, s_name, schema, current_columns) local sql_create_index = "CREATE %s IF NOT EXISTS %s ON %s (%s);" local opt = {_unique = "UNIQUE INDEX", _index = "INDEX"} -- , _check = "CHECK"} for option_type, options in pairs(schema.options) do if option_type == "_unique" or option_type == "_index" then for _, value in pairs(options) do -- If an index references a column which does not presently exist within the schema -- this will fail. if db:_index_valid(current_columns, value) then --assert(db:_index_valid(current_columns, value), -- "In sheet "..s_name.." an index field is specified that does not exist.") sql = sql_create_index:format( opt[option_type], db:_index_name(s_name, value), s_name, db:_sql_columns(value) ) db:echo_sql(sql) conn:execute(sql) end end end end end --- Adds one or more new rows to the specified sheet. If any of these rows would violate a UNIQUE index, --- a lua error will be thrown and execution will cancel. As such it is advisable that if you use a UNIQUE --- index, you test those values before you attempt to insert a new row.

--- --- Each table is a series of key-value pairs to set the values of the sheet, but if any keys do not exist --- then they will be set to nil or the default value. As you can see, all fields are optional. --- --- @usage Adding one record. ---
---   db:add(mydb.enemies, {name="Bob Smith", city="San Francisco"})
---   
--- @usage Adding multiple records. ---
---   db:add(mydb.enemies,
---     {name="John Smith", city="San Francisco"},
---     {name="Jane Smith", city="San Francisco"},
---     {name="Richard Clark"}
---   )
---   
function db:add(sheet, ...) local db_name = sheet._db_name local s_name = sheet._sht_name assert(s_name, "First argument to db:add must be a proper Sheet object.") local conn = db.__conn[db_name] local sql_insert = "INSERT OR %s INTO %s %s VALUES %s" for _, t in ipairs({...}) do if t._row_id then -- You are not permitted to change a _row_id t._row_id = nil end local sql = sql_insert:format(db.__schema[db_name][s_name].options._violations, s_name, db:_sql_fields(t), db:_sql_values(t)) db:echo_sql(sql) assert(conn:execute(sql), "Failed to add item: this is probably a violation of a UNIQUE index or other constraint.") end if db.__autocommit[db_name] then conn:commit() end end --- Execute SQL select query against database. This only useful for some very specific cases.
--- Use db:fetch if possible instead - this function should not be normally used! --- --- @release post Mudlet 1.1.1 (TODO update before release) --- --- @usage Following will select all distinct area from my kills DB. ---
---   db:fetch_sql(mydb.kills, "SELECT distinct area FROM kills")
---   
--- --- @see db:fetch function db:fetch_sql(sheet, sql) local db_name = sheet._db_name local conn = db.__conn[db_name] db:echo_sql(sql) local cur = conn:execute(sql) if cur ~= 0 then local results = {} local row = cur:fetch({}, "a") while row do results[#results+1] = db:_coerce_sheet(sheet, row) row = cur:fetch({}, "a") end cur:close() return results else return nil end end --- Returns a table array containing a table for each matching row in the specified sheet. All arguments --- but sheet are optional. If query is nil, the entire contents of the sheet will be returned.

--- --- Query is a string which should be built by calling the various db: expression functions, such as db:eq, --- db:AND, and such. You may pass a SQL WHERE clause here if you wish, but doing so is very dangerous. --- If you don't know SQL well, its best to build the expression.

--- --- Query may also be a table array of such expressions, if so they will be AND'd together implicitly.

--- --- The results that are returned are not in any guaranteed order, though they are usually the same order --- as the records were inserted. If you want to rely on the order in any way, you must pass a value to the --- order_by field. This must be a table array listing the columns you want to sort by. --- It can be { "column1" }, or { "column1", "column2" }

--- --- The results are returned in ascending (smallest to largest) order; to reverse this pass true into the final field. --- --- @usage The first will fetch all of your enemies, sorted first by the city they reside in and then by their name. ---
---   db:fetch(mydb.enemies, nil, {"city", "name"})
---   
--- @usage The second will fetch only the enemies which are in San Francisco. ---
---   db:fetch(mydb.enemies, db:eq(mydb.enemies.city, "San Francisco"))
---   
--- @usage The third will fetch all the things you've killed in Undervault which have Drow in their name. ---
---   db:fetch(mydb.kills,
---      {
---         db:eq(mydb.kills.area, "Undervault"),
---         db:like(mydb.kills.name, "%Drow%")
---      }
---   )
---   
--- --- @see db:fetch_sql function db:fetch(sheet, query, order_by, descending) local s_name = sheet._sht_name local sql = "SELECT * FROM "..s_name if query then if type(query) == "table" then sql = sql.." WHERE "..db:AND(unpack(query)) else sql = sql.." WHERE "..query end end if order_by then local o = {} for _, v in ipairs(order_by) do assert(v.name, "You must pass field instances (as obtained from yourdb.yoursheet.yourfield) to sort.") o[#o+1] = v.name end sql = sql.." ORDER BY "..db:_sql_columns(o) if descending then sql = sql.." DESC" end end return db:fetch_sql(sheet, sql) end --- Returns the result of calling the specified aggregate function on the field and its sheet.

--- --- The supported aggregate functions are: ---
---   COUNT - Returns the total number of records that are in the sheet or match the query.
---   AVG   - Returns the average of all the numbers in the specified field.
---   MAX   - Returns the highest number in the specified field.
---   MIN   - Returns the lowest number in the specified field.
---   TOTAL - Returns the value of adding all the contents of the specified field.
---   
--- --- @param query optional --- --- @usage Example: ---
---   local mydb = db:get_database("my database")
---   echo(db:aggregate(mydb.enemies.name, "count"))
---   
function db:aggregate(field, fn, query) local db_name = field.database local s_name = field.sheet local conn = db.__conn[db_name] assert(type(field) == "table", "Field must be a field reference.") assert(field.name, "Field must be a real field reference.") local sql_chunks = {"SELECT", fn, "(", field.name, ")", "AS", fn, "FROM", s_name} if query then if type(query) == "table" then sql_chunks[#sql_chunks+1] = db:AND(unpack(query)) else sql_chunks[#sql_chunks+1] = query end end if order_by then local o = {} for _, v in ipairs(order_by) do assert(v.name, "You must pass field instances (as obtained from yourdb.yoursheet.yourfield) to sort.") o[#o+1] = v.name end sql_chunks[#sql_chunks+1] = "ORDER BY" sql_chunks[#sql_chunks+1] = db:_sql_columns(o) if descending then sql_chunks[#sql_chunks+1] = "DESC" end end local sql = table.concat(sql_chunks, " ") db:echo_sql(sql) local cur = conn:execute(sql) if cur ~= 0 then local row = cur:fetch({}, "a") local count = row[fn] cur:close() return count else return 0 end end --- Deletes rows from the specified sheet. The argument for query tries to be intelligent:
--- * if it is a simple number, it deletes a specific row by _row_id
--- * if it is a table that contains a _row_id (e.g., a table returned by db:get) it deletes just that record.
--- * Otherwise, it deletes every record which matches the query pattern which is specified as with db:get.
--- * If the query is simply true, then it will truncate the entire contents of the sheet.
--- --- @usage When passed an actual result table that was obtained from db:fetch, it will delete the record for that table. ---
---   enemies = db:fetch(mydb.enemies)
---   db:delete(mydb.enemies, enemies[1])
---   
--- @usage When passed a number, will delete the record for that _row_id. This example shows getting the row id from a table. ---
---   enemies = db:fetch(mydb.enemies)
---   db:delete(mydb.enemies, enemies[1]._row_id)
---   
--- @usage As above, but this example just passes in the row id directly. ---
---   db:delete(mydb.enemies, 5)
---   
--- @usage Here, we will delete anything which matches the same kind of query as db:fetch uses - namely, --- anyone who is in the city of San Francisco. ---
---   db:delete(mydb.enemies, db:eq(mydb.enemies.city, "San Francisco"))
---   
--- @usage And finally, we will delete the entire contents of the enemies table. ---
---   db:delete(mydb.enemies, true)
---   
function db:delete(sheet, query) local db_name = sheet._db_name local s_name = sheet._sht_name local conn = db.__conn[db_name] assert(query, "must pass a query argument to db:delete()") if type(query) == "number" then query = "_row_id = "..tostring(query) elseif type(query) == "table" then assert(query._row_id, "Passed a non-result table to db:delete, need a _row_id field to continue.") query = "_row_id = "..tostring(query._row_id) end local sql = "DELETE FROM "..s_name if query ~= true then sql = sql.." WHERE "..query end db:echo_sql(sql) assert(conn:execute(sql)) if db.__autocommit[db_name] then conn:commit() end end --- Merges the specified table array into the sheet, modifying any existing rows and adding any that don't exist. --- --- This function is a convenience utility that allows you to quickly modify a sheet, changing --- existing rows and add new ones as appropriate. It ONLY works on sheets which have a unique --- index, and only when that unique index is only on a single field. For more complex situations --- you'll have to do the logic yourself. --- --- The table array may contain tables that were either returned previously by db:fetch, or new tables --- that you've constructed with the correct fields, or any mix of both. Each table must have a value --- for the unique key that has been set on this sheet. --- --- @usage For example, consider this database: ---
---   local mydb = db:create("peopledb",
---     {
---       friends = {
---         name = "",
---         race = "",
---         level = 0,
---         city = "",
---         _index = { "city" },
---         _unique = { "name" }
---       }
---     }
---   )
---   
--- --- Here you have a database with one sheet, which contains your friends, their race, level, --- and what city they live in. Let's say you want to fetch everyone who lives in San Francisco, you could do: ---
---   local results = db:fetch(mydb.friends, db:eq(mydb.friends.city, "San Francisco"))
---   
--- --- The tables in results are static, any changes to them are not saved back to the database. --- But after a major radioactive cataclysm rendered everyone in San Francisco a mutant, --- you could make changes to the tables as so: ---
---   for _, friend in ipairs(results) do
---     friend.race = "Mutant"
---   end
---   
--- --- If you are also now aware of a new arrival in San Francisco, you could add them to that existing table array: ---
---   results[#results+1] = {name="Bobette", race="Mutant", city="San Francisco"}
---   
--- --- And commit all of these changes back to the database at once with: ---
---   db:merge_unique(mydb.friends, results)
---   
--- --- The db:merge_unique function will change the 'city' values for all the people who we previously fetched, but then add a new record as well. function db:merge_unique(sheet, tables) local db_name = sheet._db_name local s_name = sheet._sht_name local unique_options = db.__schema[db_name][s_name].options._unique assert(unique_options, "db:merge_unique only works on a sheet with a unique index.") assert(#unique_options == 1, "db:merge_unique only works on a sheet with a single unique index.") local unique_index = unique_options[1] local unique_key = "" if type(unique_index) == "table" then assert(#unique_index == 1, "db:merge_unique currently only supports sheets with a single unique index with a single column.") unique_key = unique_index[1] else unique_key = unique_index end db:echo_sql(":: Unique index = "..unique_key) local conn = db.__conn[db_name] local mydb = db:get_database(db_name) mydb:_begin() for _, tbl in ipairs(tables) do assert(tbl[unique_key], "attempting to db:merge_unique with a table that does not have the unique key.") local results = db:fetch(sheet, db:eq(sheet[unique_key], tbl[unique_key])) if results and results[1] then local t = results[1] for k, v in pairs(tbl) do t[k] = v end db:update(sheet, t) else db:add(sheet, tbl) end end mydb:_commit() mydb:_end() end --- This function updates a row in the specified sheet, but only accepts a row which has been previously --- obtained by db:fetch. Its primary purpose is that if you do a db:fetch, then change the value of a field --- or tow, you can save back that table. --- --- @usage This obtains a database reference, and queries the friends sheet for someone named Bob. As this --- returns a table array containing only one item, it assigns that one item to the local variable named bob. --- We then change the notes on Bob, and pass it into db:update() to save the changes back. ---
---   local mydb = db:get_database("my database")
---   local bob = db:fetch(mydb.friends, db:eq(mydb.friends.name, "Bob"))[1]
---   bob.notes = "He's a really awesome guy."
---   db:update(mydb.friends, bob)
---   
function db:update(sheet, tbl) assert(tbl._row_id, "Can only update a table with a _row_id") assert(not table.is_empty(tbl), "An empty table was passed to db:update") local db_name = sheet._db_name local s_name = sheet._sht_name local conn = db.__conn[db_name] local sql_chunks = {"UPDATE OR", db.__schema[db_name][s_name].options._violations, s_name, "SET"} local set_chunks = {} local set_block = [["%s" = %s]] for k, v in pairs(db.__schema[db_name][s_name]['columns']) do if tbl[k] then local field = sheet[k] set_chunks[#set_chunks+1] = set_block:format(k, db:_coerce(field, tbl[k])) end end sql_chunks[#sql_chunks+1] = table.concat(set_chunks, ",") sql_chunks[#sql_chunks+1] = "WHERE _row_id = "..tbl._row_id local sql = table.concat(sql_chunks, " ") db:echo_sql(sql) assert(conn:execute(sql)) if db.__autocommit[db_name] then conn:commit() end end --- The db:set function allows you to set a certain field to a certain value across an entire sheet. --- Meaning, you can change all of the last_read fields in the sheet to a certain value, or possibly only --- the last_read fields which are in a certain city. The query argument can be any value which is appropriate --- for db:fetch, even nil which will change the value for the specified column for EVERY row in the sheet. --- --- For example, consider a situation in which you are tracking how many times you find a certain --- type of egg during Easter. You start by setting up your database and adding an Eggs sheet, and --- then adding a record for each type of egg. ---
---   local mydb = db:create("egg database", {eggs = {color = "", last_found = db.Timestamp(false), found = 0}})
---   db:add(mydb.eggs,
---     {color = "Red"},
---     {color = "Blue"},
---     {color = "Green"},
---     {color = "Yellow"},
---     {color = "Black"}
---   )
---   
--- --- Now, you have three columns. One is a string, one a timestamp (that ends up as nil in the database), --- and one is a number.

--- --- You can then set up a trigger to capture from the mud the string, "You pick up a (.*) egg!", and you --- end up arranging to store the value of that expression in a variable called "myegg".

--- --- To increment how many we found, we will do this: ---
---   myegg = "Red" -- We will pretend a trigger set this.
---   db:set(mydb.eggs.found, db:exp("found + 1"), db:eq(mydb.eggs.color, myegg))
---   db:set(mydb.eggs.last_found, db.Timestamp("CURRENT_TIMESTAMP"), db:eq(mydb.eggs.color, myegg))
---   
--- --- This will go out and set two fields in the Red egg sheet; the first is the found field, which will --- increment the value of that field (using the special db:exp function). The second will update the --- last_found field with the current time.

--- --- Once this contest is over, you may wish to reset this data but keep the database around. --- To do that, you may use a more broad use of db:set as such: ---
---   db:set(mydb.eggs.found, 0)
---   db:set(mydb.eggs.last_found, nil)
---   
function db:set(field, value, query) local db_name = sheet._db_name local s_name = sheet._sht_name local conn = db.__conn[db_name] local sql_update = [[UPDATE OR %s %s SET "%s" = %s]] if query then sql_update = sql_update .. [[ WHERE %s]] end local sql = sql_update:format(db.__schema[db_name][s_name].options._violations, s_name, field.name, db:_coerce(field, value), query) db:echo_sql(sql) assert(conn:execute(sql)) if db.__autocommit[db_name] then conn:commit() end end --- This is a debugging function, which echos any SQL commands if db.debug_sql is true. --- You should not call this function directly from Mudlet. --- --- @usage Set following lua variable to enable SQL echos. ---
---   db.debug_sql=true
---   
function db:echo_sql(sql) if db.debug_sql then echo("\n"..sql.."\n") end end -- NOT LUADOC -- After a table so retrieved from the database, this function coerces values to -- their proper types. Specifically, numbers and datetimes become the proper -- types. function db:_coerce_sheet(sheet, tbl) if tbl then tbl._row_id = tonumber(tbl._row_id) for k, v in pairs(tbl) do if k ~= "_row_id" then local field = sheet[k] if field.type == "number" then tbl[k] = tonumber(tbl[k]) or tbl[k] elseif field.type == "datetime" then tbl[k] = db:Timestamp(datetime:parse(tbl[k], nil, true)) end end end return tbl end end -- NOT LUADOC -- The function converts a Lua value into its SQL representation, depending on the -- type of the specified field. Strings will be single-quoted (and single-quotes -- within will be properly escaped), numbers will be rendered properly, and such. function db:_coerce(field, value) if field.type == "number" then return tonumber(value) or "'"..value.."'" elseif field.type == "datetime" then if value._timestamp == false then return "NULL" else return tonumber(value._timestamp) or "'"..value.."'" end else return "'"..tostring(value):gsub("'", "''").."'" end end --- Returns a database expression to test if the field in the sheet is equal to the value. --- --- @see db:fetch function db:eq(field, value, case_insensitive) if case_insensitive then local v = db:_coerce(field, value):lower() return "lower("..field.name..") == "..v else local v = db:_coerce(field, value) return field.name.." == "..v end end --- Returns a database expression to test if the field in the sheet is NOT equal to the value. --- --- @see db:fetch function db:not_eq(field, value, case_insensitive) if case_insensitive then local v = db:_coerce(field, value):lower() return "lower("..field.name..") != "..v else local v = db:_coerce(field, value) return field.name.." != "..v end end --- Returns a database expression to test if the field in the sheet is less than the value. --- --- @see db:fetch function db:lt(field, value) local v = db:_coerce(field, value) return field.name.." < "..v end --- Returns a database expression to test if the field in the sheet is less than or equal to the value. --- --- @see db:fetch function db:lte(field, value) local v = db:_coerce(field, value) return field.name.." <= "..v end --- Returns a database expression to test if the field in the sheet is greater than to the value. --- --- @see db:fetch function db:gt(field, value) local v = db:_coerce(field, value) return field.name.." > "..v end --- Returns a database expression to test if the field in the sheet is greater than or equal to the value. --- --- @see db:fetch function db:gte(field, value) local v = db:_coerce(field, value) return field.name.." >= "..v end --- Returns a database expression to test if the field in the sheet is nil. --- --- @see db:fetch function db:is_nil(field) return field.name.." IS NULL" end --- Returns a database expression to test if the field in the sheet is not nil. --- --- @see db:fetch function db:is_not_nil(field) return field.name.." IS NOT NULL" end --- Returns a database expression to test if the field in the sheet matches the specified pattern.

--- --- LIKE patterns are not case-sensitive, and allow two wild cards. The first is an underscore which matches --- any single one character. The second is a percent symbol which matches zero or more of any character. ---
---   LIKE with "_" is therefore the same as the "." regular expression.
---   LIKE with "%" is therefore the same as ".*" regular expression.
---   
--- --- @see db:not_like --- @see db:fetch function db:like(field, value) local v = db:_coerce(field, value) return field.name.." LIKE "..v end --- Returns a database expression to test if the field in the sheet does not match the specified pattern. --- --- LIKE patterns are not case-sensitive, and allow two wild cards. The first is an underscore which matches --- any single one character. The second is a percent symbol which matches zero or more of any character. ---
---   LIKE with "_" is therefore the same as the "." regular expression.
---   LIKE with "%" is therefore the same as ".*" regular expression.
---   
--- --- @see db:like --- @see db:fetch function db:not_like(field, value) local v = db:_coerce(field, value) return field.name.." NOT LIKE "..v end --- Returns a database expression to test if the field in the sheet is a value between lower_bound and upper_bound. --- This only really makes sense for numbers and Timestamps. --- --- @see db:not_between --- @see db:fetch function db:between(field, left_bound, right_bound) local x = db:_coerce(field, left_bound) local y = db:_coerce(field, right_bound) return field.name.." BETWEEN "..x.." AND "..y end --- Returns a database expression to test if the field in the sheet is NOT a value between lower_bound and upper_bound. --- This only really makes sense for numbers and Timestamps. --- --- @see db:between --- @see db:fetch function db:not_between(field, left_bound, right_bound) local x = db:_coerce(field, left_bound) local y = db:_coerce(field, right_bound) return field.name.." NOT BETWEEN "..x.." AND "..y end --- Returns a database expression to test if the field in the sheet is one of the values in the table array.

--- --- First, note the trailing underscore carefully! It is required. --- --- @usage The following example illustrates the use of in_: --- This will obtain all of your kills which happened in the Undervault, Hell or Purgatory. Every db:in_ expression --- can be written as a db:OR, but that quite often gets very complex. ---
---   local mydb = db:get_database("my database")
---   local areas = {"Undervault", "Hell", "Purgatory"}
---   db:fetch(mydb.kills, db:in_(mydb.kills.area, areas))
---   
--- --- @see db:fetch function db:in_(field, tbl) local parts = {} for _, v in ipairs(tbl) do parts[#parts+1] = db:_coerce(field, v) end return field.name.." IN ("..table.concat(parts, ",")..")" end --- Returns a database expression to test if the field in the sheet is not one of the values in the table array. --- --- @see db:in_ --- @see db:fetch function db:not_in(field, tbl) local parts = {} for _, v in ipairs(tbl) do parts[#parts+1] = db:_coerce(field, v) end return field.name.." NOT IN ("..table.concat(parts, ",")..")" end --- Returns the string as-is to the database.

--- --- Use this function with caution, but it is very useful in some circumstances. One of the most --- common of such is incrementing an existing field in a db:set() operation, as so: ---
---   db:set(mydb.enemies, db:exp("kills + 1"), db:eq(mydb.enemies.name, "Ixokai"))
---   
--- --- This will increment the value of the kills field for the row identified by the name Ixokai.

--- --- But there are other uses, as the underlining database layer provides many functions you can call --- to do certain things. If you want to get a list of all your enemies who have a name longer then --- 10 characters, you may do: ---
---   db:fetch(mydb.enemies, db:exp("length(name) > 10"))
---   
--- --- Again, take special care with this, as you are doing SQL syntax directly and the library can't --- help you get things right. --- --- @see db:fetch function db:exp(text) return text end --- Returns a compound database expression that combines all of the simple expressions passed into it. --- These expressions should be generated with other db: functions such as db:eq, db:like, db:lt and the like.

--- --- This compound expression will only find items in the sheet if all sub-expressions match. --- --- @see db:fetch function db:AND(...) local parts = {} for _, expression in ipairs({...}) do parts[#parts+1] = "("..expression..")" end return "("..table.concat(parts, " AND ")..")" end --- Returns a compound database expression that combines both of the simple expressions passed into it. --- These expressions should be generated with other db: functions such as db:eq, db:like, db:lt and the like.

--- --- This compound expression will find any item that matches either the first or the second sub-expression. --- --- @see db:fetch function db:OR(left, right) if not string.starts(left, "(") then left = "("..left..")" end if not string.starts(right, "(") then right = "("..right..")" end return left.." OR "..right end --- TODO function db:close() for _, c in pairs(db.__conn) do c:close() end db.__env:close() end -- Timestamp support db.__Timestamp = {} db.__TimestampMT = { __index = db.__Timestamp } function db.__Timestamp:as_string(format) if not format then format = "%m-%d-%Y %H:%M:%S" end return os.date(format, self._timestamp) end function db.__Timestamp:as_table() return os.date("*t", self._timestamp) end function db.__Timestamp:as_number() return self._timestamp end --- TODO function db:Timestamp(ts, fmt) local dt = {} if type(ts) == "table" then dt._timestamp = os.time(ts) elseif type(ts) == "number" then dt._timestamp = ts elseif type(ts) == "string" and assert(ts == "CURRENT_TIMESTAMP", "The only strings supported by db.DateTime:new is CURRENT_TIMESTAMP") then dt._timestamp = "CURRENT_TIMESTAMP" elseif ts == nil then dt._timestamp = false else assert(nil, "Invalid value passed to db.Timestamp()") end return setmetatable(dt, db.__TimestampMT) end -- function db.Timestamp:new(ts, fmt) -- local dt = {} -- if type(ts) == "table" then -- dt._timestamp = os.time(ts) -- elseif type(ts) == "number" then -- dt._timestamp = ts -- elseif assert(ts == "CURRENT_TIMESTAMP", "The only strings supported by db.DateTime:new is CURRENT_TIMESTAMP") then -- dt._timestamp = "CURRENT_TIMESTAMP" -- end -- return setmetatable(dt, db.__TimestampMT) -- end db.Field = {} db.__FieldMT = { __index = db.Field } db.Sheet = {} db.__SheetMT = { __index = function(t, k) local v = rawget(db.Sheet, k) if v then return v end local db_name = rawget(t, "_db_name") local sht_name = rawget(t, "_sht_name") local f_name = k:lower() local errormsg = "Attempt to access field %s in sheet %s in database %s that does not exist." local field = db.__schema[db_name][sht_name]['columns'][f_name] if assert(field, errormsg:format(k, sht_name, db_name)) then type_ = type(field) if type_ == "table" and field._timestamp then type_ = "datetime" end rt = setmetatable({database=db_name, sheet=sht_name, type=type_, name=f_name}, db.__FieldMT) rawset(t,k,rt) return rt end end } db.Database = {} db.__DatabaseMT = { __index = function(t, k) local v = rawget(t, k) if v then return v end local v = rawget(db.Database, k) if v then return v end local db_name = rawget(t, "_db_name") if assert(db.__schema[db_name][k:lower()], "Attempt to access sheet '"..k:lower().."'in db '"..db_name.."' that does not exist.") then rt = setmetatable({_db_name = db_name, _sht_name = k:lower()}, db.__SheetMT) rawset(t,k,rt) return rt end end } function db.Database:_begin() db.__autocommit[self._db_name] = false end function db.Database:_commit() local conn = db.__conn[self._db_name] conn:commit() end function db.Database:_rollback() local conn = db.__conn[self._db_name] conn:rollback() end function db.Database:_end() db.__autocommit[self._db_name] = true end function db.Database._drop(s_name) local conn = db.__conn[self._db_name] local schema = db.__schema[self._db_name] if schema.options._index then for _, value in schema.options._index do conn:execute("DROP INDEX IF EXISTS " .. db:_index_name(s_name, value)) end end if schema.options._unique then for _, value in schema.options._unique do conn:execute("DROP INDEX IF EXISTS " .. db:_index_name(s_name, value)) end end conn:execute("DROP TABLE IF EXISTS "..s_name) conn:commit() end --- Returns a reference of an already existing database. This instance can be used to get references --- to the sheets (and from there, fields) that are defined within the database. You use these --- references to construct queries.

--- --- These references do not contain any actual data, they only point to parts of the database structure. --- --- @usage If a database has a sheet named enemies, you can obtain a reference to that sheet by simply doing: ---
---   local mydb = db:get_database("my database")
---   local enemies_ref = mydb.enemies
---   local name_ref = mydb.enemies.name
---   
function db:get_database(db_name) db_name = db:safe_name(db_name) assert(db.__schema[db_name], "Attempt to access database that does not exist.") db_inst = {_db_name = db_name} return setmetatable(db_inst, db.__DatabaseMT) end mudlet-2.1/src/mudlet-lua/lua/Logging.lua0000644000175000017500000002160512070466512017677 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Logging ---------------------------------------------------------------------------------- --
-- The basic design of this system is inspired by Python's logging module, which is
-- in turn inspired by log4J. However it does diverge from both.
--
-- The system creates a hierarchy of Loggers. A logger is the interface through which
-- code sends messages into the logging system. These messages can be simple strings
-- (commonly), or tables. In either case, the logger converts the message into an
-- event which is a table with certain standard keys, and a number of custom keys
-- that a logger can provide if it wishes.
--
-- Events have a number of standard properties: a timestamp, the name of the logger,
-- a severity(level) of the event, and the message itself.
--
-- By default, a logger has a level of ANY, which means that any events passed into
-- it are handled. You can set this level higher if you want, in which case the
-- logger will ignore any events which are of a lesser severity.
--
-- The level of severities are:
--   ANY, DEBUG, INFO, WARNING, ERROR, CRITICAL
--
-- A logger can have any number of handlers assigned to it.
--
-- A handler is responsible for actually writing/saving the data to the device,
-- and has a formatter associated with it.
--
-- Precisely what a "device" is depends on the type of handler; for a FileHandler,
-- its an actual filename. For a ConsoleHandler, its always just true as it writes
-- to the main console. For a MiniConsoleHandler, its the name of a miniconsole.
-- For a SheetHandler, its a db frontend sheet reference, e.g:
--    local mydb = db:get_database("tracker")
--    local device = mydb.kills
--
-- Each handler can also have its own severity, which means it will ignore any
-- events that are below that. This is useful if you want a logger to write only
-- important messages to the screen, but write more to a file.
--
-- Every logger has a "propagate" property which defaults to true. When true,
-- any events it handles will propagate to the parent logger. Its important to note
-- that a single event will only ever be written to a certain device once, so its
-- safe to propagate up the chain even if a parent logger would write things out
-- too. Whatever handler is assigned to the event first for a given device, wins.
-- 
logging = { -- Formatters are used to convert a logging event into a form which is appropriate -- for a certain kind of output device. Handlers actually write to such a device, -- but formatters are used by handlers. -- -- By default, there are four kinds of output devices that are supported and thus -- four default formatters that are used when outputting to devices of that type. -- A specific logger can override this for specific handlers, of course. -- -- The file default is used when writing to the actual filesystem, and is the -- most verbose output format. -- -- The console default is meant to write to the actual main mud window. -- -- The miniconsole is meant to write to miniconsoles, which we assume may be -- much smaller then the main window and so we write only the message by default. -- -- Finally, the sheet default is meant to be used with the handler that writes -- logging events to database sheets that are constructed with Mudlet's db -- frontend. This formatter is a table and not a string, and contains a key -- for each field in the table you want to add, and either a function that -- returns what value to write, or a string which is the key of the given -- event. _formatters = { default_file = "[${timestamp}] ${system} [${levelname:pad:8}]: ${message}\n", default_console = "[${system} ${levelname:pad:8}]: ${message}\n", default_miniconsole = "${message}\n", default_sheet = { timestamp = os.time, system="system", level="levelname", message="message" } }, _timestamp = { display = "%Y-%m-%d %H:%M:%S", filesystem = "%Y-%m-%d_%H.%M.%S" }, -- Levels: ANY = 0, DEBUG = 10, INFO = 20, WARNING = 30, ERROR = 40, CRITICAL = 50, _levelnames = { [0] = "ANY", [10] = "DEBUG", [20] = "INFO", [30] = "WARNING", [40] = "ERROR", [50] = "CRITICAL" } } -- Handler Interface logging.Handler = {} logging.__handlerMT = {__index=logging.Handler} --- logging.Handler:create(name, device) function logging.Handler:create(name, device) assert(name) assert(device) local handler = {_name=name, _device=device, emit=function() end} setmetatable(handler, logging.__handlerMT) return handler end --- logging.Handler:process(event) function logging.Handler:process(event) if event.level >= self.level then if self.emit then self.emit(self, event) end end end logging.FileHandler = {} --- logging.FileHandler:create(path) function logging.FileHandler:create(path) end -- Logger Interface logging.Logger = {} logging.__loggerMT = {__index=logging.Logger} --- logging.Logger:create(name, parent) function logging.Logger:create(name, parent) local logger = { _name=name, _parent=parent, _children={}, _handlers = {}, _customizers = {}, propagate=true, level=logging.ANY, } setmetatable(logger, logging.__loggerMT) return logger end --- logging.Logger:add_event_customizer(fn) function logging.Logger:add_event_customizer(fn) local customizers = self._customizers customizers[#customizers+1] = fn end --- logging.Logger:clear_event_customizers() function logging.Logger:clear_event_customizers() self._customizers = {} end --- logging.Logger:_prepare_event(event) function logging.Logger:_prepare_event(event) local name_chunks = {self._name} if self._name ~= "mudlet" then parent = self._parent while parent._name ~= "mudlet" do name_chunks[#name_chunks+1] = parent._name parent = parent._parent end end event.system = table.concat(name_chunks, ".") event.timestamp = os.time() return event end --- logging.Logger:_customize_event(event) function logging.Logger:_customize_event(event) for _, customizer in ipairs(self._customizers) do customizer(event) end return event end --- logging.Logger:_do_log(evt, extras, level) function logging.Logger:_do_log(evt, extras, level) if type(evt) == "string" then evt = {message=evt} else assert(type(evt)=="table", "The first argument to the logging call must be a string or table.") assert(evt.message, "If passing a table to the logging call, it must contain a message value.") end assert(level) evt.level = level if extras then for k, v in pairs(extras) do evt[k] = v end end self:_log_event(self:_prepare_event(evt)) end --- logging.Logger:_log_event(evt) function logging.Logger:_log_event(evt) local event = self._customize_event(evt) if event.level >= self.level then for _, handler in self._handlers do handler:process(event) end end if self.propagate then self._parent:_log_event(event) end end --- logging.Logger:debug(event, extras) function logging.Logger:debug(event, extras) return self:_do_log(event, extras, logging.DEBUG) end --- logging.Logger:info(event, extras) function logging.Logger:info(event, extras) return self:_do_log(event, extras, logging.INFO) end --- logging.Logger:warning(event, extras) function logging.Logger:warning(event, extras) return self:_do_log(event, extras, logging.WARNING) end --- logging.Logger:error(event, extras) function logging.Logger:error(event, extras) return self:_do_log(event, extras, logging.ERROR) end --- logging.Logger:critical(event, extras) function logging.Logger:critical(event, extras) return self:_do_log(event, extras, logging.CRITICAL) end -- General Logging System logging._root = logging.Logger:create("mudlet", nil) --- logging:get_logger(name) function logging:get_logger(name) local name = name or "mudlet" local loggers = name:split(".") local parent = logging._root for _, logger in ipairs(loggers) do if parent._children[logger] == nil then local child = logging.Logger:create(logger, parent) parent._children[logger] = child parent = child else parent = parent._children[logger] end end return parent end --- logging:format_event(event, formatter) function logging:format_event(event, formatter) local format = formatter or logging._formatters.default_file local pattern = [[(\${(.-)})]] local output = format:gsub(pattern, function(complete, chunk) local compound = {chunk:match("([^:]+):([^:]+):(.+)")} if table.is_empty(compound) then return event[chunk] or complete else local value = event[compound[1]] or complete if compound[2] == "pad" then return string.format("%"..compound[3].."s", value) else return complete end end end ) return output end logging:format_event({timestamp=os.date(logging._timestamp.display, os.time()), system="crucible.core", levelname="ERROR", message="Err"}) local log = logging:get_logger("crucible.core") local root = logging:get_logger() log:add_event_customizer( function(evt) evt["test"] = 1 end ) mudlet-2.1/src/mudlet-lua/lua/DebugTools.lua0000644000175000017500000001456512076170616020372 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Debug Tools ---------------------------------------------------------------------------------- --- Function colorizes all matched regex capture groups on the screen. --- This is very handy if you make complex regex and want to see what really matches in the text. --- --- @see matches function showCaptureGroups() for k, v in pairs ( matches ) do selectCaptureGroup( tonumber(k) ) setFgColor( math.random(0,255), math.random(0,255), math.random(0,255) ) setBgColor( math.random(0,255), math.random(0,255), math.random(0,255) ) end end --- Prints the content of the table multimatches[n][m] to the screen. This is meant --- as a tool to help write multiline trigger scripts. This helps you to easily see --- what your multiline trigger actually captured in all regex. You can use these values --- directly in your script by referring to it with multimatches[regex-number][capturegroup]. --- --- @usage Just call this s function from your trigger to show the info. ---
---   showMultimatches()
---   
--- --- @see multimatches function showMultimatches() echo("\n-------------------------------------------------------"); echo("\nThe table multimatches[n][m] contains:"); echo("\n-------------------------------------------------------"); for k,v in ipairs(multimatches) do echo("\nregex " .. k .. " captured: (multimatches["..k .."][1-n])"); for k2,v2 in ipairs(v) do echo("\n key="..k2.." value="..v2); end end echo("\n-------------------------------------------------------\n"); end --- get the Lua keywords as a set-like table. -- So res["and"] etc would be true. -- @return a table local function get_keywords () if not lua_keyword then lua_keyword = { ["and"] = true, ["break"] = true, ["do"] = true, ["else"] = true, ["elseif"] = true, ["end"] = true, ["false"] = true, ["for"] = true, ["function"] = true, ["if"] = true, ["in"] = true, ["local"] = true, ["nil"] = true, ["not"] = true, ["or"] = true, ["repeat"] = true, ["return"] = true, ["then"] = true, ["true"] = true, ["until"] = true, ["while"] = true } end return lua_keyword end local function quote_if_necessary (v) if not v then return '' else if v:find ' ' then v = '"'..v..'"' end end return v end local keywords local function is_identifier (s) return type(s) == 'string' and s:find('^[%a_][%w_]*$') and not keywords[s] end local function quote (s) if type(s) == 'table' then return prettywrite(s,'') else return ('%q'):format(tostring(s)) end end local function index (numkey,key) if not numkey then key = quote(key) end return '['..key..']' end --- Create a string representation of a Lua table. (From Steve Donovans Penlight library) -- This function never fails, but may complain by returning an -- extra value. Normally puts out one item per line, using -- the provided indent; set the second parameter to '' if -- you want output on one line. -- @param tbl {table} Table to serialize to a string. -- @param space {string} (optional) The indent to use. -- Defaults to two spaces; make it the empty string for no indentation -- @param not_clever {bool} (optional) Use for plain output, e.g {['key']=1}. -- Defaults to false. -- @return a string -- @return a possible error message local append = table.insert function prettywrite (tbl,space,not_clever) if type(tbl) ~= 'table' then if type(tbl) == "string" then return string.format("\"%s\"\n", tostring(tbl)) else return string.format("%s\n", tostring(tbl)) end end -- return a nice {} instead of {\n} on blanks if not next(tbl) then return '{}' end if not keywords then keywords = get_keywords() end local set = ' = ' if space == '' then set = '=' end space = space or ' ' local lines = {} local line = '' local tables = {} local function put(s) if #s > 0 then line = line..s end end local function putln (s) if #line > 0 then line = line..s append(lines,line) line = '' else append(lines,s) end end local function eat_last_comma () local n,lastch = #lines local lastch = lines[n]:sub(-1,-1) if lastch == ',' then lines[n] = lines[n]:sub(1,-2) end end local writeit writeit = function (t,oldindent,indent) local tp = type(t) if tp ~= 'string' and tp ~= 'table' then putln(quote_if_necessary(tostring(t))..',') elseif tp == 'string' then if t:find('\n') then putln('[[\n'..t..']],') else putln(quote(t)..',') end elseif tp == 'table' then if tables[t] then putln(',') return end tables[t] = true local newindent = indent..space putln('{') local used = {} if not not_clever then for i,val in ipairs(t) do put(indent) writeit(val,indent,newindent) used[i] = true end end for key,val in pairs(t) do local numkey = type(key) == 'number' if not_clever then key = tostring(key) put(indent..index(numkey,key)..set) writeit(val,indent,newindent) else if not numkey or not used[key] then -- non-array indices if numkey or not is_identifier(key) then key = index(numkey,key) end put(indent..key..set) writeit(val,indent,newindent) end end end tables[t] = nil eat_last_comma() putln(oldindent..'},') else putln(tostring(t)..',') end end writeit(tbl,'',space) eat_last_comma() return table.concat(lines,#space > 0 and '\n' or '') end function display(what) echo((prettywrite(what, ' ') or 'nil')..'\n') end mudlet-2.1/src/mudlet-lua/lua/StringUtils.lua0000644000175000017500000001076012070466512020600 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet String Utils ---------------------------------------------------------------------------------- --- Cut string to specified maximum length. --- --- @release post Mudlet 1.1.1 (TODO update before release) --- --- @usage Following call will return 'abc'. ---
---   string.cut("abcde", 3)
---   
--- @usage You can easily pad string to certain length. --- Example bellow will print 'abcde ' e.g. pad/cut string to 10 characters. ---
---   local s = "abcde"
---   s = string.cut(s .. "          ", 10)   -- append 10 spaces
---   echo("'" .. s .. "'")
---   
function string.cut(s, maxLen) if string.len(s) > maxLen then return string.sub(s, 1, maxLen) else return s end end --- Enclose string by long brackets.
function string.enclose(s, maxlevel) s = "["..s.."]" local level = 0 while 1 do if maxlevel and level == maxlevel then error( "error: maxlevel too low, "..maxlevel ) elseif string.find( s, "%["..string.rep( "=", level ).."%[" ) or string.find( s, "]"..string.rep( "=", level ).."]" ) then level = level + 1 else return "["..string.rep( "=", level )..s..string.rep( "=", level ).."]" end end end --- Test if string is ending with specified suffix. --- --- @see string.starts function string.ends(String, Suffix) return Suffix=='' or string.sub(String,-string.len(Suffix))==Suffix end --- Generate case insensitive search pattern from string. --- --- @release post Mudlet 1.1.1 (TODO update before release) --- --- @return case insensitive pattern string --- --- @usage Following example will generate and print "123[aA][bB][cC]" string. ---
---   echo(string.genNocasePattern("123abc"))
---   
function string.genNocasePattern(s) s = string.gsub(s, "%a", function (c) return string.format("[%s%s]", string.lower(c), string.upper(c)) end) return s end --- Return first matching substring or nil. --- --- @release post Mudlet 1.1.1 (TODO update before release) --- --- @return nil or first matching substring --- --- @usage Following example will print: "I did find: Troll" string. ---
---   local match = string.findPattern("Troll is here!", "Troll")
---   if match then
---      echo("I did find: " .. match)
---   end
---   
--- @usage This example will find substring regardless of case. ---
---   local match = string.findPattern("Troll is here!", string.genNocasePattern("troll"))
---   if match then
---      echo("I did find: " .. match)
---   end
---   
--- --- @see string.genNocasePattern function string.findPattern(text, pattern) if string.find(text, pattern, 1) then return string.sub(text, string.find(text, pattern, 1)) else return nil end end --- Splits a string into a table by the given delimiter. --- --- @usage Split string by ", " delimiter. ---
---   names = "Alice, Bob, Peter"
---   name_table = names:split(", ")
---   display(name_table)
---   
--- --- Previous code will print out: ---
---   table {
---     1: 'Alice'
---     2: 'Bob'
---     3: 'Peter'
---   }
---   
--- --- @return array with split strings function string:split(delimiter) local result = { } local from = 1 local delim_from, delim_to = string.find( self, delimiter, from ) while delim_from do table.insert( result, string.sub( self, from , delim_from-1 ) ) from = delim_to + 1 delim_from, delim_to = string.find( self, delimiter, from ) end table.insert( result, string.sub( self, from ) ) return result end --- Test if string is starting with specified prefix. --- --- @see string.ends function string.starts(String, Prefix) return string.sub(String,1,string.len(Prefix))==Prefix end --- Capitalize first character in a string. --- --- @usage Variable testname is now Anna. ---
---   testname = string.title("anna")
---   
--- @usage Example will set test to "Bob". ---
---   test = "bob"
---   test = string.title(test)
---   
function string:title() self = self:gsub("^%l", string.upper, 1) return self end --- Trim string (remove all white spaces around string). --- --- @release post Mudlet 1.1.1 (TODO update before release) --- --- @usage Example will print 'Troll is here!'. ---
---   local str = string.trim("  Troll is here!  ")
---   echo("'" .. str .. "'")
---   
function string.trim(s) if s then return string.gsub(s, "^%s*(.-)%s*$", "%1") else return s end end mudlet-2.1/src/mudlet-lua/lua/geyser/0000755000175000017500000000000012076170616017103 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/lua/geyser/GeyserLabel.lua0000644000175000017500000000727112070466512022010 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Represents a label like we all know and love. -- @class table -- @name Geyser.Label -- @field fillBg 1 if the background is to be filled, 0 for no background. Geyser.Label = Geyser.Window:new({ name = "LabelClass", format = "", args = "", fillBg = 1, }) --- Prints a message to the window. All parameters are optional and if not -- specified will use the last set value. -- @param message The message to print. Can contain html formatting. -- @param color The color to use. -- @param format A format list to use. 'c' - center, 'b' - bold, 'i' - italics, -- 'u' - underline, '##' - font size. For example, "cb18" -- specifies center bold 18pt font be used. Order doesn't matter. function Geyser.Label:echo(message, color, format) message = message or self.message self.message = self.message format = format or self.format self.format = format color = color or self.fgColor self.fgColor = color local fs = "" -- check for formatting commands if format then if string.find(format, "b") then message = "" .. message .. "" end if string.find(format, "i") then message = "" .. message .. "" end if string.find(format, "c") then message = "
" .. message .. "" end if string.find(format, "u") then message = "" .. message .. "" end fs = string.gmatch(format, "%d+")() if not fs then fs = tostring(self.fontSize) end fs = "font-size: " .. fs .. "pt; " end message = [[
]] .. message .. [[
]] echo(self.name, message) end function Geyser.Label:setFgColor(color) self:echo(nil,color,nil) end function Geyser.Label:setFormat(format) self:echo(nil,nil,format) end --- Sets a background image for this label. -- @param imageFileName The image to use for a background image. function Geyser.Label:setBackgroundImage (imageFileName) setBackgroundImage(self.name, imageFileName) end --- Sets a tiled background image for this label. -- @param imageFileName The image to use for a background image. function Geyser.Label:setTiledBackgroundImage (imageFileName) self:setStyleSheet("background-image: url(" .. imageFileName .. ");") end --- Sets a callback to be used when this label is clicked. -- @param func The function to use. -- @param ... Parameters to pass to the function. Must be strings or numbers. function Geyser.Label:setClickCallback (func, ...) setLabelClickCallback(self.name, func, ...) end --- Sets the style sheet of the label -- @param css The style sheet string function Geyser.Label:setStyleSheet(css) setLabelStyleSheet(self.name, css) end -- Save a reference to our parent constructor Geyser.Label.parent = Geyser.Window -- Overridden constructor function Geyser.Label:new (cons, container) -- Initiate and set label specific things cons = cons or {} cons.type = cons.type or "label" -- Call parent's constructor local me = self.parent:new(cons, container) -- Set the metatable. setmetatable(me, self) self.__index = self -- Create the label using primitives createLabel(me.name, me:get_x(), me:get_y(), me:get_width(), me:get_height(), me.fillBg) -- Set any defined colors Geyser.Color.applyColors(me) me:echo() -- Set up the callback if we have one if me.callback then me:setClickCallback(me.callback, me.args) end --print(" New in " .. self.name .. " : " .. me.name) return me end mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserGeyser.lua0000644000175000017500000000456712070466512022234 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --================================================== -- Create the Geyser Root Container --================================================== --- Create the Geyser namespace. -- Geyser is considered to be a "container window" for the purposes -- of default limits for new windows, in fact, it is the root container -- window, and is the metatable for Geyser.Container. It has the -- minimum number of functions needed to behave as a Container. Geyser = Geyser or {i = 0, x = 0, y = 0} --Layout policies. Fixed = Do not stretch/shrink, Dynamic = Do stretch/shrink Geyser.Fixed, Geyser.Dynamic = 0, 1 Geyser.width, Geyser.height = getMainWindowSize() Geyser.get_x = function () return 0 end Geyser.get_y = function () return 0 end Geyser.get_width = function () return getMainWindowSize() end Geyser.get_height = function () local w,h = getMainWindowSize() return h end Geyser.name = "Geyser Root Window" Geyser.__index = Geyser -- Create the window list for updates Geyser.windowList = Geyser.windowList or {} Geyser.windows = Geyser.windows or {} Geyser.defer_updates = false function Geyser:begin_update() self.defer_updates = true end function Geyser:end_update() self.defer_updates = false self:reposition() end function Geyser:reposition() if not self.defer_updates then GeyserReposition() end end --- Add a window to the list that this container manages. -- @param window The window to add this container function Geyser:add (window, cons) cons = cons or window -- 'cons' is optional -- Stop other container from controlling this window if window.container then window.container:remove(window) end -- Assume control of this window window.container = self self.windowList[window.name] = window table.insert(self.windows, window.name) Geyser.set_constraints(window, cons, self) if not self.defer_updates then window:reposition() end window:show() end --- Removes a window from the list that it manages -- @param window The window to remove from this container's -- windowList function Geyser:remove (window) self.windowList[window.name] = nil index = table.index_of(self.windows, window.name) or 0 table.remove(self.windows, index) end mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserGauge.lua0000644000175000017500000001065411560161350022013 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Represents a gauge that can be either vertical or horizontal. -- @class table -- @name Geyser.Gauge -- @field value Percentage value of how "full" the gauge is. -- @field orientation "horizontal" is the default and creates a horizontal -- gauge that fills from left to right. "vertical" creates -- a gauge that fills from bottom to top. "goofy" is -- horizontal but fills right to left. "batty" is -- vertical but fills from top to bottom. -- @field color Color base for this gauge. Default is #808080 Geyser.Gauge = Geyser.Container:new({ name = "GaugeClass", value = 100, -- ranges from 0 to 100 color = "#808080", orientation = "horizontal"}) --- Sets the gauge amount. -- @param currentValue Current numeric value, or if maxValue is ommitted, then -- it is assumed that currentValue is a value between 0 and 100 and is -- used to set the gauge. -- @param maxValue Maximum numeric value. Optionally nil, see above. -- @param text The text to display on the gauge, it is optional. function Geyser.Gauge:setValue (currentValue, maxValue, text) -- Use sensible defaults for missing parameters. if currentValue < 0 then currentValue = 0 end if maxValue then self.value = currentValue/maxValue * 100 else self.value = currentValue end -- Update gauge in the requested orientation local shift = tostring(self.value) .. "%" if self.orientation == "horizontal" then self.front:resize(shift, "100%") elseif self.orientation == "vertical" then self.front:move("0px", "-" .. shift) self.front:resize("100%", "-0px") -- bind to bottom container border elseif self.orientation == "goofy" then self.front:move("-" .. shift, "0px") self.front:resize("-0px", "100%") -- bind to right container border else -- batty self.front:resize("100%", shift) end if text then self.front:echo(text) self.back:echo(text) end end --- Sets the gauge color. -- @param r The red component, or a named color like "green". -- @param g the green component, or nil if using a named color. -- @param b the blue component, or nil if using a named color. -- @param text The text to display on the gauge, it is optional. function Geyser.Gauge:setColor (r, g, b, text) r,g,b = Geyser.Color.parse(r,g,b) self.front:setColor(r,g,b) self.back:setColor(r,g,b,100) if text then self.front:echo(text) self.back:echo(text) end end --- Sets the text on the gauge. -- @param text The text to set. function Geyser.Gauge:setText (text) if text then self.front:echo(text) self.back:echo(text) end end -- Sets the style sheet for the gauge -- @param css Style sheet for the front label -- @param cssback Style sheet for the back label function Geyser.Gauge:setStyleSheet(css, cssback) self.front:setStyleSheet(css) self.back:setStyleSheet(cssback or css) end -- Save a reference to our parent constructor Geyser.Gauge.parent = Geyser.Container -- Overridden constructor function Geyser.Gauge:new (cons, container) -- Initiate and set gauge specific things cons = cons or {} cons.type = cons.type or "gauge" -- Call parent's constructor local me = self.parent:new(cons, container) -- Set the metatable. setmetatable(me, self) self.__index = self ----------------------------------------------------------- -- Now create the Gauge using primitives and tastey classes -- Set up the constraints for the front label, the label that changes size to -- indicated levels in the gauges. local front = Geyser.copyTable(cons) front.name = me.name .. "_front" front.color = me.color front.x, front.y, front.width, front.height = 0,0,"100%","100%" -- Set up the constraints for the back label, which is always the size of the gauge. local back = Geyser.copyTable(front) back.name = me.name .. "_back" local br, bg, bb = Geyser.Color.parse(me.color) back.color = Geyser.Color.hexa(br,bg,bb,100) -- Create back first so that the labels are stacked correctly. me.back = Geyser.Label:new(back, me) me.front = Geyser.Label:new(front, me) --print(" New in " .. self.name .. " : " .. me.name) return me end mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserMiniConsole.lua0000644000175000017500000001073412076170616023211 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Represents a miniconsole primitive -- @class table -- @name Geyser.MiniConsole -- @field wrapAt Where line wrapping occurs. Default is 300 characters. Geyser.MiniConsole = Geyser.Window:new({ name = "MiniConsoleClass", wrapAt = 300,}) --- Replaces the currently selected text. -- @param with The text to use as a replacement. function Geyser.MiniConsole:replace (with) replace(self.name, with) end --- Sets the size of this miniconsole's buffer. -- @param linesLimit The number of lines to store - same limitations as Mudlet -- function of the same name. -- @param sizeOfBatchDeletion See Mudlet documentation. (I don't know offhand =) function Geyser.MiniConsole:setBufferSize (linesLimit, sizeOfBatchDeletion) setConsoleBufferSize(self.name, linesLimit, sizeOfBatchDeletion) end --- Sets the point at which text is wrapped in this miniconsole -- @param wrapAt The number of characters to start wrapping. function Geyser.MiniConsole:setWrap (wrapAt) if wrapAt then self.wrapAt = wrapAt end setWindowWrap(self.name, self.wrapAt) end --- Sets the text format for this window. Note that the *echo() -- functions will override these settings. -- @param r1 The red foreground component. -- @param g1 The green foreground component. -- @param b1 The blue foreground component. -- @param r2 The red background component. -- @param g2 The green background component. -- @param b2 The blue background component. -- @param bold The bolded status. 1 is bold, 0 is normal. -- @param underline The underlined status. 1 is underlined, 0 is normal. -- @param italics The italicized status. 1 is italicized, 0 is normal. function Geyser.MiniConsole:setTextFormat(r1, g1, b1, r2, g2, b2, bold, underline, italics) setTextFormat(self.name, r1, g1, b1, r2, g2, b2, bold, underline, italics) end --- Sets bold status for this miniconsole -- @param bool True for bolded function Geyser.MiniConsole:setBold(bool) setBold(self.name, val) end --- Sets underline status for this miniconsole -- @param bool True for underlined function Geyser.MiniConsole:setUnderline(bool) setUnderline(self.name, val) end --- Sets italics status for this miniconsole -- @param bool True for italicized function Geyser.MiniConsole:setItalics(bool) setItalics(self.name, val) end --- Sets the font size for this miniconsole. -- @param size The font size. function Geyser.MiniConsole:setFontSize(size) self.parent:setFontSize(size) setMiniConsoleFontSize(self.name, size) end --- Appends copied selection to this miniconsole. function Geyser.MiniConsole:appendBuffer() appendBuffer(self.name) end --- sets the current foreground color of cursor in this miniconsole. function Geyser.MiniConsole:fg(color) fg(self.name, color) end --- sets the current background color of cursor in this miniconsole. function Geyser.MiniConsole:bg(color) bg(self.name, color) end --- inserts clickable text into the miniconsole at the end of the current line function Geyser.MiniConsole:echoLink(...) echoLink(self.name, ...) end --- inserts clickable text into the miniconsole at the current cursor position function Geyser.MiniConsole:insertLink(...) insertLink(self.name, ...) end --- turns selected text info clickable text into the miniconsole function Geyser.MiniConsole:setLink(...) setLink(self.name, ...) end -- Save a reference to our parent constructor Geyser.MiniConsole.parent = Geyser.Window -- Overridden constructor function Geyser.MiniConsole:new (cons, container) -- Initiate and set gauge specific things cons = cons or {} cons.type = cons.type or "miniConsole" -- Call parent's constructor local me = self.parent:new(cons, container) -- Set the metatable. setmetatable(me, self) self.__index = self ----------------------------------------------------------- -- Now create the MiniConsole using primitives createMiniConsole(me.name, me:get_x(), me:get_y(), me:get_width(), me:get_height()) -- Set any defined colors Geyser.Color.applyColors(me) if cons.wrapAt then me:setWrap(cons.wrapAt) end if cons.fontSize then me:setFontSize(cons.fontSize) elseif container then me:setFontSize(container.fontSize) else me:setFontSize(8) end --print(" New in " .. self.name .. " : " .. me.name) return me end mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserMapper.lua0000644000175000017500000000302411624306130022176 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- createMapper support by Vadi -- -- -- -------------------------------------- --- Represents a mapper primitive -- @class table -- @name Geyser.Mapper -- @field wrapAt Where line wrapping occurs. Default is 300 characters. Geyser.Mapper = Geyser.Window:new({ name = "MapperClass" }) -- Save a reference to our parent constructor Geyser.Mapper.parent = Geyser.Window -- Overridden reposition function - mapper does it differently right now function Geyser.Mapper:reposition() if self.hidden then return end createMapper(self:get_x(), self:get_y(), self:get_width(), self:get_height()) end function Geyser.Mapper:hide_impl() createMapper(self:get_x(), self:get_y(), 0, 0) end function Geyser.Mapper:show_impl() createMapper(self:get_x(), self:get_y(), self:get_width(), self:get_height()) end -- Overridden constructor function Geyser.Mapper:new (cons, container) cons = cons or {} cons.type = cons.type or "mapper" -- Call parent's constructor local me = self.parent:new(cons, container) me.was_hidden = false -- Set the metatable. setmetatable(me, self) self.__index = self ----------------------------------------------------------- -- Now create the Mapper using primitives createMapper(me:get_x(), me:get_y(), me:get_width(), me:get_height()) -- Set any defined colors Geyser.Color.applyColors(me) --print(" New in " .. self.name .. " : " .. me.name) return me endmudlet-2.1/src/mudlet-lua/lua/geyser/GeyserUtil.lua0000644000175000017500000000273211563331411021676 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Generate a window name unique to this session. function Geyser.nameGen (type) local index = Geyser.i local t = type or "window" Geyser.i = Geyser.i + 1 return "anon_" .. t .. "_" .. index end --- Hide all managed windows. function Geyser.hideAll(type) for _,v in pairs(Geyser.windowList) do if v.type == type or not type then v:hide() end end end --- Show all managed windows. function Geyser.showAll(type) for _,v in pairs(Geyser.windowList) do if v.type == type or not type then v:show() end end end --- Non-recursive display of an item, because the normal 'display' was -- causing Mudlet to hang. Not sure why. function Geyser.display (table) echo("------ " .. type(table) .. " ------\n") if type(table) == "table" then for k,v in pairs(table) do echo("'" .. tostring(k) .. "' - " .. tostring(v) .. "\n") end else echo(tostring(table) .. "\n") end end --- Clone a table, for good fun and profit. function Geyser.copyTable (table) local copy = {} if table then for k,v in pairs(table) do -- do deep copy on a table if it requests one by having the __clone function defined. if type(v) == "table" and v.__clone then copy[k] = v.__clone() else copy[k] = v end end end return copy end mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserVBox.lua0000644000175000017500000000306511624306130021635 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -- VBox by Beliar -- -- -- -------------------------------------- Geyser.VBox = Geyser.Container:new({ name = "VBoxClass" }) function Geyser.VBox:add (window, cons) Geyser.add(self, window, cons) if not self.defer_updates then self:reposition() end end --- Responsible for placing/moving/resizing this window to the correct place/size. -- Called on window resize events. function Geyser.VBox:reposition() self.parent:reposition() local window_height = self:calculate_dynamic_window_size().height local start_y = 0 for _, window_name in ipairs(self.windows) do local window = self.windowList[window_name] window:move(0, start_y) local width = window.width local height = window.height if window.h_policy == Geyser.Dynamic then width = self:get_width() end if window.v_policy == Geyser.Dynamic then height = window_height * window.v_stretch_factor end window:resize(width, height) start_y = start_y + window:get_height() end end Geyser.VBox.parent = Geyser.Container function Geyser.VBox:new(cons, container) -- Initiate and set Window specific things cons = cons or {} cons.type = cons.type or "VBox" -- Call parent's constructor local me = self.parent:new(cons, container) setmetatable(me, self) self.__index = self return me endmudlet-2.1/src/mudlet-lua/lua/geyser/GeyserContainer.lua0000644000175000017500000002366412070466512022717 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Represents a generic container with positional information. -- Has no notion of contents and is used to contain other windows -- and impose some sense of order. -- @class table -- @name Geyser.Container -- @field parent The parent class of this window -- @field type The type of this window, usually lowercase of the classname and -- can be used in checks for certain types. For a Container -- instance, type is “container.” -- @field name The name of this window. This is the same name that Mudlet will -- use internally for primitive types like labels and -- miniconsoles. If not specified in the constraints table during -- creation, an anonymous name unique to this session will be -- made up. -- @field x The x-coordinate relative to this window's container, not absolute -- from the Mudlet main window. This is not a number, but a -- constraint specification. To find out the numeric x-coordinate in -- terms of pixels from the Mudlet main window's origin, use the -- get_x() method. Default is "10px". -- @field y The y-coordinate relative to this window's container, not absolute -- from the Mudlet main window. This is not a number, but a -- constraint specification. To find out the numeric y-coordinate in -- terms of pixels from the Mudlet main window's origin, use the -- get_y() method. Default is "10px". -- @field width The width of this window, possibly relative to the window's -- container. This is not a number, but a constraint -- specification. To find out the numeric width in terms of -- pixels, use the get_width() method. Default is "300px". -- @field height The height of this window, possibly relative to the window's -- container. This is not a number, but a constraint -- specification. To find out the numeric width in terms of -- pixels, use the get_width() method. Default is "200px". -- @field windowList This is a list of all windows held by this container. It -- used to handle proper resizing of held windows as well as -- during show()s and hide()s to recursive show and hide all -- children windows. -- @field windows This is an ordered list of the names of the window held by this container. -- @field fontSize The default size font used when calculating dimensions -- based on the character constraint. Default is 8. -- @field h_policy This sets if this widget should be stretched/shrinked horizontally or not -- @field v_policy This sets if this widget should be stretched/shrinked vertically or not -- @field v_stretch_factor This sets by how much more then window will be stretched horizontally in comparison to -- other windows -- @field v_stretch_factor This sets by how much more then window will be stretched vertically in comparison to -- other windows Geyser.Container = { name = "ContainerClass", x = "10px", y = "10px", height = "200px", width = "300px", windowList = {}, windows = {}, fontSize = 8, h_policy = Geyser.Dynamic, v_policy = Geyser.Dynamic, h_stretch_factor = 1.0, v_stretch_factor = 1.0, } function Geyser.Container:calculate_dynamic_window_size() local total_count = #self.windows local fixed_horizontal_count = 0 local fixed_vertical_count = 0 local fixed_width_sum = 0 local fixed_height_sum = 0 local ret_size = {} ret_size.width = self.get_width() ret_size.height = self.get_height() local dynamic_horizontal_count = 0.0 local dynamic_vertical_count = 0.0 if total_count <= 1 then --If there is only one window it can have all the width/height, if there are none then it doesn't matter return ret_size end for _, window in pairs(self.windowList) do if window.h_policy == Geyser.Fixed then fixed_horizontal_count = fixed_horizontal_count + 1 fixed_width_sum = fixed_width_sum + window.get_width() else dynamic_horizontal_count = dynamic_horizontal_count + window.h_stretch_factor - 1.0 end if window.v_policy == Geyser.Fixed then fixed_vertical_count = fixed_vertical_count + 1 fixed_height_sum = fixed_height_sum + window.get_height() else dynamic_vertical_count = dynamic_vertical_count + window.v_stretch_factor - 1.0 end end dynamic_horizontal_count = dynamic_horizontal_count + total_count - fixed_horizontal_count dynamic_vertical_count = dynamic_vertical_count + total_count - fixed_vertical_count if dynamic_horizontal_count == 0 then ret_size.width = 0 else ret_size.width = (self.get_width() - fixed_width_sum) / dynamic_horizontal_count end if dynamic_vertical_count == 0 then ret_size.height = 0 else ret_size.height = (self.get_height() - fixed_height_sum) / dynamic_vertical_count end return ret_size end --- Responsible for placing/moving/resizing this window to the correct place/size. -- Called on window resize events. function Geyser.Container:reposition () local x,y,w,h = self:get_x(), self:get_y(), self:get_width(), self:get_height() moveWindow(self.name, self:get_x(), self:get_y()) resizeWindow(self.name, self:get_width(), self:get_height()) -- deal with all children of this container for k,v in pairs(self.windowList) do if k ~= self then v:reposition() end end -- Calls optional redraw method if it is available to cause a gui element to -- redraw itself after moving. if self.redraw then self:redraw() end end --- Hides this window and all its contained windows. function Geyser.Container:hide (auto) if not (self.hidden or self.auto_hidden) then self:hide_impl() end auto = auto or false if auto then self.auto_hidden=true else self.hidden=true end for _,v in pairs(self.windowList) do v:hide(true) end end function Geyser.Container:hide_impl() hideWindow(self.name) end --- Shows this window and all windows it contains. function Geyser.Container:show (auto) auto = auto or false if auto then self.auto_hidden=false else self.hidden=false end if not self.hidden and not self.auto_hidden then self:show_impl() end for _,v in pairs(self.windowList) do v:show(true) end end function Geyser.Container:show_impl() showWindow(self.name) end --- Moves this window according to the new x and y contraints set. -- @param x New x constraint to use. If nil, uses current value. -- @param y New y constraint to use. If nil, uses current value. function Geyser.Container:move (x, y) self.x = x or self.x self.y = y or self.y self:set_constraints(self) end --- Resizes this window according to the new width and height constraints set. -- @param width New width constraint to use. If nil, uses current value. -- @param height New height constraint to use. If nil, uses current value. function Geyser.Container:resize (width, height) self.width = width or self.width self.height = height or self.height self:set_constraints(self) end --- Sets the default font size for this window. -- Will resizes this window if necessary to meet constraints. -- @param fontSize The new font size to use. function Geyser.Container:setFontSize (fontSize) if type(fontSize) ~= "number" then error("fontSize must be a number") return end self.fontSize = fontSize or self.fontSize self:set_constraints() end --- Sets all contraints (x, y, width, height) for this window. -- @param cons Any Lua table that contains appropriate constraint entries. function Geyser.Container:set_constraints (cons) cons = cons or self Geyser.set_constraints(self, cons, self.container) for k,v in pairs(self.windowList) do v:set_constraints(v) end end --- Flashes a white box over the dimensions of this container. -- This is very useful to see where a container actually is if you've -- forgotten its details. -- @param time Time in seconds to flash for, default is 1.0s. function Geyser.Container:flash (time) local time = time or 1.0 local x, y, width, height = self.get_x(), self.get_y(), self.get_width(), self.get_height() local name = self.name .. "_dimensions_flash" createLabel(name, x, y, width, height, 1) resizeWindow(name, width, height) moveWindow(name, x, y) setBackgroundColor(name, 190, 190, 190, 128) showWindow(name) tempTimer(time, "hideWindow(\"" .. name .. "\")") end Geyser.Container.parent = Geyser.Container -- I'm my own grandpa too! -- Someone has to be the root! setmetatable(Geyser.Container, Geyser) --- Constructor for containers. -- This function creates a new container/window -- @param cons Any Lua table that contains appropriate constraint entries. -- Include any parameter such as name or fontSize in cons -- that are to be used for the new window. function Geyser.Container:new(cons, container) -- create new table for the container and copy over constraints local me = Geyser.copyTable(cons) -- enforce a default type, name and parent me.type = me.type or "container" me.name = me.name or Geyser.nameGen() me.windowList = {} me.windows = {} me.hidden = false me.auto_hidden = false -- Set the metatable. setmetatable(me, self) self.__index = self -- If we're not not a class definition then add to a controlling -- container. if not string.find(me.name, ".*Class") then -- If passed in a container, add me to that container if container then container:add(me) else -- Else assume the root window is my container Geyser:add(me) end end --print("New in " .. self.name .. " : " .. me.name) return me end mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserTests.lua0000644000175000017500000001351511520630027022062 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- -- TESTS FOR GEYSER -- --- Test labels. Creates 101 Labels of varying hue and transparency. function Geyser.testLabels() labelTestContainer = Geyser.Container:new({x=0,y=0,width="100%",height="100%",name="labelTestContainer"}) for i=0,90,10 do for j=0,90,10 do local myName = "TestLabel_" .. i .. "_" .. j local l = Geyser.Label:new({ name = myName, x = i .. "%", y = j .. "%", width = "8%", height = "8%", message = myName, fgColor = "white"}, labelTestContainer) l:setColor(i,j,100, i*j/8100 * 128 + 127) end end Geyser.Label:new({ name = "Clickable", fontSize = 22, message = [[

Click me

]], x = "53%", y = "53%", width = "-40px", height = "-3c", backgroundAlpha = 240, callback = "echo", args = "You Clicked Me!!\n"}, labelTestContainer) end --- Test gauges. Creates 100 gauges of varying fullness. function Geyser.testGauges() gaugeTestContainer = Geyser.Container:new({x=0,y=0,width="100%",height="100%",name="gaugeTestContainer"}) for i=0,90,10 do for j=0,90,10 do local myName = "TestGauge_" .. i .. "_" .. j local g = Geyser.Gauge:new({name = myName, x = i .. "%", y = j .. "%", width = "9%", height = "9%", message = myName, fgColor = "red",}, gaugeTestContainer) g:setValue(1.0 * i) --g:setText(myName) end end end --- Used by Geyser.demo1(). Sorry about the namespace polution, -- but callbacks can't use functions contained in a table. Anyway, -- it just echoes some status info to the two miniconsoles. function demoCallback1 (value) local g1 = geyserDemoContainer.windowList.myGauge local g2 = geyserDemoContainer.windowList.myGoofyGauge local c1 = geyserDemoContainer.windowList["console 1"] local c2 = geyserDemoContainer.windowList["console 2"] g1:setValue((g1.value - value) % 100) g2:setValue((g2.value - 2*value) % 100) local v1 = tostring(g1.value) local v2 = tostring(g2.value) c1:decho(string.format("<90,90,%d> You are at %d \n", v1, v1)) c2:decho(string.format("<90,%d,%d> You are at %d \n", 255-v2, v2, v2)) end local myDemoState = 0 --- Used by Geyser.demo1(). It moves the location of the -- container window. Look how easy it is to shift around all those -- gui elements! function demoCallback2 () if myDemoState == 0 then geyserDemoContainer:resize(nil, "50%") geyserDemoContainer:move("-90c") myDemoState = 1 else geyserDemoContainer:resize(nil, "100%") geyserDemoContainer:move("-42c") myDemoState = 0 end end --- This demonstrates some of the neat features in Geyser. function Geyser.demo1() ---------------------------------------- -- 1. Create a container on the left side of the screen wide -- enough for 40 characters geyserDemoContainer = Geyser.Container:new( { x = "-42c", y = "0px", width = "40c", height = "100%", name = "myContainer"}) ---------------------------------------- -- 2. Add a miniconsole to the top of the container, -- full width, with 20 lines of text local console1 = Geyser.MiniConsole:new( { x = "0px", y = "0px", width = "100%", height = "20c", name = "console 1"}, geyserDemoContainer) -- add console1 to container directly console1:setColor(80,40,20,255) console1:echo("Go ahead - resize the Mudlet window\n") ---------------------------------------- -- 3. Add two gauges and a clickable label just below the -- miniconsole local g1 = Geyser.Gauge:new( { x = "0px", y = console1.height, width = "60%", height = "4c", orientation = "batty", color = "violet", name = "myGauge"}) g1:setValue(77) geyserDemoContainer:add(g1) -- add gauge after creation local g2 = Geyser.Gauge:new( { x = "10%", y = console1.height, width = "50%", height = "4c", orientation = "goofy", name = "myGoofyGauge"}, geyserDemoContainer) -- add gauge directly g2:setValue(55) g2:setColor("cyan") local label1 = Geyser.Label:new( { x = g1.width, y = console1.height, width = "40%", height = "4c", name = "label with callback", callback = "demoCallback1", args=5, fontSize = 8, fgColor = "white", message = "Click me"}) geyserDemoContainer:add(label1) -- you know the drill ---------------------------------------- -- 4. Add another miniconsole below the gauge that extends -- to the bottom of the screen and wraps at 40 characters and -- another clickable label. echo("adfa\n") local console2 = Geyser.MiniConsole:new({ x = "0px", y = "24c", width = "100%", height = "-0px", name = "console 2", wrapAt = 40, color = "<10,20,40>",}, geyserDemoContainer) -- add console2 to geyserDemoContainer directly console2:echo("Vampire Gauges!\n") local label2 = Geyser.Label:new( { x = g1.width, y = "60%", width = "40%", height = "4c", name = "label with another callback and a long name!", callback = "demoCallback2", message = [[
and me
]]}) geyserDemoContainer:add(label2) -- same here ---------------------------------------- -- 5. hide all windows just created geyserDemoContainer:hide() ---------------------------------------- -- 6. now show them again geyserDemoContainer:show() end mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserWindow.lua0000644000175000017500000001240411520630027022223 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- local cparse = Geyser.Color.parse --- Represents an abstract window class designed to be subclassed for windows -- that are built on Mudlet primitives, like labels. -- @class table -- @name Geyser.Window -- @field message The message last *echo()'d to this window. Default is “”. -- @field bgColor Text background color, default "white" -- @field fgColor Text foreground color, default "black" -- @field color Window background color, default "#202020" Geyser.Window = Geyser.Container:new({ name = "WindowClass", message = "", -- default colors. The are boring fgColor = "white", bgColor = "black", color = "#202020", }) -- Add regular window methods, these are mostly just OO-ized wrappers --- Prints a message to the window -- @param message The message to print. Can contain html formatting. function Geyser.Window:echo(message) self.message = message echo(self.name, self.message) end --- Prints a message to the window. -- @param message The message to print. Uses color formatting information - -- a message of "Hi" would make 'Hi' red. function Geyser.Window:cecho(message) self.message = message or self.message cecho(self.name, self.message) end --- Prints a message to the window. -- @param message The message to print. Uses color formatting information - -- a message of "<255,0,0>Hi" would make 'Hi' red. function Geyser.Window:decho(message) self.message = message or self.message decho(self.name, self.message) end --- Prints a message to the window. -- @param message The message to print. Uses color formatting information - -- a message of "|cff0000Hi" would make 'Hi' red. function Geyser.Window:hecho(message) self.message = message or self.message hecho(self.name, self.message) end --- Get the window's foreground color. -- @return The foreground color of this window primitive as a Geyser.Color object. function Geyser.Window:getFgColor () return getFgColor(self.name) end --- Get the window's background color -- @return The background color of this window primitive as a Geyser.Color object. function Geyser.Window:getBgColor () return getBgColor(self.name) end --- Sets the background color of this window primitive. If this primitive -- was using a shared color, then it creates a new, personal color. -- @param r The red value, or a quoted color name, like "green". -- @param g The green value, or nil if using a name. -- @param b The blue value, or nil if using a name. function Geyser.Window:setBgColor (r,g,b) setBgColor(self.name, cparse(r,g,b)) end --- Sets the foreground color of this window primitive. If this primitive -- was using a shared color, then it creates a new, personal color. -- @param r The red value, or a quoted color name, like "green". -- @param g The green value, or nil if using a name. -- @param b The blue value, or nil if using a name. function Geyser.Window:setFgColor (r,g,b) setFgColor(self.name, cparse(r,g,b)) end --- Sets the background color and alpha. If this primitive -- was using a shared color, then it creates a new, personal color. -- @param r The red component of the color, or a named color like "green". -- @param g The green component, or nil if using named colors. -- @param b The blue component, or nil if using named colors. -- @param a The alpha component. If nil, uses current alpha value. function Geyser.Window:setColor (r,g,b,a) setBackgroundColor(self.name, cparse(r,g,b,a)) end --- Pastes text from the clipboard into this window primitive. function Geyser.Window:paste () paste(self.name) end --- Sets the text format for this window. Note that the *echo() -- functions will override these settings. -- @param r1 The red foreground component. -- @param g1 The green foreground component. -- @param b1 The blue foreground component. -- @param r2 The red background component. -- @param g2 The green background component. -- @param b2 The blue background component. -- @param bold The bolded status. 1 is bold, 0 is normal. -- @param underline The underlined status. 1 is underlined, 0 is normal. -- @param italics The italicized status. 1 is italicized, 0 is normal. function Geyser.Window:setTextFormat(r1, g1, b1, r1, g2, b2, bold, underline, italics) setTextFormat(self.name, r1, g1, b1, r1, g2, b2, bold, underline, italics) end --- Sets bolded text. -- @param bool True for bold. function Geyser.Window:setBold(bool) setBold(self.name, bool) end --- Sets underlined text. -- @param bool True for underlined. function Geyser.Window:setUnderline(bool) setUnderline(self.name, bool) end --- Sets italicized text. -- @param bool True for italicized. function Geyser.Window:setItalics(bool) setItalics(self.name, bool) end -- Save a reference to our parent's constructor Geyser.Window.parent = Geyser.Container function Geyser.Window:new (cons, container) -- Initiate and set Window specific things cons = cons or {} cons.type = cons.type or "window" -- Call parent's constructor local me = self.parent:new(cons, container) -- Set the metatable. setmetatable(me, self) self.__index = self --print(" New in " .. self.name .. " : " .. me.name) return me end mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserSetConstraints.lua0000644000175000017500000001255112070466512023751 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- This function sets the constraints of a window. -- It doesn't mess with anything other than positioning data. It -- creates get_x(), get_y(), get_width(), and get_height() functions -- for 'window' -- @param window The window to create the constraints for. -- @param cons A table that holds the constraints. -- @param container A table that holds maximum position values and -- represents the dimensions of the "window" that holds whatever -- widget is being created. function Geyser.set_constraints (window, cons, container) oldlocale = os.setlocale(nil, "numeric") os.setlocale("C", "numeric") -- If container is nil then by default it is the dimensions of the main window container = container or Geyser -- GENERATE CONSTRAINT AWARE POSITIONING FUNCTIONS -- Parse the position constraints to generate functions that will get -- window dimensions according to those constraints. Also, update position -- information. The order that the dimensions are specified in the for -- loop is important so that get_x() and get_y() are defined before they -- needed by width and height. for _,v in ipairs{"x", "y", "width", "height"} do local getter = "get_" .. v -- name of the function to calculate the -- if passed a number assume pixels are meant if type(cons[v]) == "number" then cons[v] = string.format("%dpx", cons[v]) end -- Parse the constraint if string.find(cons[v], "%%") then -- This handles dimensions as a percentage of the container. -- Negative percentages are converted to the equivalent positive. -------------------------------------------------------------- -- scale is a value between 0 and 1 local scale = tonumber((string.gsub(cons[v], "%%", ""))) / 100.0 if scale < 0 then scale = 1 + scale end local dim = "" local min, max = 0,0 if v == "x" then min = "container.get_x()" max = "container.get_width()" elseif v == "width" then max = "container.get_width()" elseif v == "y" then min = "container.get_y()" max = "container.get_height()" else max = "container.get_height()" end -- Define the getter function -- Heiko: on European locales this leads to compile errors because -- scale will be "0,5" instead of "0.5"-> syntax error -- Need to find out if there's more such cases in Geyse -- Need to find out if there's more such cases in Geyser h_scale = tostring(scale) local src = "local self,container = ... return function () return " .. min .. " + (" .. h_scale .. " * " .. max .. ") end" -- compile the getter window[getter] = assert(loadstring(src, "getter for " .. v))(window,container) else -- This handles absolute positioning and character positioning -- Negative values indicated positioning from the anti-origin. -- Pre: cons[v] must contain "px" or "c" -------------------------------------------------------------- -- Create default values local x_mult, y_mult = 1,1 -- by default assume not "c" local negative = string.find(cons[v], "-") or false -- detect "negative" 0 -- As is, font size is considered a constraint if string.find(cons[v], "c") then x_mult, y_mult = calcFontSize(window.fontSize) end local pos = tonumber((string.gsub(cons[v], "%a", ""))) local max = 0 local min = 0 if v == "x" then min = "container.get_x()" pos = x_mult * pos elseif v == "width" then pos = x_mult * pos elseif v == "y" then min = "container.get_y()" pos = y_mult * pos else pos = y_mult * pos end -- Treat negative values differently if negative then if v == "x" then min = "container.get_x()" max = "container.get_width()" elseif v == "width" then min = "container.get_x()" max = "container.get_width()" pos = string.format("(%d - self:get_x())", pos) elseif v == "y" then min = "container.get_y()" max = "container.get_height()" else -- v == "height" min = "container.get_y()" max = "container.get_height()" pos = string.format("(%d - self:get_y())", pos) end end -- Define the getter function local src = "local self, container = ... return function () return " .. max .. " + " .. min .. " + " .. pos .. " end" -- compile the getter window[getter] = assert(loadstring(src, "getter for " .. v))(window, container) end -- Here the actual value of the dimension is set according to the -- constraints requested. --window[v] = window[getter]() end -- END for that generates POSITION FUNCTIONS os.setlocale(oldlocale, "numeric") window:reposition() end mudlet-2.1/src/mudlet-lua/lua/geyser/Geyser.lua0000644000175000017500000000135411520630027021035 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- -- -- Load code in following order: -- Geyser.lua -- GeyserGeyser.lua -- GeyserUtil.lua -- GeyserColor.lua -- GeyserSetConstraints.lua -- GeyserContainer.lua -- GeyserWindow.lua -- GeyserLabel.lua -- GeyserGauge.lua -- GeyserMiniConsole.lua -- GeyserMapper.lua -- GeyserReposition.lua -- GeyserTests.lua -- UNCOMMENT EVERYTHING BELOW THIS LINE FOR VERSIONS PRIOR TO 1.1.0 --myoldresizer = myoldresizer or handleWindowResizeEvent --function handleWindowResizeEvent() -- raiseEvent("sysWindowResizeEvent") --end mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserReposition.lua0000644000175000017500000000075511561116467023131 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Responds to sysWindowResizeEvent and causes all windows managed -- by Geyser to update their sizes and positions. function GeyserReposition() for _,window in pairs(Geyser.windowList) do window:reposition() end end registerAnonymousEventHandler("sysWindowResizeEvent", "GeyserReposition") mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserColor.lua0000644000175000017500000001356311520630027022041 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- Geyser.Color = {} --- Converts color to 3 hex values as a string, no alpha, css style -- @return The color formatted as a hex string, as accepted by html/css function Geyser.Color.hex (r,g,b) return string.format("#%02x%02x%02x", Geyser.Color.parse(r, g, b)) end --- Converts color to 4 hex values as a string, with alpha, css style -- @return The color formatted as a hex string, as accepted by html/css function Geyser.Color.hexa (r,g,b,a) return string.format("#%02x%02x%02x%02x", Geyser.Color.parse(r, g, b, a)) end --- Converts color to 3 hex values as a string, no alpha, hecho style -- @return The color formatted as a hex string, as accepted by hecho function Geyser.Color.hhex (r,g,b) return string.format("|c%02x%02x%02x", Geyser.Color.parse(r, g, b)) end --- Converts color to 4 hex values as a string, with alpha, hecho style -- @return The color formatted as a hex string, as accepted by hecho function Geyser.Color.hhexa (r,g,b,a) return string.format("|c%02x%02x%02x%02x", Geyser.Color.parse(r, g, b, a)) end --- Converts color to 3 decimal values as a string, no alpha, decho style -- @return The color formatted as a decho() style string function Geyser.Color.hdec (r,g,b) return string.format("<%d,%d,%d>", Geyser.Color.parse(r, g, b)) end --- Converts color to 4 decimal values as a string, with alpha, decho style -- @return The color formatted as a decho() style string function Geyser.Color.hdeca (r,g,b,a) return string.format("<%d,%d,%d,%d>", Geyser.Color.parse(r, g, b, a)) end --- Returns 4 color components from (nearly any) acceptable format. Colors can be -- specified in two ways. First: as a single word in english ("purple") or -- hex ("#AA00FF", "|cAA00FF", or "0xAA00FF") or decimal ("<190,0,255>"). If -- the hex or decimal representations contain a fourth element then alpha is -- set too - otherwise alpha can't be set this way. Second: by passing in -- distinct components as unsigned integers (e.g. 23 or 0xA7). When using the -- second way, at least three values must be passed. If only three are -- passed, then alpha is 255. Third: by passing in a table that has explicit -- values for some, all or none of the keys r,g,b, and a. -- @param red Either a valid string representation or the red component. -- @param green The green component. -- @param blue The blue component. -- @param alpha The alpha component. function Geyser.Color.parse(red, green, blue, alpha) local r,g,b,a = 0,0,0,255 -- have to have something to set, else can't do anything! if not red then print("No color supplied.\n") return end -- function to return next number local next_num = nil local base = 10 -- assigns all the colors, used after we figure out how the color is -- represented as a string local assign_colors = function () r = tonumber(next_num(), base) g = tonumber(next_num(), base) b = tonumber(next_num(), base) local has_a = next_num() if has_a then a = tonumber(has_a, base) end end -- Check if we were passed a string or table that needs to be parsed, i.e., -- there is only a valid red value, and other params are nil. if not green or not blue then if type(red) == "table" then -- Here just copy over the appropriate values with sensible defaults r = red.r or 127 g = red.g or 127 b = red.b or 127 a = red.a or 255 return r,g,b,a elseif type(red) == "string" then -- first case is a hex string, where first char is '#' if string.find(red, "^#") then local pure_hex = string.sub(red, 2) -- strip format char next_num = string.gmatch(pure_hex, "%w%w") base = 16 -- second case is a hex string, where first chars are '|c' or '0x' elseif string.find(red, "^[|0][cx]") then local pure_hex = string.sub(red, 3) -- strip format chars next_num = string.gmatch(pure_hex, "%w%w") base = 16 -- third case is a decimal string, of the format "" elseif string.find(red, "^<") then next_num = string.gmatch(red, "%d+") -- fourth case is a named string elseif color_table[red] then local i = 0 local n = #color_table[red] next_num = function () -- create a simple iterator i = i + 1 if i <= n then return color_table[red][i] else return nil end end else -- finally, no matches, do nothing return end end else -- Otherwise we weren't passed a complete string, but instead discrete -- components as either decimal or hex -- Yes, this is a little silly to do this way, but it fits with the -- rest of the parsing going on... local i = 0 next_num = function () i = i + 1 if i == 1 then return red elseif i == 2 then return green elseif i == 3 then return blue elseif i == 4 then return alpha else return nil end end end assign_colors() return r,g,b,a end --- Applies colors to a window drawing from defaults and overridden values. -- @param cons The window to apply colors to function Geyser.Color.applyColors(cons) cons:setFgColor(cons.fgColor) cons:setBgColor(cons.bgColor) cons:setColor(cons.color) end mudlet-2.1/src/mudlet-lua/lua/geyser/GeyserHBox.lua0000644000175000017500000000310711624306130021614 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -- HBox by Beliar -- -- -- -------------------------------------- Geyser.HBox = Geyser.Container:new({ name = "HBoxClass" }) function Geyser.HBox:add (window, cons) Geyser.add(self, window, cons) if not self.defer_updates then self:reposition() end end --- Responsible for placing/moving/resizing this window to the correct place/size. -- Called on window resize events. function Geyser.HBox:reposition() self.parent:reposition() local window_width = self:calculate_dynamic_window_size().width local start_x = 0 for _, window_name in ipairs(self.windows) do local window = self.windowList[window_name] local width = window.width local height = window.height window:move(start_x, 0) if window.h_policy == Geyser.Dynamic then width = window_width * window.h_stretch_factor end if window.v_policy == Geyser.Dynamic then height = self:get_height() end window:resize(width, height) start_x = start_x + window:get_width() end end Geyser.HBox.parent = Geyser.Container function Geyser.HBox:new(cons, container) -- Initiate and set Window specific things cons = cons or {} cons.type = cons.type or "hbox" -- Call parent's constructor local me = self.parent:new(cons, container) setmetatable(me, self) self.__index = self me:reposition() return me endmudlet-2.1/src/mudlet-lua/lua/Other.lua0000644000175000017500000003752112070466512017376 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Unsorted Stuff ---------------------------------------------------------------------------------- -- Extending default libraries makes Babelfish happy. setmetatable( _G, { ["__call"] = function(func, ...) if type(func) == "function" then return func(...) else local h = metatable(func).__call if h then return h(func, ...) elseif _G[type(func)][func] then _G[type(func)][func](...) end end end, }) --- Mudlet's support for ATCP. This is primarily available on IRE-based MUDs, but Mudlets impelementation is generic enough --- such that any it should work on others.

--- --- The latest ATCP data is stored in the atcp table. Whenever new data arrives, the previous is overwritten. An event is also --- raised for each ATCP message that arrives. To find out the available messages available in the atcp table and the event names, --- you can use display(atcp).

--- --- Note that while the typical message comes in the format of Module.Submodule, ie Char.Vitals or Room.Exits, in Mudlet the dot is --- removed - so it becomes CharVitals and RoomExits. Here's an example: ---
---   room_number = tonumber(atcp.RoomNum)
---   echo(room_number)
---   
--- --- Triggering on ATCP events:
--- If you'd like to trigger on ATCP messages, then you need to create scripts to attach handlers to the ATCP messages. --- The ATCP handler names follow the same format as the atcp table - RoomNum, RoomExits, CharVitals and so on.

--- --- While the concept of handlers for events is to be explained elsewhere in the manual, the quick rundown is this - place --- the event name you'd like your script to listen to into the Add User Defined Event Handler: field and press the + button --- to register it. Next, because scripts in Mudlet can have multiple functions, you need to tell Mudlet which function --- should it call for you when your handler receives a message. You do that by setting the Script name: to the function --- name in the script you'd like to be called.

--- --- For example, if you'd like to listen to the RoomExits event and have it call the process_exits() function - --- register RoomExits as the event handler, make the script name be process_exits, and use this in the script: ---
---   function process_exits(event, args)
---       echo("Called event: " .. event .. "\nWith args: " .. args)
---   end
---   
--- --- Feel free to experiment with this to achieve the desired results. A ATCP demo package is also available on the forums --- for using event handlers and parsing its messages into Lua datastructures.
--- --- @release Mudlet 1.0.6 --- --- @see sendATCP --- --- @class function --- @name atcp atcp = {} --- TODO Table walklist. --- --- @class function --- @name walklist walklist = {} --- TODO Variable walkdelay. --- --- @class function --- @name walkdelay walkdelay = 0 --- TODO Table SavedVariables. --- --- @class function --- @name SavedVariables SavedVariables = {} --- Sends a list of commands to the MUD. You can use this to send some things at once instead of having --- to use multiple send() commands one after another. --- --- @param ... list of commands --- @param echoTheValue optional boolean flag (default value is true) which determine if value should --- be echoed back on client. --- --- @usage Use sendAll instead of multiple send commands. ---
---   sendAll("stand", "wield shield", "say ha!")
---   
--- Instead of calling: ---
---   send ("stand")
---   send ("wield shield")
---   send ("say ha!")
---   
--- @usage Use sendAll and do not echo sent commnad on the main window. ---
---   sendAll("stand", "wield shield", "say ha!", false)
---   
--- --- @see send function sendAll(...) local args = {...} local echo = true if type(args[#args]) == 'boolean' then echo = table.remove(args, #args) end for i, v in ipairs(args) do if type(v) == 'string' then send(v, echo) end end end --- Creates a group of a given type that will persist through sessions. --- --- @param name name of the teim --- @param itemtype type of the item - can be trigger, alias, or timer --- --- @usage ---
---   --create a new trigger group
---   permGroup("Combat triggers", "trigger")
--- 
--- @usage ---
---   --create a new alias group only if one doesn't exist already
---   if exists("Defensive aliases", "alias") == 0 then
---     permGroup("Defensive aliases", "alias")
---   end
--- 
function permGroup(name, itemtype) assert(type(name) == "string", "permGroup: need a name for the new thing") local t = { timer = function(name) return (permTimer(name, "", 0, "") == -1) and false or true end, trigger = function(name) return (permSubstringTrigger(name, "", {""}, "") == -1) and false or true end, alias = function(name) return (permAlias(name, "", "", "") == -1) and false or true end } assert(t[itemtype], "permGroup: "..tostring(itemtype).." isn't a valid type") return t[itemtype](name) end --- Checks to see if a given file or folder exists. If it exists, it'll return the Lua true boolean value, otherwise false. --- --- @usage ---
---   if io.exists("/home/user/Desktop") then
---      echo("This folder exists!")
---   else
---      echo("This folder doesn't exist.")
---   end
---
---   if io.exists("/home/user/Desktop/file.txt") then
---      echo("This file exists!")
---   else
---      echo("This file doesn't exist.")
---   end
---   
--- --- @return true or false function io.exists(fileOfFolderName) local f = io.open(fileOfFolderName) if f then io.close(f) return true end return false end --- Implementation of boolean exclusive or. --- --- @usage All following will return false. ---
---   xor(false, false)
---   xor(true, true)
---   
--- --- @return true or false function xor(a, b) if (a and (not b)) or (b and (not a)) then return true else return false end end --- Determine operating system. --- --- @usage ---
---   if "linux" == getOS() then
---	     echo("We are using GNU/Linux!")
---   end
---   
--- --- @return "linux", "mac" or "windows" string function getOS() if string.char(getMudletHomeDir():byte()) == "/" then if string.find(os.getenv("HOME"), "home") == 2 then return "linux" else return "mac" end else return "windows" end end --- This function flags a variable to be saved by Mudlet's variable persistence system. --- Variables are automatically unpacked into the global namespace when the profile is loaded. --- They are saved to "SavedVariables.lua" when the profile is closed or saved. --- --- @usage remember("varName") --- --- @see loadVars function remember(varName) if not _saveTable then _saveTable = {} end _saveTable[varName] = _G[varName] end --- This function should be primarily used by Mudlet. It loads saved settings in from the Mudlet home directory --- and unpacks them into the global namespace. --- --- @see remember function loadVars() if string.char(getMudletHomeDir():byte()) == "/" then _sep = "/" else _sep = "\\" end local l_SettingsFile = getMudletHomeDir() .. _sep .. "SavedVariables.lua" local lt_VariableHolder = {} if (io.exists(l_SettingsFile)) then table.load(l_SettingsFile, lt_VariableHolder) for k,v in pairs(lt_VariableHolder) do _G[k] = v end end end --- This function should primarily be used by Mudlet. It saves the contents of _saveTable into a file for persistence. --- --- @see loadVars function saveVars() if string.char(getMudletHomeDir():byte()) == "/" then _sep = "/" else _sep = "\\" end local l_SettingsFile = getMudletHomeDir() .. _sep .. "SavedVariables.lua" for k,_ in pairs(_saveTable) do remember(k) end table.save(l_SettingsFile, _saveTable) end --- The below functions (table.save, table.load) can be used to save individual Lua tables to disc and load --- them again at a later time e.g. make a database, collect statistical information etc. --- These functions are also used by Mudlet to load & save the entire Lua session variables.

--- --- Original code written by CHILLCODE™ on https://board.ptokax.ch, distributed under the same terms as Lua itself.

--- --- Notes:
--- Userdata and indices of these are not saved
--- Functions are saved via string.dump, so make sure it has no upvalues
--- References are saved
--- --- @usage Saves the globals table (minus some lua enviroment stuffs) into a file (only Mudlet should use this). ---
---   table.save(file)
---   
--- @usage Saves the given table into the given file. ---
---   table.save(file, table)
---   
--- --- @see table.load function table.save( sfile, t ) assert(type(sfile) == "string", "table.save requires a file path to save to") local tables = {} table.insert( tables, t ) local lookup = { [t] = 1 } local file = io.open( sfile, "w" ) file:write( "return {" ) for i,v in ipairs( tables ) do table.pickle( v, file, tables, lookup ) end file:write( "}" ) file:close() end --- TODO table.pickle( t, file, tables, lookup ) function table.pickle( t, file, tables, lookup ) file:write( "{" ) for i,v in pairs( t ) do -- escape functions if type( v ) ~= "function" and type( v ) ~= "userdata" and (i ~= "string" and i ~= "xpcall" and i ~= "package" and i ~= "os" and i ~= "io" and i ~= "math" and i ~= "debug" and i ~= "coroutine" and i ~= "_G" and i ~= "_VERSION" and i ~= "table") then -- handle index if type( i ) == "table" then if not lookup[i] then table.insert( tables, i ) lookup[i] = table.maxn( tables ) end file:write( "[{"..lookup[i].."}] = " ) else local index = ( type( i ) == "string" and "[ "..string.enclose( i, 50 ).." ]" ) or string.format( "[%d]", i ) file:write( index.." = " ) end -- handle value if type( v ) == "table" then if not lookup[v] then table.insert( tables, v ) lookup[v] = table.maxn( tables ) end file:write( "{"..lookup[v].."}," ) else local value = ( type( v ) == "string" and string.enclose( v, 50 ) ) or tostring( v ) file:write( value.."," ) end end end file:write( "},\n" ) end --- Restores a Lua table from a data file that has been saved with table.save(). --- --- @usage Loads a serialized file into the globals table (only Mudlet should use this). ---
---   table.load(file)
---   
--- @usage Loads a serialized file into the given table. ---
---   table.load(file, table)
---   
--- --- @see table.save function table.load( sfile, loadinto ) assert(type(sfile) == "string", "table.load requires a file path to load") local tables = dofile( sfile ) if tables then if loadinto ~= nil and type(loadinto) == "table" then table.unpickle( tables[1], tables, loadinto ) else table.unpickle( tables[1], tables, _G ) end end end --- TODO table.unpickle( t, tables, tcopy, pickled ) function table.unpickle( t, tables, tcopy, pickled ) pickled = pickled or {} pickled[t] = tcopy for i,v in pairs( t ) do local i2 = i if type( i ) == "table" then local pointer = tables[ i[1] ] if pickled[pointer] then i2 = pickled[pointer] else i2 = {} table.unpickle( pointer, tables, i2, pickled ) end end local v2 = v if type( v ) == "table" then local pointer = tables[ v[1] ] if pickled[pointer] then v2 = pickled[pointer] else v2 = {} table.unpickle( pointer, tables, v2, pickled ) end end tcopy[i2] = v2 end end --- TODO speedwalktimer() function speedwalktimer() send(walklist[1]) table.remove(walklist, 1) if #walklist>0 then tempTimer(walkdelay, [[speedwalktimer()]]) end end --- TODO speedwalk(dirString, backwards, delay) function speedwalk(dirString, backwards, delay) local dirString = dirString:lower() walklist = {} walkdelay = delay local reversedir = { n = "s", en = "sw", e = "w", es = "nw", s = "n", ws = "ne", w = "e", wn = "se", u = "d", d = "u", ni = "out", tuo = "in" } if not backwards then for count, direction in string.gmatch(dirString, "([0-9]*)([neswudio][ewnu]?t?)") do count = (count == "" and 1 or count) for i=1, count do if delay then walklist[#walklist+1] = direction else send(direction) end end end else for direction, count in string.gmatch(dirString:reverse(), "(t?[ewnu]?[neswudio])([0-9]*)") do count = (count == "" and 1 or count) for i=1, count do if delay then walklist[#walklist+1] = reversedir[direction] else send(reversedir[direction]) end end end end if walkdelay then speedwalktimer() end end --- TODO _comp(a, b) function _comp(a, b) if type(a) ~= type(b) then return false end if type(a) == 'table' then for k, v in pairs(a) do if not b[k] then return false end if not _comp(v, b[k]) then return false end end else if a ~= b then return false end end return true end --- TODO phpTable(...) - abuse to: http://richard.warburton.it function phpTable(...) local newTable, keys, values = {}, {}, {} newTable.pairs = function(self) -- pairs iterator local count = 0 return function() count = count + 1 return keys[count], values[keys[count]] end end setmetatable(newTable, { __newindex = function(self, key, value) if not self[key] then table.insert(keys, key) elseif value == nil then -- Handle item delete local count = 1 while keys[count] ~= key do count = count + 1 end table.remove(keys, count) end values[key] = value -- replace/create end, __index=function(self, key) return values[key] end, isPhpTable = true, }) local args = {...} for x=1, #args do for k, v in pairs(args[x]) do newTable[k] = v end end return newTable end --- TODO getColorWildcard(color) function getColorWildcard(color) local color = tonumber(color) local startc local endc local results = {} for i = 1, string.len(line) do selectSection(i, 1) if isAnsiFgColor(color) then if not startc then if i == 1 then startc = 1 else startc = i + 1 end else endc = i + 1 if i == line:len() then results[#results + 1] = line:sub(startc, endc) end end elseif startc then results[#results + 1] = line:sub(startc, endc) startc = nil end end return results[1] and results or false end do local oldsetExit = setExit local exitmap = { n = 1, ne = 2, nw = 3, e = 4, w = 5, s = 6, se = 7, sw = 8, u = 9, d = 10, ["in"] = 11, out = 12 } function setExit(from, to, direction) if type(direction) == "string" and not exitmap[direction] then return false end return oldsetExit(from, to, type(direction) == "string" and exitmap[direction] or direction) end end do local oldlockExit = lockExit local oldhasExitLock = hasExitLock local exitmap = { n = 1, north = 1, ne = 2, northeast = 2, nw = 3, northwest = 3, e = 4, east = 4, w = 5, west = 5, s = 6, south = 6, se = 7, southeast = 7, sw = 8, southwest = 8, u = 9, up = 9, d = 10, down = 10, ["in"] = 11, out = 12 } function lockExit(from, direction, status) if type(direction) == "string" and not exitmap[direction] then return false end return oldlockExit(from, type(direction) == "string" and exitmap[direction] or direction, status) end function hasExitLock(from, direction) if type(direction) == "string" and not exitmap[direction] then return false end return oldhasExitLock(from, type(direction) == "string" and exitmap[direction] or direction) end end ioprint = print function print(...) local t, echo, tostring = {...}, echo, tostring for i = 1, #t do echo((tostring(t[i]) or '?').." ") end echo("\n") end function deleteFull() deleteLine() tempLineTrigger(1,1, [[if isPrompt() then deleteLine() end]]) end mudlet-2.1/src/mudlet-lua/lua/GMCP.lua0000644000175000017500000001006712076170616017042 0ustar csmallcsmall-- [[ A framework to track GMCP module usage ]] -- module("gmod",package.seeall) local registeredUsers = registeredUsers or {} local registeredModules = registeredModules or {} -- Central text output function for the module. function print(text) cecho(string.format("\n[GMCP Tracker] %s\n",text)) end -- Register a user to the system. function registerUser(user) if registeredUsers[user] then return "user exists" else registeredUsers[user] = true end return "user registered" end -- Add a user to a module local function addUser(user,module) registeredModules[module][user] = true return "user added" end -- Drop a user from a module local function dropUser(user,module) if not registeredModules[module] then return "no registered module" end if not registeredModules[module][user] then return "user not linked" end registeredModules[module][user] = nil return "user dropped" end -- Get the user count of a module. local function getUserCount(module) if not registeredModules[module] then return 0 end local count = 0 for i,v in pairs(registeredModules[module]) do count = count + 1 end return count end -- Check to see if the module is registered. Return a user list if it is. function isRegisteredModule(mod) if not registeredModules[mod] then return false end return registeredModules[mod] end -- Enable a module that isn't already enabled, and register it's use to a user. function enableModule(user,module) registerUser(user) -- Check to see if the module is already enabled. if not isRegisteredModule(module) then local addString = nil local ttlString = "" for _,mod in pairs(module:split("%.")) do if not addString then addString = mod else addString = string.format("%s.%s",addString,mod) end ttlString = string.format("%s\"%s 1\",",ttlString,addString) end ttlString = string.format("[%s]",ttlString:gsub("(.+),","%1")) sendGMCP(string.format([[Core.Supports.Add %s ]],ttlString)) registeredModules[module] = {} end -- Add the user to the module's user list. addUser(user,module) end -- Send the module list again on reconnect, so activated modules stay enabled during -- a session unless explicitly disabled function gmod.reenableModules() local list = {} for module, users in pairs(registeredModules) do list[#list+1] = module.." 1" end sendGMCP("Core.Supports.Set "..yajl.to_string(list)) end registerAnonymousEventHandler("sysConnectionEvent", "gmod.reenableModules") -- Remove a user from a module's user list. Disable the module if nobody is using it. function disableModule(user,module) registerUser(user) -- Make sure the module is enabled in the first place if not isRegisteredModule(module) then return "no registered module" end dropUser(user,module) -- The user is now removed from the list. Check the user count. if getUserCount(module) < 1 then sendGMCP(string.format([[Core.Supports.Remove ["%s"] ]],module)) registeredModules[module] = nil end end function printModules(user) -- If a user is specified, print the name of all associated modules. if user then if not registeredUsers[user] then print(string.format("%s is not a registered user.",user)) return end cecho(string.format("\n\nModule listing for user: %s",user)) cecho(string.format("\n%s",string.rep("-",45))) for i,v in pairs(registeredModules) do if v[user] then cecho(string.format("\n%s",i)) end end return end -- No user specified, print all existing Modules with a user list. print("Current modules:") for i,v in pairs(registeredModules) do cecho(string.format("\n%s\n ",i)) local doComma = false for j,_ in pairs(v) do if not doComma then doComma = true else cecho(", ") end cecho(string.format("%s",j)) end end end mudlet-2.1/src/mudlet-lua/lua/GUIUtils.lua0000644000175000017500000010241012070466512017750 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet GUI Utils ---------------------------------------------------------------------------------- --- The gaugesTable table. First we need to make this table which will be --- used later to store important data in. --- --- @class function --- @name gaugesTable gaugesTable = {} --- The color_table table holds definition of color names. These are intended to be --- used in conjunction with fg() and bg() colorizer functions. --- --- @see showColors --- @see bg --- @see fg --- --- @class function --- @name color_table color_table = { snow = {255, 250, 250}, ghost_white = {248, 248, 255}, GhostWhite = {248, 248, 255}, white_smoke = {245, 245, 245}, WhiteSmoke = {245, 245, 245}, gainsboro = {220, 220, 220}, floral_white = {255, 250, 240}, FloralWhite = {255, 250, 240}, old_lace = {253, 245, 230}, OldLace = {253, 245, 230}, linen = {250, 240, 230}, antique_white = {250, 235, 215}, AntiqueWhite = {250, 235, 215}, papaya_whip = {255, 239, 213}, PapayaWhip = {255, 239, 213}, blanched_almond = {255, 235, 205}, BlanchedAlmond = {255, 235, 205}, bisque = {255, 228, 196}, peach_puff = {255, 218, 185}, PeachPuff = {255, 218, 185}, navajo_white = {255, 222, 173}, NavajoWhite = {255, 222, 173}, moccasin = {255, 228, 181}, cornsilk = {255, 248, 220}, ivory = {255, 255, 240}, lemon_chiffon = {255, 250, 205}, LemonChiffon = {255, 250, 205}, seashell = {255, 245, 238}, honeydew = {240, 255, 240}, mint_cream = {245, 255, 250}, MintCream = {245, 255, 250}, azure = {240, 255, 255}, alice_blue = {240, 248, 255}, AliceBlue = {240, 248, 255}, lavender = {230, 230, 250}, lavender_blush = {255, 240, 245}, LavenderBlush = {255, 240, 245}, misty_rose = {255, 228, 225}, MistyRose = {255, 228, 225}, white = {255, 255, 255}, black = {0, 0, 0}, dark_slate_gray = {47, 79, 79}, DarkSlateGray = {47, 79, 79}, dark_slate_grey = {47, 79, 79}, DarkSlateGrey = {47, 79, 79}, dim_gray = {105, 105, 105}, DimGray = {105, 105, 105}, dim_grey = {105, 105, 105}, DimGrey = {105, 105, 105}, slate_gray = {112, 128, 144}, SlateGray = {112, 128, 144}, slate_grey = {112, 128, 144}, SlateGrey = {112, 128, 144}, light_slate_gray = {119, 136, 153}, LightSlateGray = {119, 136, 153}, light_slate_grey = {119, 136, 153}, LightSlateGrey = {119, 136, 153}, gray = {190, 190, 190}, grey = {190, 190, 190}, light_grey = {211, 211, 211}, LightGrey = {211, 211, 211}, light_gray = {211, 211, 211}, LightGray = {211, 211, 211}, midnight_blue = {25, 25, 112}, MidnightBlue = {25, 25, 112}, navy = {0, 0, 128}, navy_blue = {0, 0, 128}, NavyBlue = {0, 0, 128}, cornflower_blue = {100, 149, 237}, CornflowerBlue = {100, 149, 237}, dark_slate_blue = {72, 61, 139}, DarkSlateBlue = {72, 61, 139}, slate_blue = {106, 90, 205}, SlateBlue = {106, 90, 205}, medium_slate_blue = {123, 104, 238}, MediumSlateBlue = {123, 104, 238}, light_slate_blue = {132, 112, 255}, LightSlateBlue = {132, 112, 255}, medium_blue = {0, 0, 205}, MediumBlue = {0, 0, 205}, royal_blue = {65, 105, 225}, RoyalBlue = {65, 105, 225}, blue = {0, 0, 255}, dodger_blue = {30, 144, 255}, DodgerBlue = {30, 144, 255}, deep_sky_blue = {0, 191, 255}, DeepSkyBlue = {0, 191, 255}, sky_blue = {135, 206, 235}, SkyBlue = {135, 206, 235}, light_sky_blue = {135, 206, 250}, LightSkyBlue = {135, 206, 250}, steel_blue = {70, 130, 180}, SteelBlue = {70, 130, 180}, light_steel_blue = {176, 196, 222}, LightSteelBlue = {176, 196, 222}, light_blue = {173, 216, 230}, LightBlue = {173, 216, 230}, powder_blue = {176, 224, 230}, PowderBlue = {176, 224, 230}, pale_turquoise = {175, 238, 238}, PaleTurquoise = {175, 238, 238}, dark_turquoise = {0, 206, 209}, DarkTurquoise = {0, 206, 209}, medium_turquoise = {72, 209, 204}, MediumTurquoise = {72, 209, 204}, turquoise = {64, 224, 208}, cyan = {0, 255, 255}, light_cyan = {224, 255, 255}, LightCyan = {224, 255, 255}, cadet_blue = {95, 158, 160}, CadetBlue = {95, 158, 160}, medium_aquamarine = {102, 205, 170}, MediumAquamarine = {102, 205, 170}, aquamarine = {127, 255, 212}, dark_green = {0, 100, 0}, DarkGreen = {0, 100, 0}, dark_olive_green = {85, 107, 47}, DarkOliveGreen = {85, 107, 47}, dark_sea_green = {143, 188, 143}, DarkSeaGreen = {143, 188, 143}, sea_green = {46, 139, 87}, SeaGreen = {46, 139, 87}, medium_sea_green = {60, 179, 113}, MediumSeaGreen = {60, 179, 113}, light_sea_green = {32, 178, 170}, LightSeaGreen = {32, 178, 170}, pale_green = {152, 251, 152}, PaleGreen = {152, 251, 152}, spring_green = {0, 255, 127}, SpringGreen = {0, 255, 127}, lawn_green = {124, 252, 0}, LawnGreen = {124, 252, 0}, green = {0, 255, 0}, chartreuse = {127, 255, 0}, medium_spring_green = {0, 250, 154}, MediumSpringGreen = {0, 250, 154}, green_yellow = {173, 255, 47}, GreenYellow = {173, 255, 47}, lime_green = {50, 205, 50}, LimeGreen = {50, 205, 50}, yellow_green = {154, 205, 50}, YellowGreen = {154, 205, 50}, forest_green = {34, 139, 34}, ForestGreen = {34, 139, 34}, olive_drab = {107, 142, 35}, OliveDrab = {107, 142, 35}, dark_khaki = {189, 183, 107}, DarkKhaki = {189, 183, 107}, khaki = {240, 230, 140}, pale_goldenrod = {238, 232, 170}, PaleGoldenrod = {238, 232, 170}, light_goldenrod_yellow= {250, 250, 210}, LightGoldenrodYellow = {250, 250, 210}, light_yellow = {255, 255, 224}, LightYellow = {255, 255, 224}, yellow = {255, 255, 0}, gold = {255, 215, 0}, light_goldenrod = {238, 221, 130}, LightGoldenrod = {238, 221, 130}, goldenrod = {218, 165, 32}, dark_goldenrod = {184, 134, 11}, DarkGoldenrod = {184, 134, 11}, rosy_brown = {188, 143, 143}, RosyBrown = {188, 143, 143}, indian_red = {205, 92, 92}, IndianRed = {205, 92, 92}, saddle_brown = {139, 69, 19}, SaddleBrown = {139, 69, 19}, sienna = {160, 82, 45}, peru = {205, 133, 63}, burlywood = {222, 184, 135}, beige = {245, 245, 220}, wheat = {245, 222, 179}, sandy_brown = {244, 164, 96}, SandyBrown = {244, 164, 96}, tan = {210, 180, 140}, chocolate = {210, 105, 30}, firebrick = {178, 34, 34}, brown = {165, 42, 42}, dark_salmon = {233, 150, 122}, DarkSalmon = {233, 150, 122}, salmon = {250, 128, 114}, light_salmon = {255, 160, 122}, LightSalmon = {255, 160, 122}, orange = {255, 165, 0}, dark_orange = {255, 140, 0}, DarkOrange = {255, 140, 0}, coral = {255, 127, 80}, light_coral = {240, 128, 128}, LightCoral = {240, 128, 128}, tomato = {255, 99, 71}, orange_red = {255, 69, 0}, OrangeRed = {255, 69, 0}, red = {255, 0, 0}, hot_pink = {255, 105, 180}, HotPink = {255, 105, 180}, deep_pink = {255, 20, 147}, DeepPink = {255, 20, 147}, pink = {255, 192, 203}, light_pink = {255, 182, 193}, LightPink = {255, 182, 193}, pale_violet_red = {219, 112, 147}, PaleVioletRed = {219, 112, 147}, maroon = {176, 48, 96}, medium_violet_red = {199, 21, 133}, MediumVioletRed = {199, 21, 133}, violet_red = {208, 32, 144}, VioletRed = {208, 32, 144}, magenta = {255, 0, 255}, violet = {238, 130, 238}, plum = {221, 160, 221}, orchid = {218, 112, 214}, medium_orchid = {186, 85, 211}, MediumOrchid = {186, 85, 211}, dark_orchid = {153, 50, 204}, DarkOrchid = {153, 50, 204}, dark_violet = {148, 0, 211}, DarkViolet = {148, 0, 211}, blue_violet = {138, 43, 226}, BlueViolet = {138, 43, 226}, purple = {160, 32, 240}, medium_purple = {147, 112, 219}, MediumPurple = {147, 112, 219}, thistle = {216, 191, 216} } --- Move a custom gauge. --- --- @usage This would move the health bar gauge to the location 1200, 400. ---
---   moveGauge("healthBar", 1200, 400)
---   
--- --- @see createGauge function moveGauge(gaugeName, newX, newY) local newX, newY = newX, newY assert(gaugesTable[gaugeName], "moveGauge: no such gauge exists.") assert(newX and newY, "moveGauge: need to have both X and Y dimensions.") moveWindow(gaugeName, newX, newY) moveWindow(gaugeName .. "_back", newX, newY) gaugesTable[gaugeName].xpos, gaugesTable[gaugeName].ypos = newX, newY end --- Hide a custom gauge. --- --- @usage This should hide the given gauge. ---
---   hideGauge("healthBar")
---   
--- --- @see createGauge, moveGauge, showGauge function hideGauge(gaugeName) assert(gaugesTable[gaugeName], "hideGauge: no such gauge exists.") hideWindow(gaugeName) hideWindow(gaugeName .. "_back", newX) end --- Show a custom gauge. --- --- @usage This should show the given gauge. ---
---   showGauge("healthBar")
---   
--- --- @see createGauge, moveGauge, hideGauge function showGauge(gaugeName) assert(gaugesTable[gaugeName], "showGauge: no such gauge exists.") showWindow(gaugeName) showWindow(gaugeName .. "_back", newX) end --- Set the text on a custom gauge. --- --- @usage ---
---   setGaugeText("healthBar", "HP: 100%", 40, 40, 40)
---   
--- @usage ---
---   setGaugeText("healthBar", "HP: 100%", "red")
---   
--- --- @param gaugeName --- @param gaugeText An empty gaugeText will clear the text entirely. --- @param color1 Colors are optional and will default to 0,0,0(black) if not passed as args. --- @param color2 --- @param color3 --- --- @see createGauge function setGaugeText(gaugeName, gaugeText, color1, color2, color3) assert(gaugesTable[gaugeName], "setGauge: no such gauge exists.") local red,green,blue = 0,0,0 local l_labelText = gaugeText if color1 ~= nil then if color2 == nil then red, green, blue = getRGB(color1) else red, green, blue = color1, color2, color3 end end -- Check to make sure we had a text to apply, if not, clear the text if l_labelText == nil then l_labelText = "" end local l__Echostring = [[]] .. l_labelText .. [[]] echo(gaugeName, l__Echostring) -- do not set the text for the back, because
tags mess with the alignment --echo(gaugeName .. "_back", l__Echostring) gaugesTable[gaugeName].text = l__Echostring gaugesTable[gaugeName].color1, gaugesTable[gaugeName].color2, gaugesTable[gaugeName].color3 = color1, color2, color3 end --- Pads a hex number to ensure a minimum of 2 digits. --- --- @usage Following command will returns "F0". ---
---   PadHexNum("F")
---   
function PadHexNum(incString) local l_Return = incString if tonumber(incString,16)<16 then if tonumber(incString,16)<10 then l_Return = "0" .. l_Return elseif tonumber(incString,16)>10 then l_Return = l_Return .. "0" end end return l_Return end --- Converts an RGB value into an HTML compliant(label usable) HEX number. --- This function is colorNames aware and can take any defined global color as its first argument. --- --- @usage Both following commands will returns "FFFFFF". ---
---   RGB2Hex(255,255,255)
---   RGB2Hex("white")
---   
--- --- @see showColor function RGB2Hex(red, green, blue) local l_Red, l_Green, l_Blue = 0,0,0 if green == nil then -- Not an RGB but a "color" instead! l_Red, l_Green, l_Blue = getRGB(red) else -- Nope, true color here l_Red, l_Green, l_Blue = red, green, blue end return PadHexNum(string.format("%X",l_Red)) .. PadHexNum(string.format("%X",l_Green)) .. PadHexNum(string.format("%X",l_Blue)) end --- Get RGB component from color name. --- --- @usage Following will display "0.255.0" on your screen. ---
---   local red, green, blue = getRGB("green")
---   echo(red .. "." .. green .. "." .. blue )
---   
function getRGB(colorName) local red = color_table[colorName][1] local green = color_table[colorName][2] local blue = color_table[colorName][3] return red, green, blue end --- Make your very own customized gauge with this function. --- --- @usage This would make a gauge at that's 300px width, 20px in height, located at Xpos and Ypos and is green. ---
---   createGauge("healthBar", 300, 20, 30, 300, nil, 0, 255, 0)
---   
--- @usage The second example is using the same names you'd use for something like fg() or bg(). ---
---   createGauge("healthBar", 300, 20, 30, 300, nil, "green")
---   
--- @usage Finally we'll add some text to our gauche. ---
---   createGauge("healthBar", 300, 20, 30, 300, "Now with some text", "green")
---   
function createGauge(gaugeName, width, height, Xpos, Ypos, gaugeText, color1, color2, color3) -- make a nice background for our gauge createLabel(gaugeName .. "_back",0,0,0,0,1) if color2 == nil then local red, green, blue = getRGB(color1) setBackgroundColor(gaugeName .. "_back", red , green, blue, 100) else setBackgroundColor(gaugeName .. "_back", color1 ,color2, color3, 100) end moveWindow(gaugeName .. "_back", Xpos, Ypos) resizeWindow(gaugeName .. "_back", width, height) showWindow(gaugeName .. "_back") -- make a nicer front for our gauge createLabel(gaugeName,0,0,0,0,1) if color2 == nil then local red, green, blue = getRGB(color1) setBackgroundColor(gaugeName, red , green, blue, 255) else setBackgroundColor(gaugeName, color1 ,color2, color3, 255) end moveWindow(gaugeName, Xpos, Ypos) resizeWindow(gaugeName, width, height) showWindow(gaugeName) -- store important data in a table gaugesTable[gaugeName] = {width = width, height = height, xpos = Xpos, ypos = Ypos,text = gaugeText, color1 = color1, color2 = color2, color3 = color3} -- Set Gauge text (Defaults to black) -- If no gaugeText was passed, we'll just leave it blank! if gaugeText ~= nil then setGaugeText(gaugeName, gaugeText, "black") else setGaugeText(gaugeName) end end --- Use this function when you want to change the gauges look according to your values. --- Typical usage would be in a prompt with your current health or whatever value, and throw --- in some variables instead of the numbers. --- --- @usage In that example, we'd change the looks of the gauge named healthBar and make it fill --- to half of its capacity. The height is always remembered. ---
---   setGauge("healthBar", 200, 400)
---   
--- @usage Change the text on your gauge. ---
---   setGauge("healthBar", 200, 400, "some text")
---   
function setGauge(gaugeName, currentValue, maxValue, gaugeText) assert(gaugesTable[gaugeName], "setGauge: no such gauge exists.") assert(currentValue and maxValue, "setGauge: need to have both current and max values.") resizeWindow(gaugeName, gaugesTable[gaugeName].width/100*((100/maxValue)*currentValue), gaugesTable[gaugeName].height) -- if we wanted to change the text, we do it if gaugeText ~= nil then echo(gaugeName .. "_back", gaugeText) echo(gaugeName, gaugeText) gaugesTable[gaugeName].text = gaugeText end end --- Make a new console window with ease. The default background is black and text color white. --- If you wish to change the color you can easily do this when updating your text or manually somewhere, using --- setFgColor() and setBackgroundColor(). --- --- @usage This will create a miniconsole window that has a font size of 8pt, will display 80 characters in width, --- hold a maximum of 20 lines and be place at 200x400 of your Mudlet window. ---
---   createConsole("myConsoleWindow", 8, 80, 20, 200, 400)
---   
function createConsole(consoleName, fontSize, charsPerLine, numberOfLines, Xpos, Ypos) createMiniConsole(consoleName,0,0,1,1) setMiniConsoleFontSize(consoleName, fontSize) local x,y = calcFontSize( fontSize ) resizeWindow(consoleName, x*charsPerLine, y*numberOfLines) setWindowWrap(consoleName, charsPerLine) moveWindow(consoleName, Xpos, Ypos) setBackgroundColor(consoleName,0,0,0,0) setFgColor(consoleName, 255,255,255) end --- Suffixes text at the end of the current line when used in a trigger. --- --- @see prefix function suffix(what, func, fg, bg, window) local length = string.len(line) moveCursor(window or "main", length-1, getLineNumber()) if func and (func == cecho or func == decho or func == hecho) then func(what, fg, bg, true, window) else insertText(what) end end --- Prefixes text at the beginning of the current line when used in a trigger. --- --- @usage Prefix the hours, minutes and seconds onto our prompt even though Mudlet has a button for that. ---
---   prefix(os.date("%H:%M:%S "))
---   
--- --- @see suffix function prefix(what, func, fg, bg, window) moveCursor(window or "main", 0, getLineNumber()); if func and (func == cecho or func == decho or func == hecho) then func(what, fg, bg, true, window) else insertText(what) end end --- Function will gag the whole line. Use deleteLine() instead. function gagLine() deleteLine() end --- Replaces all occurrences of what in the current line with with. --- --- @usage This will replace all occurrences of John with the word Doe. ---
---   replaceAll("John", "Doe")
---
---   -- also handles recursive matches:
---   replaceAll("you", "you and me")
---   
function replaceAll(word, what) local startp, endp = 1, 1 while true do startp, endp = getCurrentLine():find(word, endp+(#what-#word)+1) if not startp then break end selectSection(startp-1, endp-startp+1) replace(what) end end --- Replace the whole with a string you'd like. --- --- @see deleteLine function replaceLine(what) selectString(line, 1) replace("") insertText(what) end --- Default resizeEvent handler function. Overwrite this function to make a custom event handler --- if the main window is being resized.

--- --- The standard implementation of this function does nothing. However, this function gets called whenever --- the main window is being manually resized. You can overwrite this function in your own scripts to handle window --- resize events yourself and e.g. adjust the screen position and size of your mini console windows, labels or --- other relevant GUI elements in your scripts that depend on the size of the main Window. To override this --- function you can simply put a function with the same name in one of your scripts thus overwriting the --- original empty implementation of this function. ---
---   function handleWindowResizeEvent()
---      -- determine the size of your screen
---      WindowWidth=0;
---      WindowHeight=0;
---      WindowWidth, WindowHeight = getMainWindowSize();
---      -- move mini console "sys" to the far right side of the screen whenever the screen gets resized
---      moveWindow("sys",WindowWidth-300,0)
---   end
---   
function handleWindowResizeEvent() end --- Clears the current selection in the main window or miniConsole window.
--- (Note: deselect(windowName) is implemented in Core Mudlet.) --- --- @usage Clear selection in main window. ---
---   deselect()
---   
--- @usage Clear selection in myMiniConsole window. ---
---   deselect("myMiniConsole")
---   
function deselect() selectString("", 1) end --- Sets current background color to a named color. --- --- @usage Set background color to magenta. ---
---   bg("magenta")
---
---   bg("my miniconsole", "blue")
---   
--- --- @see fg --- @see showColors function bg(console, colorName) local colorName = colorName or console assert(color_table[colorName], "bg: no such colour name") if console == colorName then setBgColor(color_table[colorName][1], color_table[colorName][2], color_table[colorName][3]) else setBgColor(console, color_table[colorName][1], color_table[colorName][2], color_table[colorName][3]) end end --- Sets current foreground color to a named color. --- --- @usage Set foreground color to black. ---
---   fg("black")
---   
--- --- @see bg --- @see showColors function fg(console, colorName) local colorName = colorName or console assert(color_table[colorName], "fg: no such colour name") if console == colorName then setFgColor(color_table[colorName][1], color_table[colorName][2], color_table[colorName][3]) else setFgColor(console, color_table[colorName][1], color_table[colorName][2], color_table[colorName][3]) end end --- Replaces the given wildcard (as a number) with the given text. --- --- @usage Replace "goodbye" with "hello" on a trigger of "^You wave (goodbye)\.$" ---
---   replaceWildcard(2, "hello")
---   
--- Is equivalent to doing: ---
---   selectString(matches[2], 1)
---   replace("hello")
---   
function replaceWildcard(what, replacement) if replacement == nil or what == nil then return end selectCaptureGroup(what) replace(replacement) end --- Prints out a formatted list of all available named colors, optional arg specifies number of columns to print in, defaults to 3 --- --- @usage Print list in 3 columns by default. ---
---   showColors()
---   
--- @usage Print list in 2 columns. ---
---   showColors(2)
---   
--- --- @see color_table function showColors(...) local cols = ... or 3 local i = 1 for k,v in pairs(color_table) do local fg local luminosity = (0.2126 * ((v[1]/255)^2.2)) + (0.7152 * ((v[2]/255)^2.2)) + (0.0722 * ((v[3]/255)^2.2)) if luminosity > 0.5 then fg = "black" else fg = "white" end cecho(string.format("<%s:%s>%s%s", fg, k, k, string.rep(" ", 23-k:len()))) echo" " if i == cols then echo"\n" i = 1 else i = i + 1 end end end --- TODO resizeGauge(gaugeName, width, height) function resizeGauge(gaugeName, width, height) assert(gaugesTable[gaugeName], "resizeGauge: no such gauge exists.") assert(width and height, "resizeGauge: need to have both width and height.") resizeWindow(gaugeName, width, height) resizeWindow(gaugeName .. "_back", width, height) -- save in the table gaugesTable[gaugeName].width, gaugesTable[gaugeName].height = width, height end --- TODO setGaugeStyleSheet(gaugeName, css, cssback) function setGaugeStyleSheet(gaugeName, css, cssback) if not setLabelStyleSheet then return end-- mudlet 1.0.5 and lower compatibility assert(gaugesTable[gaugeName], "setGaugeStyleSheet: no such gauge exists.") setLabelStyleSheet(gaugeName, css) setLabelStyleSheet(gaugeName .. "_back", cssback or css) end if rex then _Echos = { Patterns = { Hex = { [[(\x5c?\|c[0-9a-fA-F]{6}?(?:,[0-9a-fA-F]{6})?)|(\|r)]], rex.new[[\|c(?:([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2}))?(?:,([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2}))?]], }, Decimal = { -- [[(\x5c?<[0-9,:]+>)|()]], [[(<[0-9,:]+>)|()]], rex.new[[<(?:([0-9]{1,3}),([0-9]{1,3}),([0-9]{1,3}))?(?::(?=>))?(?::([0-9]{1,3}),([0-9]{1,3}),([0-9]{1,3}))?>]], }, Color = { [[(<[a-zA-Z_,:]+>)]], rex.new[[<([a-zA-Z_]+)?(?:[:,](?=>))?(?:[:,]([a-zA-Z_]+))?>]], }, Ansi = { [[(<[0-9,:]+>)]], rex.new[[<([0-9]{1,2})?(?::([0-9]{1,2}))?>]], }, }, Process = function(str, style) local t = {} local tonumber = tonumber for s, c, r in rex.split(str, _Echos.Patterns[style][1]) do if c and (c:byte(1) == 92) then c = c:sub(2) if s then s = s .. c else s = c end c = nil end if s then t[#t+1] = s end if r then t[#t+1] = "\27reset" end if c then if style == 'Hex' or style == 'Decimal' then local fr, fg, fb, br, bg, bb = _Echos.Patterns[style][2]:match(c) local color = {} if style == 'Hex' then if fr and fg and fb then fr, fg, fb = tonumber(fr, 16), tonumber(fg, 16), tonumber(fb, 16) end if br and bg and bb then br, bg, bb = tonumber(br, 16), tonumber(bg, 16), tonumber(bb, 16) end end if fr and fg and fb then color.fg = { fr, fg, fb } end if br and bg and bb then color.bg = { br, bg, bb } end t[#t+1] = color elseif style == 'Color' then if c == "" then t[#t+1] = "\27reset" else local fcolor, bcolor = _Echos.Patterns[style][2]:match(c) local color = {} if fcolor and color_table[fcolor] then color.fg = color_table[fcolor] end if bcolor and color_table[bcolor] then color.bg = color_table[bcolor] end if color.fg or color.bg then t[#t+1] = color else t[#t+1] = c end end end end end return t end, } --- Generic color echo and insert function (allowing hecho, decho, cecho, hinsertText, dinsertText and cinsertText). --- --- @param style Hex, Decimal or Color --- @param insert boolean flag to determine echo/insert behaviour --- @param win windowName optional --- @param str text with embedded color information --- --- @see cecho --- @see decho --- @see hecho --- @see cinsertText --- @see dinsertText --- @see hinsertText function xEcho(style, func, ...) local win, str, cmd, hint, fmt local out, reset local args = {...} local n = #args if func == 'echoLink' then if n < 3 then error'Insufficient arguments, usage: ([window, ] string, command, hint)' elseif n == 3 then str, cmd, hint = ... elseif n == 4 and type(args[4]) == 'boolean' then str, cmd, hint, fmt = ... elseif n >= 4 and type(args[4]) == 'string' then win, str, cmd, hint = ... if win == "main" then win = nil end else error'Improper arguments, usage: ([window, ] string, command, hint)' end else if args[1] and args[2] and args[1] ~= "main" then win, str = args[1], args[2] elseif args[1] and args[2] and args[1] == "main" then str = args[2] else str = args[1] end end out = function(...) _G[func](...) end if win then reset = function() resetFormat(win) end else reset = function() resetFormat() end end local t = _Echos.Process(str, style) deselect() reset() for _, v in ipairs(t) do if type(v) == 'table' then if v.fg then local fr, fg, fb = unpack(v.fg) if win then setFgColor(win, fr, fg, fb) else setFgColor(fr, fg, fb) end end if v.bg then local br, bg, bb = unpack(v.bg) if win then setBgColor(win, br, bg, bb) else setBgColor(br, bg, bb) end end elseif v == "\27reset" then reset() else if func == 'echo' or func == 'insertText' then if win then out(win, v) else out(v) end if func == 'insertText' then moveCursor(window or "main", getColumnNumber() + string.len(v), getLineNumber()) end else -- if win and fmt then setUnderline(win, true) elseif fmt then setUnderline(true) end -- not sure if underline is necessary unless asked for if win then out(win, v, cmd, hint, (fmt == true and true or false)) else out(v, cmd, hint, (fmt == true and true or false)) end end end end reset() end --- Echo string with embedded hex color information.

--- --- Color changes can be made within the string using the format |cFRFGFB,BRBGBB where FR is the foreground red value, --- FG is the foreground green value, FB is the foreground blue value, BR is the background red value, etc., BRBGBB is optional. --- |r can be used within the string to reset the colors to default. --- --- @usage Print red test on green background. ---
---   hecho("|cff0000,00ff00test")
---   
--- --- @see xEcho --- @see hinsertText function hecho(...) xEcho("Hex", "echo", ...) end --- Echo string with embedded decimal color information.

--- --- Color changes can be made using the format <FR,FG,FB:BR,BG,BB> where each field is a number from 0 to 255. --- The background portion can be omitted using <FR,FG,FB> or the foreground portion can be omitted using <:BR,BG,BB>. --- --- @usage Print red test on green background. ---
---   decho("<255,0,0:0,255,0>test")
---   
--- --- @see xEcho --- @see dinsertText function decho(...) xEcho("Decimal", "echo", ...) end --- Echo string with embedded color name information. --- --- @usage Consider following example: ---
---   cecho("<green>green text <blue>blue text <red>red text")
---   
--- --- @see xEcho --- @see cinsertText function cecho(...) xEcho("Color", "echo", ...) end --- Inserts string with embedded hex color information. --- --- @see xEcho --- @see hecho function hinsertText(...) xEcho("Hex", "insertText", ...) end --- Inserts string with embedded decimal color information. --- --- @see xEcho --- @see decho function dinsertText(...) xEcho("Decimal", "insertText", ...) end --- Inserts string with embedded color name information. --- --- @see xEcho --- @see cecho function cinsertText(...) xEcho("Color", "insertText", ...) end --- Echos a link with embedded hex color information. --- --- @usage hechoLink([window, ] string, command, hint) --- --- @see xEcho --- @see hecho function hechoLink(...) xEcho("Hex", "echoLink", ...) end --- Echos a link with embedded decimal color information. --- --- @usage dechoLink([window, ] string, command, hint) --- --- @see xEcho --- @see decho function dechoLink(...) xEcho("Decimal", "echoLink", ...) end --- Echos a link with embedded color name information. --- --- @usage cechoLink([window, ] string, command, hint) --- --- @see xEcho --- @see cecho function cechoLink(...) xEcho("Color", "echoLink", ...) end -- Backwards compatibility checho = cecho else -- NOT LUADOC -- See xEcho/another cecho for description. function cecho(window, text) local win = text and window local s = text or window if win == "main" then win = nil end if win then resetFormat(win) else resetFormat() end for color,text in string.gmatch(""..s, "<([a-z_0-9, :]+)>([^<>]+)") do local colist = string.split(color..":", "%s*:%s*") local fgcol = colist[1] ~= "" and colist[1] or "white" local bgcol = colist[2] ~= "" and colist[2] or "black" local FGrgb = color_table[fgcol] or string.split(fgcol, ",") local BGrgb = color_table[bgcol] or string.split(bgcol, ",") if win then setFgColor(win, FGrgb[1], FGrgb[2], FGrgb[3]) setBgColor(win, BGrgb[1], BGrgb[2], BGrgb[3]) echo(win,text) else setFgColor(FGrgb[1], FGrgb[2], FGrgb[3]) setBgColor(BGrgb[1], BGrgb[2], BGrgb[3]) echo(text) end end if win then resetFormat(win) else resetFormat() end end -- NOT LUADOC -- See xEcho/another decho for description. function decho(window, text) local win = text and window local s = text or window if win == "main" then win = nil end local reset if win then reset = function() resetFormat(win) end else reset = function() resetFormat() end end reset() for color, text in s:gmatch("<([0-9,:]+)>([^<>]+)") do if color == "reset" then reset() if win then echo(win, text) else echo(text) end else local colist = string.split(color..":", "%s*:%s*") local fgcol = colist[1] ~= "" and colist[1] or "white" local bgcol = colist[2] ~= "" and colist[2] or "black" local FGrgb = color_table[fgcol] or string.split(fgcol, ",") local BGrgb = color_table[bgcol] or string.split(bgcol, ",") if win then setFgColor(win, FGrgb[1], FGrgb[2], FGrgb[3]) setBgColor(win, BGrgb[1], BGrgb[2], BGrgb[3]) echo(win,text) else setFgColor(FGrgb[1], FGrgb[2], FGrgb[3]) setBgColor(BGrgb[1], BGrgb[2], BGrgb[3]) echo(text) end end end reset() end end do local oldreplace = replace function replace(text, keep_color) local text = text or "" if keep_color then setBgColor(getBgColor()) setFgColor(getFgColor()) end oldreplace(text) end end mudlet-2.1/src/mudlet-lua/lua/TableUtils.lua0000644000175000017500000002070212070466512020356 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Table Utils ---------------------------------------------------------------------------------- --- Tests if a table is empty: this is useful in situations where you find --- yourself wanting to do 'if my_table == {}' and such. --- --- @usage Testing if the table is empty. ---
---   myTable = {}
---   if table.is_empty(myTable) then
---      echo("myTable is empty")
---   end
---   
function table.is_empty(tbl) if next(tbl) == nil then return true else return false end end --- Lua debug function that prints the content of a Lua table on the screen, split up in keys and values. --- Useful if you want to see what the capture groups contain i. e. the Lua table "matches". --- --- @see display function printTable( map ) echo("-------------------------------------------------------\n"); for k, v in pairs( map ) do echo( "key=" .. k .. " value=" .. v .. "\n" ) end echo("-------------------------------------------------------\n"); end -- NOT LUADOC -- This is supporting function for printTable(). function __printTable( k, v ) insertText ("\nkey = " .. tostring (k) .. " value = " .. tostring( v ) ) end --- Lua debug function that prints the content of a Lua table on the screen.
--- There are currently 3 functions with similar behaviour. --- --- @see display --- @see printTable function listPrint( map ) echo("-------------------------------------------------------\n"); for k,v in ipairs( map ) do echo( k .. ". ) "..v .. "\n" ); end echo("-------------------------------------------------------\n"); end --- TODO listAdd( list, what ) function listAdd( list, what ) table.insert( list, what ); end --- TODO listRemove( list, what ) function listRemove( list, what ) for k,v in ipairs( list ) do if v == what then table.remove( list, k ) end end end --- Gets the actual size of non-index based tables.

--- --- For index based tables you can get the size with the # operator:
--- This is the standard Lua way of getting the size of index tables i.e. ipairs() type of tables with --- numerical indices. To get the size of tables that use user defined keys instead of automatic indices --- (pairs() type) you need to use the function table.size() referenced above. ---
---   myTableSize = # myTable
---   
function table.size(t) if not t then return 0 end local i = 0 for k, v in pairs(t) do i = i + 1 end return i end --- Determines if a table contains a value as a key or as a value (recursive). function table.contains(t, value) for k, v in pairs(t) do if v == value then return true elseif k == value then return true elseif type(v) == "table" then if table.contains(v, value) then return true end end end return false end --- Table Union. --- --- @return Returns a table that is the union of the provided tables. This is a union of key/value --- pairs. If two or more tables contain different values associated with the same key, --- that key in the returned table will contain a subtable containing all relevant values. --- See table.n_union() for a union of values. Note that the resulting table may not be --- reliably traversable with ipairs() due to the fact that it preserves keys. If there --- is a gap in numerical indices, ipairs() will cease traversal. --- --- @usage Example: ---
---   tableA = {
---      [1] = 123,
---      [2] = 456,
---      ["test"] = "test",
---   }
---
---   tableB = {
---      [1] = 23,
---      [3] = 7,
---      ["test2"] = function() return true end,
---   }
---
---   tableC = {
---      [5] = "c",
---   }
---
---   table.union(tableA, tableB, tableC) will return:
---   {
---      [1] = {
---         123,
---         23,
---      },
---      [2] = 456,
---      [3] = 7,
---      [5] = "c",
---      ["test"] = "test",
---      ["test2"] = function() return true end,
---   }
---   
function table.union(...) local sets = {...} local union = {} for _, set in ipairs(sets) do for key, val in pairs(set) do if union[key] and union[key] ~= val then if type(union[key]) == 'table' then table.insert(union[key], val) else union[key] = { union[key], val } end else union[key] = val end end end return union end --- Table Union. --- --- @return Returns a numerically indexed table that is the union of the provided tables. This is --- a union of unique values. The order and keys of the input tables are not preserved. function table.n_union(...) local sets = {...} local union = {} local union_keys = {} for _, set in ipairs(sets) do for key, val in pairs(set) do if not union_keys[val] then union_keys[val] = true table.insert(union, val) end end end return union end --- Table Intersection. --- --- @return Returns a table that is the intersection of the provided tables. This is an --- intersection of key/value pairs. See table.n_intersection() for an intersection of values. --- Note that the resulting table may not be reliably traversable with ipairs() due to --- the fact that it preserves keys. If there is a gap in numerical indices, ipairs() will --- cease traversal. --- --- @usage Example: ---
---   tableA = {
---      [1] = 123,
---      [2] = 456,
---      [4] = { 1, 2 },
---      [5] = "c",
---      ["test"] = "test",
---   }
---
---   tableB = {
---      [1] = 123,
---      [2] = 4,
---      [3] = 7,
---      [4] = { 1, 2 },
---      ["test"] = function() return true end,
---   }
---
---   tableC = {
---      [1] = 123,
---      [4] = { 1, 2 },
---      [5] = "c",
---   }
---
---   table.intersection(tableA, tableB, tableC) will return:
---   {
---      [1] = 123,
---      [4] = { 1, 2 },
---   }
---   
function table.intersection(...) sets = {...} if #sets < 2 then return false end local intersection = {} local function intersect(set1, set2) local result = {} for key, val in pairs(set1) do if set2[key] then if _comp(val, set2[key]) then result[key] = val end end end return result end intersection = intersect(sets[1], sets[2]) for i, _ in ipairs(sets) do if i > 2 then intersection = intersect(intersection, sets[i]) end end return intersection end --- Table Intersection. --- --- @return Returns a numerically indexed table that is the intersection of the provided tables. --- This is an intersection of unique values. The order and keys of the input tables are --- not preserved. function table.n_intersection(...) sets = {...} if #sets < 2 then return false end local intersection = {} local function intersect(set1, set2) local intersection_keys = {} local result = {} for _, val1 in pairs(set1) do for _, val2 in pairs(set2) do if _comp(val1, val2) and not intersection_keys[val1] then table.insert(result, val1) intersection_keys[val1] = true end end end return result end intersection = intersect(sets[1], sets[2]) for i, _ in ipairs(sets) do if i > 2 then intersection = intersect(intersection, sets[i]) end end return intersection end --- Table Complement. --- --- @return Returns a table that is the relative complement of the first table with respect to --- the second table. Returns a complement of key/value pairs. function table.complement(set1, set2) if not set1 and set2 then return false end if type(set1) ~= 'table' or type(set2) ~= 'table' then return false end local complement = {} for key, val in pairs(set1) do if not _comp(set2[key], val) then complement[key] = val end end return complement end --- Table Complement. --- --- @return Returns a table that is the relative complement of the first table with respect to --- the second table. Returns a complement of values. function table.n_complement(set1, set2) if not set1 and set2 then return false end local complement = {} for _, val1 in pairs(set1) do local insert = true for _, val2 in pairs(set2) do if _comp(val1, val2) then insert = false end end if insert then table.insert(complement, val1) end end return complement end --- TODO table:update(t1, t2) function table:update(t1, t2) for k,v in pairs(t2) do if type(v) == "table" then t1[k] = self.update(t1[k] or {}, v) else t1[k] = v end end return t1 end ---Returns the index of the value in a table function table.index_of(table, element) for index, value in ipairs(table) do if value == element then return index end end return nil end mudlet-2.1/src/mudlet-lua/lua/LuaGlobal.lua0000644000175000017500000000570312070466512020154 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Lua packages loader ---------------------------------------------------------------------------------- if package.loaded["rex_pcre"] then rex = require "rex_pcre" end if package.loaded["lpeg"] then lpeg = require "lpeg" end if package.loaded["zip"] then zip = require "zip" end if package.loaded["lfs"] then lfs = require "lfs" end -- TODO this is required by DB.lua, so we might load it all at one place --if package.loaded["luasql.sqlite3"] then require "luasql.sqlite3" end json_to_value = yajl.to_value gmcp = {} function __gmcp_merge_gmcp_sub_tables( a, key ) local _m = a.__needMerge; for k,v in pairs(_m) do a[key][k] = v; end a.__needMerge = nil end function unzip( what, dest ) -- cecho("\nunpacking package:<"..what.."< to <"..dest..">\n") local z, err = zip.open( what ) if not z then cecho("\nerror unpacking: "..err) return end local createdDirs = {} for file in z:files() do local _f, err = z:open( file.filename ) local _data = _f:read("*a") local _path = dest .. file.filename local _dir = string.split( file.filename, '/' ) local created = dest; for k,v in ipairs( _dir ) do if k < # _dir then created = created .. '/'.. v; if not table.contains( createdDirs, created ) then table.insert( createdDirs, created ); lfs.mkdir( created ); -- cecho("--> creating dir:" .. created .. "\n"); end elseif file.uncompressed_size == 0 then if not table.contains( createdDirs, created ) then -- cecho("--> creating dir:" .. file.filename .. "\n") table.insert( createdDirs, created ); lfs.mkdir( file.filename ) end end end local _path = dest .. file.filename if file.uncompressed_size > 0 then local out = io.open( _path, "wb" ) if out then -- cecho("unpacking file:".._path.."\n") out:write( _data ) out:close() else cecho("ERROR: can't write file:".._path.."\n") end end _f:close(); end z:close() end function onConnect() end function handleWindowResizeEvent() end local packages = { "StringUtils.lua", "TableUtils.lua", -- "Logging.lua", -- never documented and fails to load now "DebugTools.lua", "DB.lua", "geyser/Geyser.lua", "geyser/GeyserGeyser.lua", "geyser/GeyserUtil.lua", "geyser/GeyserColor.lua", "geyser/GeyserSetConstraints.lua", "geyser/GeyserContainer.lua", "geyser/GeyserWindow.lua", "geyser/GeyserLabel.lua", "geyser/GeyserGauge.lua", "geyser/GeyserMiniConsole.lua", "geyser/GeyserMapper.lua", "geyser/GeyserReposition.lua", "geyser/GeyserHBox.lua", "geyser/GeyserVBox.lua", -- TODO probably don't need to load this file "geyser/GeyserTests.lua", "GUIUtils.lua", "Other.lua", "GMCP.lua", } for _, package in ipairs(packages) do local result, msg = pcall(dofile, "./mudlet-lua/lua/" .. package) if not result then echo("Error attempting to load file: " .. package .. ": "..msg.."\n") end end mudlet-2.1/src/mudlet-lua/lua/CoreMudlet.lua0000644000175000017500000021150712070466512020356 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Core Lua Functions --- (file holds LuaDoc for all function implemented with in Mudlet Core) ---------------------------------------------------------------------------------- -- ensure that those function will not get defined if false then --- Pastes the previously copied rich text (including text formats like color) into user window name. --- --- @usage ---
---   selectString(line, 1)
---   copy()
---   appendBuffer("chat")
---   
--- --- @see selectString --- @see copy --- @see echo function appendBuffer(windowName) end --- This returns you the height and the length of letters for the given font size. As the primary intended --- usage is for calculating the needed dimensions of a miniConsole, it doesn't accept a font argument - --- as the miniConsoles currently only work with the default font for the sake of portability. --- --- @usage Get font dimensions in pixes. ---
---   x,y = calcFontSize(10)
---   
--- @usage Create a miniConsole that is 45 letters in length and 25 letters in height for font size 7 ---
---   font_size = 7
---   local x, y = calcFontSize( font_size )
---   createMiniConsole("map",0,0,0,0)
---   setMiniConsoleFontSize("map", font_size)
---   resizeWindow( "map", x*45, y*25 )
---   
function calcFontSize(fontSize) end --- The channel102 table is used by Aardwolf mud for returning various information about you state.
--- Read http://www.aardwolf.com/blog/2008/07/10/telnet-negotiation-control-mud-client-interaction/ --- page for details. --- --- @usage Display content of channel10 table. ---
---   display(channel102)
---   
--- @usage Function for detecting AFK status on Aardwolf mud. ---
---   function amIafk()
---      for k,v in pairs(channel102) do
---         if k==100 and v==4 then
---            return true
---         end
---      end
---      return false
---   end
---   
--- --- @see sendTelnetChannel102 --- --- @class function --- @name channel102 channel102 = {} --- Clears the user window or a mini console with the name given as argument. --- TODO is this still working? function clearUserWindow(windowName) end --- TODO clearWindow - TLuaInterpreter::clearUserWindow function clearWindow(windowName) end --- Clears the user window or a mini console with the name given as argument. --- --- @param windowName optinal function closeUserWindow(windowName) end --- The command variable holds initial user command e.g. unchanged by any aliases or triggers. --- This is typically used in alias scripts. --- --- @see line --- --- @class function --- @name command command = "" --- Copies the current selection to the clipboard. This function operates on rich text, i.e. --- the selected text including all its format codes like colors, fonts etc. in the clipboard --- until it gets overwritten by another copy operation. example: This script copies the current --- line on the main screen to a user window (mini console) named chat and gags the output on --- the main screen. --- --- @usage ---
---   selectString(line)
---   copy()
---   appendBuffer("chat")
---   replace("This line has been moved to the chat window!")
---   
--- --- @see paste --- @see appendBuffer function copy() end --- Creates a named buffer for formatted text, much like a user terminal window, but the buffer --- cannot be shown on the screen; intended for temporary buffer work function createBuffer(name) end --- TODO createButton - TLuaInterpreter::createButton function createButton() end --- Labels are intended for very small variable or prompt displays or images. labels are clickable and if you specify a callback function with --- setLabelClickCallback( labelName, myLabelOnClickFunction ) your function will get called if the user clicks on the label with the mouse. --- If fillBackground = 0, the background will be hidden, if fillBackground = 1 the background will be shown i.e. you can see the background color. --- labels can be transparent. You can place labels anywhere within then main display, also als overlays over the main displays e.g. for on --- screen buttons, micro display, etc. DON'T use labels for larger text displays because they are a lot slower than the highspeed mini consoles. ---

--- Labels accept some HTML and CSS code for text formating. --- --- @return true or false --- --- @usage This example creates a transparent overlay message box to show a big warning message "You are under attack!" in the middle of the screen. --- Because the background color has a transparency level of 150 (0-255, with 0 being completely transparent and 255 non-transparent) the background --- text can still be read through. The message box will disappear after 2.3 seconds. ---
---   local width, height = getMainWindowSize()
---   createLabel("messageBox",(width/2)-300,(height/2)-100,250,150,1)
---   resizeWindow("messageBox",500,70)
---   moveWindow("messageBox", (width/2)-300,(height/2)-100 )
---   setBackgroundColor("messageBox", 150,100,100,200)
---   echo("messageBox", [[<p style="font-size:35px"><b><center><font color="red">You are under attack!</font></center></b></p>]] )
---   showWindow("messageBox")
---   -- close the warning message box after 2.3 seconds
---   tempTimer(2.3, [[hideWindow("messageBox")]] )
---   
--- @usage see forum for more examples ---
---  http://mudlet.sourceforge.net/phpBB3/viewtopic.php?f=6&t=95
---  http://mudlet.sourceforge.net/phpBB3/viewtopic.php?f=6&t=865
---  
--- --- @see createMiniConsole --- @see hideWindow --- @see showWindow --- @see resizeWindow --- @see setLabelClickCallback --- @see setTextFormat --- @see moveWindow --- @see setMiniConsoleFontSize --- @see handleWindowResizeEvent --- @see setBorderTop --- @see setBorderColor function createLabel(name, posX, posY, width, height, fillBackground) end --- Opens a console window inside the main window of Mudlet. MiniConsole is openes at position posX/posY with size --- according to width/height (values depend on your own screen resolution usually between 0-1600 for x and 0-1024 --- for y). This console is the ideal fast colored text display for everything that requires a bit more text e.g. --- status screens, log windows, chat windows etc.. You can use clearWindow/moveCursor etc. functions for this window --- for custom printing as well as copy & paste functions for colored text copies from the main window or normal --- echoUserWindow(name, text) for normal printing. To set word wrap see setWindowWrap. To move the main window to --- make room for miniconsole windows on your screen (if you want to do this as you can also layer mini console --- and label windows) see setBorderTop, setBorderColor To have your screen layout adjusted after the window size --- of the main screen gets resized see handleWindowResizeEvent --- --- @usage Set up the small system message window in the top right corner ---
---   -- determine the size of your screen
---   WindowWidth = 0
---   WindowHeight = 0
---   WindowWidth, WindowHeight = getMainWindowSize()
---
---   createMiniConsole("sys",WindowWidth-650,0,650,300)
---   setBackgroundColor("sys",85,55,0,255)
---   setMiniConsoleFontSize("sys", 8)
---   -- wrap lines in window "sys" at 65 characters per line
---   setWindowWrap("sys", 40)
---   -- set default font colors and font style for window "sys"
---   setTextFormat("sys",0,35,255,50,50,50,0,0,0)
---
---   echo("sys","Hello world!")
---   
--- --- @see createLabel --- @see hideWindow --- @see showWindow --- @see resizeWindow --- @see setTextFormat --- @see moveWindow --- @see setMiniConsoleFontSize --- @see handleWindowResizeEvent --- @see setBorderTop --- @see setBorderColor --- @see setWindowWrap --- --- @return true or false function createMiniConsole(name, posX, posY, width, height) end --- This function creates a stop watch. It is high resolution time --- measurement tool. Stop watches can be started, stopped, reset and asked --- how much time has passed since the stop watch has been started. Returns --- the ID of a high resolution clock with milliseconds to measure time more --- accurately than what is possible with std. Lua routines ? --- startStopWatch, stopStopWatch, resetStopWatch, getStopWatchTime example: --- In a global script you create all stop watches that you need in your --- system and store the respective stopWatch-IDs in global variables: --- --- @return stop watch ID --- --- @usage ---
---   fightStopWatchID = createStopWatch()
---   -- you store the watchID in a global variable to access it from anywhere
---   startStopWatch(fightStopWatch)
---   -- To stop the watch and measure its time in e.g. a trigger script you can write:
---   fightTime = stopStopWatch(fightStopWatchID)
---   echo("The fight lasted for " .. fightTime .. " seconds.")
---   resetStopWatch(fightStopWatchID)
---   
--- --- @see startStopWatch --- @see resetStopWatch --- @see getStopWatchTime function createStopWatch() end --- TODO cut - TLuaInterpreter::cut function cut() end --- Deletes the current Line under the user cursor. Note: This is a high speed gagging tool --- and it is very good at this task. It is meant to be used when the line can be omitted --- entirely in the output. If you want to replace this line with something else have a look --- at the replace() functions below.

--- --- Note that scripts such as: deleteLine(); echo("this line is gone"); will not work because --- lines that have been gagged with deleteLine() will not be rendered even if there is text --- in the buffer. See wrapLine for details on how to force a re-render if this is necessary --- for some reason. This is not the recommended way of replacing text. --- --- @see wrapLine --- @see replace function deleteLine() end --- Disables/deactivates an alias with the given name. This means that when you type in text that should --- match it's pattern, it won't match and will be sent to the MUD. If several aliases have this name, they'll all be disabled. function disableAlias(name) end --- Uses trigger name as id or the id returned by tempTrigger() TODO tempKey? function disableKey(name) end --- Disables a timer from running it's script when it fires - so the timer --- cycles will still be happening, just no action on them. If you'd like to --- permanently delete it, use killTimer() instead.

--- --- Use timer name or the id returned by tempTimer() to identify the timer --- that you want to disable. --- --- @see tempTimer --- @see killTimer function disableTimer(name) end --- Use trigger name or the id returned by tempTrigger() to identify the --- timer that you want to disable. --- --- @see tempTrigger function disableTrigger(name) end --- Disconnect from current session without a proper logout. --- --- @see reconnect function disconnect() end --- This function appends text at the end of the current line. The current cursor position is ignored. --- Use moveCursor() and insertText() if you want to print at a different cursor position.
--- If the first argument is omitted the main console is used, otherwise the mini console windowName. --- --- @param windowName optional --- --- @usage Writes text to main window. ---
---   echo("Hello world\n")
---   
--- @usage Writes text to the mini console named "info" if such a window exists. ---
---   echo("info", "Hello this is the info window\n")
---   
--- --- @see moveCursor --- @see insertText function echo(windowName, text) end --- Echos a piece of text as a clickable link.
--- --- @release Mudlet 1.1.0-pre1 --- --- @usage Following will create "click me now" link. ---
---   echoLink("hi", [[echo("hey bub!")]], "click me now")
---   
--- --- @param windowName optional window name --- @param text to display in the echo. Same as a normal echo(). --- @param command lua code to do when the link is clicked. --- @param hint text for the tooltip to be displayed when the mouse is over the link. --- @param useCurrentFormat true/false - controls whenever the current text formatting (colors, underline, bold, etc) --- should be used, or the default link format. --- --- @see setLink --- @see insertLink function echoLink(windowName, text, command, hint, useCurrentFormat) end --- Same as setPopup() except it doesn't require a selection. Method echoPopup creates a link from the given text that it echos. --- --- @release Mudlet 1.1.0-pre1 --- --- @usage ---
---   echoPopup("activities to do", {[[send "sleep"]], [[send "sit"]], [[send "stand"]]}, {"sleep", "sit", "stand"})
---   
--- --- @see setPopup --- @see insertPopup function echoPopup() end --- This function will print text to both mini console windows, dock windows and labels. --- This function is outdated. Use echo( windowName, text ) instead. --- --- @see echo function echoUserWindow(windowName, text) end --- Enables/activates the alias by it's name. If several aliases have this name, they'll all be enabled. function enableAlias(name) end --- Enable key or key group "name" (hot keys or action keys). function enableKey(name) end --- Enables or activates a timer that was previously disabled. The parameter --- "name" expects the timer ID that was returned by tempTimer() on creation --- of the timer or the name of the timer in case of a GUI timer function enableTimer(name) end --- Enables a Trigger. see enableTimer() for more details. --- --- @see enableTimer function enableTrigger(name) end --- Tells you how many things of the given type exist. --- --- @param type can be "alias", "trigger", or "timer". --- --- @return number --- --- @usage ---
---   echo("I have " .. exists("my trigger", "trigger") .. " triggers called 'my trigger'!")
---   
--- @usage You can also use this alias to avoid creating duplicate things, for example: ---
---   -- this code doesn't check if an alias already exists and will keep creating new aliases
---   permAlias("Attack", "General", "^aa$", [[send ("kick rat")]])
---
---   -- while this code will make sure that such an alias doesn't exist first
---   -- we do == 0 instead of 'not exists' because 0 is considered true in Lua
---   if exists("Attack", "alias") == 0 then
---       permAlias("Attack", "General", "^aa$", [[send ("kick rat")]])
---   end
---   
--- --- @see isActive function exists(name, type) end --- Like send(), but without bypassing alias expansion. This function may lead to infinite recursion if --- you are not careful!

--- --- Now, while in Mudlet you can call another alias with the expandAlias() function, this is strongly --- discouraged. What you do instead if create a function (for example, send() and echo() are functions) --- that you can then call from your alias or trigger. This has many advantages - it's faster, you can --- easily give your function values, and your function can return you values, too.

--- --- Note: The variable "command" contains what was entered in the command line or issued via the expandAlias() --- function. If you use expandAlias( command ) inside an alias script the command would be doubled. You have --- to use send( ) inside an alias script to prevent recursion. This will send the data directly and bypass --- the alias expansion. --- --- @see send function expandAlias(command, print=1) end --- This function will have Mudlet parse the given text as if it came from the MUD - one great application --- is trigger testing. You can use \n to represent a new line. The function also accept ANSI color codes that --- are used in MUDs. A sample table can be found here. --- --- @usage Usage of new line characters. ---
---   feedTriggers("\nYou sit yourself down.\n")
---   
--- @usage Demonstration of ANSI color.
---
---   feedTriggers("\nThis is \27[1;32mgreen\27[0;37m, \27[1;31mred\27[0;37m, " ..
---      "\27[46mcyan background\27[0;37m,\27[32;47mwhite background and green foreground\27[0;37m.\n")
---   
function feedTriggers(text) end --- Get the RGB values of the first character of the current selection. --- --- @param windowName optional --- --- @usage Getting RGB component. ---
---   r,g,b = getBgColor(windowName)
---   
--- --- @see getFgColor function getBgColor(windowName) end --- This function can be used in checkbox button scripts (2-state buttons) to determine the current state of the checkbox. --- --- @usage ---
---   checked = getButtonStated()
---   if checked == 1 then
---       hideExits()
---   else
---       showExits()
---   end
---   
--- --- @return numneric state; state = 1 button is checked and state = 0, button is not checked function getButtonState() end --- Gets the absolute column number of the current user cursor. function getColumnNumber() end --- Returns the content of the current line under the user cursor in the --- buffer. The Lua variable line holds the content of getCurrentLine() --- before any triggers have been run on this line. When triggers change the --- content of the buffer, the variable line will not be adjusted and thus --- hold an outdated string. line = getCurrentLine() will update line to the --- real content of the current buffer. This is important if you want to --- copy the current line after it has been changed by some triggers. --- selectString( line,1 ) will return false and won't select anything --- because line no longer equals getCurrentLine(). Consequently, --- selectString( getCurrentLine(), 1 ) is what you need. --- --- @usage Update line variable with content of current line. ---
---   line = getCurrentLine()
---   
--- --- @see selectString function getCurrentLine() end --- This function returns the RGB values of the color of the first character of the current selection --- on mini console (window) windowName. --- --- @param windowName optional - if windowName is omitted Mudlet will use the main screen. --- --- @usage ---
---   r,g,b = getFgColor(windowName)
---   
--- @usage ---
---   local r,g,b
---   selectString("troll", 1)
---   r,g,b = getFgColor()
---   if r == 255 and g == 0 and b == 0 then
---       echo("HELP! troll is written in red letters, the monster is aggressive!\n")
---   end
---   
--- --- @see getBgColor function getFgColor(windowName) end --- Returns number of the last line in the text buffer. function getLastLineNumber() end --- Gets the absolute amount of lines in the current console buffer. --- --- @return number function getLineCount() end --- Gets the absolute line number of the current user cursor. function getLineNumber() end --- Returns a Lua table with the content of the lines on a per line basis. Absolute line numbers are used. --- --- @return section of the content of the screen text buffer. The form of the return value is: Lua_table[relative_linenumber, content] function getLines(from_line_number, to_line_number) end --- Return window width and window height (function have two return values). This is useful for calculating the window dimensions and --- placement of custom GUI toolkit items like labels, buttons, mini consoles etc. --- --- @usage ---
---   mainWindowWidth, mainWindowHeight = getMainWindowSize()
---   
--- --- @return 2 numbers, width and height in pixels function getMainWindowSize() end --- Returns the current home directory of the current profile. This can be used to store data, --- save statistical information or load resource files. --- --- @usage Get directory to current profile. ---
---   homedir = getMudletHomeDir()
---   
function getMudletHomeDir() end --- Returns the last measured response time between the sent command and the server reply. --- --- @return number of seconds (0.058 (=58 milliseconds lag) or 0.309 (=309 milliseconds)) function getNetworkLatency() end --- Returns the time without stoping stop watch (milliseconds based) in form of 0.058 --- (= clock ran for 58 milliseconds before it was stopped). --- @see createStopWatch function getStopWatchTime(watchID) end --- Return time information. --- --- @release Mudlet 1.0.6 --- --- @usage Get time as a table. ---
---   getTime()
---   
--- @usage Get time as a string (with default formatting). ---
---   getTime(true)
---   
--- @usage Get time as a string with user defined formatting. ---
---   getTime(true, "hh:mm")
---   
--- --- @param returnType Takes a boolean value (in Lua anything but false or nil will translate to true). If true, --- the function will return a table in the following format:
--- { hour = #, min = #, sec = #, msec = # }
--- If false or nil, it will return the time as a string using a format passed to the second arg or the --- default of hh:mm:ss.zzz --- --- @param format Format expressions built from following elements: ---
---   h               the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
---   hh              the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
---   H               the hour without a leading zero (0 to 23, even with AM/PM display)
---   HH              the hour with a leading zero (00 to 23, even with AM/PM display)
---   m               the minute without a leading zero (0 to 59)
---   mm              the minute with a leading zero (00 to 59)
---   s               the second without a leading zero (0 to 59)
---   ss              the second with a leading zero (00 to 59)
---   z               the milliseconds without leading zeroes (0 to 999)
---   zzz             the milliseconds with leading zeroes (000 to 999)
---   AP or A         use AM/PM display. AP will be replaced by either "AM" or "PM".
---   ap or a         use am/pm display. ap will be replaced by either "am" or "pm".
---
---   d               the day as number without a leading zero (1 to 31)
---   dd              the day as number with a leading zero (01 to 31)
---   ddd             the abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses QDate::shortDayName().
---   dddd            the long localized day name (e.g. 'Monday' to 'Qt::Sunday'). Uses QDate::longDayName().
---   M               the month as number without a leading zero (1-12)
---   MM              the month as number with a leading zero (01-12)
---   MMM             the abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses QDate::shortMonthName().
---   MMMM            the long localized month name (e.g. 'January' to 'December'). Uses QDate::longMonthName().
---   yy              the year as two digit number (00-99)
---   yyyy            the year as four digit number
---   
--- All other input characters will be ignored. Any sequence of characters that are enclosed in singlequotes will be treated as text and not be --- used as an expression. Two consecutive singlequotes ("''") are replaced by a singlequote in the output. function getTime(returnType, format) end --- Returns the timestamp string as it's seen when you enable the timestamps view (blue 'i' button bottom right of the Mudlet screen). --- --- @release Mudlet 1.1.0-pre1 --- --- @usage Echo the timestamp of the current line in a trigger. ---
---   echo( getTimestamp(getLineCount()) )
---   
--- --- @param console_name optional parameter function getTimestamp(console_name, lineNumber) end --- TODO hasFocus - TLuaInterpreter::hasFocus function hasFocus() end --- Hides tool bar name and makes it disappear. If all tool bars of a tool bar area (top, left, right) --- are hidden, the entire tool bar area disappears automatically. function hideToolBar(name) end --- This function hides a mini console label. To show it again use showWindow. --- --- @see showWindow --- @see createMiniConsole function hideWindow(name) end --- TODO insertHTML - TLuaInterpreter::insertHTML function insertHTML() end --- Same as echoLink() but inserts the text at the current cursor position, while echoLink inserts at the end --- of the current line. --- --- @release Mudlet 1.1.0-pre1 --- --- @see echoLink --- @see setLink function insertLink(windowName, text, command, hint, useCurrentFormat) end --- Same as echoPopup(), but inserts text at the current cursor position. --- --- @release Mudlet 1.1.0-pre1 --- --- @see setPopup --- @see echoPopup function insertPopup(windowName, text, commands, hints, useCurrentFormat) end --- Inserts text at the current cursor position in the main window. If the cursor has not been explicitly --- moved this function will always print at the beginning of the line whereas the echo() function will --- always print at the end of the line. --- --- @param windowName optional --- --- @see echo function insertText(windowName, text) end --- Opens a file chooser dialog, allowing the user to select a file or a folder visually. The function returns --- the selected path or nil if there was none chosen. --- --- @usage ---
---   local path = invokeFileDialog(false, "Find me the gfx folder, please")
---   if path then
---      echo(path)
---   end
---   
--- --- @param selection true for file selection, false for folder selection. --- @param dialogTitle name that the dialog (file chooser window) will have function invokeFileDialog(selection, dialogTitle) end --- You can use this function to check if something, or somethings, are active. Type can be either --- "alias", "trigger", or "timer", and name is the name of the said item you'd like to check. --- --- @param type could be "alias", "trigger", or "timer" --- --- @usage This will check is my "my trigger" is active. ---
---   echo("I have " .. isActive("my trigger", "trigger") .. " currently active triggers called 'my trigger'!")
---   
function isActive(name, type) end --- This function tests if the first character of the current selection has the background color specified by ansiBgColorCode. --- --- @see isAnsiFgColor function isAnsiBgColor(ansiBgColorCode) end --- This function tests if the first character of the current selection has the foreground color specified by --- ansiFgColorCode. Codes are: --- ---
---   0 = default text color
---   1 = light black
---   2 = dark black
---   3 = light red
---   4 = dark red
---   5 = light green
---   6 = dark green
---   7 = light yellow
---   8 = dark yellow
---   9 = light blue
---   10 = dark blue
---   11 = light magenta
---   12 = dark magenta
---   13 = light cyan
---   14 = dark cyan
---   15 = light white
---   16 = dark white
---   
--- --- @usage ---
---   selectString(matches[1], 1)
---   if isAnsiFgColor(5) then
---       bg("red")
---       resetFormat()
---       echo("yes, the text is light green")
---   else
---       echo( "no sorry, some other foreground color" )
---   end
---   
--- --- Note that matches[1] holds the matched trigger pattern - even in substring, exact match, begin of line substring trigger --- patterns or even color triggers that do not know about the concept of capture groups. Consequently, you can always test --- if the text that has fired the trigger has a certain color and react accordingly. This function is faster than using --- getFgColor() and then handling the color comparison in Lua. function isAnsiFgColor(ansiFgColorCode) end --- Returns true or false depending on if the current line being processed is a prompt. This infallible --- feature is available for MUDs that supply GA events (to check if yours is one, look to bottom-right --- of the main window - if it doesn't say <No GA>, then it supplies them). --- --- @return true/false function isPrompt() end --- Deletes an alias with the given name. If several aliases have this name, they'll all be deleted. --- --- @see killTimer --- @see killTrigger function killAlias(name) end --- Deletes a tempTimer. Use the Timer ID returned by tempTimer() as name parameter. ID is a string and not a number. --- This function returns true on success and false if the timer id doesn't exist anymore (=timer has already fired) --- or the timer is not a temp timer. Note that non-temporary timers that you have set up in the GUI cannot be deleted --- with this function. Use disableTimer() to turn them on or off. --- --- @see killAlias --- @see killTrigger --- --- @return true or false function killTimer(id) end --- Deletes a tempTrigger according to trigger ID. ID is a string value, not a number. --- --- @see killAlias --- @see killTimer --- --- @return true or false function killTrigger(id) end --- The line variable holds the content of the current line as being processed by the trigger engine. --- The engine runs all triggers on each line as it arrives from the MUD. --- --- @see command --- --- @class function --- @name line line = "" --- TODO loadRawFile - TLuaInterpreter::loadRawFile function loadRawFile() end --- The matches table contains captured group. This available only within trigger context. --- First item of matches table (matches[1]) holds current line, all other contains capture groups --- defined by regular expression trigger. --- --- @usage Let say that you defined following trigger to detect and get dropped items. ---
---   RegEx:
---      ^The (.*) drops (.*)\.$
---   Code:
---      display(matches)
---      send("get " .. matches[3])
---   
--- --- Now let's say that MUD will send you following text (which will invoke your trigger). ---
---   The skeleton drops scimitar.
---   
--- --- This will send "get scimitar" to your MUD and also print following table: ---
---   table {
---     1: 'The skeleton drops scimitar.'
---     2: 'skeleton'
---     3: 'scimitar'
---   }
---   
--- --- @see showCaptureGroups --- @see multimatches --- @fee feedTriggers --- --- @class function --- @name matches matches = {} --- Moves the user cursor of the window windowName to the absolute point (x,y). This function returns false --- if such a move is impossible e.g. the coordinates don't exist. To determine the correct coordinates use --- getLineNumber(), getColumnNumber() and getLastLineNumber(). The trigger engine will always place the user --- cursor at the beginning of the current line before the script is run. If you omit the windowName argument, --- the main screen will be used. --- --- @return true or false --- --- @usage Set up the small system message window in the top right corner. ---
---   -- determine the size of your screen
---   WindowWidth=0;
---   WindowHeight=0;
---   WindowWidth, WindowHeight = getMainWindowSize();
---
---   -- define a mini console named "sys" and set its background color
---   createMiniConsole("sys",WindowWidth-650,0,650,300)
---   setBackgroundColor("sys",85,55,0,255);
---
---   -- you *must* set the font size, otherwise mini windows will not work properly
---   setMiniConsoleFontSize("sys", 12);
---   -- wrap lines in window "sys" at 65 characters per line
---   setWindowWrap("sys", 60);
---   -- set default font colors and font style for window "sys"
---   setTextFormat("sys",0,35,255,50,50,50,0,0,0);
---   -- clear the window
---   clearUserWindow("sys")
---
---   moveCursorEnd("sys")
---   setFgColor("sys", 10,10,0)
---   setBgColor("sys", 0,0,255)
---   echo("sys", "test1---line1\n\n\n")
---   echo("sys", "test1---line2\n")
---   echo("sys", "test1---line3\n")
---   setTextFormat("sys",158,0,255,255,0,255,0,0,0);
---   --setFgColor("sys",255,0,0);
---   echo("sys", "test1---line4\n")
---   echo("sys", "test1---line5\n")
---   moveCursor("sys", 1,1)
---
---   -- deleting lines 2+3
---   deleteLine("sys");
---   deleteLine("sys");
---
---   -- inserting a line at pos 5,2
---   moveCursor("sys", 5,2);
---   setFgColor("sys", 100,100,0)
---   setBgColor("sys", 255,100,0)
---   insertText("sys","############## line inserted at pos 5/2 ##############");
---
---   -- inserting a line at pos 0,0
---   moveCursor("sys", 0,0)
---   selectCurrentLine("sys");
---   setFgColor("sys", 255,155,255);
---   setBold( "sys", true );
---   setUnderline( "sys", true );
---   setItalics( "sys", true );
---   insertText("sys", "------- line inserted at: 0/0 -----\n");
---
---   setBold( "sys", true )
---   setUnderline( "sys", false )
---   setItalics( "sys", false )
---   setFgColor("sys", 255,100,0)
---   setBgColor("sys", 155,155,0)
---   echo("sys", "*** This is the end. ***\n");
---   
function moveCursor(windowName, x, y) end --- Moves the cursor to the end of the buffer. "main" is the name of the main window, otherwise use the name of your user window. --- --- @return true or false --- --- @see moveCursor function moveCursorEnd(windowName) end --- This function moves window name to the given x/y coordinate. The main screen cannot --- be moved. Instead you'll have to set appropriate border values in preferences to move --- the main screen e.g. to make room for chat or information mini consoles, or other GUI --- elements. In the future moveWindow() will set the border values automatically if the name --- parameter is omitted. --- --- @see createMiniConsole --- @see createLabel --- @see handleWindowResizeEvent --- @see resizeWindow --- @see setBorderTop function moveWindow(name, x, y) end --- The multimatches table is being used by Mudlet in the context of multiline triggers that use Perl regular expression. --- It holds the table matches[n] as described above for each Perl regular expression based condition of the multiline trigger. --- multimatches[5][4] may hold the 3rd capture group of the 5th regex in the multiline trigger. This way you can examine and --- process all relevant data within a single script.

--- --- What makes multiline triggers really shine is the ability to react to MUD output that is spread over multiple lines --- and only fire the action (=run the script) if all conditions have been fulfilled in the specified amount of lines. --- --- @usage Have a look at this example (can be tested on the MUD batmud.bat.org).
--- In the case of a multiline trigger with these 2 Perl regex as conditions: ---
---   ^You have (\w+) (\w+) (\w+) (\w+)
---   ^You are (\w+).*(\w+).*
---   
--- The command "score" generates the following output on batMUD: ---
---   You have an almost non-existent ability for avoiding hits.
---   You are irreproachably kind.
---   You have not completed any quests.
---   You are refreshed, hungry, very young and brave.
---   Conquer leads the human race.
---   Hp:295/295 Sp:132/132 Ep:182/181 Exp:269 >
---   
--- If you add this script to the trigger: ---
---   showMultimatches()
---   
--- The script, i.e. the call to the function showMultimatches() generates this output: ---
---   -------------------------------------------------------
---   The table multimatches[n][m] contains:
---   -------------------------------------------------------
---   regex 1 captured: (multimatches[1][1-n])
---             key=1 value=You have not completed any quests
---             key=2 value=not
---             key=3 value=completed
---             key=4 value=any
---             key=5 value=quests
---   regex 2 captured: (multimatches[2][1-n])
---             key=1 value=You are refreshed, hungry, very young and brave
---             key=2 value=refreshed
---             key=3 value=young
---             key=4 value=and
---             key=5 value=brave
---   -------------------------------------------------------
---   
--- The function showMultimatches() prints out the content of the table multimatches[n][m]. You can now see what the table --- multimatches[][] contains in this case. The first trigger condition (=regex 1) got as the first full match --- "You have not completed any quests". This is stored in multimatches[1][1] as the value of key=1 in the sub-table matches[1] --- which, in turn, is the value of key=1 of the table multimatches[n][m].

--- --- Following script would use matched values from previously defined regex in the multiline trigger: ---
---   myGold = myGold + tonumber( multimatches[1][2] )
---   mySilver = mySilver + tonumber( multimatches[1][3] )
---   
--- --- @see showMultimatches --- @see matches --- --- @class function --- @name multimatches multimatches = {} --- Opens a user dockable console window for user output e.g. statistics, chat etc. If a window of such --- a name already exists, nothing happens. You can move these windows, dock them, make them into notebook --- tabs or float them.

--- --- Note: There isn't currently way how to set size and position of user windows at the moment, so you might --- consider to use mini console instead. --- --- @usage This command will open new user windows with name "Chat". ---
---   openUserWindow("Chat")
---   
--- --- @see createMiniConsole function openUserWindow(windowName) end --- Pastes the previously copied text including all format codes like color, font etc. at the current user --- cursor position. The copy() and paste() functions can be used to copy formated text from the main window --- to a user window without losing colors e. g. for chat windows, map windows etc. --- --- @see copy function paste(windowName) end --- TODO pasteWindow - TLuaInterpreter::pasteWindow function pasteWindow() end --- Creates a persistent alias that stays after Mudlet is restarted and shows up in the Script Editor.

--- --- Note that Mudlet by design allows duplicate names - so calling permAlias with the same name will keep creating --- new aliases. You can check if an alias already exists with the exists() function. --- --- @param name is the name you'd like the alias to have. --- @param parent is the name of the group, or another alias you want the trigger to go in - however if such a group/alias --- doesn't exist, it won't do anything. Use "" to make it not go into any groups. --- @param regex is the pattern that you'd like the alias to use. --- @param luaCode is the script the alias will do when it matches. --- --- @usage Creates an alias called "new alias" in a group called "my group". ---
---   permAlias("new alias", "my group", "^test$", [[echo ("say it works! This alias will show up in the script editor too.")]])
---   
--- --- @see exists function permAlias(name, parent, regex, luaCode) end --- Creates a persistent trigger with a begin of line substring pattern that shows up in the Script Editor --- and stays after Mudlet is restarted.
---
--- Note that Mudlet by design allows duplicate names - so calling permBeginOfLineStringTrigger with the same --- name will keep creating new triggers. You can check if a trigger already exists with the exists() function. --- --- @param name is the name you'd like the trigger to have. --- @param parent is the name of the group, or another trigger you want the trigger to go in - however --- if such a group/trigger doesn't exist, it won't do anything. Use "" to make it not go into any groups. --- @param patternTable is a table of patterns that you'd like the trigger to use - it can be one or many. --- @param luaCode is the script the trigger will do when it matches. --- --- @usage Create a trigger that will match on anything that starts with "You sit" and do "stand". --- It will not go into any groups, so it'll be on the top. ---
---   permBeginOfLineStringTrigger("Stand up", "", {"You sit"}, [[send ("stand")]])
---   
--- @usage Another example - lets put our trigger into a "General" folder and give it several patterns. ---
---   permBeginOfLineStringTrigger("Stand up", "General", {"You sit", "You fall", "You are knocked over by"}, [[send ("stand")]])
---   
function permBeginOfLineStringTrigger(name, parent, patternTable, luaCode) end --- Creates a persistent trigger with a regex pattern that stays after Mudlet is restarted and shows up in the --- Script Editor.

--- --- Note that Mudlet by design allows duplicate names - so calling permRegexTrigger with the same name will keep creating --- new aliases. You can check if an alias already exists with the exists() function. --- --- @param name is the name you'd like the alias to have. --- @param parent is the name of the group, or another alias you want the trigger to go in - however if such a group/alias --- doesn't exist, it won't do anything. Use "" to make it not go into any groups. --- @param regex is the pattern that you'd like the alias to use. --- @param luaCode is the script the alias will do when it matches. --- --- @usage Create a regex trigger that will match on the prompt to record your status. ---
---   permRegexTrigger("Prompt", "", {"^(\d+)h, (\d+)m"}, [[health = tonumber(matches[2]; mana = tonumber(matches[3])]]
---   
--- --- @see exists function permRegexTrigger(name, parent, pattern, luaCode) end --- Creates a persistent trigger with a substring pattern that stays after Mudlet is restarted and shows up in --- the Script Editor.

--- --- Note that Mudlet by design allows duplicate names - so calling permSubstringTrigger with the same name will keep creating --- new aliases. You can check if an alias already exists with the exists() function. --- --- @param name is the name you'd like the alias to have. --- @param parent is the name of the group, or another alias you want the trigger to go in - however if such a group/alias --- doesn't exist, it won't do anything. Use "" to make it not go into any groups. --- @param regex is the pattern that you'd like the alias to use. --- @param luaCode is the script the alias will do when it matches. --- --- @usage Create a trigger to highlight the word "pixie" for us. ---
---   permSubstringTrigger("Highlight stuff", "General", {"pixie"}, [[selectString(line, 1) bg("yellow") resetFormat()]])
---   
--- @usage Another trigger to highlight several different things. ---
---   permSubstringTrigger("Highlight stuff", "General", {"pixie", "cat", "dog", "rabbit"}, [[selectString(line, 1) fg ("blue") bg("yellow") resetFormat()]])
---   
--- --- @see exists function permSubstringTrigger(name, parent, pattern, luaCode) end --- Creates a persistent timer that stays after Mudlet is restarted and shows up in the Script Editor.

--- --- Note that Mudlet by design allows duplicate names - so calling permTimer with the same name will keep creating --- new timers. You can check if a timer already exists with the exists() function. --- --- @param name timer name, parent is the name of the timer group you want the timer to go in. --- @param seconds number specifying a delay after which the timer will execute the lua code. --- @param luaCode code to execute --- --- @usage Creates new time that will tick each 4.5s. ---
---   permTimer("my timer", "first timer group", 4.5, [[send ("my timer that's in my first timer group fired!")]])
---   
function permTimer(name, parent, seconds, luaCode) end --- This function plays a sound file. To make sound work on your operating system you may need to install additional packages:
--- Microsoft Windows: The underlying multimedia system is used; only WAVE format sound files are supported. (works out of the box)
--- Mac OS X: NSSound is used. All formats that NSSound supports, including QuickTime formats, are supported by Qt for Mac OS X --- (should work out of the box).
--- X11: The Network Audio System is used if available, otherwise all operations work silently. NAS supports WAVE and AU files. Please use --- following workaround for Linux systems: ---
---   if "linux" == getOS() then
---	     os.execute("aplay /usr/share/sounds/alsa/Front_Center.wav")
---   end
---   
function playSoundFile(fileName) end --- Raises the event event_name. The event system will call the main --- function (the one that is called exactly like the script name) of all --- such scripts that have registered event handlers. If an event is raised, --- but no event handler scripts have been registered with the event system, --- the event is ignored and nothing happens. This is convenient as you can --- raise events in your triggers, timers, scripts etc. without having to --- care if the actual event handling has been implemented yet - or more --- specifically how it is implemented. Your triggers raise an event to tell --- the system that they have detected a certain condition to be true or --- that a certain event has happened. How - and if - the system is going to --- respond to this event is up to the system and your trigger scripts don't --- have to care about such details. For small systems it will be more --- convenient to use regular function calls instead of events, however, the --- more complicated your system will get, the more important events will --- become because they help reduce complexity very much.

--- --- The corresponding event handlers that listen to the events raised with --- raiseEvent() need to use the script name as function name and take the --- correct number of arguments. NOTE: If you raise an event with 5 --- arguments but your event handlers functions only take 2,10 or 0 --- arguments, the functions will not be called. For example: --- raiseEvent("fight") a correct event handler function would be: --- myScript(event_name). In this example raiseEvent uses minimal arguments, name --- the event name. There can only be one event handler function per script, --- but a script can still handle multiple events as the first argument is --- always the event name. So you can call your own special handlers for --- individual events. The reason behind this is that you should rather use --- many individual scripts instead of one huge script that has all your --- function code etc. Scripts can be organized very well in trees and thus --- help reduce complexity on large systems.

--- --- As an example, your prompt trigger could raise an onPrompt event if you want to attach 2 functions to it. --- In your prompt trigger, all you'd need to do is raiseEvent("onPrompt") Now we go about creating functions --- that attach to the event. Lets say the first one is check_health_stuff() and the other is check_salve_stuff(). --- We would like these to be executed when the event is raised. So create a script and give it a name of check_health_stuff. --- In the Add user defined event handler, type onPrompt, and press enter to add it to the list. In the script box, --- create: function check_health_stuff()blah blah end. When the onPrompt event comes along, that script catches it, --- and does check_health_stuff() for you.

--- --- Default events raised by Mudlet
--- Mudlet itself also creates events for your scripts to hook on. The following events are generated currently:
--- --- sysWindowResizeEvent
--- Raised when the main window is resized, with the new height and width coordinates passed to the event. --- A common usecase for this event is to move/resize your UI elements according to the new dimensions. --- This sample code will echo whenever a resize happened with the new dimensions: ---
---   function resizeEvent( event, x, y )
---      echo("RESIZE EVENT: event="..event.." x="..x.." y="..y.."\n")
---   end
---   
--- --- sysWindowMousePressEvent
--- Raised when a mouse button is pressed down anywhere on the main window (note that a click is composed of a mouse --- press and mouse release). The button number and the x,y coordinates of the click are reported. ---
---   function onClickHandler( event, button, x, y )
---      echo("CLICK event:"..event.." button="..button.." x="..x.." y="..y.."\n")
---   end
---   
--- --- sysWindowMouseReleaseEvent
--- Raised when a mouse button is released after being pressed down anywhere on the main window (note that a click is composed --- of a mouse press and mouse release). See sysWindowMousePressEvent for example use. --- --- ATCP events

--- Mudlets ATCP implementation generates events for each message that comes, allowing you to trigger on them easily. --- Since ATCP messages vary in name, event names will vary as well. See the atcp section on how to use them. function raiseEvent(eventName, ...) end --- Reconnect to currect session. --- --- @see disconnect function reconnect() end --- Replaces the currently selected text with the new text. To select text, use selectString() and similar function. --- --- @usage Replace word "troll" with "cute trolly". ---
---   selectString("troll",1)
---   replace("cute trolly")
---   
--- --- @usage Lets replace the whole line. If you'd like to delete/gag the whole line, use deleteLine()! ---
---   selectString(line, 1)
---   replace("Out with the old, in with the new!")
---   
--- --- @see selectString --- @see deleteLine function replace(with) end --- Resets the character format to default. This should be used after you have highlighted some text --- or changed the current foreground or background color, but you don't want to keep using these --- colors for further prints. If you set a foreground or background color, the color will be used --- until you call resetFormat() on all further print commands. --- --- @param windowName optional function resetFormat(windowName) end --- This function resets the time to 0:0:0.0, but does not start the stop watch. You can start it with startStopWatch. --- --- @see createStopWatch --- @see startStopWatch function resetStopWatch(watchID) end --- Resizes a mini console or label. --- --- @see createMiniConsole --- @see createLabel --- @see handleWindowResizeEvent --- @see setBorderTop function resizeWindow(name, width, height) end --- Selects the content of the capture group number in your Perl regular expression e.g. "you have (\d+) Euro". --- If you want to color the amount of money you have green you do: --- --- @usage ---
---   setFgColor(0,255,0)
---   selectCaptureGroup(1)
---   
--- --- @param groupNumber with first group = 1 function selectCaptureGroup() end --- Selects the content of the current buffer line. ---
TODO It this valid? selectCurrentLine("sys")
function selectCurrentLine() end --- Select text on the line under the current cursor position. Use absolute column number for start of selection --- and length of selection The function returns true on success and false if the selection is not possible. --- --- @param windowName is optional function selectSection(windowName, from, lengthOfString) end --- Selects a substring from the line where the user cursor is currently positioned. You can move --- the user cursor with moveCursor(). When a new line arrives from the MUD, the user cursor is --- positioned at the beginning of the line. However, if one of your trigger scripts moves the --- cursor around you need to take care of the cursor position yourself and make sure that the --- cursor is in the correct line if you want to call one of the select functions. To deselect --- text, see deselect(). --- --- @usage Select "big monster" in the line. ---
---   selectString("big monster", 1)
---   
--- @usage Note: To prevent selection of random data use the error return if not found like this. ---
---   if selectString("big monster", 1) > -1 then
---      setFgColor(255,0,0)
---   end
---   
--- @usage In a trigger, lets color all words on the current line green. ---
---   selectString(line, 1)
---   fg("green")
---   resetFormat()
---   
--- --- @return returns position in line or -1 on error (text not found in line) --- --- @see deselect function selectString(text, numberOfMatch) end --- This sends "command" directly to the network layer, skipping the alias matching. The optional --- second argument of type boolean (print) determines if the outgoing command is to be echoed on the screen. --- Send honours command separator defined within Mudlet settings. If you want your command to be checked --- if it's an alias, use expandAlias() instead. --- --- @usage Echos the command on the screen. ---
---   send("Hello Jane")
---   
--- @usage Echos the command on the screen. ---
---   send("Hello Jane", true)
---   
--- @usage Does not echo the command on the screen. ---
---   send("Hello Jane", false)
---   
--- --- @param echoTheValue optional boolean flag (default value is true) which determine if value should --- be echoed back on client. --- --- @see expandAlias --- @see sendAll function send(command, echoTheValue) end --- TODO sendATCP - TLuaInterpreter::sendATCP --- @see atcp function sendATCP() end --- Send telnet channel 102 commands to MUD. This is widely used on Aardwolf for setting up user tags. --- --- @usage Following command will enable all Aardwolf channel tags. You need to have active session. ---
---   sendTelnetChannel102("\5\1")
---   
--- --- @see channel102 function sendTelnetChannel102() end --- Sets RGB color values and the transparency for the given window. Colors are from 0 to 255 (0 being black), --- and transparency is from - to 255 (0 being completely transparent).

--- --- Note that transparency only works on labels, not miniConsoles for efficiency reasons. function setBackgroundColor(windowName, red, green, blue, transparency) end -- Loads an image file (png) as a background image for a label. This can be used to display clickable images etc. function setBackgroundImage(labelName, imageFileName) end --- Sets the current text background color in window windowName (or in main windows if you haven't specified that). If you have selected --- text prior to this call, the selection will be highlightd otherwise the current text background color will be changed. If you set a --- foreground or background color, the color will be used until you call resetFormat() on all further print commands. --- --- @param windowName optional --- --- @usage Highlights the first occurrence of the string "Tom" in the current line with a red background color. ---
---   selectString( "Tom", 1 )
---   setBgColor( 255,0,0 )
---   
--- --- @usage Prints "Hello" on red background and "You" on blue. ---
---   setBgColor(255,0,0)
---   echo("Hello")
---   setBgColor(0,0,255)
---   echo(" You!")
---   resetFormat()
---   
--- --- @see setFgColor function setBgColor(windowName, r, g, b) end --- Sets the current text font to bold (true) or non-bold (false) mode. If the windowName parameters omitted, the main screen will be used. --- --- @param windowName optional function setBold(windowName, bool) end --- Sets the height of the bottom border to size pixel and thus effectively moves down the main console --- window by size pixels to make room for e.g. mini console windows, buttons etc.. --- --- @see setBorderTop --- @see setBorderLeft --- @see setBorderRight function setBorderBottom(size) end --- Sets the color of the border in RGB color. --- --- @usage Sets the border to red. ---
---   setBorderColor( 255, 0, 0 )
---   
function setBorderColor(red, green, blue) end --- Sets the width of the left border and thus effectively moves down the main console --- window by size pixels to make room for e.g. mini console windows, buttons etc.. --- @see setBorderTop --- @see setBorderBottom --- @see setBorderRight function setBorderLeft(size) end --- Sets the width of the right border and thus effectively moves down the main console --- window by size pixels to make room for e.g. mini console windows, buttons etc.. --- --- @see setBorderTop --- @see setBorderBottom --- @see setBorderLeft function setBorderRight(size) end --- Sets the height of the top border to size pixel and thus effectively moves down the main console --- window by size pixels to make room for e.g. mini console windows, buttons etc.. --- --- @see setBorderBottom --- @see setBorderLeft --- @see setBorderRight function setBorderTop(size) end --- Set the scrollback buffer size to linesLimit and determine how many lines are deleted at once in --- case the lines limit is reached. The lower the limit the less memory being used. On machines with --- low RAM you should consider limiting the size of buffers that don't need a lot of scrollback --- e.g. system notification windows, chat windows etc..
--- Default values are linesLimit = 100000 lines with 10000 lines of batch deletion.
--- Minimum buffer size is 100 lines with 10 lines batch deletion. function setConsoleBufferSize(consoleName, linesLimit, sizeOfBatchDeletion) end --- Sets the current text foreground color in the main window. Values are RGB: red, green, blue ranging from 0-255 e.g. --- --- @param windowName optional --- --- @usage Set blue foreground. ---
---   setBgColor(0,0,255)
---   
--- @param windowName optional --- --- @setBgColor function setFgColor(windowName, r, g, b) end --- Sets the current text font to italics/non-italics mode. If the windowName parameters omitted, the main screen will be used. --- --- @param windowName optional function setItalics(windowName, bool) end --- Specify a Lua function to be called if the user clicks on the --- label/image. E.g. setLabelClickCallback( "compassNorthImage", "onClickGoNorth" )

--- --- UPDATE: this function can now pass any number of string or integer number values as additional parameters. --- These parameters are then used in the callback. Thus you can associate data with the label/button. --- Check the forum for more information on how to use this. FIXME function setLabelClickCallback(labelName, luaFunctionName, ...) end --- TODO setLabelStyleSheet - TLuaInterpreter::setLabelStyleSheet function setLabelStyleSheet() end --- Turns the selected text into a clickable link - upon being clicked, the link will do the command code. --- Tooltip is a string which will be displayed when the mouse is over the selected text. --- --- @release Mudlet 1.1.0-pre1 --- --- @usage In a sewer grate substring trigger, the following code will make clicking on the words do the send("enter grate") command: ---
---   selectString(matches[1], 1)
---   setLink([[send("enter grate")]], "Clicky to enter grate")
---   
--- --- @see echoLink --- @see insertLink function setLink(command, tooltip) end --- Sets the font size of the mini console. --- --- @see createMiniConsole --- @see createLabel function setMiniConsoleFontSize(name, fontSize) end --- Turns the selected text into a left-clickable link, and a right-click menu. The selected text, --- upon being left-clicked, will do the first command in the list. Upon being right-clicked, it'll --- display a menu with all possible commands. The menu will be populated with hints, one for each line. --- --- @release Mudlet 1.1.0-pre1 --- --- @usage In a Raising your hand in greeting, you say "Hello!" exact match trigger, the following code will --- make left-clicking on Hello show you an echo, while left-clicking will show some commands you can do. ---
---   selectString("Hello", 1)
---   setPopup("main", {[[send("bye")]], [[echo("hi!")]]}, {"left-click or right-click and do first item to send bye", "click to echo hi"})
---   
--- --- @param name the name of the console to operate on. If not using this in a miniConsole, use "main" as the name. --- @param commands a table of lua code strings to do e.g. {[[send("hello")]], [[echo("hi!"]]}. --- @param hints a table of strings which will be shown on the popup and right-click menu e.g. {"send the hi command", "echo hi to yourself"}. function setPopup(name, commands, hints) end --- Sets current text format of window. A more convenient way to control the text format in a mini console is to --- use setFgColor, setBold, setItalics, setUnderline etc. --- --- @param windowName --- @param fgR foreground color(r,g,b) --- @param fgG foreground color(r,g,b) --- @param fgB foreground color(r,g,b) --- @param bgR background color(r,g,b) --- @param bgG background color(r,g,b) --- @param bgB background color(r,g,b) --- @param bold bold flag (1/0) --- @param underline underline flag (1/0) --- @param italics italics flag (1/0) --- --- @usage This script would create a mini text console and write with yellow foreground color and blue background color "This is a test". ---
---   createMiniConsole("con1", 0, 0, 300, 100)
---   setTextFormat("con1", 0,0,255, 255,255,0, 1,1,1)
---   echo("con1", "This is a test")
---   
--- --- @see createMiniConsole --- @see setBold --- @see setBgColor --- @see setFgColor --- @see setItalics --- @see setUnderline function setTextFormat(windowName, fgR, fgG, fgB, bgR, bgG, bgB, bold, underline, italics) end --- Set for how many more lines a trigger script should fire or a chain should stay open after the trigger has matched. --- The main use of this function is to close a chain when a certain condition has been met. --- --- @param number should be 0 to close the chain, or a positive number to keep the chain open that much longer. function setTriggerStayOpen(name, number) end --- Sets the current text font to underline/non-underline mode. If the windowName parameters omitted, the main screen will be used. --- --- @param windowName optional function setUnderline(windowName, bool) end --- Sets at what position in the line the console or miniconsole will start word wrap. function setWindowWrap(windowName, wrapAt) end --- TODO setWindowWrapIndent - TLuaInterpreter::setWindowWrapIndent function setWindowWrapIndent() end --- Shows tool bar name on the screen. function showToolBar(name) end --- This function shows a mini console or label. To hide it use hideWindow. --- @see hideWindow --- @see createMiniConsole --- @see createLabel function showWindow(name) end --- TODO spawn - TLuaInterpreter::spawn function spawn() end --- TODO startLogging - TLuaInterpreter::startLogging function startLogging() end --- Starts the stop watch. --- @see createStopWatch function startStopWatch(watchID) end --- Stops the stop watch and returns the elapsed time in milliseconds in form of 0.001. --- @see createStopWatch --- @return returns time as a number function stopStopWatch() end --- Creates a temporary (lasts only until the profile is closed) alias. This means that it won't exist anymore after Mudlet restarts. --- --- @usage This triggers waits for "hi" string. ---
---   tempAlias("^hi$", [[send ("hi") echo ("we said hi!")]]
---   
--- --- @return id function tempAlias(regex, luaCode) end --- Makes a color trigger that triggers on the specified foreground and background color. Both colors need to be --- supplied in form of these simplified ANSI 16 color mode codes: --- ---
---   0 = default text color
---   1 = light black
---   2 = dark black
---   3 = light red
---   4 = dark red
---   5 = light green
---   6 = dark green
---   7 = light yellow
---   8 = dark yellow
---   9 = light blue
---   10 = dark blue
---   11 = light magenta
---   12 = dark magenta
---   13 = light cyan
---   14 = dark cyan
---   15 = light white
---   16 = dark white
---   
--- --- @usage This script will re-highlight all text in blue foreground colors on a black background with a red foreground --- color on a blue background color until another color in the current line is being met. temporary color triggers --- do not offer match_all or filter options like the GUI color triggers because this is rarely necessary for scripting. --- A common usage for temporary color triggers is to schedule actions on the basis of forthcoming text colors --- in a particular context. ---
---   tempColorTrigger(9,2,[[selectString(matches[1],1); fg("red"); bg("blue");]] );
---   
function tempColorTrigger(foregroundColor, backgqroundColor, luaCode) end --- TODO example with luaCode - --- Temporary trigger that will fire on n consecutive lines following the --- current line. This is useful to parse output that is known to arrive in --- a certain line margin or to delete unwanted output from the MUD. --- --- @return the string ID of the newly created temporary trigger. --- You can use this ID to enable/disable or kill this trigger later on. --- --- @usage Following will fire 3 times starting with the line from the MUD. ---
---   tempLineTrigger( 1, 3, [[send("shout Help")]])
---   
--- @usage This will fire 20 lines after the current line and fire twice on 2 consecutive lines. ---
---   tempLineTrigger( 20, 2, [[send("shout Help")]])
---   
function tempLineTrigger(from, howMany, luaCode) end --- Temporary trigger using Perl regex pattern matching. --- --- @return the string ID of the newly created temporary trigger. --- You can use this ID to enable/disable or kill --- this trigger later on. --- --- @see killTrigger --- @see tempTrigger function tempRegexTrigger(regex, luaCode) end --- Creates a temporary single shot timer and returns the timer ID for subsequent enableTimer(), disableTimer() and killTimer() calls. --- You can use 2.3 seconds or 0.45 etc. After it has fired, the timer will be deactivated and killed.

--- --- Note [[ ]] can be used to quote strings in Lua. The difference to the usual `" " quote syntax is that `[[ ]] also accepts the --- character ". Consequently, you don't have to escape the " character in the above script. The other advantage is that it can be --- used as a multiline quote. --- --- @usage This script will send the command "kill rat" 0.3 seconds after this function has been called. Note that this function --- does not wait until 0.3 seconds have been passed, but it will start a timer that will run the Lua script that you have provided --- as a second argument after 0.3 seconds. ---
---   tempTimer(0.3, [[send("kill rat")]] )
---   
--- --- @usage Also note that the Lua code that you provide as an argument is compiled from a string value when the timer fires. --- This means that if you want to pass any parameters by value e.g. you want to make a function call that uses the value --- of your variable myGold as a parameter you have to do things like this: ---
---   tempTimer(3.8, [[echo("at the time of the tempTimer call I had ]] .. myGold .. [[ gold.")]] )
---   
--- --- @return timer ID, ID is a string and not a number. function tempTimer(seconds, luaCode) end --- This function creates a temporary trigger using substring matching. --- Contrary to tempTimers, tempTriggers lives throughout the entire session --- until it is explicitly disabled or killed. Disabled tempTimers can be --- re-enabled with enableTrigger(). This is much faster than killing the --- trigger and creating a new one. This is the second fastest trigger (with --- begin of line substring patterns being the fastest) and should be used --- instead of regex triggers whenever possible. --- --- @return trigger ID, ID is a string and not a number. --- --- @usage You can put the following script into your targeting alias highlight your target.
--- (Note: trigger will stay active unless you'll kill it.) ---
---   target = "rat"
---   if id then
---      killTrigger(id)
---   end
---   id = tempTrigger(target, [[selectString("]] .. target .. [[", 1) fg("gold") resetFormat()]])
---   
--- --- @see killTrigger --- @see tempRegexTrigger function tempTrigger(string, luaCode) end --- Wait for specified time in milliseconds. --- Use tempTimer instead! Don't use this function, because it freezes main thread. --- --- @usage Preferred use of tempTimer - wait for 2 seconds and than send "kill rat". ---
---   tempTimer(2, [[send("kill rat")]] )
---   
--- @usage Discouraged use of wait function. ---
---   -- This will freeze Mudlet for 2 seconds!!!
---   wait(2000)
---   send("kill rat")
---   
--- @usage This example is demonstrating transition from Nexus/Zmud wait. --- You can simply rewrote following nexus/zmud code bellow with tempTimers. ---
---   #send jerk fish
---   #wait 1500
---   #send pull line
---   #wait 500
---   #send jump
---   
--- Since timers are created instantly, if you want two or more, or means the times --- for consecutive timers should be to the starting point, unlike relatives times you do with waits. ---
---   -- Mudlet code
---   send ("jerk fish")
---   tempTimer (1.5, [[send ("pull line")]])
---   tempTimer (2,   [[send ("jump")]])
---   
--- --- @see tempTimer function wait(time) end --- Wrap line lineNumber of mini console (window) windowName. This function will interpret \n characters, --- apply word wrap and display the new lines on the screen. This function may be necessary if you use --- deleteLine() and thus erase the entire current line in the buffer, but you want to do some further --- echo() calls after calling deleteLine(). You will then need to re-wrap the last line of the buffer --- to actually see what you have echoed and get you \n interpreted as newline characters properly.

--- --- Using this function is not good programming practice and should be avoided. There are better ways of --- handling situations where you would call deleteLine() and echo afterwards e.g.: ---
---   selectString(line,1)
---   replace("")
---   
--- This will effectively have the same result as a call to deleteLine() but the buffer line will not --- be entirely removed. Consequently, further calls to echo() etc. sort of functions are possible --- without using wrapLine() unnecessarily. function wrapLine() end end mudlet-2.1/src/mudlet-lua/lua/luadoc/0000755000175000017500000000000011520630027017042 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/lua/luadoc/README.txt0000644000175000017500000000134111520630027020537 0ustar csmallcsmall Mudlet taglet and doclet are extension to LuaDoc which is - supporting
 formatted text (see simple example bellow)
  - generating master index of function (we are assuming that all function names are unique)
  - correctly linking to functions from different file
  - keeping link menu accessible in the top left corner all the time
  - improving visual side of generated documentation

based on LuaDoc 3.0.1



-------------------------------------------------------------------------------
-- This is just copy of standard.lua with support for 
 tag in 
-- documentation. See example bellow:
--
-- 
--	if info ~= nil then
--		assert(info.name, "function name undefined")
--	end
-- 
-- function test(a, b, c) end mudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/0000755000175000017500000000000011520630027020314 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/mudlet.lua0000644000175000017500000002260111520630027022312 0ustar csmallcsmall------------------------------------------------------------------------------- -- Doclet that generates HTML output. This doclet generates a set of html files -- based on a group of templates. The main templates are: --
    --
  • index.lp: index of modules and files;
  • --
  • file.lp: documentation for a lua file;
  • --
  • module.lp: documentation for a lua module;
  • --
  • function.lp: documentation for a lua function. This is a -- sub-template used by the others.
  • --
-- -- @release $Id: html.lua,v 1.29 2007/12/21 17:50:48 tomas Exp $ ------------------------------------------------------------------------------- local assert, getfenv, ipairs, loadstring, pairs, setfenv, tostring, tonumber, type = assert, getfenv, ipairs, loadstring, pairs, setfenv, tostring, tonumber, type local io = require"io" local lfs = require "lfs" local lp = require "luadoc.lp" local luadoc = require"luadoc" local package = package local string = require"string" local table = require"table" module "luadoc.doclet.mudlet" ------------------------------------------------------------------------------- -- Looks for a file `name' in given path. Removed from compat-5.1 -- @param path String with the path. -- @param name String with the name to look for. -- @return String with the complete path of the file found -- or nil in case the file is not found. local function search (path, name) for c in string.gfind(path, "[^;]+") do c = string.gsub(c, "%?", name) local f = io.open(c) if f then -- file exist? f:close() return c end end return nil -- file not found end ------------------------------------------------------------------------------- -- Include the result of a lp template into the current stream. function include (template, env) -- template_dir is relative to package.path local templatepath = options.template_dir .. template -- search using package.path (modified to search .lp instead of .lua local search_path = string.gsub(package.path, "%.lua", "") local templatepath = search(search_path, templatepath) assert(templatepath, string.format("template `%s' not found", template)) env = env or {} env.table = table env.io = io env.lp = lp env.ipairs = ipairs env.tonumber = tonumber env.tostring = tostring env.type = type env.luadoc = luadoc env.options = options return lp.include(templatepath, env) end ------------------------------------------------------------------------------- -- Returns a link to a html file, appending "../" to the link to make it right. -- @param html Name of the html file to link to -- @return link to the html file function link (html, from) local h = html from = from or "" string.gsub(from, "/", function () h = "../" .. h end) return h end ------------------------------------------------------------------------------- -- Returns the name of the html file to be generated from a module. -- Files with "lua" or "luadoc" extensions are replaced by "html" extension. -- @param modulename Name of the module to be processed, may be a .lua file or -- a .luadoc file. -- @return name of the generated html file for the module function module_link (modulename, doc, from) -- TODO: replace "." by "/" to create directories? -- TODO: how to deal with module names with "/"? assert(modulename) assert(doc) from = from or "" if doc.modules[modulename] == nil then -- logger:error(string.format("unresolved reference to module `%s'", modulename)) return end local href = "modules/" .. modulename .. ".html" string.gsub(from, "/", function () href = "../" .. href end) return href end ------------------------------------------------------------------------------- -- Returns the name of the html file to be generated from a lua(doc) file. -- Files with "lua" or "luadoc" extensions are replaced by "html" extension. -- @param to Name of the file to be processed, may be a .lua file or -- a .luadoc file. -- @param from path of where am I, based on this we append ..'s to the -- beginning of path -- @return name of the generated html file function file_link (to, from) assert(to) from = from or "" local href = to href = string.gsub(href, "lua$", "html") href = string.gsub(href, "luadoc$", "html") href = "files/" .. href string.gsub(from, "/", function () href = "../" .. href end) return href end ------------------------------------------------------------------------------- -- Returns a link to a function or to a table -- @param fname name of the function or table to link to. -- @param doc documentation table -- @param kind String specying the kinf of element to link ("functions" or "tables"). function link_to (fname, doc, module_doc, file_doc, from, kind) assert(fname) assert(doc) from = from or "" kind = kind or "functions" if file_doc then for _, func_name in pairs(file_doc[kind]) do if func_name == fname then return file_link(file_doc.name, from) .. "#" .. fname end end end local _, _, modulename, fname = string.find(fname, "^(.-)[%.%:]?([^%.%:]*)$") assert(fname) -- if fname does not specify a module, use the module_doc if string.len(modulename) == 0 and module_doc then modulename = module_doc.name end local module_doc = doc.modules[modulename] if not module_doc then -- logger:error(string.format("unresolved reference to function `%s': module `%s' not found", fname, modulename)) return end for _, func_name in pairs(module_doc[kind]) do if func_name == fname then return module_link(modulename, doc, from) .. "#" .. fname end end -- logger:error(string.format("unresolved reference to function `%s' of module `%s'", fname, modulename)) end ------------------------------------------------------------------------------- -- Make a link to a file, module or function function symbol_link (symbol, doc, module_doc, file_doc, from) assert(symbol) assert(doc) local href = -- file_link(symbol, from) or module_link(symbol, doc, from) or link_to(symbol, doc, module_doc, file_doc, from, "functions") or link_to(symbol, doc, module_doc, file_doc, from, "tables") if not href then logger:error(string.format("unresolved reference to symbol `%s'", symbol)) end return href or "" end ------------------------------------------------------------------------------- --- Generate link to function e.g. CoreMudlet.html#wait. function genLinkToFunction(doc, funcId) if funcId then funcIdTrim = string.gsub(funcId, "^%s*(.-)%s*$", "%1") -- trim local miFunc = doc.mIndex[funcIdTrim] if miFunc then local htmlFile = string.gsub(miFunc.filename, "[.]lua", ".html") return string.format("%s", (htmlFile .. "#" .. funcIdTrim), funcIdTrim) else return "MISSING LINK: '" .. funcId .. "'" end end end ------------------------------------------------------------------------------- -- Assembly the output filename for an input file. -- TODO: change the name of this function function out_file (filename) local h = filename h = string.gsub(h, "lua$", "html") h = string.gsub(h, "luadoc$", "html") h = "files/" .. h -- h = options.output_dir .. string.gsub (h, "^.-([%w_]+%.html)$", "%1") h = options.output_dir .. h return h end ------------------------------------------------------------------------------- -- Assembly the output filename for a module. -- TODO: change the name of this function function out_module (modulename) local h = modulename .. ".html" h = "modules/" .. h h = options.output_dir .. h return h end ----------------------------------------------------------------- -- Generate the output. -- @param doc Table with the structured documentation. function start (doc) -- Generate index file -- if (#doc.files > 0 or #doc.modules > 0) and (not options.noindexpage) then -- local filename = options.output_dir.."index.html" -- logger:info(string.format("generating file `%s'", filename)) -- local f = lfs.open(filename, "w") -- assert(f, string.format("could not open `%s' for writing", filename)) -- io.output(f) -- include("index.lp", { doc = doc }) -- f:close() -- end -- Generate Mudlet master index file if (#doc.mIndex > 0) and (not options.noindexpage) then local filename = options.output_dir.."index.html" logger:info(string.format("generating file `%s'", filename)) local f = lfs.open(filename, "w") assert(f, string.format("could not open `%s' for writing", filename)) io.output(f) include("mIndex.lp", { doc = doc }) f:close() end -- Process modules if not options.nomodules then for _, modulename in ipairs(doc.modules) do local module_doc = doc.modules[modulename] -- assembly the filename local filename = out_module(modulename) logger:info(string.format("generating file `%s'", filename)) local f = lfs.open(filename, "w") assert(f, string.format("could not open `%s' for writing", filename)) io.output(f) include("module.lp", { doc = doc, module_doc = module_doc }) f:close() end end -- Process files if not options.nofiles then for _, filepath in ipairs(doc.files) do local file_doc = doc.files[filepath] -- assembly the filename local filename = out_file(file_doc.name) logger:info(string.format("generating file `%s'", filename)) local f = lfs.open(filename, "w") assert(f, string.format("could not open `%s' for writing", filename)) io.output(f) include("file.lp", { doc = doc, file_doc = file_doc} ) f:close() end end -- copy extra files local f = lfs.open(options.output_dir.."luadoc.css", "w") io.output(f) include("luadoc.css") f:close() end mudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/html/0000755000175000017500000000000011520630027021260 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/html/file.lp0000644000175000017500000000554711520630027022547 0ustar csmallcsmall Reference

File <%=file_doc.name%>

<%if file_doc.description then%>

<%=file_doc.description%>

<%end%> <%if file_doc.author then%>

<%= #file_doc.author>1 and "Authors" or "Author" %>: <%for _, author in ipairs(file_doc.author) do%> <%end%>
<%= author %>

<%end%> <%if file_doc.copyright then%>

Copyright ©<%=file_doc.copyright%>

<%end%> <%if file_doc.release then%>

Release: <%=file_doc.release%>

<%end%> <%if #file_doc.functions > 0 then%>

Functions

<%for _, func_name in ipairs(file_doc.functions) do local func_data = file_doc.functions[func_name]%> <%end%>
<%=func_data.private and "local " or ""%><%=func_name%> (<%=table.concat(func_data.param, ", ")%>) <%=func_data.summary%>
<%end%> <%if #file_doc.tables > 0 then%>

Tables

<%for _, tab_name in ipairs(file_doc.tables) do%> <%end%>
<%=tab_name%> <%=file_doc.tables[tab_name].summary%>
<%end%>

<%if #file_doc.functions > 0 then%>

Functions

<%for _, func_name in ipairs(file_doc.functions) do%> <%=luadoc.doclet.mudlet.include("function.lp", { doc=doc, file_doc=file_doc, func=file_doc.functions[func_name] })%> <%end%>
<%end%> <%if #file_doc.tables > 0 then%>

Tables

<%for _, tab_name in ipairs(file_doc.tables) do%> <%=luadoc.doclet.mudlet.include("table.lp", { doc=doc, file_doc=file_doc, tab=file_doc.tables[tab_name] })%> <%end%>
<%end%>

Valid XHTML 1.0!

mudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/html/menu.lp0000644000175000017500000000210111520630027022553 0ustar csmallcsmall<% if module_doc then from = "modules/"..module_doc.name elseif file_doc then from = "files/.."..file_doc.name else from = "" end %>

LuaDoc

    <%if not module_doc and not file_doc then%>
  • Index
  • <%else%>
  • ">Index
  • <%end%>
<%if not options.nomodules and #doc.modules > 0 then%>

Modules

    <%for _, modulename in ipairs(doc.modules) do if module_doc and module_doc.name == modulename then%>
  • <%=modulename%>
  • <%else%>
  • <%=modulename%>
  • <% end end%>
<%end%> <%if not options.nofiles and #doc.files > 0 then%>

Files

    <%for _, filepath in ipairs(doc.files) do if file_doc and file_doc.name == filepath then%>
  • <%=filepath%>
  • <%else%>
  • <%=filepath%>
  • <% end end%>
<%end%> mudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/html/module.lp0000644000175000017500000000564311520630027023112 0ustar csmallcsmall Reference

Module <%=module_doc.name%>

<%=module_doc.description%>

<%if module_doc.author then%>

<%= #module_doc.author>1 and "Authors" or "Author" %>: <%for _, author in ipairs(module_doc.author) do%> <%end%>
<%= author %>

<%end%> <%if module_doc.copyright then%>

Copyright© <%=module_doc.copyright%>

<%end%> <%if module_doc.release then%>

Release: <%=module_doc.release%>

<%end%> <%if #module_doc.functions > 0 then%>

Functions

<%for _, func_name in ipairs(module_doc.functions) do local func_data = module_doc.functions[func_name]%> <%end%>
<%=func_data.private and "local " or ""%><%=func_name%> (<%=table.concat(module_doc.functions[func_name].param, ", ")%>) <%=module_doc.functions[func_name].summary%>
<%end%> <%if #module_doc.tables > 0 then%>

Tables

<%for _, tab_name in ipairs(module_doc.tables) do%> <%end%>
<%=tab_name%> <%=module_doc.tables[tab_name].summary%>
<%end%>

<%if #module_doc.functions > 0 then%>

Functions

<%for _, func_name in ipairs(module_doc.functions) do%> <%=luadoc.doclet.mudlet.include("function.lp", { doc=doc, module_doc=module_doc, func=module_doc.functions[func_name] })%> <%end%>
<%end%> <%if #module_doc.tables > 0 then%>

Tables

<%for _, tab_name in ipairs(module_doc.tables) do%> <%=luadoc.doclet.mudlet.include("table.lp", { doc=doc, module_doc=module_doc, tab=module_doc.tables[tab_name] })%> <%end%>
<%end%>

Valid XHTML 1.0!

mudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/html/function.lp0000644000175000017500000000262311520630027023445 0ustar csmallcsmall<% if module_doc then from = "modules/"..module_doc.name elseif file_doc then from = "files/.."..file_doc.name else from = "" end %>
<%=func.private and "local " or ""%> <%=func.name%> (<%=table.concat(func.param, ", ")%>)
<%=func.description or ""%> <%if func.release then%>
Release: <%=func.release%> <%end%>
<%if type(func.param) == "table" and #func.param > 0 then%> Parameters
    <%for p = 1, #func.param do%>
  • <%=func.param[p]%>: <%=func.param[func.param[p]] or ""%>
  • <%end%>
<%end%> <%if type(func.usage) == "string" then%> Usage:
  • <%=func.usage%>
<%elseif type(func.usage) == "table" then%> Usage
    <%for _, usage in ipairs(func.usage) do%>
  • <%= usage %> <%end%>
<%end%> <%if type(func.ret) == "string" then%> Return value:
  • <%=func.ret%>
<%elseif type(func.ret) == "table" then%> Return values:
    <%for _, ret in ipairs(func.ret) do%>
  1. <%= ret %> <%end%>
<%end%> <%if type(func.see) == "string" then %> See also:
  • <%=luadoc.doclet.mudlet.genLinkToFunction(doc, func.see)%>
<%elseif type(func.see) == "table" and #func.see > 0 then %> See also:
    <%for i = 1, #func.see do%>
  • <%=luadoc.doclet.mudlet.genLinkToFunction(doc, func.see[i])%> <%end%>
<%end%>
mudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/html/table.lp0000644000175000017500000000045711520630027022712 0ustar csmallcsmall
<%=tab.name%>
<%=tab.description%> <%if type(tab.field) == "table" and #tab.field > 0 then%> Fields
    <%for p = 1, #tab.field do%>
  • <%=tab.field[p]%>: <%=tab.field[tab.field[p]] or ""%>
  • <%end%>
<%end%>
mudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/html/mIndex.lp0000644000175000017500000000262311520630027023044 0ustar csmallcsmall Reference " type="text/css" />
<%if not options.nofiles and #doc.files > 0 then%>

All Functions

<%for _,funcId in ipairs(doc.mIndex) do%> <%end%>
<%=doc.mIndex[funcId].filename%> <%=doc.mIndex[funcId].name%> <%=doc.mIndex[funcId].summary%>
<%end%>

Valid XHTML 1.0!

mudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/html/luadoc.css0000644000175000017500000001260511520630027023245 0ustar csmallcsmallbody { margin-left: 1em; margin-right: 1em; font-family: arial, helvetica, geneva, sans-serif; background-color:#ffffff; margin:0px; } code { font-family: "Andale Mono", monospace; } tt { font-family: "Andale Mono", monospace; } body, td, th { font-size: 11pt; } h1, h2, h3, h4 { margin-left: 0em; } textarea, pre, tt { font-size:10pt; } body, td, th { color:#000000; } small { font-size:0.85em; } h1 { font-size:1.5em; } h2 { font-size:1.25em; } h3 { font-size:1.15em; } h4 { font-size:1.06em; } pre { border:1px solid silver; background-color:#f4fff4; padding-top:0.5em; width: 80% } a:link { font-weight:bold; color: #004080; text-decoration: none; } a:visited { font-weight:bold; color: #006699; text-decoration: none; } a:link:hover { text-decoration:underline; } hr { color:#cccccc } img { border-width: 0px; } h3 { padding-top: 1em; } p { margin-left: 1em; } p.name { font-family: "Andale Mono", monospace; padding-top: 1em; margin-left: 0em; } blockquote { margin-left: 3em; } pre.example { background-color: rgb(245, 245, 245); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: silver; border-right-color: silver; border-bottom-color: silver; border-left-color: silver; padding: 1em; margin-left: 1em; margin-right: 1em; font-family: "Andale Mono", monospace; font-size: smaller; } hr { margin-left: 0em; background: #00007f; border: 0px; height: 1px; } ul { list-style-type: disc; } table.index { border: 1px #00007f; } table.index td { text-align: left; vertical-align: top; } table.index ul { padding-top: 0em; margin-top: 0em; } table { border: 1px solid black; border-collapse: collapse; margin-left: auto; margin-right: auto; } th { border: 1px solid black; padding: 0.5em; } td { border: 1px solid black; padding: 0.5em; } div.header, div.footer { margin-left: 0em; } #container { margin-left: 1em; margin-right: 1em; background-color: #f0f0f0; } #product { text-align: center; border-bottom: 1px solid #cccccc; background-color: #ffffff; } #product big { font-size: 2em; } #product_logo { } #product_name { } #product_description { } #main { background-color: #f0f0f0; border-left: 2px solid #cccccc; } #navigation { float: left; width: 18em; margin: 0; vertical-align: top; background-color: #f0f0f0; overflow:visible; position:fixed; left: 17px; top: 1px } #navigation h1 { background-color:#e7e7e7; font-size:1.1em; color:#000000; text-align:left; margin:0px; padding:0.2em; border-top:1px solid #dddddd; border-bottom:1px solid #dddddd; } #navigation ul { font-size:1em; list-style-type: none; padding: 0; margin: 1px; } #navigation li { text-indent: -1em; margin: 0em 0em 0em 0.5em; display: block; padding: 3px 0px 0px 12px; } #navigation li li a { padding: 0px 3px 0px -1em; } #content { margin-left: 18em; padding: 1em; border-left: 2px solid #cccccc; border-right: 2px solid #cccccc; background-color: #ffffff; } #about { clear: both; margin: 0; padding: 5px; border-top: 2px solid #cccccc; background-color: #ffffff; } @media print { body { font: 12pt "Times New Roman", "TimeNR", Times, serif; } a { font-weight:bold; color: #004080; text-decoration: underline; } #main { background-color: #ffffff; border-left: 0px; } #container { margin-left: 2%; margin-right: 2%; background-color: #ffffff; } #content { margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff; } #navigation { display: none; } pre.example { font-family: "Andale Mono", monospace; font-size: 10pt; page-break-inside: avoid; } } table.module_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.module_list td.name { background-color: #f0f0f0; } table.module_list td.summary { width: 100%; } table.file_list { border-width: 1px; border-style: solid; border-color: #cccccc; border-collapse: collapse; } table.file_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.file_list td.name { background-color: #f0f0f0; } table.file_list td.summary { width: 100%; } table.function_list { border-width: 1px; border-style: solid; border-color: #cccccc; border-collapse: collapse; } table.function_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.function_list td.name { background-color: #f0f0f0; } table.function_list td.summary { width: 100%; } table.table_list { border-width: 1px; border-style: solid; border-color: #cccccc; border-collapse: collapse; } table.table_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.table_list td.name { background-color: #f0f0f0; } table.table_list td.summary { width: 100%; } dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} dl.function dd {padding-bottom: 1em;} dl.function h3 {padding: 0; margin: 0; font-size: medium;} dl.table dt {border-top: 1px solid #ccc; padding-top: 1em;} dl.table dd {padding-bottom: 1em;} dl.table h3 {padding: 0; margin: 0; font-size: medium;} #TODO: make module_list, file_list, function_list, table_list inherit from a list mudlet-2.1/src/mudlet-lua/lua/luadoc/doclet/html/index.lp0000644000175000017500000000332411520630027022726 0ustar csmallcsmall Reference " type="text/css" />
<%if not options.nomodules and #doc.modules > 0 then%>

Modules

<%for _, modulename in ipairs(doc.modules) do%> <%end%>
<%=modulename%> <%=doc.modules[modulename].summary%>
<%end%> <%if not options.nofiles and #doc.files > 0 then%>

Files

<%for _, filepath in ipairs(doc.files) do%> <%end%>
<%=filepath%>
<%end%>

Valid XHTML 1.0!

mudlet-2.1/src/mudlet-lua/lua/luadoc/taglet/0000755000175000017500000000000011520630027020322 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/lua/luadoc/taglet/standard/0000755000175000017500000000000011520630027022122 5ustar csmallcsmallmudlet-2.1/src/mudlet-lua/lua/luadoc/taglet/standard/tags.lua0000644000175000017500000001221311520630027023562 0ustar csmallcsmall-- added filename tag ------------------------------------------------------------------------------- -- Handlers for several tags -- @release $Id: tags.lua,v 1.8 2007/09/05 12:39:09 tomas Exp $ ------------------------------------------------------------------------------- local luadoc = require "luadoc" local util = require "luadoc.util" local string = require "string" local table = require "table" local assert, type, tostring = assert, type, tostring module "luadoc.taglet.standard.tags" ------------------------------------------------------------------------------- local function author (tag, block, text) block[tag] = block[tag] or {} if not text then luadoc.logger:warn("author `name' not defined [["..text.."]]: skipping") return end table.insert (block[tag], text) end ------------------------------------------------------------------------------- -- Set the class of a comment block. Classes can be "module", "function", -- "table". The first two classes are automatic, extracted from the source code local function class (tag, block, text) block[tag] = text end ------------------------------------------------------------------------------- local function copyright (tag, block, text) block[tag] = text end ------------------------------------------------------------------------------- local function description (tag, block, text) block[tag] = text end ------------------------------------------------------------------------------- local function filename (tag, block, text) block[tag] = text end ------------------------------------------------------------------------------- local function field (tag, block, text) if block["class"] ~= "table" then luadoc.logger:warn("documenting `field' for block that is not a `table'") end block[tag] = block[tag] or {} local _, _, name, desc = string.find(text, "^([_%w%.]+)%s+(.*)") assert(name, "field name not defined") table.insert(block[tag], name) block[tag][name] = desc end ------------------------------------------------------------------------------- -- Set the name of the comment block. If the block already has a name, issue -- an error and do not change the previous value local function name (tag, block, text) if block[tag] and block[tag] ~= text then luadoc.logger:error(string.format("block name conflict: `%s' -> `%s'", block[tag], text)) end block[tag] = text end ------------------------------------------------------------------------------- -- Processes a parameter documentation. -- @param tag String with the name of the tag (it must be "param" always). -- @param block Table with previous information about the block. -- @param text String with the current line beeing processed. local function param (tag, block, text) block[tag] = block[tag] or {} -- TODO: make this pattern more flexible, accepting empty descriptions local _, _, name, desc = string.find(text, "^([_%w%.]+)%s+(.*)") if not name then luadoc.logger:warn("parameter `name' not defined [["..text.."]]: skipping") return end local i = table.foreachi(block[tag], function (i, v) if v == name then return i end end) if i == nil then luadoc.logger:warn(string.format("documenting undefined parameter `%s'", name)) table.insert(block[tag], name) end block[tag][name] = desc end ------------------------------------------------------------------------------- local function release (tag, block, text) block[tag] = text end ------------------------------------------------------------------------------- local function ret (tag, block, text) tag = "ret" if type(block[tag]) == "string" then block[tag] = { block[tag], text } elseif type(block[tag]) == "table" then table.insert(block[tag], text) else block[tag] = text end end ------------------------------------------------------------------------------- -- @see ret local function see (tag, block, text) -- see is always an array block[tag] = block[tag] or {} -- remove trailing "." text = string.gsub(text, "(.*)%.$", "%1") local s = util.split("%s*,%s*", text) table.foreachi(s, function (_, v) table.insert(block[tag], v) end) end ------------------------------------------------------------------------------- -- @see ret local function usage (tag, block, text) if type(block[tag]) == "string" then block[tag] = { block[tag], text } elseif type(block[tag]) == "table" then table.insert(block[tag], text) else block[tag] = text end end ------------------------------------------------------------------------------- local handlers = {} handlers["author"] = author handlers["class"] = class handlers["copyright"] = copyright handlers["description"] = description handlers["field"] = field handlers["name"] = name handlers["param"] = param handlers["release"] = release handlers["return"] = ret handlers["see"] = see handlers["usage"] = usage handlers["filename"] = filename ------------------------------------------------------------------------------- function handle (tag, block, text) if not handlers[tag] then luadoc.logger:error(string.format("undefined handler for tag `%s'", tag)) return end -- assert(handlers[tag], string.format("undefined handler for tag `%s'", tag)) return handlers[tag](tag, block, text) end mudlet-2.1/src/mudlet-lua/lua/luadoc/taglet/mudlet.lua0000644000175000017500000004114111520630027022320 0ustar csmallcsmall------------------------------------------------------------------------------- -- This is just copy of standard.lua with support for
 tag in 
-- documentation. See example bellow:
-- 
--	if info ~= nil then
--		assert(info.name, "function name undefined")
--	end
-- 
-- -- -- LuaDoc modules functionality was amended (misused) to generate -- index of all functions. -- ------------------------------------------------------------------------------- -- @release $Id: standard.lua,v 1.39 2007/12/21 17:50:48 tomas Exp $ ------------------------------------------------------------------------------- local assert, pairs, tostring, type = assert, pairs, tostring, type local io = require "io" local lfs = require "lfs" local luadoc = require "luadoc" local util = require "luadoc.util" local tags = require "luadoc.taglet.standard.tags" local string = require "string" local table = require "table" module 'luadoc.taglet.mudlet' ------------------------------------------------------------------------------- -- Creates an iterator for an array base on a class type. -- @param t array to iterate over -- @param class name of the class to iterate over function class_iterator (t, class) return function () local i = 1 return function () while t[i] and t[i].class ~= class do i = i + 1 end local v = t[i] i = i + 1 return v end end end -- Patterns for function recognition local identifiers_list_pattern = "%s*(.-)%s*" local identifier_pattern = "[^%(%s]+" local function_patterns = { "^()%s*function%s*("..identifier_pattern..")%s*%("..identifiers_list_pattern.."%)", "^%s*(local%s)%s*function%s*("..identifier_pattern..")%s*%("..identifiers_list_pattern.."%)", "^()%s*("..identifier_pattern..")%s*%=%s*function%s*%("..identifiers_list_pattern.."%)", } ------------------------------------------------------------------------------- -- Checks if the line contains a function definition -- @param line string with line text -- @return function information or nil if no function definition found local function check_function (line) line = util.trim(line) local info = table.foreachi(function_patterns, function (_, pattern) local r, _, l, id, param = string.find(line, pattern) if r ~= nil then return { name = id, private = (l == "local"), param = util.split("%s*,%s*", param), } end end) -- TODO: remove these assert's? if info ~= nil then assert(info.name, "function name undefined") assert(info.param, string.format("undefined parameter list for function `%s'", info.name)) end return info end ------------------------------------------------------------------------------- -- Checks if the line contains a module definition. -- @param line string with line text -- @param currentmodule module already found, if any -- @return the name of the defined module, or nil if there is no module -- definition local function check_module (line, currentmodule) line = util.trim(line) -- module"x.y" -- module'x.y' -- module[[x.y]] -- module("x.y") -- module('x.y') -- module([[x.y]]) -- module(...) local r, _, modulename = string.find(line, "^module%s*[%s\"'(%[]+([^,\"')%]]+)") if r then -- found module definition logger:debug(string.format("found module `%s'", modulename)) return modulename end return currentmodule end ------------------------------------------------------------------------------- -- Extracts summary information from a description. The first sentence of each -- doc comment should be a summary sentence, containing a concise but complete -- description of the item. It is important to write crisp and informative -- initial sentences that can stand on their own -- @param description text with item description -- @return summary string or nil if description is nil local function parse_summary (description) -- summary is never nil... description = description or "" -- append an " " at the end to make the pattern work in all cases description = description.." " -- read until the first period followed by a space or tab local summary = string.match(description, "(.-%.)[%s\t]") -- if pattern did not find the first sentence, summary is the whole description summary = summary or description return summary end ------------------------------------------------------------------------------- -- @param f file handle -- @param line current line being parsed -- @param modulename module already found, if any -- @return current line -- @return code block -- @return modulename if found local function parse_code (f, line, modulename) local code = {} while line ~= nil do if string.find(line, "^[\t ]*%-%-%-") then -- reached another luadoc block, end this parsing return line, code, modulename else -- look for a module definition modulename = check_module(line, modulename) table.insert(code, line) line = f:read() end end -- reached end of file return line, code, modulename end ------------------------------------------------------------------------------- -- Simply tests if trimmed line without pre /pre tags is blank -- @return true/false function skipNewline(line) if string.find(line, "<[pP][rR][eE]>") or string.find(line, "") then line = string.gsub(line, "<[pP][rR][eE]>", "") line = string.gsub(line, "", "") line = string.gsub(line, "^%s*(.-)%s*$", "%1") return line == "" else return false end end ------------------------------------------------------------------------------- -- Simply tests if trimmed line without @usage tags is blank -- @return true/false function addNewlineAfterUsage(line) line = string.gsub(line, "@usage", "") line = string.gsub(line, "^%s*(.-)%s*$", "%1") return line == "" end ------------------------------------------------------------------------------- -- Removes lua comment from the begining of the line and add newLine char. -- This was implemented to add
 support to LuaDoc.
-- @param s string to be trimmed
-- @return trimmed string
local function trim_comment_pre(s) 
	-- detect start/end of pre block - case sensitive
	if string.find(s, "<[pP][rR][eE]>") then luadoc_taglet_mudlet_pre = true end
	if string.find(s, "") then luadoc_taglet_mudlet_pre = false end
	-- process line
	s = string.gsub(s, "%-%-+(.*)$", "%1")
	if luadoc_taglet_mudlet_pre then
		if not skipNewline(s) then
			return s .. "\n"
		else
			return s
		end 
	else
		s = string.gsub(s, "^%s*(.-)%s*$", "%1")
		if string.find(s, "@usage") then 
			if addNewlineAfterUsage(s) then
				s = s .. "\n"
			end
		end
		return s
	end
end


-------------------------------------------------------------------------------
-- Parses the information inside a block comment
-- @param block block with comment field
-- @return block parameter

local function parse_comment (block, first_line)

	-- get the first non-empty line of code
	local code = table.foreachi(block.code, function(_, line)
		if not util.line_empty(line) then
			-- `local' declarations are ignored in two cases:
			-- when the `nolocals' option is turned on; and
			-- when the first block of a file is parsed (this is
			--	necessary to avoid confusion between the top
			--	local declarations and the `module' definition.
			if (options.nolocals or first_line) and line:find"^%s*local" then
				return
			end
			return line
		end
	end)
	
	-- parse first line of code
	if code ~= nil then
		local func_info = check_function(code)
		local module_name = check_module(code)
		if func_info then
			block.class = "function"
			block.name = func_info.name
			block.param = func_info.param
			block.private = func_info.private
		elseif module_name then
			block.class = "module"
			block.name = module_name
			block.param = {}
		else
			block.param = {}
		end
	else
		-- TODO: comment without any code. Does this means we are dealing
		-- with a file comment?
	end

	-- parse @ tags
	local currenttag = "description"
	local currenttext
	
	table.foreachi(block.comment, function (_, line)
		-- added new line char to support 
 formatted code
		line = trim_comment_pre(line)

		local r, _, tag, text = string.find(line, "@([_%w%.]+)%s+(.*)")
		if r ~= nil then
			-- found new tag, add previous one, and start a new one
			-- TODO: what to do with invalid tags? issue an error? or log a warning?
			tags.handle(currenttag, block, currenttext)
			
			currenttag = tag
			currenttext = text
		else
			currenttext = util.concat(currenttext, line)
-- commented out, so I can user 
 formatted code
--			assert(string.sub(currenttext, 1, 1) ~= " ", string.format("`%s', `%s'", currenttext, line))
		end
	end)
	tags.handle(currenttag, block, currenttext)

	-- Store file name info
	tags.handle("filename", block, luadoc_taglet_mudlet_filename)

	-- extracts summary information from the description
	block.summary = parse_summary(block.description)
-- commented out, so I can user 
 formatted code
--	assert(string.sub(block.description, 1, 1) ~= " ", string.format("`%s'", block.description))

	return block
end

-------------------------------------------------------------------------------
-- Parses a block of comment, started with ---. Read until the next block of
-- comment.
-- @param f file handle
-- @param line being parsed
-- @param modulename module already found, if any
-- @return line
-- @return block parsed
-- @return modulename if found

local function parse_block (f, line, modulename, first)
	local block = {
		comment = {},
		code = {},
	}

	while line ~= nil do
		if string.find(line, "^[\t ]*%-%-") == nil then
			-- reached end of comment, read the code below it
			-- TODO: allow empty lines
			line, block.code, modulename = parse_code(f, line, modulename)
			
			-- parse information in block comment
			block = parse_comment(block, first)

			return line, block, modulename
		else
			table.insert(block.comment, line)
			line = f:read()
		end
	end
	-- reached end of file
	
	-- parse information in block comment
	block = parse_comment(block, first)
	
	return line, block, modulename
end

-------------------------------------------------------------------------------
-- Parses a file documented following luadoc format.
-- @param filepath full path of file to parse
-- @param doc table with documentation
-- @return table with documentation

function parse_file (filepath, doc)
	local blocks = {}
	local modulename = nil
	
	-- read each line
	local f = io.open(filepath, "r")
	local i = 1
	local line = f:read()
	local first = true
	while line ~= nil do
		if string.find(line, "^[\t ]*%-%-%-") then
			-- reached a luadoc block
			local block
			line, block, modulename = parse_block(f, line, modulename, first)
			table.insert(blocks, block)
		else
			-- look for a module definition
			modulename = check_module(line, modulename)
			
			-- TODO: keep beginning of file somewhere
			
			line = f:read()
		end
		first = false
		i = i + 1
	end
	f:close()
	-- store blocks in file hierarchy
	assert(doc.files[filepath] == nil, string.format("doc for file `%s' already defined", filepath))
	table.insert(doc.files, filepath)
	doc.files[filepath] = {
		type = "file",
		name = filepath,
		doc = blocks,
--		functions = class_iterator(blocks, "function"),
--		tables = class_iterator(blocks, "table"),
	}

	-- added initial file comment
	local first = doc.files[filepath].doc[1]
	if first and modulename then
		doc.files[filepath].author = first.author
		doc.files[filepath].copyright = first.copyright
		doc.files[filepath].description = first.description
		doc.files[filepath].release = first.release
		doc.files[filepath].summary = first.summary
	end

	-- if module definition is found, store in module hierarchy
	if modulename ~= nil then
		if modulename == "..." then
				modulename = string.gsub (filepath, "%.lua$", "")
				modulename = string.gsub (modulename, "/", ".")
		end
		if doc.modules[modulename] ~= nil then
			-- module is already defined, just add the blocks
			table.foreachi(blocks, function (_, v)
				table.insert(doc.modules[modulename].doc, v)
			end)
		else
			-- TODO: put this in a different module
			table.insert(doc.modules, modulename)
			doc.modules[modulename] = {
				type = "module",
				name = modulename,
				doc = blocks,
--				functions = class_iterator(blocks, "function"),
--				tables = class_iterator(blocks, "table"),
				author = first and first.author,
				copyright = first and first.copyright,
				description = "",
				release = first and first.release,
				summary = "",
			}
			
			-- find module description
			for m in class_iterator(blocks, "module")() do
				doc.modules[modulename].description = util.concat(
					doc.modules[modulename].description, 
					m.description)
				doc.modules[modulename].summary = util.concat(
					doc.modules[modulename].summary, 
					m.summary)
				if m.author then
					doc.modules[modulename].author = m.author
				end
				if m.copyright then
					doc.modules[modulename].copyright = m.copyright
				end
				if m.release then
					doc.modules[modulename].release = m.release
				end
				if m.name then
					doc.modules[modulename].name = m.name
				end
			end
			doc.modules[modulename].description = doc.modules[modulename].description or (first and first.description) or ""
			doc.modules[modulename].summary = doc.modules[modulename].summary or (first and first.summary) or ""
		end
		
		-- make functions table
		doc.modules[modulename].functions = doc.modules[modulename].functions or {}
		for f in class_iterator(blocks, "function")() do
			table.insert(doc.modules[modulename].functions, f.name)
			doc.modules[modulename].functions[f.name] = f
		end
		
		-- make tables table
		doc.modules[modulename].tables = {}
		for t in class_iterator(blocks, "table")() do
			table.insert(doc.modules[modulename].tables, t.name)
			doc.modules[modulename].tables[t.name] = t
		end
	end
	
	-- make functions table
	doc.files[filepath].functions = {}
	for f in class_iterator(blocks, "function")() do
		table.insert(doc.files[filepath].functions, f.name)
		-- added link, so we can refer this function later
		f.link = string.gsub(filepath, ".lua", ".html") .. "#" .. f.name
		doc.files[filepath].functions[f.name] = f
		-- new array for master index of all functions
		local funcId = f.name
		table.insert(doc.mIndex, funcId)
		doc.mIndex[funcId] = f
	end
	
	-- make tables table
	doc.files[filepath].tables = {}
	for t in class_iterator(blocks, "table")() do
		table.insert(doc.files[filepath].tables, t.name)
		doc.files[filepath].tables[t.name] = t
	end
	
	return doc
end

-------------------------------------------------------------------------------
-- Checks if the file is terminated by ".lua" or ".luadoc" and calls the 
-- function that does the actual parsing
-- @param filepath full path of the file to parse
-- @param doc table with documentation
-- @return table with documentation
-- @see parse_file

function file (filepath, doc)
	local patterns = { "%.lua$", "%.luadoc$" }
	local valid = table.foreachi(patterns, function (_, pattern)
		if string.find(filepath, pattern) ~= nil then
			return true
		end
	end)
	
	if valid then
		logger:info(string.format("processing file `%s'", filepath))
		doc = parse_file(filepath, doc)
	end
	
	return doc
end

-------------------------------------------------------------------------------
-- Recursively iterates through a directory, parsing each file
-- @param path directory to search
-- @param doc table with documentation
-- @return table with documentation

function directory (path, doc)
	for f in lfs.dir(path) do
		local fullpath = path .. "/" .. f
		local attr = lfs.attributes(fullpath)
		assert(attr, string.format("error stating file `%s'", fullpath))
		
		if attr.mode == "file" then
			doc = file(fullpath, doc)
		elseif attr.mode == "directory" and f ~= "." and f ~= ".." then
			doc = directory(fullpath, doc)
		end
	end
	return doc
end

-- Recursively sorts the documentation table
local function recsort (tab)
	table.sort (tab)
	-- sort list of functions by name alphabetically
	for f, doc in pairs(tab) do
		if doc.functions then
			table.sort(doc.functions)
		end
		if doc.tables then
			table.sort(doc.tables)
		end
	end
end

-------------------------------------------------------------------------------

function start (files, doc)
	assert(files, "file list not specified")
	
	-- Create an empty document, or use the given one
	doc = doc or {
		files = {},
		modules = {},
		mIndex = {}, -- master index
	}
	assert(doc.files, "undefined `files' field")
	assert(doc.modules, "undefined `modules' field")
	
	table.foreachi(files, function (_, path)
		local attr = lfs.attributes(path)
		assert(attr, string.format("error stating path `%s'", path))
	
		-- current file
		luadoc_taglet_mudlet_filename = path
	
		if attr.mode == "file" then
			doc = file(path, doc)
		elseif attr.mode == "directory" then
			doc = directory(path, doc)
		end
	end)
	
	-- order arrays alphabetically
	recsort(doc.files)
	recsort(doc.modules)
	table.sort(doc.mIndex)

	return doc
end
mudlet-2.1/src/mudlet-lua/luadoc-guide.txt0000644000175000017500000000373611520630027020126 0ustar  csmallcsmallThis file should give you basic guidelines for documenting mudlet-lua code 
with LuaDoc. (Keep in mind that we did few extensions to LuaDoc,
so this is not generic LuaDoc guide. All Mudlet LuaDoc extensions are 
freely available in lua/luadoc/ folder.)

I hope that everything will be clear from following example. 
You can always ask for clarification on Mudlet forum...
Please use 
 tag for any code - even if it's just one line.
You will need to to escape all html characters.

We would appreciate if you can follow this as close as 
possible to keep it consistent and easily maintainable. 
Thank you!




--- Short description, which should end with dot. More extended description
--- can be across many lines (including blank ones).
---
--- You can use pre tag anywhere you like. (Please indent it by 2 spaces.)
---   
---   if info ~= nil then
---      assert(info.name, "function name undefined")
---   end
---   
--- You can also force
new line with HTML tag. --- --- @release Mudlet 1.1.1 --- --- @param a is used for ... param description. --- @param b LuaDoc will generate basic doc for all omitted parameters. --- --- @return truu/false (to keep if brief) --- --- @usage Description of example. ---
---   test(1, 2)
---   
--- @usage Description of second example can be very long, --- so I need to carry on following lines. ---
---   local res = test("hit", 2)
---   echo(res)
---   
--- --- @see functionName --- @see anotherFunctionName --- function test(a, b) end --- You can also document tables, but you have to manually set class and name tag. --- Set class to 'function' for all tables or variables or it will not appear in master index! --- --- @see fg --- --- @class function --- @name color_table color_table = {} -- NOT LUADOC -- This is function will not be in generated LuaDoc, but you can still -- document it in save fashion. -- -- normal lua comments -- -- LuaDoc documentation --- -- function _privateFunction() end mudlet-2.1/src/mudlet-lua/TODO0000644000175000017500000000106511520630027015504 0ustar csmallcsmallneed to sort out single GIT repozitory for all mudlet code (well it's not so bad now ... there is one for lua and one for rest) Lua Code test it properly e.g. that all functions are working test new loading clean up lua dependences rex_pcre, lpeg, luasql.sqlite3 LuaDoc gen LuaDoc and link it from main manual (this will be just API documentation) e.g. LuaDoc will replace Alphabetic Function List, but still need most of original doc make generated LuaDoc more appealing (check lua/luadoc/doclet/html folder for it) this mainly includes better css mudlet-2.1/src/mudlet-lua/genDoc.sh0000644000175000017500000000016211520630027016544 0ustar csmallcsmall cd lua luadoc *.lua geyser/*.lua -d ../mudlet-lua-doc --taglet luadoc.taglet.mudlet -doclet luadoc.doclet.mudlet mudlet-2.1/src/dlgSearchArea.h0000644000175000017500000000326211513237311015603 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef dlg_search_area_h #define dlg_search_area_h #include "ui_extended_search_area.h" #include class dlgSearchArea : public QWidget , public Ui::extended_search_area { Q_OBJECT public: dlgSearchArea(QWidget *); signals: public slots: }; #endif mudlet-2.1/src/TToolBar.cpp0000644000175000017500000001371511513237311015143 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "Host.h" #include "HostManager.h" #include "TToolBar.h" #include "mudlet.h" TToolBar::TToolBar( TAction * pA, QString name, QWidget * pW ) : QDockWidget( pW ) , mpTAction( pA ) , mVerticalOrientation( false ) , mpWidget( new QWidget( this ) ) , mName( name ) , mRecordMove( false ) , mpLayout( 0 ) , mItemCount( 0 ) { setFeatures( QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable ); setWidget( mpWidget ); if( ! mpTAction->mUseCustomLayout ) { mpLayout = new QGridLayout( mpWidget ); setContentsMargins(0,0,0,0); mpLayout->setContentsMargins(0,0,0,0); mpLayout->setSpacing(0); QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred); mpWidget->setSizePolicy( sizePolicy ); } QWidget * test = new QWidget; setTitleBarWidget(test); setStyleSheet( mpTAction->css ); mpWidget->setStyleSheet( mpTAction->css ); } void TToolBar::moveEvent( QMoveEvent * e ) { if( mRecordMove ) { if( ! mpTAction ) return; mpTAction->mPosX = e->pos().x(); mpTAction->mPosY = e->pos().y(); } e->ignore(); } void TToolBar::addButton( TFlipButton * pB ) { if( ! mpTAction->mUseCustomLayout ) { QSize size = pB->minimumSizeHint(); if( pB->mpTAction->getButtonRotation() > 0 ) { size.transpose(); } pB->setMaximumSize( size ); pB->setMinimumSize( size ); } else { QSize size = QSize(pB->mpTAction->mSizeX, pB->mpTAction->mSizeY ); pB->setMaximumSize( size ); pB->setMinimumSize( size ); pB->setParent( mpWidget ); pB->setGeometry( pB->mpTAction->mPosX, pB->mpTAction->mPosY, pB->mpTAction->mSizeX, pB->mpTAction->mSizeY ); } pB->setStyleSheet( pB->mpTAction->css ); pB->setFlat( pB->mpTAction->getButtonFlat() ); int rotation = pB->mpTAction->getButtonRotation(); switch( rotation ) { case 0: pB->setOrientation( Qt::Horizontal ); break; case 1: pB->setOrientation( Qt::Vertical ); break; case 2: pB->setOrientation( Qt::Vertical ); pB->setMirrored( true ); break; } if( ! mpTAction->mUseCustomLayout ) { // tool bar mButtonColumns > 0 -> autolayout // case == 0: use individual button placment for user defined layouts int columns = mpTAction->getButtonColumns(); if( columns <= 0 ) columns = 1; if( columns > 0 ) { mItemCount++; int row = mItemCount / columns; int col = mItemCount % columns; if( mVerticalOrientation ) { mpLayout->addWidget( pB, row, col ); } else { mpLayout->addWidget( pB, col, row ); } } } else { pB->move( pB->mpTAction->mPosX, pB->mpTAction->mPosY ); } connect( pB, SIGNAL(pressed()), this, SLOT(slot_pressed()) ); } void TToolBar::finalize() { if( mpTAction->mUseCustomLayout ) { return; } QWidget * fillerWidget = new QWidget; QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding ); fillerWidget->setSizePolicy( sizePolicy ); int columns = mpTAction->getButtonColumns(); if( columns <= 0 ) columns = 1; mpLayout->addWidget( fillerWidget, ++mItemCount/columns, mItemCount%columns ); } void TToolBar::slot_pressed() { TFlipButton * pB = dynamic_cast( sender() ); if( ! pB ) { return; } TAction * pA = pB->mpTAction; pB->showMenu(); if( pB->isChecked() ) { pA->mButtonState = 2; } else { pA->mButtonState = 1; } if( pB->isChecked() ) pA->mpHost->mpConsole->mButtonState = 1; else pA->mpHost->mpConsole->mButtonState = 0; QStringList sL; pA->_execute( sL ); } void TToolBar::clear() { QWidget * pW = new QWidget( this ); setWidget( pW ); mpWidget->deleteLater(); mpWidget = pW; if( ! mpTAction->mUseCustomLayout ) { mpLayout = new QGridLayout( mpWidget ); mpLayout->setContentsMargins(0,0,0,0); mpLayout->setSpacing(0); QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); mpWidget->setSizePolicy( sizePolicy ); } else mpLayout = 0; QWidget * test = new QWidget; setStyleSheet( mpTAction->css ); mpWidget->setStyleSheet( mpTAction->css ); setTitleBarWidget( test ); mudlet::self()->removeDockWidget( this ); } mudlet-2.1/src/dlgOptionsAreaAction.h0000644000175000017500000000334011513237311017164 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _dlgOptionsAreaAction_h #define _dlgOptionsAreaAction_h #include "ui_options_area_actions.h" #include #include "TAction.h" class dlgOptionsAreaAction : public QWidget , public Ui::options_area_actions { Q_OBJECT public: dlgOptionsAreaAction(QWidget *); signals: public slots: }; #endif mudlet-2.1/src/Vyzor.zip0000644000175000017500000277240512070466512014646 0ustar csmallcsmallPK ~A Vyzor-master/PK ~A67Vyzor-master/READMEMJ@_o*ļ'EvLg: =[@*4~G K_=gfu#GLeHqZǭPyw޹_.8*yzj|-Q6u;'=1"({̉^۞8 uA[~% )V$)$V'bM`q6ut)z4 4u0&[.Vi3E \Wb`EAT h'MRIKM_v+ WQlKbtݧ854~}nY%PK ~AVyzor-master/base/PK ~AJdxpEVyzor-master/base/frame.luaYoF-HjEb7 d0J[\S쨋oҴ{!gk{ȋx"N, q[|/u%F˱xsc\!~N2+JWk)NOމgU=yr{{;ͷ0X> ͗q*^ťQBcr$7(t3C1Vp?'0X,,ԯ*ɳDm^&8$B(|3Uӭg-r[`,ƫԖdW 0x2m 4RQL.DѱL2Y EXY(``U%M9eRą@>L7IL/Vb:OW"B..Zh@FCkH*TL\&EY/I`~w#Ar+)- oOC=/U g%!Eݮ%fyEE\%y:.BLD`4΄B5hqZl/"Ԋ)*PLSm I!/=0Q$ ya*/f"A6F:]x*(:`+1BZ%h~ XI>=)2ޥ]."6YUk@;3ZKNDjWd4hٸND|E(VA6<# 9hr4rY&=#{rNN' 6D_5 NVҪo3}+R,97ͺ4i:nNH4qKEW?^hQRY͌Gc37[zn|4єd+hLKGChJ3/ kVS+=WIŢ9M/#PcBw0| A?BrK` ,hI)7S8qhѝiaJBj=Gz_4W-ɧ:TKOZ0=:[.@/mQ>$tk2-C -es؟IBǕj~mWxab^+癉:LFo4fc=xCR8RGsu`پvb[KV?D䌖2EWL`De#Om8 sGJLnDm &m,V9)yrl:OF Q@"=t{A2(_ţ񞪉H1Fd:dʹ)LEZ^.FJC;r"O`z)^B94B#m:xs 9N;s+8vCc;$.C\]jn^%p~s6bD?qZxe8SL҆R\Zv'5.jzYmE-/*{U mN^0/Ѽ&RC)r/?h|^0Q"6x^eHn~GNͺy0n&!7zy]TgoG,BI۶\-B7boߋeI`n=D`ٵ[v&%A ӓd*͵4),n+s8ٶT{L[ߙ= ۩~|gxR9;lՁ낯݃^( ]otOL8J\G溫 nrſofC /ۣn =:n+iWwGDஞ>d9CoY;-PMG>Xr-G7|&n}ION|i,٩z!h̯~J MҚ")>N=8$qE7v{!1GK|S2ė 8hߢe`MRT;~:0<śv%Jw+&;$]%G3_ycos;1Eg8["q1ak5.WT*UNmL9̓I@|;Io/ڠq6Lͯ{ ւO^JT$[H^fy仒^0^vfc)M$Lp4)]*:oxt $aM5s_[~=`{:t$уa6 .qYFS+?1 e侩k4>SWuUdr,͚萱%yܵ^C;5GၟDөgq.X9&1bb Q"ݪO[w ~7l}o~ gCm|"_т(i?=a_ jDT6^o"7P@lf^;Jab= D?"V``vOndMG@ڦ j^TԋiG@DGav+(Օ\ݟh>g|p bkB=NmKjŽf .+/b rnGdf I3<\(19/aKF1|nX"%\݉t8!ȡJKZϹol`vWVo>y'>'*~qS Xmlz1cHM480osk"KPGn{4_3x:aI\]wy VHqa'ZhFH_[_|{0U#7$NHQtoPK ~A"% Vyzor-master/base/hud.luaYms6, T_"udGO'iju'N<P$#@j&o_)%L v.ggߦFrJ0\ٙxm6R/WNKK9mq;=WU J" Vm.?v Ssroρj8\m)J fTtbEATZ,HLۍӦG~bw:sixZ)Rs&H]|;O@ΕUW +mE7^r? ?OA$u+2ͬ%P<HK&B;r.Rʧ"(+楒N YdT U&e:O:[v%7J8}̊Wd"̘ M9=e(k@,,oL&s033= C2a[%jQ>z˟pw^*\V9tU>ڋڡX1v{//R/D"Yf!tq(1[6 ɺ~cY:*xꅨ6?#=۞}Tb+ B 5֧^W*wپk=IJKLs ^ u`d#SJq6.e} h`. TJK`Q[4 c$HO9!.F&-I-huPcõFS Rh-b% Q֠ހeQ +L ,nKq tHNX5π6!2W9{q,BIo0k' D 灟bS3dxwrkl&F#vi\Eo UF#P'Ksϧ=9!O3"94̼Z?kz,%کV%zU0.jH(*D\Cm4&[w}6V1TVAcܳGla@:T@*F_I fPnHjEmdb*E-NY?u-BLG;j.B XXgѷ~sTa!cфk9SU+lR ne:]!TUO =h`﫨ᮥ6:;I"҇!A yOKKp7Cx(+E,YCCt!^jƗ /;VB;-s4ѐث0qܹRbvm 37Ar_0#3Td[&*TT%R_Vħ %[͕xY5YЅJquRօd |SBMTswp{kylS_d9 ?}=bΧIW ·o -UpmjiR!t phI-4ʒ%ˊ xGN`*C0f 67^>h`%wgsla Qs0ßC}8$ZON)69z=!98^=z_rk]ᜇ9-=ۮ:6_~2J(gPxx 30=6Vz µj <]Tb51 O~٪"Ꭳ1xhiB( SצxT=Ab.//-B8JD0wR%plMC&ւmgNhlJW7,^sE-Q½z_ܘ m= Dyc h '_NHrQL9V;}ԌdL}&8F &D! WtWou~ p6}a;^p`g%gҕ2Ъ\p85t̪UěS ?A8cj2ܨaHy`osLJ~F>C|kTMAVІp it纣L6iSℾ}_3jdu.z + [aȪѶ)ob2aH|:V*$Ch[v9|S @%RY4AN&5ou%ڠ*M 0/`E"47YgZCr^ Eʔ3Zҫ p}gΓKrs#Ўwe A#2!Q8Z:HRds;\0'EspGKW@Xi19:6e)<<#yrRk ob9K:}{-߇jOw۷Ln[p!JHO~D%sxţvh"pϿPK ~A{!WVyzor-master/base/options.luaXmo6,a6&;m?ˀi R!0 ڢmΊTy 3js҉_LVfPwsf5nPY8hPLs `_2'B9մ j|x$)g4r7kta;IrTO9s(TxN3{Aƈ29e&6m^UUUVz(0h>@FN)t9HO;d ;iU!-b+*/XoZmq)ئ5o/$ɿNrͶxTnI.׽[ݵ_Rg|M``ՠ$ ZRKQ`䷒@΂l`@+JX'6ly-J@UGg[沦h&KIwפȯsA8UdzD]%YHw*Y^gg+!'YBWD ;Z(4 V,㔴@5/Ipwsy3{UH2\H&ERs+aELf,? Qν]yQ=]dlҷs{Βc#DDxy) W{0s.Sj'E q*ڨHvyJrȷ -=FQз|[|9;1OPD6c]EwuyŧyY8`0~.]j',2y;dN Jjh6& 6C,0+VZ_kMvZ;(hʇ唏^kHBUW R{Xr)&I{Bs/q.hڈiG:U3"ٔZUfkUmf|jO|j7h.:^Y<?Z +xBBo%i@I#k`FͰ,,Y҈1 zʦ`3ʧ)V-0Cf+1℉c& 6ƇetjIaGhLZ0+]a5RS^R╥6IՇ\݄jK6弉JÏ*f8^wTw~:p 5.O#U|w[[nLQyKdwJvCN+WgB4rؽC v0iNQgK."#iƷTl7ab % ؈%$/UnW\][rtb,9fqSЍG4{)dB- ["9|==ƘpomCDL 98*B0 NMeBAk3/U,װG̘18R=\GlSǘMU t(\D`N7!K纔u. L z:/DC8HDwd#@'|(̑O8zzKCu|Fׅ@հ`KoW6 d@6?1]Ka>\e-暗&j4-`?lZ ~ z`aAuŊ2zF0s+?YX ~:kSaZBȒh6,wmIt¸:e۲[ &5μ'xs(0 cS|Qܙ3eZ ?V(H#w5an̖بSUw!z]|V0;P&5)v&8|eRq G'?xCE/]bpm>`9PlGB nӈ 8lF|+V(pة3ABbY($|Q]Ɯ~Z]Vmk/9lNDŽ7 a(v}&kZ-@9\n/l0>Ff@lۙ +Ȧn^pHl-YDh ٶwfVsh}6t|ǮwD}FEb~^rn1 ;C}_s^&lWETQ``;!錔6PYR41^|vד75rK5|v=Ak@_x`:`,]}jy&v~M÷„tv$&i$&4U(i#2 aeXA7xPK ~Aga!Vyzor-master/component/border.luaXnF}&bJr 8N 0J\[SJ.A흙p)ӊv綇g5§?E9pR(JLp8b-VA4ϞwB)Y9y%RխLVu|rr?*ָQ\ryb  ì'H*AײQoCf[nj^E.r5IPXD|M+uU۬Wʹ "K*6a qҋܴlz4IRe=WEC.0xJ(QV1fT{*k:?$&gU3@~$"Q,b5I* zdORg )-"WXIpzB 07?YI\2Ie]Rwʂ!2*05}ڰ &I}UWJ%%A~#a^̙@D}]\"gh:r33|6|'v0afץ᭫v(HMo%p:3VRB뷐2ˢFhb}^ipGuKOϧ#P7;2=ݧ:🳿\C؃rx#2o4(?L!inW)#PY#V@ubX_Xv}7fRŪ#؍xXtgwcK&>|]ޢ^ da2QS2qg~2îG^٩ѫVFrSx #sVA5ds֢`96ZVk{Kir "cWY0xu_}=GPp"{c?S{r;xeݶì\yܕNee]?YAuŴ>Ĝ}.*lL.AP 2+) D;$DU_YIp|"0۾[]ZpZm;h5DZO6 `fN>`:⸞) ;T䁻]o,QY_ >P#E<ЯCB?Ӄ=\AXwԀæSioFb`*`7 'ƱLJ=oy^;᝘IExɔti\vckQݱ$Y- %bȟS4CpohZ)UfA´īlF=AuѣM:f pszk##ŠF@ג0*$;-Y%Z;f`o){'$n={.X\fo0̚ p;fGlf钆\f`>ei;03[Z3pwg}lyU @Weߏyݹ:j -vüxϱ‰;~@pM)OK)5b˙,vMr[7hIW{^ ]=)~,xCU>Pid -5pD0 6=*HB<`@On :g̤"UQ2L֊t=rtdp|ʄfDfx"Y<==er/d,j~hi)$T3$Ɉ(wvhËN <^u [LT,"2A;<|w&g%zXK3q410\I62|=tIʧhO:L4^FUS#ՐN* "E&9#RM Tͫ%X#FOq (M.KfC7'^0 7pW 5[VЎ>Ewq Vш ` RDSU,/!!təMTWL=Ra`z Kc2H36K{VRXO?{/I/M\$+ņK9FpBSC \ ӤjG8yD9E4Z!z-8#v%]asq}y=uB{cƮ;ynQ7fgY%Dn Yp6/ m暀,k iH/B}9pѱPK ~Ak11² Vyzor-master/component/brush.luaTMO@=Q.%i9ZiH !˱'g7]@J̼1|V:o0dD aV%Z>TmvZ,W<p W"GiJTnW[(p vL&6VJJ+4@3*Kg%g1vVBcG4SfaðR{TJTA-_"QV8wtMBg@i_-\6ƽlZf$p+}ąh #hQb~3'~v" F>7lʭ Hrή3Ѣ6  )l+iᖖBxڨZЮy UI7([GNhξgN+3.*[F'4䌮OViLs'~3Csi>ٛkM>3m.]>_δ$~mK%ݕhVR)-rivv^v-}n"RzCYDRcSTը˨R#k*9 -NAɿL!  h+uS%v-eQL- Lw ǭyrR3s5E]4?SaB9:AH_POPڨ&6C)0Z$Բ)OC-دDb;\BU!|D䞅$GqUbe-y T x7zXTC|d_Wc\?Z|4`1z7p !4 кB\x"#"EpBH:VYmߤiTɉ?R?1-2&76C-^;o³iu0c.".0݌sV"3 $ZePYB5Cl^ 1cGxo>hMNB}-gw^ۅ|/)t5evOX#Zj. ({$wKnc>&]!A߹uxҒ\8Ghnt;^+ ѭ\L0Iy4fZ]!d̂IӸ9 e[OWf]0-q2@BK8M'IȠs<\'}\!W2 .LQ5eڒEK#g1KBÄSb?ɦڣ!¶aL[V ٨IG˾Նd[@yl/PK ~AA֓&P Vyzor-master/component/font.luaVQo6~~@1j\k"Ҧu=AKE&=#)Qr;X";~wI1|j. Re]T1*+I>׿>1&ʜ Ef* ^+c6vM7drJ<⸒9O9DxM@RdpOs ٹR1SJfEk]EH<5斐^[knx8z_13G_kK-!\4@r`@[Fչ*q]1p3+E)Qp7 dR"*Yq* )ͻ\`^ ځ|x Knc[6d,*ڼ.km`΁um)NP:۪ G_#/ߢE#d6-Cr8rE|@twգKȹ2`k&M]pϏ)E.'Lepm!&$8BJ.4< ö$ƅ<&s{.i[!-ޤCI?```PS>)F|zQ 6)|ci)anz#}?*74` 6~HHLh{h)fbL~Zi2-L7ID0V5_{48ˤ;=Dnޤ3%4RvR^!,Pi#6+M7&4d]Qr樌VZ l+_{;=RBt߼P p Mϓr?Ӗ-rҶ};"?u/6p=g|Ϫ;|v0I }ԧ1Ϻw+/B c7r !MG5ݾfy}Z%A2<~0K͋ndsJ6K _w|g<@nm;KJo]lf3}jYd%`K ø% ]вk@o B+ QPK ~Aq#Vyzor-master/component/gradient.luaXoHlMN'"V%z(𥊢IV8]fWzpWTxv{ro\LeLRixVQr<mnMחPE i` ^Z_&܊ q*1NzQyµUv5Q7ըjmR8Pp&[}>[2û 1S螷?"Ȟq3Z&i9ϛ}kgY-gb]58h@h҂~i>G?2Qlc3M?XGJ.=4}CY?">0boꂵ35<1Ċ"' :{k?PK ~AjC5& Vyzor-master/component/hover.luaWn6}b࢈d$@6vl&0hȔJRv݅!k\oڇr83g~|{&ْ+X 4&6/vJ,W)=x ?) H;nQ^F^GZyC}0;9\⿗B`CYFs\q2 یiÇ|U?\s+%& S\YC& FU o0x`JPHafIBny!_45\ $b$40",0gnJ%mJHmR&tК g#wU*/ODiվ!^l`u^j>#:d kʄi(dxޝƂ1eIV;_! 7J] M nQUu_F@J, 1X ӖX̀mW`BK8!mZse sӊ>D >En!. 1)eg0ǭ~8cbm{@# m:5v7p\}mB A]r/2g.B@Rensk~b蟣*5I\NAXI R,~.$dY m| C5Wl>s:sd\=@Ӡur]Ǜ c@-C̷]0#fDЙ+pBGhD-Ö SF,XJ3;נ E$C( [p»ҠO4tՅŽE͚ >9+|a?X",[T8!vF:|{PëKr|۾#\V—Tl.j3_E톎E-1)$Ų步7Ԛ%VC$%)v1mn6^d"lmt? ;p}{BTi,tr&@uG4z(#H:>p,Py~2ply:էw_BUu1otM jി<lUhl#8l`e\Ot"CIvXٯ]1dzAWsbV6L?:c|g'谑 nMj֢%)JYhbXl)6,+m:s`)ž!_PBh1BAgٶ-=\QH|oPK ~A1DJ Vyzor-master/component/image.luaVmo6L6 +[?jk ͖5N! ڢ-.2Tw0N?F>pNZoYn"Jer8&ɝ+Ӌ/te"fQ BoyW `lFYI#0z@ ^`R]rB9xn)TuHxc}}6bgJX*aŇR+I:Q.Кb]?V֙jIAcnA8al+S`ml +j' Qru2U͉NbL*mmPt,h(].>z$ >X= giB0CľWEp/}fWZx9IĐtaܩD =a\IDR+pgumB0%~+#R+Zv-jF38VYhײo~!.7^^}!bJ_ݗ0i^8~śl< I*8kg)@%~RT 07%I(a>{fU `Ћ M/\w9S˖}߂ &I}{;ZsD&ޓ8הUyT 9͋FrD^zM~ R2%MH%`.7"OQm,GG6 XKQGFQU2NɛXP2#]2Nd4 4" t2*ELFAELaUV癐\ʜOIFa\<~r1g,cr#A0ÂA'7d RţtJ>yp3C&r2"+ T:y s.!*)RDaة(7y8&$4S˂.18KRCa tAlQ5ZũCP;IP>IT%TkMx!tN %q<D˾yT|8jBU>Qmkyy@ &\K+vaN/9yT iV%K S)T*bpP6(M8raδ]YApSYOjN'Vu&\Zk5hp€+t͒1>E1NK؊*9#U.d)`PJ ء}<^w="1*6`n{W=P-w̵i߆0 Vf ~n6f{wJ{ O3Su1CT"LWuGR;l(jrM51C 9pj+;sFr֫nö"DV2cԀu&ϴ ʎ:#ѱJÎ2QuNfg2ܑ|bph|v*]W]WBוum.M[9C?{v0h97A_fвqVt[oQ ^P5J+p[ ,8;(̳7/L_% 7{qˎۭ n sNϥh!e7@T+Ti4&Hh*dha raN&s6՝хrBnaekgJ<T:3iKH{ԭu[ygNN]L>]eZrOrsUo_@$y0',;|DH&>r_b^*s) El IOM#f,K{;m鰦0V|β|LPU6t7;X׳VS7Bv!OcP>p_š$޼j> @PK ~Akl !Vyzor-master/component/margin.luaVmk985W80I iG!)!IK0FY˶Zr%mҤߌ$^wޞy}!bl_?åb!-̍jVJ Z,=ʑŅ*vr_J| e?K鉛5*Le ɍ]W% 'V)+Gʒߣ70]>¹1mJg}sDjmԞgI T'ڦC/*{@ o|2v%XI/#&p:fZݣ fҋ ^$)(0 Mck+C3Y J^0Ab&[Y9/uۥrM!vɃp;ѥ֩h)c d-ߖQpV:C4)7ϵyPf5z:-niR~XTΛz_òY˝ɶrɘOwʎj(XUPJAiL޴q)pԳ: Mu_bkYx(nʒ4')X:Żژ/*1i"p\NԨ5!,弻LRVe(A } ~xEch޿]ˊ?RK+<ڣ{3| V>þ 9vnYB5n  +qɌ7)/px S)桯C?TxeW^hD5pbqjBї6i\~sosA(a2P4c]w(0͏"C:aSHM6,۳}e%C$ h{lu"n-ռ%Pk 놽\:h u޴'>]$Vnv,?xD~-S?$IsJfQP5 K' Jp@<O H:,ؑC\U~ nYdCTYӏ,n.N5ZMŀ'uNx%ah|$~PK ~Ak ,'Vyzor-master/component/mini_console.luaZmo8, "=M{_zAS ^nAKt,iIߙ!%%C#K+NOLNo7-OlIG*K?43ZƏVh+%EDĊ4vHVZOl6YÃe%TOk4J'g`RQR9[6OFU•:go4@d"FAJ,T(y,>jTՄ'SvPXRJ^5WZy+uDș!*-)Xn8RjӀG"ԙ0F,(J 8o#@d\ g*q$%đ^1 lv{MD(sts^0S1aD,\WBtʌAyh+8KpS**TV4 i)bj=:E1l<2 攙ؿKƇFh2 c+*n H"'u`.xOIWHÈ]V)Vc^k&1 ^q1H>D581/ `<sP-/B}HvsĢAd BgklV"e-Q\vk.k!%j.k>WRmڨ7;!T,߯chil/|hTGm?e4ݨn0~`CL h9#ÑSOQҮ0?3i4@|. ,.6(Ux/RGs\){jw4rT^:5ټfWvo15m_lj6m `"4J#, 0;f;卧8զx+9;w;MP_Oe3vd/0_Va6mn 6U}7 ; jsdgOཐG53{߃Z M?y]渣J7ƦHRI4oӑ[C8e“v:hkI=Y@nt~p;#HGwӜ`pߞA@2awS a uȔj<ޜx[vOu5wMf -;ΞY՟ENlCfd6P;+Q[Ȼ8 YM7xˣj7xee g;i#Go;CvVf򹳗`WBja۾SWo ,3~IIJ4)BଞŰǖ)ڵ=?NQd}Ȑfz넔3% Yfr:' csDL7&55țO(E}dʞkmw7ChH߉ֹ.8mRxl쇕eүž[^I>鮑V|z=;3cΔ5*jMkf^u7T7nCKWԶï$ cf?7g5+ N7E5눇W_=#+WWLpTp5PpEG)b'4h~mf%$\D@dXb-g{Rpt ]sd/#Az?,jZl!^]we; -Ya1YA\GX TJKX}^Q;ȭW{ɫS\:l24SƓ~"0/PK ~AQ "Vyzor-master/component/padding.luaVmk8,!\r[80mݽ=#RBPl%1u$$7.7zdmPbfgg8N/p]祰t8zbi '.`,-qUdBC-stK_ ǩU:k*4Zg)ŋf^*%\r# VZ{%io@1=%KnL c\PB>y! )_UJ iLb\%Ћ@J*kJɘkVh"0c p) j^##S< g<[C^Jɍ>iBZfP_O@BJ{rZO nY6`W?8v-X$pKq\*V(rɐ87ˤz(8j94WfاRvƪUliW9%8 cӪi X %DYwv~Id"V ʼnU8Q-N5&0"dN]ᓪg%ت?u{f[tkw0\XCB1ui#~N&Δz _NØNӧzjz?B;e k\cBsjXbUͅqOSs՟ _HKЬ~T㌒ a| 5~-N\ޙ^XXV%tIdKAĿAw |cm!Zi+ZLQ5a:fYç8yJ>cy 8oPW~"jO /.ARˌkXCQK>k9K4D[\O+48 m4O@ 4;@ʢhr?B ]e\40I+*Ns@w4H80mM;dގ'8w[lÈr< y 'b?5.𖫗JwRq|ӍkJLXU$v"t6lqw2 TzĖs5]))vWpm. ],8LXbtO]!\e#5XKɏz`Ӱ%$6jP?[8Š ~{c%k +[;ٺkYLF ؉)VNnvmD`)`_ao^F\y/=v_\aGW= N>y;\^Uq/Ur-a(V} d玫QOX#\Lg^Cg}.(ؾmCW*?n⽉rqx82w*$psٍWC2LPp7\\PK ~Ad &Vyzor-master/component/size.luaY[o6~~ڋ4]Fm6@eMC[L$wx)˵ C+\Hz?H&((Q)Fq|ka` Ƒ>R OF̂_J `x V*7RZ$T,8HZ]-i] 1(R}Wf\bi'zXXq5xiA4vs$LD.iR W?E/6`#X|ڮڭ7ˡaϺJ L0KG ڳgmT؆yY[,JܥїhUU"9-kQէfŇpb9^HVDJNܚ 9; ą~h@hK|9Ry^ZKjhhLe$|a6Vb= 䅝J(Aʟ(@Z5Z)YJ`r[VDV?3L-8%&:8UuJMVa~eӲƐPՁjrUlz2E(%| s ؅ٟ4%Ǎ\_s,Dz+,y@"CmJem~mahF'_C!Ef*buy))LU C ?hvM-aiPnMX$ipP`.|l}"〯CWUb=iuo-P(DTqOԢo'Xi`w&hrZn?vC8˃\7N7[A7p u3렻l |Wn{&~@io'*\nM-le?qH/H&K9BЬXWj1pUS'lw]euU`u + G-si| 41'iŗTqX30R=Lf^H̡&XS:yJ|Qݭ*:s4_r UgYS7RSޞ=̭>{cJS&V)[BjBB-zPL hhewgh!7^z\ZH]6TU[G2kkMh㈺6{N՞lvC/C_P3!Κ| zWW.?dfXkwϴY N܅bi~@Biu nC%TT]O_v| sHmho٭;w7punwv h(*&P5i&o-c0 F?9y.;~Dzn榸5yPMޫ\-"M8jތ 5;LHA. JAѢ~PK ~AVyzor-master/compound/PK ~AcVyzor-master/compound/box.luaWmo6,a(Ì ]h`m A`msECD;N G"yx<6C| i` 7e%]zpzcb 96 \H%wj&k+KhR'Doztxx{{[5nd0CJJD/$c0k7g1A s]=1Y7b&+ߩFyu&*a,I򋜫ZZPnjRhڀ0F ;U%gNeNXI[}|0f( ^Z#C! pcO][gfMB-'mMd'_LD]h^ D%[Z8 c| Z9IJz ES9 N[m72RuS1Dž!x^k-;9%o&l0F'JU/3Ԣ975l2d~Ё `xQie^a` Z5TmJat-H%K>r#;U$"-cTsU]Vt N+{L`Y["VC4Q8k7kũ\=BDǑO 94j-Z&+5:n'~{( 2&OL(:`)PTzjDZgVX^Q ;|2k1e]T\ᘍYQNAWl[L]ށu Xm %{kq S'>Ņ}aLa?A}zQQ}oľ[ɷ(RxYY%6& ڝc@obxo-[kmY+MƏ+z+alV\[TU,q]Jc&K,0LC $Jp=> >V R~~Y'pԩGzL#㳭h. NXOaпvU[=cMEPZۭ;RXi`֛hԊ/pdЭ>臡O{} s1A~8TߘPm;mGL=|iE硆e;W_ƾ+I$l;[;GP/zd7;&nDHoa! ' u7:89LېGj% b\; ?up)0؟v>oaI? Y ;m7Pû f;k"01R>ׇ< O)(]JlvjD-mre১gv^!I' aJ.PK ~Ao ;Vyzor-master/compound/chat.luanF!*3vuGM!q(rd͚"!eYYt}9s(v}ggtt~~KK6${ ؤZm^4,F J7q[9[9,o{s ϢiVϟo6Z@O*y\Oê`/ZVEgL?B o$e!ٵ5gQԱn#޼{ɬ r%Ξ.aDEL 紖(PF Z"e73(dn[1U!fn;QI{[t8Xif-<4*Ҥi'JЮA4)Һ>eE HirRKfܧ @RMiDp9O3No~$+#dH֐aħp4r5Hy`.@[m"[X ȭ2vM~t]4 (l_8 @.ZO4*IĩK"K_ ql8/qrLJvT,!cSɜMo^J= a-ТWe rlMfej1[Ljh&v]Du>Y%A띈zh-1Y׏F_Gy<8v1aiGג@v;ѹFː;S2٢"扠\ԫ"݊>X$׍hRj-iMAFLaC __0'ϚS*FG0k;b`Q. 񖝹QފpM^3=AʀlDQPD )AZEb;B qLR!8T6by^yya aǑv 1m{ od~쉽~_Tn$zY5MRs}r#jRļYXR 31F^/$ lP}8&枓,)p='!5RsvRإ"1(sT tuhh(hd( %>\CrH hΊmA_%&b0L>Hx~|ƣ uM |JS䎹gw`zs #&)R$zyjڂ1,t y?]@C0z(Z$0K 6h0Ar+;Ef^_>?) 02c/ZNÅ8QQsb{:4CO!oK$F9Q,k3)@Ahw 7\^>Def~ؔO6݈oH b-VF0{n" )I>gvQ/n7?,$"7Z`+!iԹYug?2w܅G;lt:\)AWv uSW%Y>"m7CY9E/::+?s Rk.'VolQq5R MNC=Y(B[К~T _4S*[<[SyQ*(!LY♘d V5sE@E^d\+dމ袓=]D9E"YAi!J"x!gM&w X6jj1K7>cjD `<hֻT:?[^-+/{8lhRv}LwMc52NSJ#WOՃl.U>fZkѬzQ+%D藢jأuKL,u^^ =ѳ/Ma">ɞ}6,Ԡ15zJQ\Ir"wUNC-{ۼ7XR4"-nlr$,6R}˄ٯFПe)_ᔄGZruWڶ 緢|X9 M|auz7Ua]K)&5l|<\xS=ofqOC$|n4~:esZƌ˪.uM6ZY kp #6SSKa:5} i1ۑ 6,v&0tED]r͛x4BׇLK4}G@ȖD̙ŀibdDtOQ8 34n XCPK ~Ah #Vyzor-master/compound/gauge.luaYoJ\uD1Ji {着I9a8)_ ŖbUrtr.Aպdb~}q+R+$RH^.DVUYZww,3$?NO}oA^r:5)pFi){_W*9SߕT"d-6DVFsG6fZ=|sxѩXyf\e4-<}\"6!IuFC5 VZ);cHjrޫ!s$ߏ˔L(+=7?=<ְs)##](3E)Tʂ7/b*L2g6`<5*($|_W٢y69NLK*ls4-E][$ '+'26ra%9'fEN%#ggEE~4 >q :)fwHvF?cXydRJ)Gfh@V'Ea-QQ^*((orSm~[f6-]:xLXk b_)/$} o>M+Y"C1&< KAm({!BQ'+(@*- {,?csF%!:0G<8&Rbb 2^l2#9~2)s5_mSkVQPeƒtƔ33ԩ 1|'m+r"ufw;FnsǕEVb -B?o`NX[lёJbKvb):kk?3ci$C +Q(t2ܥzS5!jj-u $[LR'nQXPb &tZ@p$; v,be]Ta+º9S=6>('9Նfr ZxƵN,hjX^nbH{DG߇ZY⃴a>GPWP3t=:tP,f3?r,"w#Bf\^J^TH 򏦎}@ɷ v|֠n*Q:C؁"eT'ZB}:+fv"%M9.8m_6,GyQ6Ĵ }.ەmOgW^KdjIi] ܐf YeZuyYD:6ebK##Pchj"Vт]5/k)Rb.$Fݍk%wCѸ (iT'!4󉵄$ =)v=:4ti)?Aȵ?Xdf -W@+XhKg:~vCa?AvV_nu9ڭqhU}.,M4F+vfqRj1_NȂ-!)䋶 o|pAǬ‰%De mŢ7>Ln^FgGoe"L;1;5森_諸R|Ӊ-Wӥ(D`騜Bk0V`ta6x3-P`0BON^F`F/ _ܿB>˷7?[}Q{y''g GٚgƧu݂xz׾ҭ;:S>5е k؁:l:+bCAPE5(dC.#v 諆u`]H@<Ƨ غk&xڸ}`?mi'^V y !/bia®_ͭ_̛5/YYUҙ_׶= y/z3*yaW-ϒTм{cm~!'(HN:t"c}NEx2̀~Gt_Z5ő;1h>kc8z6<&04g`k^h>?CD4rHnBgΕOA<"ԚH&EEPK ~AVyzor-master/doc/PK ~AVyzor-master/doc/Data/PK ~Aȉ'Vyzor-master/doc/Data/ClassHierarchy.ndN0hr r &<*MvzּS }~Hׯ n}r'tLQ'B([d ފPzAaH5m(ДۏELtуFn|*Ies 9S?QċhkfI^cG߼`)d*YM-V(K5K2i ĖefEa>&UkJ ӻ>sB ]T[ 3ngnB"* OfwY0WU7'5#yx"7x3RUveȆ<`xwN!~lc-K 8#5 5bbSXhI$BN8&$,dQha׬+ĕ4{("/BJ!4d݉F0 ?R 6slJbm֕'z]+Z)Vu}{UuYJң C.B$rp&c% Es/X* &xےJVe0UmE CN Fa(虡t_C0Vʬ{|6;!PK ~A*hX)Vyzor-master/doc/Data/PreviousSettings.ndcc4a```bF s -N-*qL,.)J,/ %('g&aU@e ѐ23bRX׆r:s;3>I=r\a#ui8Hɝaw YWOh8P_Oɠ;·λd|SHx;y9꧇e')pw{AE=,8쬼ԙ u|y'S2,-tKݴӹet^+=wT GY1>TZy'@.2I{râ1 YVtκ1J5ǍMxAF|u5Gp;Ys O{rso8sJIZ?PvHm烬l&'~6VKXɖZ>@n;LJr"67 k3<{!ϤN1:(NY|8..tGmɨ2.MeF<11v]o^' $K/ꃈUN6d2TM՟]MR ^ `tL:73:Ş z?)\k{}w8Ժ楞MדLmC*>=V27FS*FD .(AYZ XǨ/|& /uٞ>+] @;oI_Q1mnݧTѪa?X tWndQj\wl{9V# lF q?F7&ͼKi~7r+Q[ɶ3UuM¬YE $PD~e6S ?hLJrQ+.lcN\mqqKu33Y?œe<%YE>?.\OdL{ ^4evbRruN܂WvEEv mnp7Be΁쿤ϰ+ƫZlTFZnC 㜇?9JlpO[l3z B~[oM3{&t7KoVNl6̄?,ӜV7 cϮ`ڝmg<8 7FYŸ+{g_<ѵ93 r#i/W߉T&oi Q'~UEW?J{~:[$I9} eV&R glGhcHj7Y/„-'`ӗspO2<=JpvHGB7ݳzᐿjM ⫑e0cbme|uJ ak{3ϠϢv3.qS|=:-1tȞ?yc ΚFfGLПkަa%aW 肟 IJ&.v{K[UGiIߜ%](s R8~68ni  4.(BG'pv2q[VdCőG؂Y9rf݆Zxvg%&O裢F|0~B(cdL"H;.@j6YY"?34F팇 a Q$ZMEV@!-"`誙*d>+iR[qdԙ]ޗ&dk,m%K=r} H 3 ;118L HǍ{hCWn%.^,AA.{YW,Gj19C2x ?Y /E_ { M阆yPKenZ-Hcʣ*|IqVjh,.{:`fؽI0.lgypp! ;KEڨPp! + E7kkLxB&ulGζe=Q Ȏ``܆#nC=RndWQEƻ)GN!\a?!c`,8"&.d7tA))Ba&OUm.u eR:r^pя݅`A;FP{a_*A+ʢ dk8DW刣(ZR!vLl} ?O"HKL.pTE%7 0Ya Sϋb^ue""厃^GJ4Fo.Ikoy0&eKÀL̘0ݨ/6haj=դels ` FIWo&j* ~>{_\ZE;tmqzϴ~Èϵ醔63(0Laz"z^JcV  *aQHa9 n YW8&jbl(?][<]4sjzA+BufXloX'C^+dF{LչR/1*SrY ᠮ{7k|MLpw)4>}G*Eخrl|<^v37$/?o Vb`?w[Ox"D@ar f7'2>A,'O':dZXFrQk-ȖG[t5pиAuZh&ǷaPAzdQCaǷ~F9`eeI;+hRNa%}7])^܄p#cM/"Wa!- }zT/;WOX5=i5q, ~weu{:7P /pGICٯU A8$ف,$̇D+b|P12y%couD ` 8JPwaz`"g ͙=0F[cG?sA3R'jHGptq˙a'‚L!=5ܲE.On d߇f#w}Xθ LJح{QZ%Q7nxwVΐM7v{+ZeuZ@2w(`{oH kzY<*k8T3kjSl B\Qc@4nٵݬ@xrpЏ-~3ErR~tgr53+Hj,S5!O]I;I=yo2g6ݹ}&:N7.XaGo,.7<'w>g_Zp.NϱZMSu NBxzr?&9ƆRpT_jl>^.3%PLo$HL?m*a[;H$ynvST;ՙ^мIcԎv~@+ԼYK 콨A,k)\ <2IV>t472DaV;F*UxGS`,MY5=X >+IQo\dRFU0P߃rɆK$]/dVNe7A6n{\L5[>N-iqmdNZ%l+W.Ú:T׬l5#F IWĻU>5ֈ=xw3?T`uڳ JL V!c1 ݴeBVn9YYYQ6#ucB:뽗cW^u9 '8{wXd\8p,р@ooGC~J;k褳eG xKH$LÝuqDWL.+znHY0oAc&#r3s Nu9N_D ~&j4!ht@ sav)FBhQFꋹjj+p91v<&{%tE[>^n |fGS kZ2J0Yh ^fmS &K8>N|Y-#YFӭ~z 5K#cC181kF ^H.7kD!o=@R*M jh'&4d"&p G@+گ4"\GbOEڡ4Hnfp&?Y-`k!4) R0\c q#^%07Uw̱[=8vNE|A`9$̷TFL^$[ h/?4p,t"[whѭDFdYL^ϱ&I$*꽑$Uу@s1( #ذصUэIVz窤%K?-% k'{y->rjM shzXA&֗.~I'CVϠNW6@C,%KW) ghǛ-IW{v:75f+7m$ :;:ñ8r֝d gfKxWG]kr;[^Ӎ=|8kyu wq΁05uhqmE7QgNmU!l+ L^1q@ţa-NZ,d?5sU-x"DFFVʉm2yKQ@vⷂ3 |=jZIlZ4Ģ]6 \m_3M4xy9Ŋq!#s"\mfCKi㽭a5ӸoJ6t&:mR։5t? ?DUt끹.L^Ī}}5;u'y!`aک*!1yː۰:4RW4OmRh 'QVB %[)Pl 呄̨J"=IJQBӎtYA-vQÂ/ eG,+kM+|Q'"ćY LRƛG5ZBέW*Le "-B]VoƷX` ܿdmNh==VBM(-phc,Lm /ydX5PCn:^H.|zR4bdhf82lB~/$*8ǜHm}H&_ 0QFTZƾYL66©֨Ơ}IdHӀ-gp5 (YZ!Ap{E6X꼃5)˂ =6ԟ5Wnmora2<ѴΥd8Yu/5܎SZv^&G9>2ǎ%BhKJhpD_f*mݰ,Y شw> 5HA\G>L)V'" ==@Mi3Ssr8+hz.]x$M@Sۡj6>n=GZ^:Hwݠk}j_4R]:)qy[l im~DR]g Gة6i|M1ńǡHxehܭyZ4'e~(C#)r-< 709MRMl.gqJ~[O61v@;DiY+oc$.\(wJrAO?y1q級QWFÉ3x{6Ld tqR% 8U1ɰVmmrݎyq^z-:Kb!\iҴ2z1V/nIA M@TFl` TƟ@xrK2N`Ij1DF|kLE~Cf*" P7.%QB8괕pת2]м!Ff"b(y@wb`+m]H,5$1Ƕ _1ˉ?Lj!M t;RV +-Usok\3'7Y V(ݺ%V#\%0+`3Hg ,:q{qļwصM?]&V5ɤ  ޺þo߳>8p_8NqA1 urgbvfbք|VZxg( Jb+1TWPl8as3ȥNQpNk7xlP'U$-;'n/GS+lq8bLՈ#شk6ٌC@nT{iqhxL Hi}F?umGQH{Vv%5߈%Zii⪪x @G;olzGDk]Er*IW*"ofkM_y2GtnV"s}3T޺<,v$D|\"Z-hT2)+>_4 _¦$p_qݧzP7o#,, QqZF{?S2]Xs`%ӍU,ѷ%`D○vLQ:2K0{qP{qS @GwբG-W)\R9eծ?Ʋ-DByg,cYPfBOTb8JjӰՁ2!״))! sԑՆ 1Ve[c^K̲ٙ [[zvz6ZEK2إh1/ jo~^~/ӂZnRGL s\|&L_x6s)lxŮkXrz;d5A/dZ)3`S ųWo1v]'H &"^?sD'bݽJslN-{jsD534% _,X̂m3ւ :b)=+ JB#ԝ) 6`Gƈ{7OW$m*1r2rا%ZtX0 8 u@tM4 3N'lmU_2 Ok$ v~k8Z(%8oKpa1^WInXOh"QC՘%J{߫^pY?Zmh*הǞC6;Ǡ peš fmuSO ='Ucl1<c 2@D3&SXY&d;n]'l_ eˈHfPd7”#e͊T4!ձ OL#߶H8;(@e,Us\8n߼*2l=`%6!v a+ƵE2^cھyJCV֔y;3c򰂵#yPO;D yjApڃ*zrXJKJDG [׵6f,g: &cfux|y- ɂY}Y\XyaLZIBhDXcr*p=oa ]GmcNK!?q /Ƹ?i3 ̋$Af;.6G9ݒ8*e_[mQvז=d%3h^GוC/nl33+hB[ 4W2)ׂtF(F.qlu`vI<|u:.rGDzOumI֑[^Se0qԒ,}ۆGe䝷 -E+[DinA"dZ\*鶞5r8k50m_T`X2˳D W,:ڠj Ix[H I5)l:]ԃgo- چMSKnCVO[b`-y'TYM͛da9Q]FS'^YȥƾZL}AVpRV5Zl ˋp!p*l Uo|wPK ~AnFVyzor-master/doc/Languages.txtX[o6~ϯlb4Min"%ѶH*}琺FnPEws.d8P,JqR6BKiFy.k kgVy qmDJQҴXa6b2Rk!Z"X|s7ޞ-ŇW{G坢E4o+őj AX:~&T dUg<<QGufͺ܈ti]5>(Y4 "W.HHacPƗg+)cQ@r.7:%'߾^aOXͳMC3xnܹ*!gk  ׍B҈*2l90M' BagЫ KB,ٙSҥ != 2'GH8 drxŔJ(hlSQ+6~{Zjq.0,'XF^)GDa=h>&^f,*S>BKj (_YWHɭ"udԡ7vXlU{]Y*Vy)5{p"D E!DCMA!y SDu~]\,I珇?lQCR +b Ar' \^ԃ9QEa SVIqN$$PoHXh|$T#d(2 Q`oaQZn?$"J.LuH)^*T^&)DnnS T&0W'w˔(`$Iznu<M+c˜g \S;(WI L[ gP6%DE2c?K->ۂ#pgoT**G\c$j4l%]l)DJ.b<dzS`N(Q'bZ ndjهeJ .m]b-p-8ѩw(e;zoTAHGGt!4gd bfoQTP'x=Y`9 ˤ- &N6WĠ4;ٻp<#C HSE"׻ e(HHWwc3КMw_m,t,Ȣ4CtvOLNa5/+'2U6:|Q"eэҼCq,qFtAMq680`ب@w("wZ3b2pT$[5V^nQvQ/Gx' XDH"MPG( 숊FQv <'9,z^ rKD*֭vkYG_E qt<8(ݙdsLg/^Ùx+e۽$loR_~s !_ħ7WԃH{Ue]i4;FGA9}SͰhh"8F8ήT&' t,c#~FQ{Aߞ drIڮTAk<!a:.h- 3f~/PK ~AG#:, Vyzor-master/doc/Menu.txt]O8+F  @^pG @UAI|/9;9Eg{><ɩpGtaE>ߌ_ߜх"VEEѩ1N#Z*m-p[@9Ui)k'EJ)\R*Z2+*vR Ŀ]%aC6L#SFؖTMEgSv6ZFF{؞iyAҹٿܙław0!M_ag1|k(''u~^Τm;ףcN9.ƾCC/#S[7U)Y3BgBuZ>JQUR?17%FeElx4U=*iei{ءk($5JRăDX]rCm5ݰ̈́V7-e4oBUƙ%>XD_(}_9b6t6ŏ%*< CL}kؚ l:x7ﶻS!=V֕LzEo} +?;Sb+WL4fRKcjtmXR8lRLƕAL!Oʃqèb):6|G%9E84eW/f' Kʤ뛆JL8\Y}.~dV'R.E}˼$EIb}GEMɠΛ4P~8zLDohrKSVF#IY.H[ƣ8]wgmT*75䡁m|β$06ZA0H 1A9K[}F)ԅfL)0VBDM1ߵ>e?rxB_ 픫!ؑcm^7# 鲫 ey+sߣC{fF&4/<ѧM)qA:D&Ɗ>侽OGY<_k/ /h2yʃG3c\i ڔO_ _ȵM2ˁ}66gv>4M944(t\̰pS"_e@ǹaXxRARzsOr_ \Lh[. u |A 7/GJ^3ҚJZ~:U"Fa]{}PK ~AC#? Vyzor-master/doc/Topics.txtVMo6W /-ЋonSۨI #JVrIQ7$Wzh xEo޼G6"ϋ_99yGVy_h%݊;VX¿FiIu؀]*,nlOU+J0[dA*ViM,Z^Kh-u5wvC+ 2YS9*p0T[=!alee{< \,'Υ2ƨ-H2>f KxF#^a1 so:aƺr$bF:Hw 'EM])f#ڕڴy%Ox*ր  p^{&)v"r#dM?D%@0ځNs:hA1Ut:W$ZM\"E_5sӠLH|ybF>&'%̽BLƍP=$ʂ(AbRO氱Eʼ4^̠)O m4ϻu#: s8ZbsCp'ȍĥ\0PAcs#9 3U?ASfݳtI!t}-wHJ"+j-OŇf*&*U\ \x~z+8m)tv:i@;3+w^fBze% Nz,x!:v˩oQgȄ-27'J_ lvFZ0͈d՚cM9:q[^'s3)&\P i2D]|CV}8YIR {/*`cB~T·u xĘȬe [*T+Sc|3Z3 ^SZr{ Uݣby_fCׇI_@Q>9w܇,y,Q3'EH ́Lu{UvWWl:{܋Z-T8rN8Kڿ5 Md4|bSU\@tq8(0)@:ӎ/)QSBw""^ AiL( $ONW Q91.E%&O1e41Qr;{Cbzwy NVұSvWR8 S4wKx_״Q険YjS5ϢٻZ'NeHvRorSD HZﻧxQøĎexqAcbbHSϙtiu?F~|_Lץoq4<1 #_~_؍=d_p)u !.(^x(#[ ƴ(8DVVz t)/aNcA4#t{Yy?SV4'hLCb]:p(ՙCFP=&l si}Dut|NyZ܇_J?p  9`8>jЍёuO{@Yu|.$p]NgNOSb(1r`>xB\<0r4j&i?q'ӱ%*2uK+[D^'ۗYlDS4<c참&0ˇ/W5C"D/Ki4i*4BN>MLjX,TxCR+|v#,S' MV“a<ܫ[K[K7RfKu6, xf+׉6y*j\SwP7)1jer5h~ |^?g׶`dqʊ=IS3j0*)9md7dEtٲ IKR!DBJ[;EDDQtƤ Me-oA0It#~BW؜v9 P":F/5g7lpN!uVOL:Sq.!r8ŗ6) g77 I-Gxfqyw8:x٧!6SDix D x I-:0 <Z:P7~oI{/p$!Qn!OQ\[`( ׆6mȷ }iD^`wM5_öx8JkC׆]ڢCM$icC UH mF0} o73~)TpmtUC_B7|>,J- pۚ0I "*k2Zhg:;IHѬ#{CL%j 5T-9}7O G"b=5??gy`I-y 8q 5T- mH֣JHqჼ "BlBDZh=u$rO4@2Z:<$2ieNvIM޲)ۦ*vg䆧;72,^NJ-3g9bo) ě"oqZhce!YCgJ^zN%$$xJѦ>ǜ&Yfj3:Y-NDf.ii˦6nXiMhk NUfɦ6niͨKj,j;˸6n i}g< TFmlqSB<+qY- K"I*6m ziMMWEPCA*6tmе ]iMhk7zp%D𫯏כmͬTWN\C1iD Rw4uJ,&hdT$؟?x\ >Qh^G/-E`ikRu+VS^3fb8F#e7f1Ք,){ ̲dNkzet`.`Im lA1ftТ* TYyJ @-sXOQ,NlUJ޾yly|#V6^ X/KztmbD7Ah8^j7h(Ļ ݕ[<伵{u9_r٪Q]8xp%{ǯxtoN9 =™ӽ3} Nh:U}6}zNYrr]v(~S,f.ukDs!BXw!;@\5{8ƺ86,S-U>yH:ӭ%$]KD*S,].aZHUT=L^ki3"R%wkiiF-2.#Zzte-ҵb̍Y;zl;Jltemu =3@*Bm ]YSft=Uĺ%u@:S;fe=UD%uWȲ̊Ǹ*1;DQw HW 0]6ݎ7(D'Z`nj-:%haXݶ(PlqeƔ-lnJnQ;:ծ'Ѿ}u=<"6mk;kvwJ2"ܿ2S^t,af/bsmzu۟T+:*ܷ.%V (o@u* ݷ8[/ ۵5rbTݡrپoF.9aGwhLu[)'&^>LST,Mo2.Lt[u3{JMQjν+XEfxOox'm.'"_ zb[ټClv\Ҿ6)@YVѾS,yQᱧǖ $^L^p6Y1/:J ݸ Q7D8z.Bb6SyztP7OT<(ᘝ 3gFB%0r0;V $,}ƃ=/=N:7b1  b HkcDR: ULR!,e I^F)Brk߬r[7`: 4OivIo+?E׉N Nճ\9ۆ2PRF(DrÖjA !;\k?54Ѩ ;``dg*j!,E-3O_wv쿐c3l|ήM$Nz0j?;Jɹo ¸D.%Ùt/~q֗AlPu`?sMgv B쌳36 M=%8'GTlC͘d z!mDHdG7>y£QVN^sQKu0E2gOT.=ΛڏЋXF/SE}<#tEDSk} kU1HjVNcݯ/l@/!@ZTENRR5.%}IUuCh+-])^4- b^d[{7'y2n/Rdm`?}HYvo,ʊݨR!g@?@]ӅcNEُCo&j?|.7B {ÛY6ahr'<CT{ /-6^^~v|M4& ~NMLjM5HCo-q T*WwOЇi[p Zg>تW"2׹VH@޼kWTreܔj7;M4ʠ*?Z_Y雚FiJ19Y=\pdaN#S6)t9jd^}{Hi@,_tb{6V]a/m"4ࣶF:4q.M(@m+mYwt>Y{8Yg]^B>Sx yq;ܾpV@/-:=9leBFZ*^LG*he"4:Xa0PHcғ_Q8&jЍёň[ϕE.a~PK ~A8Jzj v;(Vyzor-master/doc/files/base/hud-lua.htmlko8{W .,@$m&!%f+Z!Rm683!/wC=]_WGm?}߿!o(eO&P}_HNYe^jVcHpjH?R:nzmKZw$&}5C͇e^!H9O7|Ոhq5=!CB$`!<4u ?48M$pfƒ{'1X#):gCce1:vc籁v2x clR5w.G?- v"Zhܾv%4Pnt j\=c'0Lg`F@'%0BǸIZr_/Uӳx5#xonX*-hulҥl{荔oKCr @^KSQ7ł"x@Q0ΑqO$ @ Q_I30=^* (8Dʉ%iaaF)atLbVMFD⏔ txFToN}c g3IGJم.3IÇ'džD?Tӭ> HJpږEF@WG arKM6*At0X ]sb Z :Xۂ^Ăԗ \!qJoOSqXiZUzO9?D0u+ W2`yPL|)pճVj+!H"צ Y5e_[!̅>Z%Q&\ u6s^`mϟsD.*3,U D&b#1+Ȋ\2NZy \i9+)dO2,Qz*X%݃m ŃGXBҧK,keIwƤdYӪߞƴ!˛)֬Q\GƗP5UpnC*(2?=zsgӪ[r4LhʴwY)5,D_$r H ?mՔUIZs$(FN%†GeS,cj)Rh_Aǒ<#8L~(ΜzOTm﵀%vΕK2KVOڴ^AYn3g.muN9oHJv8[g 5GEB>1x<~IkW輜0b'/ cVdl!Bxy)gK[ol!Cxyt1 [P=^lI9Ϫ;Ѧpfږ 4E1?M$V.pyhH0 B} c*0ՅsW:١> ΁.MrdjLu?O!+S2zDÐSۼYBMrɨGF4p^.>Z L՘f(vCԝc= T={3C:l\RcrQ/ 8”e\H0j#JԞasB-TD$s1HǺÑ-pm6JX pS{ 22~_:=,Lsֹdť;*(hH@gux*. ծ {"jڕaǬU{qHI{U!5v>vejW} N*4. WE֋.nHzݡrgzU%a*<'K}|M#Gt.R@}]VCl;;1D9kKrVx|G;xgQWBq$ ?!Y; 氫_zXʠX=C~1ÞfCdzl()Ff)YLԆ'̇N2Ϟ;>:vaEo7:~F%oY.R7Rfjm^w:]Yhw4QI}y:H+`w|'S J2MהVQZG棟H浮u?:E"Ŗշ n\}3ͮDI+ȼ!xÞ" I\#&H<,W8-9y45D\nQ=D)}_kmPK ~Aݓf -)Vyzor-master/doc/files/base/init-lua.htmlZo8} oNBmV- ^iQ3ZN$d@% WU?]g[}toP溃~=Bw4\AN DAܻz Ɂ =߽kJj췛S"04E}Hǜ:i(#Qb"$ z;(`dr 5;aܐ&Xx igiyٸo@՜z79Ք-0FNj]q8 |,D"y=vo([ŝU;U:-z,^\vz]8FsNOt 2s Rs~8ģ#ZN;0fП.׋Ƀ z}"1aX]Pa<1:l| )Fw+4A';|UU{R!Ȕkʯ Ϥ!X1H׵ܑ.S!.﹃8؀aR#3G8_Þ3PG>>iivSyo|h ?[L~bi ل a"$ҎEcٛ "?%Ԝ: u\OH!IfP&fV- IjŇJV/)A S+ŬQDS*K*4 J6&G;'cH3d{L$r3Nڠ1q#d(Ԗ KȀ KUDN $1 zmAֹ*6upg5څ-cMŒu;7:·k& FYur{8h}w^_oa6֬ؠfEvN^+@3AEn֕Rpt:ku͞%,[-/dxUXqV2 ^>&s=VInU|_g.A-)%^H<,wTF=fϩWJkwh`$?Od#S nOCߧ4o0!T@-鈰}~p?V;gufs(OKva}duq'~DDiMQ*Eq(Q1 2BY 2IDk41z"ʟS ZҨ7M |Fvk3ked{)o}~]b=//w摴fNCk#m^&aqP9q-Qߖy!} V'٪0v'dNrhνVEh9݄9'c*w?(K>mY_D!N>곛(+-_`} ԩ<ᙇVeU4/Fe ƬW 8}vKgY(3y h.Y 'vݣfH_~D^ Jͱ};mS;P~Ed.X1~ bGzF,Vyzor-master/doc/files/base/options-lua.html\yo8[9{6Iݤ bgbmk*YwC%_L={</vKw{/nȪmwzpZ?˯Fm{2''uʆv~lF|g.w֫W Qjv[15G=76 8 x7 UjZxfUjpur_RְUuiE|hDꚨE12hZ T?{.[a^ȑa/.bN2wU=P[l@#dso0ݖND0sF.@VSwGQ = n(vΝ.e3/PZLK>0a}?:x'djsdsƯ&} 诿lj BI@E)y̰:ԉ3ax:zD쥺EhͽKʑTs-Sv[|Zf]GCnd&QڪF)"|'(Gܡ[!8 w?TQ(P&[aާSov71檔aCK20ԗ!rG!v`K!v]]҄"\Iˀ iHA89C A B6g9>3{`2 AD=p%q>rB,Al gJ_4p5HC4>2\-H1m 5y7jfjoW6AD[k]RyAh6r0" 7wz@n TLs*`7y@ \:*u_K0mxv `r@Ą3shH(+lv㧛9|IжmU8 6dfOYepiĹ.⋗n6=th1ˋ#Ctg\q昅~?G "J{k!֋hav bo%7-!϶"N`0:K`$fطD<:(ŌY6eۈnܤ`^/ﲣoZ,Dp@ ds}|?R&O$_n|Npa.d{ J=҂='[J\S& s8er3{st|xt.݋vs]uG=LfnwrG>qIh oqZ+.ݔynI־U^2unW-xol|ajKQs)Lz`y5?uBdiƙ%Hl>pMW>t' OnZKm@l=nCp9X'&8{YjFq~)64Z<^W! ܜm#XnPs .TVLjd!ʕQwOMڢ\9*hv=YWUcQ7~-ʕQР} )䈋\P\Z-˽<,tUe<ޠ߅ OdFeJNUm{`-q ]MϮ.偷=iaQtD1GUR/78NmIVlOO.q()*vNP; 690ߌx q<$OmWTBz/SWR@=Ȋ*HC$ >]VˮЧmLE,;OvF9ӵG[.%-=kڍRsHSodRȪgDR̩(=V7~!|Gkۖ0h$J5gF1oB0[(V?EsvavQ._ݹM+9vRP)Fc"ndLȜ$?].q'Z}zwibev@ٍ_") `ow52i *v O+d-J&C^I%3. ww̓ FMJ_Ѱ,8dYB 1B<}{8/LvnɿY<'Y7V$.2caS4\2wG4Z-vﴺ:C.&ÿ{ܗm!~V9RO5e0JspBhjcsLCߞ056]>4>\_[5u<O?phkHP??f@Fߐ6 >`|!6C@ihg'eC#Ōh8G1(vщ? _{BCP{r<rGb{9 E=.*f>T az~K8{-g.j]=uBƎGBz,=]3 >o//n~N yIz&d}j ]p9D=ضՓgDE-9]& 11[zBbTˆO50]Y8NTV򻊾b1 ߈]<\am\nSa[Fk?bm#M؄ P+J|A``n8$.q#3h(Xl*ubuJ,% h.UcJSo/V-QB{Ur݋W"Wg)U̝:l ~{|Or@pZid L.*)R/{CGXtENI@  o~3igЫ- +r z̪8}[ۘӷ%>+^`ꄩ˸_<C₼Zw+YgqT{+ƇP*-ULeWӲ+5B#RFʼnki2pY )[ U'$!]p^Aۙm^xڈy)P`#[8 ] ԟ5 yn6W {(1\c18N"$?@#(,Foh+u$) w3,I_NE>H]{4yU.N-McD0_i+EZ ~,9 ia cyGD(Z|PeǶC~X1߄))"T.&[EˇD[B 'x1K""2X~$ 4NW֑e#,ܹ+^z08@'d#!Șd\S'99eH($ #9RX[rq'QOmr/sϧ ,qOpO´S\|b]&vY0Z'?Üho"ѮL%vYS+)ve-qRhXk Whe#ͱ 9ڕi.c=j7ҷven-Ip˒k,ѮHkIۘZZX`NFc/P'QRqvl6Tr"s]~RVjkCj>e;kIw1`.dE*Bzdio&)篏([͑ eR%J;ȹwr(7BHK=eh7^%nAâ8Z%,z4U* 6+siYd- 6ƹ e'k,IMT*iJY26&=~SzXZc@@ݡ>wS*4zdz9j}뼟Du-B),d-NC&G.-4c'G\t( i˖u*opNcՆ$J2liӹaEa:^)B936nDe 3:e+O/Ȣ=n(o`f \=RS$5d: i*wk(S"*SPe4{P˓+mkp:&W}L8#I ctC-v@kL >h|Eae4n"<1BB 8.8'Cav^h_C3u'DkśEМġ{{]Е$(}$&E 觡 F~Lh bq사K.BMBlwL: 4u<ߗ AjV2Y @rΝglzprT2ҒA)D8yHG`HO1Fꦕ5S̎t(x3lkQ7 N:ӧt7N¬Mޫ Ɂ"noZ)Hk,J$(NDOvrp719>)yipE$΁nr @J%-0(BVLiEf/aF i|zv]fzSJèb\㡗9+ydY2GKbu쁏8гADP{zZUoI{1$GO= ޑe^.<\6S`iBӥhJ#YtȆIhzKٸi.ߡQ3k y͗z Y&ElT՚N^(3}YVjb $Lef."nc,-ш'իl,'#rRD:c[#:lK4WvS1"uYڽjY@c8>chajea}2~%?ճf&>i[tئ'nCpJS_<|iFnFqb"Q!;'.'z݆`:;[KnJp  gG Z$/|WxiK_VDȡ[NU!9 ,)ԋ~-I%]g-ҫ,kyFk,"~rV]_6dCXugm|]#d,ed-ғF8UIUDY1 b2C|Ci? 3t;u\W?i!ieqfI2ꊺa Mb[z#cS#8>؝g,Ӫ;~]%L(tI8-O橩",grmp{g$t:W֞o0F I=v㰴o/%(hOYo%P^ Y mQq~u{=IdYr w_d J _o%hk4~\_mbmȶ&@f|W(E?qx}ykgCӳA33L|zיl#'e`V)<~Gzy䟞K/ޅJؠG-v &n2\?=T݃EVsY%?/9ZEҷ@jiٜRvP^x?VN.}ݽ Dn\)#XSKEt Mk7u Ow(Tu[nPDiFm,X؅HwL0ibGz6p'Q*XcMB*M8(F2ʪO3cG0PK ~A]E W5Vyzor-master/doc/files/component/border_side-lua.htmlko6 V&Ċ죍IvӋ\8ڢmueIxC (ˎZ"̐b3yлD7w']îNŋƁ]iHR1?lDg)Gz@}kD&55ի6k5SM=##6~Z:8tF⩣Ql1MڹЌ6M7߷Lїśm9ߐOЅM)!TC&pGAOOaiF;GI'3~}hܯ*zh x.`451H5hd 5:.6;5{qZC)3FW }wttG h}mZH O+04A@h?!Cq)1p0 }lSwfm#uwD@'`zx/-s3vgn7g( qR,#au쯦ug؀hjo `{b%L b5 P dl9$@)&ug0u˹?x;:zoaN T@Mi&Z捇6AC9@#bہG3O6M$0ЏgaŒ9aM J1=%B@1yÆO!wC/4K8<.o9߈Y5q̱6I0 `-|CzCi =jq|gN`m{$a࿃?Q-fq M¾*"!*Ĩ)TȤWsS ~Dp8@t)2ZXe w\{wX{S/ط`gPj .^ϣ"~F<'!Aw K2ѭ5vwJR^eiL"z"zxapE&B8@| Eۈy\Sr(f08ǘBHp vKKA)Te֠+tM+ b!/HskP/>`-C#?P>VkxqԵY0g{b]DVrZЃ "}cEEMs!΍/7Z|OII_%} 9%NE$*/ig4WQə$,0T益]Lf:֞(|JUC}ţFTˊHLL1*P112v}r} ?@HTZ)֚~yNa$,RvV5-}bމEրT=W~7{(6}P[fk U**mRhʨ6RA7$~oR?VHmv"Zx)7;7@I€;kN3*&F;uJJˊ%wK'SSCsV"[,5GG-t[ ( {=Lӥ &NYu>ِ{nE3V~#JIm4i=pHKiW+]vE Ma(J˹%!jr JLiN&6a$ݤx'8,,ى'5*mC!K`Vu6{V/e3x8("Ӳ*FrvgMƀGӔӵUuh:fڥ5\' ;a'OEv|{%z[ "Q;Z v^i,g.AHƠ=={xx*Z60CM#>_ՍǺsmQ޷\_(&y>w`بÿH'-;ZCЉ+œ lIӅA"`Q2")т\AGŬq(ꇄׂO/=v ,f e7񂂂.(A֣4~I=1 zY դ+I{WœdWIJRv]WTmyo嬞b7Q_]p c-+obm$;ng=T oiJ}e2\ Q\XF)eeĔ>C3*joPE qtD+mėj%dFn- G/2XsN! Ye ZP߽jKz _#f >l+:ܪrS|FR]2ν%;F(wEwj?ļG85n@RC( 3&Urӕ79~?PK ~A6 :/Vyzor-master/doc/files/component/brush-lua.html[}o6Ӏ6V]'i vZ C@KU5!)J.vaHͷ+I]w%0ݠ.jk pZ?[ YO=Nӓ:ec{`?\vkv̙]EKvZn5!#1F~Kե!'! fJm/ϐa~\Zy@:,=TCgSֲUe+ψm|#[v ıe>'V5ydtձ m }5FZ>yA`$$ s b0 G虰ا!j_7tB쥺0GNP‚qኡr$'Tsjݮ20F֪LO@ݥ V@sPN+\alK' ŊH ?x0xx?z~kYJ񒶴lh)4SACYj#Aai)®R`12N}+e785B  r1(&_.i~n^bz&D3q7`#$SKhp 0MbrV<zy#{: KD_lhm_->iQo8t0G {PQFȡe u~bH65׭[S[sź"&cK lv}(3ާ5;Y܉fds  2?b FHzvFf q[S+QuRux6X_o5qSFq_e^YU ,Wb*ȬB_ f7Zt"vAɪĈ2E1BwXz S\:4 rR!;@݆ e3!G"%GVH GؑN`n蠤}R@)QAmۂϟ2/WnpטRN?!Vcװ?%t/n/)tI,/a^s4$R6?9֓yx  S = u&Ys|˶g@ tBF5̾j<}m|yۨ :~PR2/gY.Ȭ#.)-2,+Zykאַ(Rbf{tjѽьSEz9]xA#W^ O'vķLIŃ3/b,S!^MM8 Ӱ{Qf U5a+6%n g1*Wn('F[) 1 t<+-91Xi'(K\>@4E~U.6ua[i@sy C ]˺kʊ!bps}[._פ1W F 8iWTﱫbĬ A0Aw' kQp# xb'Hp:9TwU.izk߫@i hU L&/d=jtƁ?'E|vjv"ݜv?T XN=Mh52O˾Х/K7/ D+SaExrC!.ZYhIٛ2I S"v1%d>hq2&O#?p(* il-듎R)F"ͅz8+ooOX秛zmIS8;nxuAK /+#òS;!Ƥƿ S|M8ی/[i5HT\$rVm$J{Cuq=}#@=Pu[y HWb^"WbK}R qHԖPh%:<{a~@1[^ub3XFIʨ{E8HH[ ^Q'&g/8K<=O2{V7xB!JE;)3)d{Z+)z^Hi `q?eѹe/e|;h-im{ש辶Z,}# yzsxVzCؐ> )|2\哔t?hԋ~3.%y7F=] wRH$=-j ~ pq8?%7_k>Jǟ h)3ywYHa@XИȃ_ƙܑAf_IpoiSiHO޺˷PK ~A+ 9D/Vyzor-master/doc/files/component/color-lua.htmlko8{W .j $vt/Ni8ZmmeIKQI7$EeKܦ{wEXpΐ[?n_onϮ>v0G] {㸹o2?SӉ93λ)fȨclUvZSNkFF||9m{x1@|j<3!xbFl4k"]p=:ox鞄vBH@I?1g(n{gb$8v;6DG ;qA+Fn] +lg V鑱)Ag4 :o0`xz7|= ӻ_vSTh6ti=-z2g> ɌG.A#Gq0Mv##` Upm`+sqnp<&U0(P>d4C >z6sҼ<ӂPIUL[ W~!v6dXFو1ɔB&)rsHw >NlB)diG4m|MӣU&4/Y Go}fdD[0^ܨ:XԘb 20IdxA8~"Ȇvrn`&Hr8Pa/㶒uex˜1b[t#kffr aFO=DD AjH! ,\'d1xWXA1<o/8ޣN;_B ͝Te8uW !W LK+89A_6LTamn)Y>Dv'q {1B sES0+6^7Iv9)( NЀ @4 m$wjc/GjT/Cˢﲂ.i "V&L k5X)"01 v9@&25(7C yl,Kxh+Bt5J_-/\SԯU}5UırwUS|)--W.J*;O[, j]褐"X͵R» oRW 0JH, ~H!P-ur7D %K~/Y`UV#.UgQIx0jDP[GzH99ȭRy_J (0*$ٱ$. >Dg ̩32ڂ'pb9u[~Q(c>;pȐT-vϦ|$|uO *t lRh}z˸&/pi̓h${?>P4wGUTrȨD sXpvbHq~K;o$Xl^q% ",z2֕m&T7W@; ^a$L~F~UHѵ! PB} .w8ʖZHQ7A: _~{3fYyjj <\u;T"qğ8ٮJtI^nH, i8Ғ?` (\cg-"$ºD yq&;3M+4B(vHAPK ~AߧAn LO.Vyzor-master/doc/files/component/font-lua.htmlio6 V $Ċ60t$;SE@KFU]//I|Hc "MC4uo:_nA ޟ]]vo?vL;G<614gYmvXdl̻Nݣ3ıhͦ~{ v9E>:O-=Ք=[  $Ćf RClρ %{W-{# (kL;gvD6wllS6#E;Fv"@ZF=`|E0664~<3AF94$]l{ ׎|'3rn@`b&'XqRD[g 3c =fqVU=~*2s+鿞u ]4r<:A@,oknp}z~M yK4M$ E`(Z`! |h9X|h۪l"{ 9(U7!@"i$Le&8Aҳ٘z.г8}ϣj9hz(#V7:[=膭vgAO @i#F~5!ۡ86cŠ]nJdɾFGDyzevlPf/0.J(WHn\$ML1%;5t#tc6@$-ħ`o^` ܅|yyC'51C#/#6AwCXX}I}Gr]G@lda"@,<E;Z#>@X ;ˤM FM%@|?P,?\kkNɲ %2q4 #i yUoo%C;C#L-$ʒ;d:tˌ}v2F`@20򰗲XI@{Qu 3?rE:Acm;Ϫ "t>vΔmK.p } \們R `:=ݑeM|+{JŁ TU,4D-9 7x74 댽izU~J5 3SiKi&GbaނgfvϷEߪ.,|oW!iFVXU+kN\ deqa8F#uuw;x ʷf)UA>DGY6K}(},o;tc$Τb³]V_ \gԮaI\B^7=Ϟu ?m#:ΡD@L( Ӕ7r,v>Vey,Hg`"> VHfT#>L҇w׮Eu'vCbĆ  ErAK'=;UWD;RlIץFu7Mir6N:NkGy XGӜNI#o_c1qOPp5[FիcFVc%8~=pj;J>o:g™4B1sY8fLDs6l 9WV#RokDhOJ R egB8YYיI=1 3V:11jˇ0,<=B5jbs YE,:OOV} :șagm/rDL3OI9M&tŤ`_Hc~Un`V MjDo76ۙپ-‘1+{F6|y1:NBe*Q!=(o%IT$5y2Ӽq|f#Y$A#lrg0xv cɆs`o%b`C;A Y>! !O9 Z1$$lR0.ERAb$9+Vo}jsc·N }E`-!7>Q.1϶|(! \'/ !uTtԛŀ8$~p]j>%a=93)%Ju۴n?Z+bْtMv }6.}UĂB+￵Bwå=HYiKVk :,A:%B*%wңF\$YWnzlAZN/Jqf|>9tYqL$\{0FU'CKfQɿjUKUFY#Dy3B+t>^uh@7ȀbQ2ױtm/Ϋm=IJ_($";svds,N]coL؝Y,['*:N6b f'jeμ4-jW.jwR12 2%w7XXk98sQ\'"Mѓ|bSrʇC̸3 ԏ _r3Koat_OYxCCABmē#1F#?1#NZzL,lJh]pg=PuUT^4P=פK=:b }N5jbZ_pxH\T2h2F+\()q@R=QʆknQ*hׯᕇ @2@*z|aԷ~@#ٹOU:ZPcloϱKV~_ی<#207EmI{1WjW3wci ˃.G|.#3!2'4uiP9^6B т(㻺]hn2\]C|ZJ!C5n*5=x|+4L '[IT(uF>OJ.i@/1ߜغ*s/jOjtI< E2fB!J$Z\mf^WNڱ7ZEsB2{3&Iaʰ)E6ƈF#8t\W# {BY:ꊺ @ #nLlO7q D4/NM#Jb*vvS87uqKQK /w#:bPq%epy!g-_wpy+z1'RFSmɂLVh#  SO{~_a=< wzB{'Il}4d(i//jfFlw@('%;14U^R1n~1~Ng!JزkŒ<:HFOm\[]Qm{WMڭnB*C¬7b|Vؕ "e{rx=!E4A¸kġ$EG)À)<{1vbXTJoXSi-K_=s׽DwgMh\׆sW/7뻞|e9 }'2xu&Jkojlզ`Zi%^H:&|o|ihkH" KNYy5e{mkC.bo}z ivQC+= #W@O!bg@ "RM#yD±$ѓ,GeIe(@$rK?v /iPK ~AVV6 V/Vyzor-master/doc/files/component/hover-lua.htmlko8{W b68I۽ bp0h%D%!m=,7isWIDysfHu9z?D7wHk ċ枮Ԑ6UMן[ߘѹ}Է 4^^gF ňo?C뾫]6 hO]Tg1~@hnxx:Ԣ6w/袱c[ta`Fd՚M~[Nu÷l %@B3\ס;ڄJt姹Oq JYXgOjTUvrxYbZ x wgr; D|綅wcJďe 3%_U GKpX 3*{pmW%ϞUkrflnBIR ɦ`M pч>es+H}`ucOwzెZ p4}}Z k7P7oTʦ:`/x|Ȝ;ἒݯD),:0\Ƕ5ui+m1ᔌ&mkVfkiV5v[*`Qa!N R>w>C(>-20856f)gUZζYvik`[qҠ_i |󤛟 `VҬL8тq*Gg9YD&vg;>40C]ӓ[#>UgsmQ^ܞ(&n>W`بwIˎ^#]%~WKmz_G\zSe郃A"`Q2"hAsaU1k^;J~!ȧv`;Iw^NpΔ UxʪoBE(_9AOLI!C@ےt%i/þ*݀VX^zQmuoDb7Q_]p c-k/aGNl4;j5:=\Sԡ /I}2~ j=<&(cˈ)?^\ dDNU| Q4Oi!7sCt">;[Ѓh}@T 9d8YDfu=#ӪvH\4 П6j4Ƀ{%!a :n }C16ahzX

# 2S{$~8L"ySXL +!̂A.B.>QIi1` D) (bia6goM"}zsPH2 ]A }c"L%$LlkIϏv#C/8?x$]+NP="`%Ю}>A%|FKgohDrexQ31v>' =|Y? ̖n.XbdvS .d< ÎF}%>#eΊHdIIq@*:QiQ-srzH9OIr,ME}|rCDHwv-X}NFL%|,5OrG)dWJsy^\MFq_a=HO $k1fspCbbȿi,c/)؊ ­Eᖱde"p‘Kj :3A^?gmN,X NE%U =&vF[` bTDY!091mw`nhmH jX_ @>0\gi eJg[kUx m9^C!:c^Z 4~@"G]I͙(]( 24(67Eo1 U'21qץxIװ$!=Fl)D))Gk%bMkl})`sk>M^DIͣ+MQO c-aqgV`Q{_N6߶@ȒZjA5S9UsEE*_n_ir(w$"V3S4E r,ȦZ=lj"auERggSS=9oX4c {ݟdD*) `$s`cD# a\<]zyr~Ugeי8ձETAɝc%T[~F$ }#3gDdИbCt]3a1t_V؛[Zj؃T68``8Upw'}nő8u&ǾQ~>^#%JOh_ՠ?G2'UD:=lrJ=75ԮIZ,uh&}s]V|#/jr+sE=2VJ8g{ 8j?p1ŝ ,]bu+)Zun^`Fu}UrGg}w T@|/kZIW|ExW֕k):3P>`Ogvq#,G&V BԜ~GI!B8͎SZ))ZI10A5ή2^{|djho4$P-s2i%|矇CvOJ7c: 9UmWމ @Gi#P N-<yPKJsXT u-#@KZ2S?Vc7894xYUٍtA d`hU9ϲ^[83 ׋&QNpdoĨvMg~aCܑXܝq/@H(_/氐|V/E (9=uyq&7lV>op*=l'yF~ߋPK ~A7醢 ]-Vyzor-master/doc/files/component/map-lua.html\S87\%xMFDc{m4{}%!;qnowOgst9]ӫ]5ZOVlp&+{G iSܟ[|ޜ4oܶnϻ)Y{-y`MY)ޙ X:6#6k .ѐ!5Fx)|ŽaYDa5Я?ӒE_Gcg SBP GZق]kz7<2da{ 9,=#JeK ڒ%p=/ PjIs ~l !Ǿry}< 7u0&6pI `03gD=Wy)='pQmBv ͋68H>zwL9G#}%f6k6*Q-L2DavbD9pv!$b7=8n '+hwHIQ~*dsafEfIh?ˤ Z%ϵlQ QZki[ȴ5XS1U`y9k1aRE R\@ 1]B*D']V$˲E kfv\^>?HvVEK,yFl;&| ΰ3 `=hD|%lرc:#pGy<o49[Oj06o Xnf7 I~p0n`'}Oc07>+~0j;Uv.iݾqo2_B Tj!FG m(wn1j? D@l*e㒀[ƀttNEn"]8ӻks~E7Î+ ;u0x{lW!F{)/Ni\ŏtjU;Pݓ!"*`$k>ymW;Y{PISv-:gqx՜(i%,gM^.0]@L gN&9S/='|--"ggĽ-Vd5ahÁ5vzTi,l8q6[ &a. O!BW2SR'@^pglv_0ebjGWadxqPfêF0B.<3NMƄiuimŤEgYtMjWtTSI}c1MQnq藟qV)^H"(T$2bEGش,A ~aikM?F;~s[ [ ܱ~IVĚv=x 4OJv4Z{4I0;v_^7P %Ellp^P BAJ J,c+ Dz9c*YVڋD>[l/ssC'dgKl q7r-J˗4Nē׷WēRK2lh\-L%,WUBJa0 (`u;9r4G۪-Ѷr Z7Qۖ@fqbY^׻G%H4}nnScIP;Jc|R/F?ms\&2@&@/f懏r4],cWOj OXF?agś9.Ρe+#;t/M@*yH?nz[RHO6ޡεClq+m i]sr|buƺ@/\.ص .>j*kp8&>PK ~An# R0Vyzor-master/doc/files/component/margin-lua.htmlio6 $ر;- qu&A(h[YT%*t<%JuXn>Hsy|9׷/`LÁiDQ4Ͽd岽Aб OV<5BJBH&+$q=p-Gabtl/Sr"f"xOaNCq ?Ί",5&\Rt]u^ ႚX!\-:x^`@ /3̀v4>}=^^ěBŋ 2M3iO r y^@g)#$`6N FL38jȹO5P,@"HB}BXlI B`wNRo3\Y2#W. ! >Z̢P'p]@r{} yCodpLgAl,oXv(LWKI@5n8Rd*8(Sk &/ߕNg u fm|U=4MU,>0 Co)e$@JWC~F8)g5Z&he@(cl)5+&*X̚}#!PH\?wb$">&4wȦLTą&9aaΣAhp~XQ )9:2D+7jmTR,35'v8Dאf|?`>0| a`QiD7_^n)pn]kHk=N=׿o>?w>ooGcMhBB]z8'zNG7NNG1ުx6^3=7j$䦓JpDdA pNY[_q1'fT^w2~SK*p3*Wgw]f[iHSM]2wg:N^~Qdf yUzJ~_EN=<ԡaӹ+~pv,:uftNJ#N[iF,9eOj<;ygmȷegO}p#pt?Jte\& ,9nG"=MH(AY*[[Pv]P?m;!]SK`}IgEVv_)r,C=_2>[scA+%͈ }zQS(:E{T j0*y 7 .%˄8ѓ DR(p:E{3Ebs*XXxC&j=XT\oycQ:{u=PЛFh4-A6it}΀5v`F%!2KI;{v}Kh؟q&Ѱł~42R%hW4lұr( sɡN>$5r4{.aA|2zet:Qyɘx5rޓ36M0JYb& 6&? #@3="7"E,V$y@Bt4QbP+g$@^gG*xp(» 4p1aT_MNxǣH7OF-8,Jvj|(9 z:ӃؗKjr?+7ln~~|LB}VBץ 9IY4 !ƙNrpHDP$Y1+f_ tY.9׈!YZc5)AeJ,Mc l] 9euG Œ^U%& ,$ٽ`.YoV%݅9+g_@NymDP;(e(켾 |k&UEL[ސ|=$úʨKvϖzY|*c"J- {5}_K32C "ݢ$$*"- 7L ܋l(pp2I:FQ 'q+廙" - 7ƯL.I^a3'3恵*ªIWl.o cI+l +46+ _Xd=up/{'*IfCdš&᫉G6 Sh_WXiIzRKuiltIc[_B|Dx!];/J× 6ơADd".]y-LDŽ?ILnqY\ʾ^%c4i*#FX`塃u6M7di*JJVE&sէ9QEQJsQu3]T0C),X\'R];{l-8EHv25~Lׁ{ob'-f/x=yXq'F[U6#'(FO2H=^Ǒ)=|Py#o>gg7TWnɧ U 5.L2VܿVc*^ LK{pD&7}"MC9^5\xW8*.0HxP$S[b.ϥ,vr$nx*MPUBV|V]wDJWitOضIVN36@b+ÙXBk3Ud~fqxl :3y^75BB"XvI YT  vYt6miic5W7G?v_ 9l]$@"6]8؀YxQ(/~mlG䘷 Qp,cё-HWa;If:EU(`;- B1У4~i=>z<$R xWMI֊1kl${T(=h--*Mҷ)R/”r3 ;QFowm{_e4rpqs ϲ X0J م gz.49t4HE֬|(bbR ZylK>\2DxD(qSpksP3Mޑ[~?~+ô`efn!U^#v.)Y,_gW&ۦK=ERm;+_­+\QpEK-JͶ BXZCP`;9ڋ%h9hiɰc Ư( U_&hRR|B0~!C3lG #~ecM}џ1 s9Cwp}_0qR\/a 쯡 F8pm6j/ЅIZsr0jP-d Ruzu&"@f5=3NnGwWW'3|LILڒi>šBC`K`#ϋhS,d)8FЁאGu9 bH)s:CBg.24IC ?өO"m65LV ճ .l ">ZLPp]ӕA!b{B} ^yEsLGA/oXfԨhq@Eюfn8+$'d*je0B$ŰͶ/Xѐ3\re*v 8,> # kƲ0t:bLVjx=ӑ!8Hﰌwwcm[ Di~**]НHBQGܣrY%5ӽFߚK{ o8FqMX% e)$2*,.l ]%ޕ6+^K0plnw pY"$^I}DX;Õȧ\v(ʺS=]k ܄8@!q6S9qsEhIlI./.i`-_23xEDH[<>ҖhJqY>1i){B "ʃ``eԁ$N2XN>^0(4(Di{9U0n 9@Q`z] v{iɄ/#az.™)}DJ'=@|m\cpv)2I_l'پ1G8l @ОVG ˄":i$O#ui:owң@2଻2`ԹIBNw_(83Fdϱ$}EE0YtCa%\rJ>¶Q]+a01meu?cIXrw{  ide[C+]L!AjJS;;A尼sW6.fSad^_ȼSJBNQ"kWyugbNi * ;E9E":fSE|BXwJSdI\)ʑ=S Kլ(V34y}ߊW>܏׼\u|f9_$jQC3U3OxM}5%uYݒA#5;\in5uT2n!rv-eG]1v(#$s*,.D`.`Z]8W H['Aa( O%cֽ][ǥ+Rկ-U q _[XWӆ2#̈]+drG <0Ȫw$h%fVM_腋_\PEP ^,$㲤hg%#T\G~6oS`w\Ly.09SY=j(,Ѧ(G[6ZQf)Inuӭ 8xK<݃NpnGGy9wcY$̘?Nu_s@V\C7EH&ȒvXWڊ1a<-w`Cp;cSmK<9u}$8EH0ӏ(~CĽW/| #~K2dFե3Lfݜe+s妀gxw H|hZďeJGNF _ǢA޳=h V6LM:VnpB&,5cCp:.ʀ C'#+7Ω%~b&0]pxHjmjx}E>tn&C6݂ӏ6C0,܍jB7s25CZ܁s?ײ([xnBϝ2\v;ЭŸs3̢ 73<ߖ-^srnVd }A6uvU-,i\yublM bZS90y*io+3ȝ4OjݖJ(@Pg-h޳dNFp|)kw`XyU-Q]&rfv!w,#\T^Ky8o.qCÒ'wu?=ݒf N|1}G[R0a܀ ֨6ۭ91wbk) E}ßVFӃh*b˫LwN-gvWE*=rM<+]vL>+L=+_L?>Y@|kW\ilp%Aw*ڤw"v7Oux0߬[D0VƺW:p2StfMCFMʟ{kQTGPK ~AxFu Z2Vyzor-master/doc/files/component/position-lua.htmlko8{O 1.c;iw7Imp8DʒxoHؒ,9;lQE ř_wW' ]}#coNs:01a՚fYqkpݺ>oMn&kZ2z`?% #>~Fsq``䑵=dN0 ;nhһٞ/?<ߒ~G8F &01A5@JFFق_km_>Cv!|#jqA)ƇdK>%٣y]8ԜX гtpܿ3[4ͯ2xLoo[[Ro%@<3ڌlУ#3<= B[[A <>P̈stYH=3D\Дݕk=d?(vc#g Tl DOZ7m8`Y4\<uW6•zN<c2] b }BMo{.~b^/on87t<$)MG-B!h(I'iǖ=EHn8gTqjpd?lAO0Yc"u^b b4Eg>ZЧ]ix^pEAwwb%3wmp^K=f v}`=?4smWtj=[m:~AfxaFhQs8s4ňq@Z# 儸תNA?*uQ ,B#k퉫^T/Eb q8 ד&}2 #Ң)%4=\A%LˆKlGl7gf|ֽKci|\],cglp-oVE6ULFY9}*ꮚ꧜J1~,-k* 51 bUuΧ }0𜐑Xs~*bGr P4QK(]h)6-l\\Wy.b}o[?GpE=-…䡚 G5TXOJ/d"rtwFru 7SDNsnNձ"Z "`稞$C3'eBfD+3\\U11#;\$p~(<& IZHoX*vmv6H@ G6 ؓ#T$"|ڢdG$;93;`I465QxA|.?ȇyh6 Wvѐ8;D=/կx Wަyy4h+n1׫ &{< c9XGn"t7#p{I$> /K*d?D奲<,맦|MXHȎޡp۹UʢxYmw,XIgaY K rYZz2l:9S1DB2BF9m,LTr8x0p;\[DfKr <_خ]lE\l+M eeva})ɦ LTl.땗*+R`y%W,v 7WyrVP%UNa=*.vQo)̫b˫)tgu7Ro%aH<,:@EV 2#$o)uHe cU 9eb.hyEC—z&B <ѽ :ɹ.]\^R^)g[Q0+EZ9|-L5/{[>QKxVǼؠ42\ΦK8-̀ⴹ-I/cZd,k1qyjc2ʒ bHJC v-\')q0k^faKb3Uѵx lw#bydɓd)#XopĝC 1k3=+lTf7)D4[el2YLɜŤKIf~[o{D bѪIE|)O-X ,Udޥ,`NKᷔeWeyI]\FJ ⺥:l)g*Ozo=nw +~01S۲<=အ[Y6\xd:$tSZ<8vOGdWMN#=szy.Sy`Tk Wt78*6;HnxtBk9e|/R  EȟLy<Ơ|dH#SR/ΞԨU&cY ›N@=aӁ׾e-Y/ktV0ڵRWu*<h> hDʟ4=ӧu@5yfT7زI 稩 :)xr W\sFǶjw >sh:УJT@C,v5}7 WONp4SXq{N&xj.ij @S/eW3'xx\t᮳^L+YM|YAx Y!kÕU'fm$0Oa2(~1܏l>`Ҭ>v]*EOΨkѰА/gY y'UpZC3Nn ؜Dן\ ZhxV :fڙ=96-b3nQWҬJEI[(9 *H4L> t 6wծCRkSY\[.ZZyT(FLHONM ^;o7j簡hgt^^o?6 aǗZarXSy;m6[;JO<:{.MDǎ|?GhP!D50hz5:_re3 hbl.ZvaD5]U# @' }?-׹ry}_{#N[O~88xcMKa&h.EО3=:'5$" uppL %Ad |$C#¾:|fc;?%gx/͇ `x3Xq(Ԅ6 9{BWȈk"#s9`b3.[W-f?L߻I+^NbJLk)c'c']-g+t4rRw_WЎvtMkZnDtR¨#pI΢az t}pZ<>ǜ92e%O"TIDaDAhJeP(]鋯1%Gc~t2]; (V!O9fOc(dj (ٻzPybCe:,5xVakw+/[HX|OvpjGe)xU:)H2_t%0 . Iͳ:9yx%y'_q,vxЬew5QHiF%A\V:ad7@N2&4@Yx2d-λ^ T jASW|QJ8pҗOU\Z>˹ee`lיeBMs^2ļr-R*5v\zi&q!jۄt*Nc/-45&$z^R98TP*nm9ldҊo {jDqgG}ù N 6vbnl6~d&ۘZƉl'/ܘ>KA,7#9ͷ(q6O, kVdjTc&[tL40!#FQ^G k1fNEL/'pf~S4b-Rb*0 Ԥ{F$*vJVl¨l3[kx?kWtv)PcP.aNm;TvuPW}룫QI*v`SmU%bݵKr:R+P& 0դN[ZlmFs\ٍ>E͝4ÔDo9yڇ687p>|2MW''&s(}D "nOoPTiv@EJ >vxp  .ׁi#4*rn#.vn*+-DgX ՟G;-/x5ǔicOjTٹqϑ`uwmpH X>> Koy״y Z@k[[R [WPæ`KG6 ~ޗΜ`QvJq:B5si3<*.kA3NփT 7E[;'x^t߮ C&Ҋ"X4Md4N![%peՉM8%Ϛ2(Wu3xjٶF߮Cf)ZdR)<eF:@ltv#3:5bnGeban'q*r7lS+ .5 bxɘtg[Ěgb .:*iӤ>u7Rko koΖ4]:`xAH(S{n!бhs,SּqS;EՃӟYg7gHr d=K:' K䉢K<)dq!k$IJ7qI6|dCͽsŒD}ul\i@>8\^Mmtss5%`0r]{dyLPI/#} ߷[6/rn5 '?i{{% d;t4_a2'GSmW0}ų).WaWG՘QpZ/k''GH[Y}!VY a||1.ϐ|l%av&Wn 4d뙸X!? `lqr`>J6x>(l6<.o}?oPK ~A Vyzor-master/doc/files/compound/PK ~A iU E,Vyzor-master/doc/files/compound/box-lua.htmlO8+9ihsvvi+A; ʌVrNg9~8qWچ;툁=NoZnE}nN.[ȪmvNAmǶϮ-d 9~x\(؝;Uwc=^sc5߽f}HӬH?"aωϫI@,S3#bxW?Y:wG'Uїw{ 15O< 9 C 7Z͆5aׯf=17 ~/d=wU3R[#`s?NH0 qߥ<oEӰOo֑ir\CkdwnUC„2ڋF6f.'O=;2&CjZ[G/s5矶Քy@ ' s]c1S aK}[;kj> Gr'gt"5*;;{,+du"&kk} ܞX TɨxC}@:3hփ)> F=yK=yDž`h3v }9<^>?w (IKQm Pw=A=ya{?[v+`!һS|.R &O`|M x6g>3w@ٻ˨G |^FlzF@@qᓱ%,N8]pmv @q * n~?r-+3p"I[Vlj&G\ (Xp!|9R}]`,Ծ` |^Onzj Q$f -01p=w ̡CI]>t}#,z!C25 cMyPD(\lb){`(ILx?X`bQDeG5xY]&$ #Y<\CzcM~ekrvYQ UkÎ.OqWzF43c-lߐNA&M w1 Q tFI0rv>_NO\H"$.T7*N,ZwV$NH2rys( RP J!dtp|}JH0Y:!Hd38a窃M\kSzɓbZ,n!(pq]P~$x1 Y.43ػITLshDX,UB3TDfb-L2+r8[]HT@ý >g:nj~pM`r\sSاا7Wvݵ f]~yu[)ܚ#2,dqɥ'U PRx# R)$'j&XdG!)E7^[fH"؋ o*I1N4EEHX, ʏ=ə#%|T{m}&g2y–u 6"XG梯~b'"S$^'za:N.b$d=4a]5H2wy - +H B􉂢&i.&3!1f"P^VXHgvfMbJeF,'6'yC_8vH(0w0PCgnť0>K{?ryCR~;|(uMȨKض4{qpϿb5^QٷMeMtmhe->ꪑK>@wX9wKnvcᚸAfňS n;ޱC+ԴXj  )+$œY*o" L/2 V?`31^<=o #_TG(SCiCwK* ,< 4t7Q]裂 D>8JdUN U"]\,3 ߦ4粠/IYrcbd!= ECvHu +oNMi$1(r(2p p4 }̰+:aW 8IL`SPw P_?sMup*}|d:. A.'~qK ɰ7(5L%^󦺩ݼr* Lx.DB̰(=V7vdOsZb UViă0NhmP\秹%H ݤ{1~x'25bKR/bx!/ާ=%^w*堵u| /94%iץA#O{]?bBsxz^DQaRVrYD%/bKg$`|pTkq(f/ϟo͐A_!PXVJ^Ɨ,bH `<ӝ={lأ皏6{q7z$-s_y|=$lo[GOӳr?3$;77W{iZJ]Y\^3\=7w{~v^֠v|kVT7w[Dˮa 0 {"]u!f0<+fl3 N>H( -C'RFE>.(343?jy4$ͣLNni-YK1Ņ.bP;.@sʔPK ~Ah C-Vyzor-master/doc/files/compound/chat-lua.html=koƲ+@jڒ%;iZb9irX+ E|Xq>%E!іӢ}kwg˓?GzCލ./糋Cbw_\Tu7 bL۝a nOOoht(ͨcE1xK'SFɌE`}GlߝCύ}fS<u114Ytyv18aFdvtEىc_IS#N h CL695:./ugv;X98 #P6^00UߡT}Ǯ]Q ?`QdOׅ2SF4+?{b:4 _`xGSGkgtnO̞qC 7wɿ-όg0Fg1N,N OhXPU_ud?< GȯeE:3=rǂ\c_CtWtBx[f!8pNw/wKmJF ˆ#ϷMp @zIPJ\:qG@\S 3?.2$-ބ\ڮ 8E": 0 Lx)jVs)4p~s!#qٌ"9BM ,ӱȘ?9NSvoO-K>I:H8 jƍ*mpI2 ,9"&pndP5b\w-^%ҝk"^`9|eV5.(h{`T.8dAԛl=c~?叻F8ζv]m*Jo$'d|/#_)8?fSFw=+L} $glh*x$'s p9c.LI l jlPݛITɘ_o$x"\*+ RUmV0xC1Q-WG.sn;DqEd lUvE!lƵH)6w)T0 _GlX{@2J@;cGvE+">F[ztjFvrd\%@r0rQ zS H6p@+0uj r3[n j 4b "X+H);FQ `VPf/`B,(yBn?h=k?&) P,"+Y`SD,^RJL}UP v&^B˱PGBFf7 σU10{@ϥo _{p!lVŮ|^oae8еbu /ju{yAs (v܉E;?p݃?-b k`K;)e&R "<Y RLR!{mT^F>d$j}^1&6myHR͞zk* ,Z%"5ڛNiȷKId^e6u`2]!g7.Ҁ"p* oIHCmSHM6.ωUF^YzRF,eWMrFze'4RSJF$k_Y|i#MMɒ~e2'78P8q!;G$s_h}J#[1Ґs1D$IH4^D6)(ү}&"E?(үt"2/Ej>(ү<"'4'ߓLyj~~3 yC 8sDTq|\(Y#F2Cǥ<\kTpVnu;Rد7(8<Z5I{"kpŎ*@7"PD|OBdX> (ZS5ljoBDr8-TWT'>1Wq`FҔ2'ʛcB '!KP$X-bD<^!vRXϺ^ҭ-+Oq#σE4ںC{eS"4a:p=-IN*+\'/aq ƿ^],vX};slAOWr_6 >ٖE)or!+T9_-c_"^ML#;Kƺ\ )_ӊ㱨B A} M^U&C;1w 9pv \%S~y)(Ih(^Ò8y2m #':8 .e\+m44>K^4 mݵ$HM'$9vH|Fo¯Ldmn1xAo0|ak(lo tgAsk1έ' طlfY1נ[|n =C[>SZn8_{F%ӵ6ܷi\FB->,jm L-G_O+xfaY,Uٚt(_ ^X(HjyeD_zk/$roC|k :_CBc"dkF^qUQ\Γʋ%kKs_xacLlї],N+#56ބ 0,TKxj :І)ɽ-N9ޢ j{1ne(E!}Ƴܟ$d40WiɎU{x7IQi?7a؃5J܀iJ[خKDE9fESQB^A۽\nVcnw>wǛt݇Ϭ=S -N a{|:U )@W Fp>x )|O?) 60 ,p./>5 J]1@ pk{dZ{U)2O{{/1yGm]=0"@LM=h|A^enD|킽Dyx|@6 F--ā-pkǧ]Zͱ@Y;ݒGٓ?i _E,7DZ 2z]> tw6@h|KQ;']A;q 46m;3 lsuY>ۋ盛_) `6"UE tɝs3GF2Y>Бe.M{^0«0}Sܴ& bM89ɠټJD# @q(Q8,a!ӓڪ9rT|`HQQGDXT<|5~μ11od xSey0`_$t@2Q_zs샄\˽T[o#,ޖ`AiY+b{ǖ3&# w$J "}nȩF4"JSj{ e@x_{f$E2%Χ2`ҧ힩S;C$iN~3@tj#[ozRhƐ E}5o49F2zRwӽ2b$YbԈ{q/P-f=E6ז\4sMDj*X#h6KD |e"HtӋ9uEe= 완 ыIX:{,3kܞԉ^|̍g7j[^KX/SSi^{mg7 υ\EtNxoW-5|MlBQy DbWijZ!3F~ "OC n!)qlGÃs[Dy 6ߟ.o/2qRF}(/3jQ^dzP,+էe MxaC5|s_QpB yК M47h@J|K536d2C1HI!:O6P.Z&_YnmǬȫ`NÛ f\ ud[U=W>BvtáLt;˫D24@Hd:5qXA'A* A$3ܐZ#F[ blEդܓgt^BPn,  Z„ #/d 5lOII~ʀ8nVxE.,M7jG\趏L~'5sy-r{EN*y_#=);l$[q<3B,:H6`d[@\Qn$4$>mk44SU6!/Lb&u#!J9ѴX@yESv+%ucٛ;(%콈| '{-%{҄J(˨l"X5,ؓfN(EYdź4ؓfMDYd+ҋU{*ME,w ƺ}dYQT ZRيc.RbT8Ǩ%V6d1IFUƏjiSIƪ(ɨ#qQ-o,X 䓌<ȟl+ /ɸ ź?onq)źxR<RUQv۬{ORjb݆NU2g})RKSoORjR,Z#|MθЛN1%ʖM]I|ӨjA`  zӸ%['s t>it*s.:isP0Y8 qMCGp@M2 W!iLQdxV M1Le6hJ&ZdG,x6 +Wb@5J}j9} +E=mIr+bpNv-Q_J, 쳍>'N7ąPlE2뻢W=QS2VoCoHʓይ .V0+%+ʕ@%Mi=Mb%{=uSrEfxŒVdtJFb2v4Ēd98q%ƃΖ0Jp8mh $dTI6pB9dc0p4U5ڍ&͚ ,S Q~CdXB*%'G:e^x'n1P{*̯̗30|^^Cur3h^O|N2n6BkFؙ^JE[L#"ҍVف nxl6g'nB8T/ %d#NIٳءo 7vbW ܄f՟db!+^-l^|PVXzn#!`̵9d,t]@6:`;Wؔl&{kv5zZWy=bMΐVY̵ȃLwɣiF^OE5c9"J}z1.t~G !,jǔD+ DݜC^F}] t[ML;EGLCE!}^s8giEaQk=ǻmþd~kL%uզGMس?Vĕ1;}~޾v)6N7I[ŷ9$KM$mqq'[,hHQ:S]7ZNMkq3,~am`!LntOV򐋠+h4Yi`;ӧptn:~eWЇ@ &meVAT?m@LGd!##Bssmn6G+v$ԑ= 4YɳAmV/9H(TdARa+2t!Ji G_FffDzr8Y!8$"4s>ќ(~FX ?#|) =NٻE H7GBq0)dC"Od`x,i)/}*JֹrVIkBnI}bJ ٥JbQ}T@Z|ID<~y}A<2|~hCpДk )UC3 ؃z|D'#A@umh+-sMTȌC,<;>| =|*!T ?Gc LىIf$ik6 bF5/IYu!+_'cN҈=^(s9*m1-и:@v y4ι*uf :Zi{o zJjo"!J'D+nUOsV8YIG9_y|=܎v E+i|?&+5 "7݈,@BL/_ȧ/} g=TQ+Ķ"p21Fݷ*$c57ItPmdQZs vF3'= ?/#tK({ /=] PK ~AVyzor-master/doc/files/enum/PK ~AM 0*.Vyzor-master/doc/files/enum/alignment-lua.htmlZ{o8Z[yuq;irg'F(hYԒa I=('qb(f8Ob]gcpG<\n:ȩӎvG]3p8r[9/X,Swt_vꁜgGzKiTf@nΈHͯ:o9Ihyr$yxsAdatUnJ*Ci4ZTGߖ3t@3$l9B.C"B$ৰ 8FÅΝa5`)lޯk(_Ts"%,s/+HKX\vz -{kN# i7? 9[•I}%PԜO{wdCi;77 zXn@p&0 >8p~x}>_(%td6|Y2,ӑ # }!n8$h[#01h4M[10g %g$T4VًŰz87s%/YMZ0JV+ݸf3'͟V%G`GyJ}r~ [h\#s=D<4''N ^S(ZMt %d@]MG){QAvs7[)}'_ģ :aE Hتr \'%i9Rm30YFъ~%@ 9}#έS:Vv,OlS^qȼ&)p&(Ksh||Nx@eyi[xHAgj6h+JB_)lt,WQ!WVl7}d1lFo@D"l8P4+mp;`Dڀ3`6-P .l}il1 bSumSSn&mw-2Q*qH͒m8)t u%wPRg0P(~35bn&&>#j{U"V5R8/evll_evۃuUۃlAA=KN@Ch,sQB'(e#(es2~^o>97hfg,>h[}c s=`uyA}1k5pHYҩ5+Y=W:K0 usᤌ 7Ԯ]`_Fl: Zb!KͫX*VJSau9Ua'½R*ķ`Uic5"T(a+8v^=M*KΐudtwLoeCe`zUfvUCmE ԓSUOvwRr! {;{'ԭ>ݼݪwˌUz`l0f/Eu`W}W}JʣOxDtٯSYi+Gַo+n2Zh`%Z|U| ËD}zs~>8_yTp*F7~TΈpDce+GG`&M>[ix`~M:=I(wȄlIB3Wsҍ|{MyK `ZxL{$mHj5?{OZ};ҟPK ~AN(SY -1Vyzor-master/doc/files/enum/border_style-lua.htmlZ{O#9>O :ŒNK #HtBNxqڽn7!{~e&Az47.Ue[nήȩfu{Þ8nᯮ;f;wϻ7zK|RNkJi͈H?bv<$"$LH"]5yS,""Ë?NKRH \0O.Zj1C`їCHBv{j$hSC`su'(30xQ%`s g`zMq2ijɈMzZ.T^<Vy( &I+ľ`5tQj*)y 68sF cXۃ{,sJQU8D9\)T >T'TQ/,DCp>#r S>ҰFt}Ҝ90|I}x5ӞͩG4 1ڈ+}(?Vv}m!lﶶAH<:Uʀ!{|4qY*-&B~~nÏ ?Z/RƖmuJ6S%+lJ*QJQ۴\i G'Dslf3I\N6%Qovh0m2n'{-T%U1=sI;%W acP Nd@ruy5"q#U8Nr (ֹji14)u{{JIk):D?*\*5L5(n2ҞA89F3禆ZFV6A3z =&0dJCf M$9S'z_pHmՁSRz8w\1!@l{.ݘix.[U ՒNłiuJx,/?,}yeїˢ/[Erʢ.FLc,:].L%' ԥE1E 8>y#B_6ThlY>E;7NfQZ zeE#p8"Ick5*9&X j|#PR3u'Fk [ w#s<)c%Lzy $'I}iرb^vط`/zU&Q sj#MCVpH'(/CJqvqA"ծ ۫U`.oΪ8ׄT)d&{u.U2t:a_ve3Z}V,&4(+Bu*=rP+-)wRQm 2^4B>х:lJ[M3: fE?Miۯf@h,H޷-#|g w #eWTʸ:\*2x''>9RK/Y.([; ω:9k.O2fCE>rT&]M-Z ģGu\!]'ԟr;-s7 ԗb"(`oZزt %xz%QDzMG;΁Qaj?ȫ[Pe}^F,LQT5w-, P/ti}FL2suC28/5R];C"$͖''T&#HH0]*7b< zIw8 Q@hSj#GW :NKiH``/N't;Nv'dOݯl݄@h\UGS=.ߟwȩvqZ;r݋9S)_]wX'5'νhWrBrɚ/}CCQ[)~1##5JY(I(eDVӑIj "ߝVCR9C o?oq4!SB$H=!4dtj5>wiXS8$ p84s<04tN3'RrWA0>i1 @.~ӹ*gZePBkgZt*#p5>Ȩ-84|:Oţ!ZN980fM_.Vs!A=p,FKteq:hN,Dǵu56a|hA"i.&0ǜP̃fz$ӦPLD6= zjHbN7 ^xog \90\ ed'= z CQ@HG#A "BI+¾`5-e~rJ Nըd27H!&HI+yAW CxoS1ԘVvR:#*@x(QRbAn!xCU@')?/ɘcW'W385:dLC"M4fQe@WζB;[HgQ)aCuaA11Ktn[J|oR1TH$ . G?@%VJP].k͠&1:,VA(}'/<uݳrqzNTʸ4+8;OgEv0IEQtI4*.\Y#b;-˛ސx4 vպ$kOm%D Y2隄?I)ɛsM9#rFN HoJn3A7tWWD-[W=Z/fb_ݞ,#3L%.G>@@#9Eln؜FjՃ3WwZ/7̾ ͘Q4e۞sصȃxdzQp(lb? SkT(Df?42'H9f~Fu&(+ [2zy%&¨MmӹQ20V Oc߂,=t9#uuhYBhmMR1qU!*CJɖ#ehžgB5-A<S[j cV!\dI{a3L _dLaes{C3X>,k GvG{DaTF,/*蚫 --^5mi/=ȵް/PHN$94sON؛ Nz!U6g +<ra92O'8$j, T9Dz~'Htsp~wY@]N1Q(o,h4 yhښnC_W$=b*°,5Pf !zWi_tUPqY9WψR/eW$q\')%*’* Rš3gj,1 97ϰb涾Zyly񑏺籬rpVzqn!yRx[2&!cFjX_P_|LM֡Azfa}CSQC/|xo?BJ2㎈8;]/c3Fh89(`0Vn!mD/i[g(k63 _U~r駌PK ~A #{R&-Vyzor-master/doc/files/enum/box_mode-lua.htmlZo8} oN]!6N{-*tF Ā!9~vBYFmycS=n.?^voȩvq^?vݫ;93)_\w\֗guƧ}jfrBrɺ/}CCQ[~1'#5F~Y(I(kUDVӑYjf "?VCR%{1x5F@'It\DzB8hɤ.7|Ӱ:[ qIp)i/qpq"%soc HY1W kA,27νR:Z[-jT}Ts̋ T",fh9-zaa|#"?p]Te/JB±$>10OႲ?CHs69lb4+ǧ?W #៞ B쩵ēcSCQO ɺF!'A~pCЫ7~y:cWeo瘯r$#.iГd'"ƺC?gW7!d~BD^A0f? m +I"sc&,Om2&Y-2%Eb{=fH>g[k@[Kc+mN.hԺ$MFr.0vkqC)<8l쒉D!N3MPZ%Wc&% S-W7OI?_)h{X}no ]&luIwz[nJ:OVz G@''W[V1}Sg"iv1nK:;3&-|LIyz@nji}%o(I` oHHm4zrTJv64KJ;Ği:WG/ j4gra.ږW~*BPOWː  j'3QYw, `OK 5)d4A`DE 䤰#-'A4H#uS!w_"[t4yWu)Q}e2ʎf%k[0Z{rщ]:.~v9# 5,טVΥNwohsSԧ@tyK&vlmADaU( :=sd]>g:]'#&c}J/br3l]gNNqHD!YAF8Vs@N.uS`_,]F 1Q(3zALXxͼX4mů+Dߧ]1{aEV~HT]o,uVǻ˘3-Y2ɶ51|a]&iLDgk̛EX>6s[hVܤ@!Z^}Gbe,+>;B9B?W/ #nU'}wx Yh 4RkH}ku^mwQvwj~qq wHl A/5ҍL~K P`l,v&HNO!@'$:mi$w@f:"mhov톰W&c7%qrnۍ:+t3uQ{FNu]3옎ډ^9 q|^] 4;E]s׹U.N>Z˴?UUFjI}%SQs*IitGG3staa|#!?t]T?J"±$>- !0OႲ>tur{ 3s6E GkOOt!ZIȱ!t45AQDo&p5 %Kp ᗇ]i}yU$)ɈL{./ ţn5OGPأ$mV F@dR\ERix[1_dOo`޴ϕ$+gIrV7̩J+{7Lp3*@d (P)¹A8`!+d蓔t $ūViN2@cQ |U`j- b1LX'i"jFBvWM\ϖfU,Y̕&M0 WӅ͠i.KkzW$5cgo"t,8['*cNNZJޫ9 {$!9}$SrǔX_2Vٺ^[xc8`l&79Zה2si[ޥB.MHzz)eф#A*L8o֣(@Kj~AzpF( /؇D5gbf=0 :#t~۔[:JECsnO vbVeTwWCz}nٽf8@ N'D=ONgWBc48Eb!c]:;;6#hܢo֛͝ gs3(O^ޞq j<ޢS%~Hdɦ֨tbQqMhDeN*P: !LBXdK,h+e)vn#<\&Ӱcak^s߂y4}l탗#.~ҤԷ|G{T䗜!#idK24O+!낖 C/$\} b&K^R&#d[F[<}0)-'4*+TҹRxu?t(mUOo)Ԯ/_vC+4 !`#mҶ/TEy\f햊K'[Ʋ'(@#ωvZ`Op2!OcvETD BN겋ev_$&6ȃ&)I-)/H;7IT@ lS_IEG{Ai~ fCkO^v}땸ItBH|9OʹUVy&4E}VDלYbB[oGbDdfZC飰\{h : p&YLy d5ٙTtm, ; sdEdy+Gjnӊ5X7_C/axʿώGKOenU҇*!?Џd2iʑ.̴-tU2 .M^vX]T# [\@DJ+C'-t#7*{  ;D!$B-4sK,O6?כ]/`͛~fPK ~A`Wh(4Vyzor-master/doc/files/enum/font_decoration-lua.htmlZmO#9>'IC`V%4$0] 3ZNv^:^MȞ_w!OUj۝7/ u:𪏜~?`:0#׽vH캫ժ:i1pEexz ɩ'[އEu^gI$Fj|Ǯg$lN1qgZ]G'骁g 0Dv聯82$Kq,)P}[x5F $pPɼZ.7|Ө:{qKh?≡ e~4cUC]CyF̉tG̽W\3毑b!5X4d:׃WLsIhmLCQcJg^4O3bs,ox3bB_HDqfkteqpƦ#, ?##e~9gK8:jte TMgO?!rqǦ,2 F^×cE9xq Cdvz=܍FoQ,&rD2Ӟ =s}!,$h[#01hH[10gɫg,T4V9z6m Ɛ 1 Y;s%/IYUZo s\~lx&`[ Qצvx !>b 7Ք 裔x d'W389 ȜFD Ghm І0eo>[Y}OģsꁽrL[,%959)ΰ~eK~mR,3Pz#Xt!Us P'd Ha3i2^ R )4ݬX NwfEgǁ,B=0Iޑ1gE91;svf2`uy4"ۢ2Cf ֻ$uO1C*deV5x{%NVh1< ɀ Uޕ&;gWa8 ,Q!;H˜iv"͈r6qMQZ:rIz{Z}S)lRɛSSqyT}l3+:/dx"G-$+4|p GY5*-%5n hN*P : )[,Bhե9(bL2b}x"[j׆Vvm-؎j^p/I KJMFJ,; vmt ۇ~ڵ/qlap\#2_ШVqARdmZ{Ò26$0AUEdm 4DUJi+9i8hYm{f\?犺:lmUKV. }0f9Ӿzo b_J-;Npڕ&$$TϾާڰ94Ϧ wM{07CEp/tGzAՄ} %ݫJҝ04]H o`6^ątVٞsG"AI昚RΥ.vOhKS@tAKo(`unĈ<̴jCPGia_&g k0,&\<6HvU长pb?b̳1H("+4)( vޕ }< (?+HWyQ*==0!]CA,d^"f eÄ=ǡ0"x ?hAQ.z,uk *7W0/[C.dWd$҂-5ra]kiLD+Rn-"mF+n2^X-/>QG<*Um=oEJo277xߩ9?e,X#ՙiy++ɍ2vyڻrtuQPQ~RZF-mOu%"  k$ATE= b~)0}I3?\fKeipŮ,p}ᦟPK ~AV'/Vyzor-master/doc/files/enum/font_style-lua.htmlZmo"9>']Y6@2$(Ntin{~e_܄=\~\/{]{]޴Suo'm ;v亗rRFb-NjO{ٮN,8=rԓ5_NÇSVcF$Fj|Y(I(eDVӑYj "ë?VCRp2 .`ᚎF@'ItSB$'r2n: ;4VCxF8xBs<04t@5fjk(;`DHI}qܛX$׬KX}v Msi}NC i5~V?18[Ւ̋g T<,fh9-J!7E@麨Z'~!􅄄cI|4Z[,ca8Dse!:}CHs69lb4+GG_6 #៞ B쩵ēcSCQO qk0Q~_8.^S Cw~]1ijɈLz./ #֑n5G@Dأ$iEVF@dR\Rix[>_dOo`ޤϕ gq7rQW̩J+{7Tp7*@x (P)¹bAxCU@')?/ɘcH'W389uȘD G2%(Wanֶ3N~6Gt>(dq"@AkjqNm_2Zz ˬ<r҄ nr%b$åM/|)NaV|MO6JfEg"e=$;8ϙdjo[@)[Kc+45 @% {\ږw+jw&n`%N׎( T8# )[1p#q@z SLDFY$&*JM,[aURRb;vb77OSrɻs91Z\YNL?h.]1Kjhd*G[8c{]$ |U߁{( iEo&81 "*"{!'eur7pl^xNVaG݄$lÝntߛ$Ow ŤPFQ޴d~ fCkO^u}노VItP|OʹV M4ba9m ;㥜nu @zi~D=4JþC}g$943ON(MFvGI7brnWȝ1ws̑B@Rqn9wН<;гûtbX9D/ 8QԜgc= &MCA,b^,fcd/=Ɓ0"ˇh?pB* ޕXT/g3_3']/H$;ĸNJY%W Rš+3Gz,0 17bIy]chy9:?XV}rNs~=8[yp(u7~`H#VԗVg[kʄ kʀEDIi5?kI8V'FfM} U0k v&HA'IC`V%4$0p"aF 9Ni +nB IF#SrUvmw ENut]7ꙎƑ^8șI岱svzFRPO6|;Zi;9u{LmIYB ϴڎ$Uϐ7""0$t.;әDum- DrH4#D:H׋"FÅϝc4Tgy1Lc<%Z$to@5fojk(;`HI'}q"7%$,˜+1EA]ߑ -Y߈x7?]0=,+te,0C=EhADDyjl2rt"Hs/s"łkGG͟6 #Vd!:j!$ȱ t85AQy(GV܀7p-G_G7`WeƜoX $#4iS>'BAcj!0أ4iVF@dVYOY.f1*ҷq0qJQU8D9(TrK'{7Tp'@xM(PiBz܂o/G4OR_Ӂ1ǐOf:p:9[:Ȅ$B\7#40 lm7w3wtaH<:%e=>yp'Zg1nP t~WJWJ7ӕnnXiէQ*sG'$ ta3IK^5i 2+,/Ȭl2n' &-v%E3=sIvsΝE1p6`2`ri쉄ocF8MUչʲ;(ӵ|O#YҨ8bY)P/aTVdNƂ`c?$_;_l C`iv!dDÕОу?P踉.}Bw<>(#`SkT+ZKj<.+Dp>w@1_F|:eDXdؒe9LRJy m  fRw7Y Rž{Ы4mhe3C7MK[y@s[7 )qO#[rnlЄ#ȴ/ X G3[jWqm+uU2VoC`Ob5!U&c;m+ծ aЯU29-+DS:|*=HkJ sKʝT'GTex[DBLFD 5_*T[m%'[bIi3Me>Wakzva߆1/E{CWo"jivṢOmv_g$$v{MR:*y /ȏYֹ͑;m bNbQެd~ fCkO.;B'iԁQgajK?oYߘF,*p(WruA> #QaU:FC28З)|֮L!f Ȯ#XL;|2w8 Q@hSj"GP 98`agyPvv +A'X}Ťm(܋=m`1G,orO0 !i6ځzdKku *w/gΧgĿoMt!k~y@QR$uTR"n@p&0 >8^8|?X edD=MzJCqHXZG#a(bhbi+V#` 2TSV)X.#iQgBEG{Ai:~ fCO~ q!~x9# u,sLMs<hY]sf9vKlu 8<̴*CTW.a_%>hveńK T&#uΤwhc1 'v̝sd.8"!j,а9Dz~tspξQ, DVdK8IUzZc0!-CA,b^"Zf5.„=0쿑Cl4%u뻥ߨf B=#u~K=s҅, D7I뤩EXz"iz>Edy+Gznϊ5XWoOaxڿOO+o)nUҗ f0ԯ(1hʑ*̴?[;k~ϑ=I(Wsl)@"w;ҍ|f2<%(`0l;Z:!$54s[,R}~#WV_J'$?PK ~A: (2Vyzor-master/doc/files/enum/gradient_mode-lua.htmlZmO#9>'IC`V%4$0"aF 9NKkWB IfOUUۭz/wj4裻u9u~uިg:NG{q '2uEcq`|n=SO6|;Zi֌H:-e$1qgZmGg骁g 0DF82$X'-g嚾VH'Iv\DHI"{B8(dv >wiP8% q4Ms<44lܯ@5fjk(;`ĜHI'}q |, ka%B,Dw MVU;8:-8$6LCNPmBVg^2ԜOxwd1C8g7 Eza<"W%xnL8Qy EƦ#, ?##e愳Jxخ5<0T)o ѱM'A#ǦvG,2 Fۑ\b<⸄}q8r?z=/,lD2Ӟ =s}!8$h[#01h4M[10g2T\g,T4Vao$0i+yIWΒ #`79UC&5 n"0?$Jfz%*ChX"-8l1q}Ҝ9\|E}x5Ӂ)߲G&4"1h8WT_.*<̶m-|ģ'Jˎh̄" {l`i_Pewկlo3[W}i,4bD' &b3i:ҟv5+> N6fg"C=0IvȄgBF"1ti2`Ouy4"{B5i8͌:4\RjnOw0kEA bS7Q0_ !赃 B-PN`L2FPb: |rY' qnĪ>, TW`~a|͞/VJmߦڛ `((xT@}8ފuxf.IR?ywR?=3O NWY-{ pxu}3<:n NН:鈏Xg>giDttr&lLZ?8Ko03٫3یeV1'Pt犺:lmUP7>iWaWo"ԂGx̜Wv^ޱUP{;F^uZ`Oq2%6nwHB)kȼۆk>FK<~Twe+0~J i^mgU{3NHq`6Ugw^ x@ڧ=mG"AY昚?+R5ohK& %8Kl]7mĈ<̴*C{\{hT}DMoɳve}4P Kv!U1ӷӌ‰`92pDBFYaA9Vs\ENvN ͳ򛻂taX9D/$UTi՟@ i b%Ѷ5kFI}1{&M a'Y>bv^k-RW?بx~s:B~E@"-uTR","iz>Edy+Gznk7kf`%Z^}y.y"k:9D>D?<)n>B)=GwCcj?[_8ysm&\YYVsJnO({"P`r6oTa/@Xô2AJ!L_L3w"+k"/ vڵ \@/ ;PK ~AwAX 81)Vyzor-master/doc/files/enum/init-lua.html[{o;wVj60 IV % ǰi\]Ǐ<s[*JilK=w> WwwvuFNu]3ځ_;ș p|^([]Yx|rO|;7ojL [U{<46DuUNԜ=DZOjZ}Qe&S/ڜT<ߑ -X {1?]UŃ H"° >-5 !Px@#tX{_c#l?JXج{b Ri Ѳn˿Mkhxr@ax4RH{A41i`9TG}<r6؄ߔmf!`'!Ǹ$d4Q2pΡvD٧}~nJESuz`~;d<҄} + ;!nɘ͟H^Ŵv>yd>4F%aQ7}; |Ӽ\W(VGb* uMlDؾZ?8K›FCMӵeօX3DW}DhH].Km7C"r:FBbQ. D5LpM\:Fr/Tz<0IH+41 ~%ezr^6S).0X* B&SFMlmc_m7tZkb@ "? )qG%[rTʶe(BC۷!} '%|j=R[Km. } b&5~VA#9T)T&[;d4`Bg88.M(. CzabKr[SKevo'@fx[!&؊C;vy]RreÖ~Qvgj>СW gP.4Kw+# + E\U CVxE7d]ģǖ,1c+E;{B EwdB (lk!Ң1l+VvCyP]wHٶ;4UoU!@ lV󩡌#idn'xW{ QU0q ax_߫#'D!斨N,3Ь yV U ᩇVi/gҰ4,Jc4&Lzd|,njX4GtK'vï̐~y QS]cu;ȑ _Ou:{'og[ٱ-I<@QyZc/ܴ)FKxӞY&UE랳0arq5.~l4!=NmqONPrx~K5e@lrJYk^eTY1wah[ϝK.nR^Wk-Hʫ0$[“P/s(E?!wjdW7a@0vgkהvH9ɉif~/7&r5y;rދo*>$7?&PK ~A80'+Vyzor-master/doc/files/enum/repeat-lua.htmlZ{o8Z[yuq;irg'F[-67%);a I=(qj[H7<(͟wѷ%{hpѻ _O;uMYu/o̤~qrX6{Sypv ɩ'wMEm7gH:=a$VqgZ-Gg骁ța.l=pMIe@$"X:x5f@'Ir\D`zB8hɤ4.7|Ӱ:MqIp)i/qpq"%socKHY1W  [mNU;8:Z-nTTs<@AFcɩ$5E*Yrz=<8!g%xn9Py-DMFX~PG(G˰ gsU;::`P=P,D۞ZgH< 963bԐ>n@dg&0 Ĉr xqAp~x}>)|x>|U aIOӅB>x4֭H{4&~JSS dU)e(68%3E41LZ.1&M\ R>sGhx}*-!wO ."FHi *CY,2rDY! 9?8s Dj5.АtS ȬAco#_*\0nfj a;ko^ÈxtBKfyBTΠH)(p|D-J&OKb gU,&@8}%mέ3߳MRYپHVyOL3L2P έtLTs J˥6GB8Kq tj_Qʪg;Lc9\ YM3NlTm;a';$b.v" GIm#-%D=C+,Mr V=d2h$g$ᭈ(` RQ1Wn[w;k"6##F-eAVNgstrt|.9}Bñ9}&ϓf "_ojvlnقDŽji5%Fqj}IfQWEcp8:6~@d֨Y+j,ծ }# pEJţIy@je%e`(I` oHHm!4zrnUJN64SJǞi:W/ qJl1f/Eյ ľȥ`4;©2ϭRf{(94WM{)y ˤ"_rRk\D!|z}GuTr_$ϲMwDyS})U}.&* fv WRq>zqG{! gajʟ9Q9:ʳ>F,LQW5'.AawOtVe }iʰP_4Y2 "u욙''T&#Hϥrc1ֶ^ N옛\pHB!YaN9VsfBN^N}/Y@^N 1Q(ALZXxżXlwůkD_^1{aEV~H])-uF3[.dg$*IRI11AJX4`|&^ϕf!FV֍7)k,PWOApڿO!*{;]ot3y F4RkH}lun"Q~k~0x=q WHl A1Aҍlʦ8%(`0֖s;: 54s[̳~+Wσ`=~pPK ~Ax'1Vyzor-master/doc/files/enum/tab_location-lua.htmlZmo"9>']6&Lr dF)21^ aW߷lwnBH޻\~\%t;pѹi!O[mY/o=M|^ָ{U);;4PP^Ç6f}JFz|YkHHUx(ȳsLD5Wxͺ;<Uѷo\}Ug4zB'Ղ9!DyH8CAF VF5٬@X!qǤO<}K"TiF,RtG,I^A* y@R.Qݶ_sӢ'h2:BsI^{ȃd 2jsAx2aoDx3|B_IDV$D*6!!C>#HpY6g9|6 5#៙ B4ݩ$.ր4CsuAQNhOn?/1*_CgmȜLX, $+6S"$ACj0&chbi+#`Ȍ։ X.#iL͝3*N Tn НJ}X? ẍbeKl.[Uɘ0j۹ ARw7 #J${.4-]lV#/]&%DN|3OcP2Fv +JE념>$9qEvigܵRKKCS?+{,`/I _SRi2&P\\vit AЧ8v8.YiTׄT<vJJ'K3+"%&C\C?'}VticFѴ_2>ҹ2k~P|\XzW0%󾨦6/^p4;2Ji/;~o0sT+߉==ɘrZkW# 1A a{Hq5=-6)lR`\L e L k.m\v[-g/1:\=vp90HzVKLCso[y741)/@ep/-7N4ViFIC4$27]1.͓JɾH7bz=Dg9D?<?o>(<u7y,րs6^+Ok3:r˻H'Cw̮Y7.0%CRs{}!X\,VqI !^07"5|h8# OǗW'\oc?^$D/Oܟ^'^$Á"Fo Th! $ P{1EoJz=_ <AGbx3= lƀ;` =.V!!1-T"^!qWgF0@`H X1e$PtLͬ\UW2Uc9m=9vkxMͩVFXhKߔYHJDoCӈg.eZ@xw6iz Y+FέRttC-f+'z{Ȁy ƈ!L-9O}~'}}<9(y:r8IJIg)F$hhzOiV2v-R'<")M mmt}QWJ~p^Qϔ_Mk\r̠WdEwrfi|=Ӳ*.E]ԏb{?oV>(* OJ L//ϧgWESJ'ByBT?zW}QVΨTycɬ^uV{Jņ3goslF<%I.e5~t#r+{ $0O>lL(G%z͞L "ٴtC, ?zTK,yE>o?PK ~AVyzor-master/doc/files/lib/PK ~AiKV 8(Vyzor-master/doc/files/lib/init-lua.html[mo8_uq'i4FX-7%$!%R^'E7 33Mw88~2?9_0:v:#^uvn;BNѹ~8hGzlJKNCM{݈Ѱߝ1M o2~",G1*(֐|$ROgڮi>!I\5P ttn%׬uC~S''0`|f [ ?}n/&%LRB2OTg@j0HfG8qXy0Ga#ẻ3ɸq퉡f$g^}wjܾH<qIY>)@IBgVa=is='cN"<WadI=$$Y3bSէӽ_ ulFe͟t}xRy/d$:EƦ hJi&歔aʁq '/[a!rhD7t~2FLw!ežRd)8NBev t{k.ʷ8K^pg ,40$y7EN #q;i:y;e$߭ypl eКwm $58ۮ  hM1!l~;ջ74I)0F8LJFTT!ROI)d饭e^*Y^$Z4$KD18dƔf,R_/ h,ۅ>/Зy@@D(1c8l-`$f08xU TF:1hOr {&,t`?^4*L^+,uNXUߜ ,""`kpCp=$CJ';zLvu=%ٜ"U Kl7>pqsSqT>U?]鈠2 ʇ~g4uOi C—m9mLUgw mOs"jL⿻7'泒$TJW6(4dV~5 z{%j&jeW\}wMR7) cdt@KC5ERU'TX0 _j*&tLi6eWnNѐz<,euԹhޯSZL$S]szE TATYA+M׃_/XB{<`bm}s3OlW?1xa3VK,1)#N\P?l4q>`Ld[aw4 j@~K,:J':WpAk7T{ouHI-X<籷N<+桷ƽY:@8"7c(=,핌!"9Azeđ7[Zf\^ڏ3TzBce@ɔVa,\sIQ-Y;5ط`r͝TRe_ȃrќ>xXf"rV99"êt,)d}Zȣ5mYN~S\zNnœ)D ։A{ntēonΙb[TO?헵7!nYu~x׵3W-dERm{46l߳=[:~e i  7MEm7#vsM$FJN~SDDmJ,U˒䫴- "߯j7%1ii@AP}x6fL/e BX(dٲ 0kLi7Ei*QUWg&x~a3)9PNH9.gyX#D}- b,>S@K -kܛ..oA)7nTKtl#WID YAGcé$V3O;o +m]ޖ0>C@iۨ^/' X-heqz,5D,A׍7J6(wb i.&`.9[ǭ_.!%v<k $Xd]4P"#6v(k(1T]@\ AAi[N ]4 $%h1M;U,]n9]E [tsu}N*]M _SI'dX0R7Ԑd'[B@-$xFH)Q2r9,:*XhIхzgv˽zyOv hCe2 #L-Sgg5͵)q@3(khBhdMij( zI E9)l q(.7(*EQKl\YRЇ}`OD;d0 ;TF"08 y@9|!($ e\+=3b٤?t<34&ܞۥ3jzpd#:c3Qg{5s9xM4w{݁x⣡;r}PORCL;eXawaǃӛNf=⌜x,Dz a9fpvN=~dsx}ckaP3;Zj(fm|8:X9ӝ}5̩TXUPAbA@npt#`Q)l9!`͔p$نIt CѬ`>cϢ3XG;uD8I>txwϠum㘮awvs"wC[Vz>p~Ay=C>b Vcp}6T̷/s0qq|Ԋ7Qt\>?gwDWR@iٸ/cWÜ'C7B Ùr!P c|qu=i:HLIv>q|=p>|XXh@xbw,ncVF'?fUD ȬS) aQ p?K ~] pIQ)(9ŋx_@Rd-s1uu36 Q %df*m[5d{N[] MNiҮAWC"ifȒl8DO8HPK,DlVcTwwqƿ˽ı0쿒<?dE..ե$%sm7 T?l_\gԿ_2ϼB%yD>Z8a}_/..e}?˼EoN9hm"p*^hH:q|ɋ]~=J-`c T˙qџL;.Qwy<"Xl߭͢ n >պ2bρPAVn9Pue?ɤ9j\_hu|ݴ>WPK ~APSZVyzor-master/doc/index.html(ͱHMLM-IT())M-,,U JM+J-PRp q U2V MI-,)Mdg1Fl&PK ~AVyzor-master/doc/index/PK ~AK̘s>oWdt~> Z`t3ͭ8Mσ潵œpc{k鍊^AիL1No?2n0a1Z1.څ)~HƏ8{~`g$3wun4G!q1rM( C_A*zp8(K%zݏ#uij&7,0- &GȢXIQ~2L4f@3UTd)ac%:K*Y-,:&$1u$jPzRd2Ƈܶvnܶ ʨ9C}98KZzY}[^*r7=|)7M n} Uw:U+TEUUEmQI.mH/Ku߷~LtCn0X|pj!I*A>hònJ:J:zQsKfȕ6[ZrU6z.*YG;1Ѽ^ z2'\+S9&}s8~I;ADR1 RDFI4,z!?;IW`y`)@%4(nrE4Y JӒQdF5|z~2ͤ'ē%;5詡DP78q3 dgr:C3r[$F5ꦰ3WXk  =iQ2[ nKu9 ]Е%)6XD?P0.F4,ɯF~M%249X9jfk\SAY9̗n2%fIP6j**CN4, F0M?%fI.6ri*%zX'YwZRhl#2ڸgaJ 4,)FL(;,N2cfI6:f*éTY+ES̒m|T1Pe| EY ZZejc\qQ=J,!CV>;³|*Ƈ>-cĎaG,k_޷o)Z)r6 l\*ƅ.-WԈF,-J.dq! G1(L9aiU2! Y LEe%aiɐU! Y dcXCbXZndjFV7Z5 |WOd*ɒF |Qœ5yXMvɛ6d7B Ϛ__˩SmnTTZ(%]>hN{+: BeZzfngºikEKZl-ϳKg<[󺺕~ٲY35b_?[,57|XuOUפvI!6 i+(dwkk`;V.)FAm7T4`ާltzuV- Q~X7 9 q2 ̗7Gj6U5~ȿtnʷrO}w PyiFc{`5V,&ŧ;5*ޝkn[]G &6FHI 4ۄX!1zS596#fcj2+''6I)7(~ҝa+VIt A|T"ӠVK15FϳAYYV/ 2%L֨!Gc}b.>ɄIO!@ +^vêJ?ǸSÈ1;?3Qf4fAizJs(,#c%njwR+`ź|[3/3?H7BJ3r :G4E[O5F0FFKųCԲ|湫=Ӊ\vMr{sE)a4_lF%_?s0aW8ML3cPMZ[d,qA [go.C@ .qUh8dU|x\J&<)Fyi5ré @9Zj!o.j'K<&Sky-WR+/ĔTqwHW}EPGFD(6Qu=5;D,(l,| ZzS፛<`hTW]WYGzQ],zQY" z&;{Q] ɐPB?+aedRTNW Wb$UVz@iƳTt8fIzx;$U}^֋bʠG.4OYdb%xCxyK{XЯ 6;ե)_95.+vQ9n

r|!.U@TC:ԥˑR4E@m4`]ܾYu`g}"Ox-ϻN Mg!ck uSzrED&C9V2 W+ij+찿P4A3 rs Yi_ W=PK ~A%2!"Vyzor-master/doc/index/Events.htmlZ{s6ߟa:Y?ْdp#0,BBPԻ3I_j~#ùq8PAѥ9zRd<a&~^H$*Iά.f#(7\;Pɬ|q!뷮׌1!2b>o:1cՌ}ש׌W%9gj\3 &&g LJQ7lB75밡dw fN8c5\U3zvP&SN'IMy+xAV!c usg(nXXYJ2!Eehwnݩ[T8w"kQMB`%U'5#VCNpg 'ͬim)W5do ՘& ;]]jF}nbVn gP돊_%4;JVZKpYzeMYPM>@cj?SU9 m/I\twr_4PI<>+l3;C=g,2_|Дfir&M"]*ڔ*E&*5'h~=ܙړ~U+\"Ƃ&2h"itS(Ɣ,uF_%S鶯Յ PK ~AX%Vyzor-master/doc/index/Functions.html]ys۸?صdNlʑ|̾rA"$1H=W "J(H_wys//vjrݨv+ hC*Kϵ ۓݲ9F+鞮߽; WCywп|Pؖ,o~2F_^2ypqwp<3QԷza[ _'?l8<\ob"w3 h\WCRGаJN9&>?c\G/fo22+A7ԡSdLo][ ]P=45`[6kֶPo;;>:mo#ҳcxhK;ЍOkimm{?F+r mC e /Bp=߁&8{RjTɳ1X{,K<V 0;c[Q$v۱#gA7JO>~7um[?~ u;GZ(sV$Eq޽}wGLk;{F#"K}GJk_ݻynMe5ڷy$]}VC"tZ"!Zk_џ \΃]9=d kC]p[숞z3uSqqV pJdBQ47KD8~T9hX7H٣[z'o!Sz~+%"(zC$ܑ|oXWc[} Y~ė8H`^m,( p7gP\-3i享tW uW*]7Gkqz(p,% L ]T;XNɥ&ǭSYZ&N-f);pƜbK 121롘ul1);*& TY5meCk45hp;2,r6Sxt؍MP@f1> :,tVfj7R[2BJmMGbFt:/fԏit˘QlX\Rgzϭ%=*BU T +_XP1 Qm$J?T1TGJ?hĩ.)beWv9!W$C7)FTA+ ,&18+RxZ" zqQ1/ Ԧr[xgЋ*ŭ\+"ZɁ䔢 NEQMXL-+"XY RM6m"JME*UvRN)brZ!jbUbK^Us+9ˏG5 \:wBӈ\)r0ZjF1`&D%S•4.'AЋ!EU"]A5)q]ZV4bKp Sb~} ЌE]>p֋_+aʑptMki D<dd/%/?GhMlKLB;)8h@[-ŴҢkIqHƑPMjH())yt헸/I APMj 3aL<3)8ܩN-Pv% plM\>)q QZFUȚ~6ب鐟I SkMZk1Q(.MuNtZH a׷|WR>iެYzF$܊WUhJ'M)uRꢔRH)sSYm#!4yNrJ=#4P_+IA囚]MmM%8+*!4y>I=#D;"#9QOƸkC2dk{{qi&0=maC1slcNW Gy6! 5[pmif# =AG*}7,] B\ 3ݥ Y!`PF&=i -Ûw\v7QqGGlƊc71 dy Sw,RQ$؇ 3zB\@ _]ޫ`~qZOE#C l*4Qce!9z=ԫ MaE9 GxRv-8*`!ׅTt*VYZQ^ %sy"9Jq[Y8\[*5,Yf$YX'2s5,[N7$&Jjћuֶ5( əi;J } }m&V7f͟ѸPMj*MI^aagFPm)Yz@h?qUwWaH akdWxPB> ؖ< eLLl7Yª ̅'1deyȊytDc`kfM0Q'،=uNs/uV36i)h}*R*/'/c#CݠǶ舜CJ%=+뛴>הȾBU꛴8>ޣ>-@g;}`mlډ "ʪ{Cd k6}-(z;/V#}4AejȾz5{[%\`x=+FEEwfشhdC))-`ZNVKDJ_**QaRXJIi6V~x['Zn c||M]X Mhef"REe2:ܖ=MM|MzÑw=~SMGI9ů4פ%]k> AsNk*v$ aAsbJXXpهW:,R:a[|!OZ"i/"|مl,) H/᳅(!!˥S {^vN&T+ py~>t*Z%ɯ1$/Y0Mqxa=yMVXWWmLS /חn"k xk- W5;Slp A0Q|ՂLܑc!*R*kWǢTAVq#}bWZ jeWO[(Ղ_Z9řD!(XY7]Dw{:a;w~y8ъ~,a9ĕSX3TT nU1}Xz#S G űqD|n1ާ{{00YP ? 唦4JJ<5_ɔ3MF:#?cuCb䃝 S,)):n<: ֙29d ZzI‹JFCg..SHVac$+Aye;Eu$%(Dc;F) q%+Oo NBhWTHW01^U'X3 .)DV#b\諩KT5wgJR:Oΰ*c?b?Qc&LO rU%/KDO0cJn/ӌ^)ͅ(|RX;T&<ᩔc3G<=])FTq[< tO.L|ԐMu;qxHJ)݋ b}Jy@x_EüHJF+u'P)9: ajtX0Jc=dh{8ezeUq=ZI(HV2d'o83FL퐫 }zE,幑Qe!˯R89]xUoB Ԑ,]`0|w.ˑi :E oLpH_⿋li_^ahvv0OF˚1*]: Vh5)KS:{]uj|0.Vڊ4]h0-<\=1qqG1cⱊ i(7a(pJA` sv;64!݊<->FC*9[4a2@jX{> 893ttd}o@>~ $M˰t>-j?j98+4!̓L(q/阶챗IF8Cz#ӓ[]~vCq;v+r4C[#;S:ePK ~A?Lr!&&Vyzor-master/doc/index/Functions2.htmlZms8>B!ug5W%@vCxX$Cحגl,;!S{Vw?R_dI^] w{zi"\uMi Z㰶8+DُX,jcgpܴՉ{v߽+[P))*- d3gZ ,t1& *e Cő'NTEw;7iB.C*&J$$=!0p:jZ1LΔQMu`&QHqLƴ i_d،J1*poI jc!  gZj]0B!g Ag^<<~0Oߑ -cK[TOAj6WpB4H]s.S.K\;W向Hs6AsIO;xC| tfQmvQe) SC lvIɮ2[' d@w"Flwخހ0fƈxSU~p}}9e9`,Q)bR]fi‚!d޷b&K"*=$S%\xxƩD UvOX:A~C6$ F%X[&9?2I?6ۥ  @ %1Ʉ44B>'(op6xPezbV78wlx"G}7ԃI*i'Mȼy E{r]9)Պ^ ֭ Ue33OKY܏綃$G#0u7C*8_7],PQ2 V) 'P|Y<4g_?xR5'Ö|V}3#] 6RNu3Nq+췚O+q3.O$-T^8Y e;žr^31oczIRb)t~4Ỡ X/<l8 %cx,dݚ]2\ʎebycC9OH%#MP1)Q1df!tɬt|D9E(нɕ@njɀbJ8Lj@ d$KV ͿRJՎ鋊&Sh')kdm5CQĂ x?ee]VRJ=SErq kٕ#\{zBHJZuXt9ViUXBhxEDdPt5Qq:6ݍ& >d^dxP\*Io(vjwRV>[WKzo{IIr(Nj׀/a) FV\i֔Kvw~wa$ya:>r5bAiSQH}˴ޤ6E6JhB6Vԓ_Wٌr4; ]ݺT96Gs‘9"@RV7EX]PR;Sնe:!Ђh'TdhN˜6 yhê]GHS}^r|#°Lg!;Fcj1hﱆ<;@ű2lx~=5ԟ;^OxyN0M)͹siYMK"Z;~OKMf82}q>FZ|hj .B>$ml E~~݂q0vI:GG^7=׻˹fk_`L)?6o+$a#'.?NFI`{a=Kfo081vH@jjshF77)Onv0^GJ>8wIȇNd9|8>2~is0;f+g}{|GJ5Xf+f*U|*iRs>/Ww}R/MZfPQ?*UrHٟ-ZZ*4{TfVE(U_*~oJkrɺw}ahL gq] E>qhpB9z@bɩIVCQjbq&!q1'J4W'\,_x_< 葇$n='|G6S'sZxsJzXPLf打0GQCf[l;/I2Cj)Jg q]R =+~'ibl=񲑠Ci=l gz;s|_DLwLwz;];]2ow( E{8ݖ pq|3 Q׍ \@Ʋ9/s8˺F%D/7Z1eZ1sZ:Bu"Lqi˜0u:ΐ~gdr}Z}Z}zʄ녥ElVAo:KVYu,zeLeod*{@eoUL;E W1%zrD4 V&\6??+RI.@w䥝KQ׎v0ܵ#^;ˡQK6~sZ5+G qzvE~)0h9aˁ]\ Dl`Yp=Hq؀ jXҷqJ؀᱁ Y  <٠ӊ( ' PҠ*3 k\aRl6`l Bg&xֵd"hF4= Kΐ.BV3zjY)gxwfLF"W "L-v>c%ikt$Sw¹ɻ*TQ]svnİ9J8E=DQtta) 1/zʢJ.dY/*a4f/q c<KgK.uH~oL+nyꤖ--]Efq> WWSEp2+%QgQGsnR j2>AC r`zXIQP 6 lE`sX6_o1?'4!CCjX ^hJ"/ܰ@)2;a meѤuPX5ulWNY"aCdwx3zNj5Y( }L-IZ N`'zQ6+$.pbx܆@=rsRȲl Dp 2 fN0g^v9 ~^)飢Wh(ʼn<Ng&o;e2:21CeE DUU9^:ѣL[= =53/D4 &Sjʊ &i1-\4y)LS'Λ qQfRVX%Q:IRd9HnUfUxk9JyU vuX<ꚉ/>Te;Pg{n՟fV6&"WBUoYԘIJ}+U*A`UXoS Uċ]WhJrJUꃗڗO s5օN'#i`U601/~<9cLx1CF\mT xuhM8PluFeĥ]1B: #d鵃[L:OxЀ2IYnQu&?Ք튦d`MQA!=ˋU&?*n~رApse[95@EhrTMG-)0h݋Uu5[|`k[3vS >+=J$9AgDN:Zu>FfmK|P6E)-*K J:S(;Me=)=SM>s)93^”GӶ0# +~5nz]h67tNɘȻj>4 Qjk̦hN: H% 9%/4c U d;'Q6KP1fOQ88ptrhxiq6…Y*VLaRvw\ն[MiuHZSR(PÇ*Tɽğf#}-s-ֶ^žZokWmvBby(j"5-&.f:+}k|3նg2"siÊ;A܄" _9.TR, @wP Ef¡G꾕qBpgfYFN0daχtQ+?U2M<#FMAGȎ}ehJjT1Q2Iß ؜Dx1"o^㙶] tpy+)dx~^8q>*Cw|| -BeҎT2ڌr.awI?IQ2O> 8l#]o0emPr$޾-o~ƙ N Q87tZ-6,>/K*%Zx?U}5nj4| Z )/ }5Juég \ʇ0= ݲ+m z $ϫUn/M6*|BNrҨLplj7 oI{|on' LJ>KO;dRYIE5ijеO^.|ldޠyu2ܛv*P$ysǓ[s9-^n>ezu,%5M#Љ&+'[yɆVxmltyE>6w_mo#&6 T$&/:{ i&%{=Mi8IXA>yD)$7i$}1wy!c0GŤ&5㕹x}sxtNYϔ lXj֧ bP(uڬ:M^O5P*>^ :uϸ'|0M6mnJ&qLS|q'Wr-ݛM5 l| 2!ēҨM)E/9#/iTyɻ(aqPFE.M G^74JEg?4=]78(PK ~A_$Vyzor-master/doc/index/General2.html]s6=ie>lI͙IJt7v>CĆ"$exH$Ѷ;"A8^? Ώ8Nŧ7|:Հpvv;0&Y6{;q2\}|<>ڞdY? ٳ=@w0~sGq(۾AC#߲M$᧫dAB}o`|+N:AD_AC#CN ,GijIoMԙzA߸( fh<7ֻdD>=:ɲKF˼Z6 0( %@y Nc?4> _[ϥ?mo? n0R`h>Ep%A?-\bp篸<>D; wYY x #x|y`&iGٳF4=R' H*,nQ7I<$<ݵK>%_! WƒzWI ^T~%[-a0Q?t<2 |?^>!ᾮ~$Np4p wpm*pO5ܷZ ; }5o(??5S-9g{&OЄ Vs=JxaՄ~g^j%2+ VφY+w]+G5m;!8ar F0 ә7 qk>ҢEWHN$W)KGp[|K|*y.i|cO_a:{UdU|xe=뇐 z)$Hp O𣝑CogG,ȇ$ f[y,Q&#.!NMR4 pX . ͐@opjDJD%"]"EDDZq`)a镰d dl{ G+eͦ,G~g5GȆf*] K*Ff˺ q"IL(F#4k87Gh3L%Jf)CX%G1l*4GzE04cXJhK%0 N!BsDe}OVb2Xl^S .|0 #Έ!(sJr\0z!mQ98HcٞRR=f{OcE`ٲ{ 2 ; p}4sdݒMwel+`L^3Hm!V!3%CPɾ%whTDMRj*pd]j,vQ\S%Oxj/ּBZaD*H9(LW2՞v[ UՔWÞ̧s  =~D ,u8wiJD^\IVJ.+lOe{".[{ThY)S }\k8?f4+SQ%J+ytOƣ{c4-ڥ):i/KI{%uɨsO@"]dW鞌LdZ]Ob$;HIJ&ٓ1޾Xc"Ø0%qı'#@W%{'cuc94V^{2k`5nS/CdMel/{5&ة"˴uSS%o_OPzd~2Y}Tsd+j}_[#5&yN4qeiX_ub/'jkW|'!d+( CPW^2(g͕%a˨AVbJy:) tV,c[Xc8؇ԣ%aJ,uQs%M@I2]RI4HK|Q}SMLFL)q0rc[[ L L)0klgqXU@q5004ltiWT.j&a2&aJ$ǚ"VY޳#҂ 7`PSJHLqT+*~ ;))ttRa $T9FԤBH6&6ۘ]/ȣiɈ)%Rh'uC"s )%L`D!qz!=0RS3Q3SJL\,Ae-5L%rBRMMK7-Md-тy98%ܖsWo] {t~ ⷕl_lZjo1oI9մ֎.KD BQkӺjn1nIY,D?VpDofP\jZjm1mI%ڃ`JpFrp'Df6cضad*Vу566jbm3bmK- փFȇ7<̮is\ی\Rrm uM#.:Zyf6cٶe-xwwM*J͵mƵm)׶\{Qㄈu-eܶq?%^ʠ ä6׶_~dnHT&6#ڂ@O5Lq\+Skk[JE/ɮȮ#%NÊ֖TWsQqQGEElY'l:l:R6JrװRMMG7,E B(阆$Dmڬ"5uuiy qMS5ttYq4]SW)sVd-kʫÈ#%bNWCMF)stY;}.|f_c_}9f)r"GdT91zS=nOhzwM]/ Ѵ29R=F#4r'HR=&nRGm {jk.e2y#'KjNk/dr9\ZxͥE7E'VS^m)Q(lB{5ᵗ25tTՔ^Ji4T}(5 )T'=4g5꾆fݶLw^% AOa-K9)E0:GRteOkT*{0;#[D&;ihXhYuyKry,GWq"Kf{a }dv0D8C_Ɠc\$q[,zQf؆B.éq5$y4 !@^^zC)̲vcXn{-PR(7qIذ_"5L\:kN*ojF5UDvw7=(R|$5* "lp4 xwjO~ɥl 7I !0.fn#xWD_SV[6.jy<3|KGo*5OZ =k$SP.&9[q[Vn#x񽠨;Spo hl솖f$( 1qRG0fIr9UG?yc"g?DՊ$r a_tO& &7Ҏ^Cq !gGl՛6Vh}#2.ѭa} "||8&mdl#Y>Z7fe,H%Ct$Ei_dW]M0ԏ$7ԄRSu⨛ CE^eGKVL?F>=VU}2#nSHŌցPr(Hה P3#k@'ҚyFoL] C|ۈnfN!N7b_t%š(V,B2(H 6"B_xA떴)%hCa\yup_'5 F,d{(=_^FD Rai226T*4aSn_6ܟRlxV)f *|~I:akzY]114@rum+,OW|…sOuL'77bFh:Ervw?4`l@O-k@f׫s[i^ܵ! Iwi6M,J:fAjDnP+?7\TO17Ddc@)>F eB .xӋv?FNm.;3ҀJ"04UB=;j1Ặ`{ v0{{UбM7lM\v(;9#e^4g%aD~|r?@5엧Y4kU LJ<ސLsy~\#y!Zmp6IǗ?4̼hLPÂXmYpaV.JĹh!w ,E}x^M>{֥iZqzS%8Bod809U#?=iK܈H_b)d3 Yj7!V2b[exnn )5Ak@[)De,<>QA}uUa3d4+*E/76G[TKgk,mciV|j6A Y&- &F6 ^!C5b{9uՓ1ph ?H]Q&L.H+7Ab^$UUӦb&MgjAFg -KMٙ&&AZ`ՍbM HZ)u7$FqB@Oeّ!kcL.4E"_+ 0M/ (C#-Sp 8u{$f}A:(gx< 0vPW O&A+Zx|z6N/՞pv7SoY+h?{fx!Ot{vmcxr ..Fl}BEihNĨyK//x mim3H8?\ܱb$صs2.-fBpe38 nђLgG5]Kdڌ]V!98c wqĒuXjG6%>0 2Ft3:_hN|dz#$`U-# ~y@oi[ qT6bd{ 6  t| nCSZx'iO|m$zU,l~} '.K#dM>n PNb$(q}B~K^k״q|x!?LߏWS/Oޥ >ķd$ 20=n{|97zW% u=!Q*Ή4ɔ&|rӻQ̲WxB\Э_i|i!>S}z^C RJHΒ.|Kw |J9=ͲNbmj\ݴeXAg.*FR;ex'iY02m);,]-y '>i[NQ˒*7.a=] pu4o0(}~ڦ,=X}jSڷEAڕ! wQʩqYvgY7]@=[ڪĺaa- *Kֱ-IWar)06Ѯ.U0܏A{w+7<͟>A_b;k8;|7*겪U{tF[TIKUpk֭ w#p;9'%WMhKݞB u C8ʠoHϱ~jW-'L k#֣pr+WLUY5_GEgʷٖ5Z5,ww$ K@ d4>C<.ٓ-{mƻS_0gH&-\.e=z݄=hIoOt!}$C^KOoeބD SLnyfé{ W֏%fQ9hLp Ҽ4MXʜy8]~KOdũWi⴬IU8uR*HۡԚJЛ{PC|0|3϶gp/i|=IY$A3G Hc)PK ~Ad $Vyzor-master/doc/index/General3.html]{s8?ùqlKd=[+b'sWW.J-N(RKR~|ŋH(Ӓjv6c`w~?>\^Gi4~m57Egh|5IٻFqF//'G;dw8Q;NƖ>~O;v0q~s=XGa ٹyA +OI&nNr/sߞ}{wAg $6#9c L"xw`6h]ُG7Ks>YGGw]>J n4-iPu 3nXW"t֧䯭Jѝvvxw`k1߂|Խy ܲC 7 _c}/#clJgvvx]  3&q8b/ @kw߲/; hy$N RX> wQ8?j6[ŧK?Ro|@;Ǎpíp |r{7A"25w]x<>j뀟x&Asg?`9ZΡM YΑQc96*xb9'%<Ӳw-cٻ39+{wn9w?.r.ʨ]ZΥZOɨglTrG&Ǭr X΍Qը7fTWը?,Fu h &Aߏg ٯ;_,8ghF/qEqS4ŖAhѱ I=qS`ާO$z \<<,ƽ;;e o?G; h6A rc $|f[ $i??XZs4gyc˳mzNke#E|H|hv@o4VnNytisti/&^ 6"d\+'d䕠=R:\){Jtd1-)}]NDi L2!HV%%WW_W=A}L3pXsz'E0nA^.(H8:VG4踲ƷWQ8QAHZ)ɫ1,)8KN$L77Ҥz0VKxAlГݔ^Y}RYEeaŬʻ-r/̕}!?5 q`~GB .GL-MJ;گлT|yS(=%ikŵn+Zߌa#\Fort.{zҁJ"jJ{EXnqKAz=vj}OD@/7D̸9d~uߍ$^ çç]JQhs~RO'u%~+Iuk-]{JݕoI_ުEUw}wKZ]J-ګiy02 K\;N@nFBɏ葒b u : $oQRmH=Dž<> %F.@TQ5la4G MuHr= z _[3*HFrj` +QJSu#wAeVDG|>] T%*̅!뱊cpy*(r7,7TBo"wƩ]35VO- ,9N'$8L&%4SdBfB(dIL,O%gڪIFvU]bb 5!]iT5&Z}+!JAHIyɑ׏_T1+ג1Ε" mW)aHilC}aJi9_",SVL$(4+^ -T_ ^rQQ&#l t=@W.$ tUE+Y=Wd6u%eƱ_R!F%CnMbz/^ (e&_5rMgo ԃ/2__ד,n^.T[t_žrWbDBz_}{Y14 f oi{=W-_[ 3ݢ\}I7/vyպޙ߷/yg_{`{F] >?qQ"+}h|;BH.R9Wa{|v\ ՓcNTNFPГsg|M0;0sI_#-yQ3<+l9>wJG/qL#fP^"0P} ?T.HG}Jo˥^"BV:S: Zc>%vKqLލQ|%(N]N_lYrSd/hJ@/UjQ<=st5PdJ=҈5W@c\V :3J+^iA k%YpΩu@%۾#(\-p%H ]Uk(mm5uk_@E T9syHu6/pGl?Тz@;hUځ$d-av6e3yeAJ k7ZUx#ACz0=R̚˵*F y WbP}QB$,0]顛Gc (F=%2!7\+$مC0s($ܚr\V4~:rP,8Xn)@gXjb؟_ZL"c1*`{T :=]qzy|0 ;1nTy;{rQfpLVh-@~K6* *|E}ԯxA#+\)^pH b쟉Ix mk(ж 2 4;(S([QJDْ \f3 ;S֖<jlj-m%NlIp"ctIg˵N f=lqi+qgKN G|-l%kIW:(7zm#GzV"V {ӣGmֽX 6KT0Kl^2h.BΤ]y`z V/A.8%parrX_.8X%f#,7OyzH␶-I1L~S*-cA?z(ls(VBa[ 7]O9?,ImJlKsﺏC̲yJXsꁳ́s[ ͳ/2ppvٕ$*l Gu6=494m+]4 ǧ6ǧm%>׎Ov +*/fZWtBAS%RD`m`JkqJ$֣Xض+KY1R6m%%;tNiO1;rhwvIL bibz8pm^M+ӹeG.%rV2|t'O„&R?E1}Lp:c-*07r>xGޝ76 /#Q5z7+NMj;Ү2(t%Z1ȘdT8#] 乵cX]`ȰԨ\bc*~Fog1&gh LQ V:joB_.D1p'wЗQ3VBGёS1Fh=ȰCGַV(Xn%K*VjI.eBՋ»ָecUIx55ٳy˦tdrs:-@e!M<,ep f)@kF #欛VJ*)2QI&4f^J\B<#=}1BV>F,= c >uQ*WB'[YUdd5:'=<`rCq*g=7 9TX^D1% J!/ؘJQ00㪫bh~@@ -(\x0Mc永&7If .ͿH|L#^HZ%>%xh@L+zK& >M۴[J;c2'/D.>A^yԫ!uVac\ c`KjtJBuͩԝU-׵9u͆/VFq4Qe/1L) d`W,HlyuI{ape=>”ds}`£x!!3r+c lL{&IX1"C5@w #!4"`}C7S&xG g^*t +ڰ Y 4|^>zeۛ-gV rrR?ӴRpÔ^W^9B:i[+G26٥>qވ^F5S!v.ߋʹS9A>Ecn7eY66Q+h :}-:KZY G>_iG¦(;{CL/M7GـI4%Eh 8 9B%"{~=-Dwpb=y>8cbf23'! !YI5?x7- }BAO-8Ff]`.南 <&ǻqɩ[GZL'1 3NwG7K݄>BCe7-br_-WCrP͌K'9To9 :^F^Ytc\`oF8dr*fgqrF"ޱbfFx캹0HY .]3|l-~J[rOQD&hSM+>V+ZyY@,'MQ'\YE!*YbzˑsDFQ͜rWp[NT8ICo0IEDŽM:e< s~Z'/n1/Ú(iSN$-N#N'` 6'btE}!c[/ݍ;`O0w2$L &b&A2Z7.DUԔ%-! Z41Ť7XY^p7&^4Uv5(c'+`*f71t p\'[/ēv@% bG ξLJr K3m0 p4Dv?By~+dI<瑶Ǵי<{z~L Z@\X>^Gٗģ1= ǻ7Ygʵhvl2J(B疗]wYy:<;׽䥳4i@H{s)Q=~y{۠۠}r(^&㹟Ŀz8|DGEˢ)(rWEB'!RD+9#+)vȿ|ɻ[(|a-Ѓ12i>F^,J"W.hzѸoPK ~AkM܇$Vyzor-master/doc/index/General4.html]s۶eߤ<[H)9xIJz޼P"lH].;/)Ѥ"燃ˣW' \}~hoݣfxtL_fB4obXt~p]7Oa8aGfzuSh Fáv{j`Bj|÷`2FG<ȅ'φ`|yx_AC-\N!4! Ij`ChB͙x <'3kyu, &?#Z~IJ V0Vd4ƾ& Ԁ}]_vv?r8! wmϐv`;)7߀+~iI)_&g"Az0"h8\pO==n; =Zb-Z]@;VGߕ|JDU+aļ \Xν![y`%G5tدy}UA2c~w.{|//ס4RcGo苂Za&|%~(NT=N>`XolMg2gjZ[f^kj5!F!,Q fBvBEBJ.Uarvrvr$ 7YAZ.'[&2r! }=&f_*fO$,2Qq8D? BChо4!\)Q;{,v'qYr>גςcq/=A$,bB/: :PXKeO(1G|˨aC]{x9VGHT> =4g `DAQ^JuأKcO_{* D _'a. @}AJ|$Uǝ>;4qT,?1q.;}A!,hؚ3!ϭyADu鳨KN_uC21Ձ. <}A<X8gqHơ ɓ>(L}ti` ST):8I<ɋkcT(CrU:rp~T**CtAkP8:$)9:,/MiP~cLpȥ uY4S37[*gkHï-іVAx)ǞꀮnHޓ)y7|YbSV t )4e>>CDQSU /t/ )U&T4UcaCItCi6hDUU gtg )%f (+&`5i9P CYFa5IYT ReĚfyM!NM5l2lHaQXvcQ7 7 (M,GQ]β}jd04'<2-պ* 3 3 (L,_Qe ,Ipʪ10@IJ>U67"֜ST Rd 4wa5')~)MM)h2J@ڬU&9`j PF ZߤK0zbjՠ`j(UF aUy)FtNrJՀ᫡_ JU.Vyәʩ:lXWCɷ̋inK=f) pKI%1dX".l>d I^YՈ{3Y{XQ{$e¦LuTp DIXNZTkԤWÖ)W'vUwؤ@WQ^y7 rkA֞(iQ-P.PNz(HɀV5lVEɌ xU򡸜+Kdu䌊z6܅l6KK9kc.96܈my9hε ͤaBDp&%Ջxae~K\,V磆,Ֆ棆i!efrm->.ge '2]I&hOn$lmpy gÊIO@R̖\afGY,I*ʆqk,U[XILbY*-K̭X)pY*Z5يZJø~Vʄf5 K%idž9%9)䔥wҩPO/BL)\fYJ)I@MSG|8"M5e '2XIFncr$fXo6JyEd1-}߅FH2.3Rn[b1Ό(C B_3 Ei;Jv*mG4DXj(fP#=Y~F@Ծ Fxig5k3ב`suyDLOWDM=.gS5l3ّv ̬!TZ uЬ]r++z-%)ȱ͐cGX="qآjfH#EzCkpآjf#_iD6ɑѻlꆜj̼h.bI}w£$gE^)ij,_6$IF*B|%zx6%31lҧG}PA 2a\^Igr{P̓O"4W86!a#*T ]vD^TC1:`//kn"-%*B]eD 4@Bvo7W&ѳ\ޛI1H4oݡT]gDOx7܀Kbk!cLkܦ6MkF^F:ImX^K]幜 bF#$ !@$X!@h4r#€V2C%n0п Q}}:'1@t,WAIT֏\s1xX\FZ&a\"fHn6E0TZϖh"(IBs)5߳B riX> B9ˎ xO4dK{uC{>>dU0Q{ ITp yKdL^}ޒ XD+h&5zZCNWvںL(JUm]|b܊YH]r`75p?b|0E7iGV?i+DBW3ܗ(=2JnXym}: zin &WTwߥ5[Ᏼ`V 댧So|HDͷDvldc$ܻOb!uLtIғաɏPDIԶn4g@MάaΏ3Q3?R?a>U`ncKHj1d SG-Pjl! PbYugu۝ms%iX"g$ߐ%zJ}<zr'+;Z42UT]íX1gZeoɥBIzˁ:Qxk<tZ8 ҫc~6yf<-|ۊX 4Ș-LHqv4ob(,'a5̱'pA߂ciFȫvȉG{.ȇϟP%4=Onu➜:ԖTQzỊ7#ޅXѝ_h#zF-K "1R4$xWi&+|\56"Vz&^$w-n4'Ktn]S]32 k恷mO|>zeK7fNyQQj[53V^nZ'Ev^\D7"^Nk`XP3'ej儁'~H4JA`Nw찝lLؤ!3:yt}>+nj>?k Q eF ѩȅzl戵''*q ;)VEjv8‡f*0-Ij>{ vk>f>`c$jZZatj:=ޟ%s.?M }/D?2އ j;mrEhڴR{xA ?i-;ҹG;%-)yTDiIbDә$N6U$tw _6 gN>KY]Ibae?trZE^C׻ͨ\e˰/6H T7kW B{`r>82r|pNFw>b' H-Z-vnQQ8?;8Z%7D="z9N3+tR-l?_':?~a؏_K^ky.xlZO Da+h7F[~UaӪް+3>Ӣsn&?hUh*^E)d؟|iؗgc}6Ϣg_ W*zͰ}7gęLȅBߏ n_ u/T͆;4'dRxEq8sc.` %.~ӦI;@zwA%ċYSًAݣ~ŶYB*zP.t s81l_G}&WWopQ g`ްWu휇~D1={=x$u?ڿ>7ȣ\|6P 6 ]uV|"r"΢H::QUr4q|%{jG9)#: KmX&,%*i&9}u0}udk*qUsavv@ZfYbf˘I>Y^naX1LmE5j5LzjzWu`XY5})fĩ8U)Ӷ ,6H}u %D 9(X7'o3c^i-i[՝O)F*F V1~טWc.L=)f 0PY ;ة+NSeQ]u^3x+kgy5x1dJSO2jc0ʔ¨F=}FLe;/oQ\j(cPΔB1V ̫V,S zKMC?,}V[l`PyVî]vDkӕUjcH")hn"`Yoj@ǀ) =PP? o.f\z -RB]ŵ7wnJUrW;s} 6eE7^Pgjd/צ_S*i ZXͺmmn ˇܗU:T{nys+W{nys[yIg%qQ5jm2ݗznS F%jm2ݗnS໷fCD7*yWmm5ިbR{nynKMoTr}- xo3mIv_}eJK+_x$T}y-󞗏d4 j*0D<.3oI=~\W.=/2rdQ>CUjAQI8sVT)i╗LgW`iKg XR<ӷ*#*fQL1d?|&Kmm `[ YR<@v{?pJ91_a>KjdTS=+399Drad;*@ s 0/X.a-`Sk-kR\kU4|,Ŝj@l1@<bS9OƲiޕ]+F (pP䩪vko'np.t!XhAAOu(Tmm eŇNLy\6x-!7W(Z?=9yӒYE;Tm(AvK}yۚKmy:*m޶4/]˩wO4ߔ7@VO SYiմ~Gƭ`[ߣ[Kߣ$ N#$_I99ձQ)*!8OWk1RyȏzL5Ҁ"LYO"%Gs|4m˜S:?2QEm%M3xpQo+L7mQEmNƗD`dO@M1.8 Rᔡ 2D F1]4Y >[: oux#:F\Wc<])c bʿS+VQ+)]: uX#jY9ϷubJ[Grq5\0֕µIMr̓WWN?_\+ G0F2x<~ }8_ kKc\Da#JCXD0A"/H :%\V{.acҮ A^J7I<X֖7YF>KbFލ8> h !4)`(`oH,# qx %QxtϢVov;?䚠FD N ӱxƧà罓̽!ɢBڍM=NXt o,#( b2ʫ"/ m'W8B*#ai:tDK4k5p A3b}lVחcɽ6%lh24ߊD&8#?oHя$8xތNO~'uOs+@4mLj O եOڢ;>$_:DKT L6RZ5 1.A-2KqXSV=K]Q`զ%-ZwH޺^Zs.YtH=+@9Kǐ`1:khOx>eSPp4FN,+bgrȷz2.!f0wg<-'gmwaUF1**ƆC Ӯkp +#U L`4'[(ȾV3YN,`U ƞlw0x!ԚO}غi >mnrӋ'ä\qTBFNt!b`KH76+!({+4}0b=% jtBNLJӂRb-p=dAajh'C#u0ɗj;?:@@&y8 2JLb9бP^'uENo|N DH2E݃NFޟ^L7= 3'N]~?/HC/o͒d[ZZHpS@; IF(v%󱗠ޥ#N|~IfD0 :<=ڍ+!w).1֯*Q76 έO#o6on|VK1k'眕J+%LBrF{I̜꫸pky|y#Vkoxo(vkYFw3HoFRn[ 6lh즩O6eO 7!Bu(Dů;[)i0(]}[s6ƭ9[ ] TQl=pD~[T5.l`B8îw :H#AT8ݰG?ڧr^I6^pIaѱgsÚUuo7&Fq] 5K&E5KesClq}X6n>PJܠޡT)DfW\ܰ?T^3nܗO0כ$[ή|5kw g uEZ}IyZ<&{Sp?KIɃGIi6 ղ"yp@>E˂dF@q)3kꩨ"?j/zȚoj*rYV gEX<27mfn H>u"C'..Yɞ=6^ }b<lѤ y`k%b3d ˔Kzt. (o2>j} t\a_F׎h~ n16c$A\C?VGɋsјcOk6`@[[JcPeCV> .RU]nj4T|;(=qx_^v,?Y] K?d$d hzdwD/B4i.c?a<gM,JO5؛D*6\4^V=6f_k.7xRPK ~A-nX&Vyzor-master/doc/index/Properties.html]is^BMOtbʹotLTy۵ĄLn /I~QLWB:Jil'pxur ο|<>vn_Vtjc$퇇CFŧyr:8Yrǰ޼AWk;Ν=s{aA}p 0#v}L`6Mv\lO k'ߵΣpF8 lONO'O]71@yȽ5Z6IԾX;, viߺ%G3IF=&Wfv4;vbizv0Oqh;VlM!v#Topz2v>_e}igf9n6++l*P=>ى8ed`?^nkCϦOd@Cub2NE=& 2w:Q$9ޭ\K4ǝ6LTHyj{vuhGs0y:&cam[{ ޞa~'^:eٰ>֡ޑaξıar;1ѽS:;33ѽs:/o^ úeqiX{iܸBv+úMŰ~ya}ݰaX?i'm=]0 #Ǎv;`~g^pZ؎d9x/;h? hN8I|i| y]>MC*= W_ixe=)H'h@vP0CX}fʍƓYxhۋ0P6S<ʲ7hB~.c ]r>\y-f$_׷MC(-NQ[g-(dbQuʔܢ—ʪ=LٞD_Y$+JZ;v]v}wX['U̚VY_Ue* U;/!ڂʕ^ Gnd$3kϒCLD3ҌHUF:ԃzx L~IGh9|#]LvqVcIՎGutdO$O6ݡJ*LiS֟E't(PȐBGܧէo?gժ_ I5ޟs+X± uBD9啸KQWhTπ(l`b] ƺ24[jNw%"RH֕a5Rs+Tb LuGR5 ln'+Ļw?ڳ?o#_wte;<%)anܬۙ$*f%lQKaYW˺`V_ޝ}[GOk%,R\֕a;vU|@rk/˕]j}X&u|e~eLJxqtU/az {Nէ|/S}gtpW^6Mi:\O^_W۽UIe/kodWTU>}h &T6V _wDd2$;e 8*"ˁ Y6( (PȀ@s68ߜJ`. ]22@frEkRdYY_|:nՕ(d@Q@BRw+qO+sVtV"EB ?,/RI=C@^;C%R1!#JFC%tR2A!)J 3~؂š )<Ѱ'NG/9J 4h(@>QKr4T!ZCrXuq"7ε2LN*l])5 ҔHrHP$<_SA)}2Ÿ"#ĮK 3(SryHPĜNPmk~)ujIc%fRd$w&3" w+kJ1c$##U}Uw%+QV0f00rK{FJ?$C#g^WOxՑغKY$GRԁ7X i \4rj* ͭ{` _`?e'/uxWEZ4~)I8|žB}hw挔mm!3%-P&H_pĉ-&)u˨ۘ3c {3!:uR^K2Q %9p&-2_A U ѹg ^|ά))YOJn5j"V ]s db´DI&vMdk"ڶ!d&_TTTɆ& Mdlh"+lbQQQc%P.2q`FEE+ӗ 9VDFZW e˘T*S٢Jv1b"c浨:; ..km,D '2T88Ij2fj:+Z3b)^+s$1d8 PW5Pt,07ǐu9dAdO-{_ⷭO"= E0[(&D-)#u,m2|f.q-Y*5GrSU#BL[R3z流(y;N*)ԅOYیt Ъ{N D#C’DGw8p;eTˁʥY CSW[j2|X%8Ji%m[6rV8!f]8qU.GެX+;^Sr۹dŢ2_'W^_ rsR'd%.sW l,4R?!zrþY-߮[E$KhPi敭@Tx^ Wd[} `hK'.5XLܒϦoQkYeU4 j$+V0N Ģ4-9=EC5( !TQZ_Z)eV9|QV/< hNF1adX)M_aX Jʼn7,ACt'>FrqB%VgP U ߵlghth#udC c ؜,., Pl[W=6+,IS)aY ]Y Ά%u/6,/K* <ޔ$|5ZjEߠl]o笛7=Y] e%е5GZ578oU N7I;oP exM) vDŽ振lKbY)V  & I'V燱[[H3ŸΠҨɻ[(|5Ƿ_+_^p`Ƒ"/q 9"o᭿Wjz:nQPK ~As<1 C'Vyzor-master/doc/index/Properties2.html\S8} jH q`%qwuE)H^Y&d?=A0;U3Z[-Yv M;^@'?jl6kGZ>&tt7ۤmZ[#M1E_¿sj=`N 0Z_ѣ6uqE<:_@ |&a@&S(tA>l5)M)p;BFš~&[^  QSIF5ENo B67;;%+ c& cOcB le#bԶ,nzCSF m0 z2jCc8ȊָG5q\S'5EOq)s g8uи)z ˚WиʊUи pяCh B6{2;h}ѹhߋU̍,g<SD>u\|b[Gl{y=FJ` f"&N֣yrjVvSVvKY]Jwt6+l&%ȳ p)cqc*#SDfJ*efk 3 f99QQbKhQUcvƸ5 5ƥ!S}KjwRwJ Y$+lz5w໿ ?yn΃XK㉚~TS%K)_)x,s5Cz.NZ wJ׷dic.3/_]vҚSZvvˌN?o^]SiM֔fQ+Mesrd3ybOO>ӷ lO9k;K+Mb;V)QK&BVOO > >9im.K?{n/,{߽YF^ὺbS/-6wv5pzi 9^`դ4'j^]ieVFYN?H/+Q/PH.KK(jU'=I/rnuMni-(J\qxyy6<R =ahz(Vꂃqik hxO☡  B$vlhۂ &\cYLϷ;1:_+~.bgvyYCnk\6eOȨ UI,;*+ ͉u:Xx]&f[!rI`!)^D+&S*%+|kF`~"omYlV؝ř }D'`Ohrb#}rGb6?k$GE'B jGQ+\|#1eZeu 㙒찼_ Z/q,@<֏ki3vMhBNGe&6FDU/ yuϲ93vI VQ0{]?,%8kj xFNK<S?en*ԏk7fnVtcޘE7+ڑvycslnu!WR;SdwLtȗov*}S OGlE/Nf4QO]ndvP%\fJˑͷ.L2aLYjN|8c}bfXFlDžhQW$$H\Z*oO(ήhߜIh)OnS|(/eM;_7UY2>8IRic*y  ď0=Sy12X"_laLe q0҄9~0Fv4] b ЈLԟ!MJ ,[eX˟/5D%/2% e C#|OTAqW%)}3{N1[&N|j1g&Xbe8r J{ eY ("E5eGlD9O6=rCgƒDÈy` ;P-$58j*Aj\\M4v](=O[r&xP7wߐ&Ѫ\GuqЭ,x o=ʇ3{Hn[&E˻}1F+n’ܾɄMt1t[woɣ7i<[Jv&}Gk8+h;ؤ2W W6;"6߈>ʛ੯A~3"@}\>pfǴe *x?\{WUMEK6Fv0\{dcǒ}<3àվtyq~-!NH*H/gc͊RDmR< _,'b_:AhDn<^jH4EVr992\*lq\6N03K'#%3hbYM2*ۉ9~H;{U~sk\ thpg7c/֋G b7]EE SXOT/8^3K,†737BrS'4PK ~A7t~%Vyzor-master/doc/index/Variables.html՝ys8ϧ@Xٱ_{;Db7EjHʲ{ H#TM㻿ߜKpXq~rwBotjzY/~WUmծCs,{F=CwלرFoૣ6,C8cw h)uh)߃#~;X؍=8j= ?NxwhEb$$I{EЪv3:gKf?ڷZNKK1:i̱c;Lm8`Qthߠ4-ZN_{o~ރI"btr^[n }L5޾ C$гi ௿u RЇCL';^Ni<0r4k~7yC(>} S~Diއ,Cph*^%o!HwxPGed?vt?i:N!q`'AY{މ5:)wjNY{Ǣ{ޅ57(+ktIص5.H"Q۝oM2x5l(>zg~1x5j(5}ORcR'A=uv =;iE8GAәFqrat9j?ƅ?v#GIy> #'(^O4S?G)wq? GX}D.Ҧ&Wj͞Di:$6M_^Fк;wQrqC^u ~Ğ]:SviK6V<BR}<`J:$S%$k#vd0vt(+(c[BV |IqWq7ոи+ט%B 0^˞.4=E.{/fE= uҥ\/Qp `/E#Tq0Y0R_6mKgnvGͰlA5T@h[Zj1j%q(>q݃?tJqr9-RRTHՒa@RXo߮Me4\\KEpm_$-7YhŐBVWRjԶ1*3kc:ށgHQMm#bn[-TڒPj*mݓE|I-Tڒ0kFnmLm29OZZm1m8%q(fD-q~Ln-ݶݶTtےǴJqܷnn[m QU̧X_c[DKmFm%ir߿`dX%6#ݶtev9gEdcqRϝs)t3A,x̻#%Zm3mp]$XZaWABdfdVu[BL\V{4,~xpZRyQyWE]]J IRʝR\/BˀMaT4-wwUޕ{lN)7>7H_d_f~^?vecj gH &!pYC]DtU^,Z*Wi-jU*{\Z1b_E]=_1+zk1Ǽ}$C&zVu\c { $46C_K='qVoYBW8$)]6\U]BS6"w9 *I>*#bvGFRavO1vMkdƐZͦоC{ea]ӻOc9PqgOL\Ŭʹg9Pg_B*PJ>6ZcVHH*"K4#R2C~qKf#@˫}ƫ%*J,{pNi*"K:ӿG3qChw߾Ω Ō 7 *K8٧Rfͻ5"tDrcm2(mJ&Y9 ~q *KֵJ4ZPn<_Sn-TyQT%P(걙әoMT}OT} g Ap_PCw$ܝJEo[DCk$J@$nHə8P(%Z0z j&Nmn 䍃D|DbPɡ *DH9VV5*Tt]<z7"<#N-U>(\VBpƬZ0zP<4Za"Z n6-@@U=tA:n5Zxq%% B/Qeύ ] $ɭ 8 99:'Ӵ"omw @σo#]܍.\ˡC!, D}yԹΗ󵽈͆;<}CC xVo]'r2o t(Ќ `-`y0ՙ y ճǙUn͆<~CzCVč-o+S]EXEߧeaǮ{/Xs - % U^' qw>ߍ?ﮯ/.nn9CYqܴD:NOnL`?A6?1IǺ 8 sZ0F7B׏^q|"4NOanCz;r}'XkQ-ܹ9[*b QSyLv3}u4S_*䓓3 }ri`S~ ҦC[z2g\815k͜&ɼ٦TN1BB]d6;3ϛ4ai*J,fR6Mj-K͙ĺU< iլl$I=d}d2P2Dr)UJ"3("# f<]A8 ;fTY]Nxhӯ^&0ICʄ{V 3Bjdϳar"3״8z^W2gZ\snUwͽxftF21ԗƋqZH]i2Ea&u/u X{S E8QDm}-o߳$Cnq^) Ld6'i 0̝IIă Ur)-1{>қ>.xnāiUC< 5WAtQ9 Ua$0& dM#uDL i7Ua|$xsGgFƎ* 6<${ӜVa@$v,2c%\(RmMLy{Jo)t+Eo/ xFNj3groJSRߜ<'䆙R87JOᡕoNys4ۦИSac7M9*[C\>u;!4ٻƻa@ r; 0So V!7GY4 0DiϨ96N5,{K 7i3ƶ-t*u9,btA}/+,K(A+Jc=ci+~CR gd,fz5m (og@p ᅰ.J!ϰtkhfAҷ(F՟P[+:  bd9$}"UK#F/Z.U̢sE̪JOd` 𵂫$ctbd#pD$gj*覤 Rex ĹAUaG<iIQԕ2{*@x6FC"*X[BTl"!ta-N¸f^|) dpSޝ&UXMw&->pmjޓgjUVS&ɦV@æU^<5S7>32t*tv5i{ G@{U"r'i%.ު*,6U͂UQy.ت9`e`+}U#F5}կ0x:XaHOӄvK>j,`%lWF|U{B 礸VC;UaD%4^su? xBm0ʄTsA *`~W1'digjQ 0I⒏`V/ĆTw/]v .J.^ Rh ^Zau֍zxO|_ilZ ~%rUݞAed[1bઝɷ3L WhOnBxCOMIvP13~'A$1e hD'ym%:*K.~ od7 Bo0W:'3یk %%vvbG*EaIJJ9$d9+23'[s,I$z"x˜re.r9BhByb{2\'6*I}] Zחs8+S`  IYt'sЏ~ɕWc;~rh;3CwCF%z(-[׋R<}$nz% $ΒeHiR  ce_"]io1tFk8ZvZ1|뼰YAp:~CW,XwW_T-7H&MxܚB*̅/]$kFX&Zb%w\9^LѡV'p .G2>}o{}oB^{zc]VYw|۽=!)؆gZjȲa y8C%`A.mLV"|q|`&.瞍}?tӁx_@#Gs0!N+uusNgkyȚ_k`Fx57ڮK6 DV0rt&GI|C.|>W'쯽9`oT/l-;hl! 4˷RPP R7g T{G ,l0yW'4|P:΁N-$x}NH-ZZh=>=×MYK?&c1`t8JWփ30 ̿xploAo1bL: ;t]Tq&}7Թ@J(8K? 5qnGp4Wcg3}^`߸08둇a̘+0 J 3I=lXgwIqVwCRY"2x7_f)R5jTj)k ((ЅMubY՝ѢQƴRcoRi*)XLZO7֦-O?MecL&"j5^ɽV=%$ RoEKdaI^C-.5*}3!-Yw7} ~u .XrO"_pBtb )ij *5/PtjXoufsk]X6y:_IчjEEV*7q*c,1['5ׇ*>,Z wG<(KP^lRRyk=*M+*-6jhT KRVm 6料nKdוby `f †";OYHQHQDړ#>2*~XwUOؚ\kDtJJD[pP:2UƢJ,m`펎6 ]vVH|,Ţ@Hdt؉֞mq5QP+ ج"gU&C/ʬIIoƵݠ4UG0em2Ze+r78aRGiC4k9B6ํdfmt "W3m4ɳd x'Ɍ y+Y]Y>d3iuU6$|k[]ʼ![J5X.TqNk)|N\Whƨ l'^*' ԙOH[ Qlz»az dH Kɝ 2s9+Jᅉx}ר[fs+*ZbIR٪q ڇ zᩔX6 LNbVL+}:7q^mr,qh"^S^ n'y SFc GltOf82ILNńŪ=(eتEM镁:1ȆPCt5:mqئUYmg!֑`ߙKZW6lJ9z!5%!2萃 (^k^|`#ϧϷ@i:8 /<-/ya|\>Oʥs*ŕDXGō,[:Yz]G$bdED^$e|'{C*E95#AHJ 2J:oU}GKѳX? Woܥ \|_q%L$d91SڻnhW^N|<ø%E5/Y#ߦfr#зSAH27>ҴihJMS&:C)d5M.¹LnF j-JI#s44@a2G ځhdo)$9 k)QyH߉kJQn=U|TAN&y2!)Dey/N4t el'v@YrC^WqYQxGoxHOSU2HkOTq%S-M~vҞ&sq=>5-ζ++Pv:Ng 'LR5*_+os8|60O}xn- #Wن1Gzî6[}J yb%e&VTͿF}Q#m.}PK ~AVyzor-master/doc/javascript/PK ~AKva#Vyzor-master/doc/javascript/main.jsvԇCr6SB ^aQΤoW@\&EXN/XvÇq'g9y 79O?}Y" G9!G%. >y=TBz[rľf k&5&Q20%G6? &TrlK2RZ$uy03$vX'hÐueHC8qp-(+<Ј È\ ֥<Q)ȅCTzU,`.Rυ~ zo}6ܤ1Qaa +CHOfLHJƂ8/G7cxt q('oIhh ؕ9@i,菐 {8ؚ-uYYT `܇!{/%1EV4OoU@(9;]X{}`eM|/E饞2~y(i|_F]tᨪ# Hc69MW, )Cğ"A,Ir;_EL =;5<;-[[9P/KUoTy/Nb&s3=#U *aL\.q; {!xvQ\ww.Y+x؅/g)lIU q}*uUDBi[{ 4.a] ֪8ye}y}d,Wp%.hVU{=)O3&,K[zd(Ǖxxa|/cdK>MhSx6m,ժF[_S8a?=g[q{zz*_beu1 lP^-H7:o1u|]q*BAv[qv* [2Y8ީɸ۾(]6TNE},eY5*=.vey#!W;~'<!]LlYpHN\q صsȤ!-VA"՞C96׀!i=8y4DLH<֘,0)qA2m4d` b)Wk@;6] m{۷nK^I}DYLAi@JE1-$w~x򸃹m! nJ,?aI 졺$49RDIj->ITF[WC^,$]bPa'sW`Tv d+݆3HZjRv "ia`Uŕ 'G;;;fh73Y<4@ɺʑCs~5w){Y'{t K0ZDšjA "U嫠TyLa%[$ø]]Bmh"LM̀iа7&r0 \ vGL,cȖMXX*rT"ug?/2}kqMdhYFBDe%wpzX  _fSۍ( +D. ,̨xi0|IK7Jd6!&4W647ÖǐVp/v8oʸCU&5 Dy5TyQT67iT',K?~0fD@ӂq:dn8qt-M=ؾRÃjK, W!$EZV^7(ҹOr _RLYCa(|;ńybC U]I+@%X{w*F{֖4'L34t%p69C`P)T%yE]jpO5Rdb~?MgPt:5eʕꜝ2S;8`a 4I`ޕ~!jP$+ط}ealC浕S~nqDr˳|#&Jjl"hvהCT{sijxYM6HmxKy;g[The>|6쌃mo<7[oǫ5&W[ FX5*  &\8}~t {FyAxP%`GoV!kS϶a#?kw|OBu+ȷAv˱ UgT I5xQ?d \I<9gH(J]>5H B)S .2n:iZSUT+e&*GYu$¾aP%Jy% 0LRRKL",q[s,OD( e +mDfrtwc[\Z!_|AZPyewX]'VL[ TBO.N/[@7ܞ ՠFёFĂ& 1{'Yws-2P*$1 cjx fM[0V=o z)4c)F}(-rCt/NB ԂuSۤKN5U punPqxmW}0}ʊkLn뇦\n(QnK)gM5;ʭ.RԷ⧽UwfΜ0DF}x-]QNq*-12ay7 Hs5;f Ht)žAy Ӥϝ=fIV*z[*k2sIٗNxLVv:k[~!{iu &5C f_j(p#\ڧ :xMC !oH 6Wxr=DAl;^-3d YCP5`L(C{SrҌ{ 8ԑc߳y , & ۇ@I/]M5e ٩4[l_~68ϝ>a[@9GaAHjn4Ҫ`ZUV=YNDwԀ+^S%.cljTiƀ@O;# E&-tIoz}mݺ_+7{]>TXqTT֚4|N}[eD;! &8OΌ,"06J X-p ޶lx (A1!V_@^}/o9-0i箃p<LMUdv D U[ڂ.+'Ԇ@h-JUuuŵ>\DKć^W!U*:TGO>x 68H7bjKMC9μwx@d9@>$+V):wgMQ״N -AV݇I* ĶA0a[oC2|.|m0 ,ZEcD?AsC=4v;&"Dzo'I;!8`I3:w1McR-O°~m}ݶSۄΕ0v[ Sh5o&c0-' e*PcT!?vgZO.!K.RfعTwo>mLkohlJk^ n|(dܐvJV'YO&f_}"OW%Rzgf>u%FI9SrNqPK ~A]ƅQ'Vyzor-master/doc/javascript/prettify.js}icFIJ<$'Cgh9E I#i$! 6 pPre'}o'3cg<,ع¥\{Ω7/r~Dsc Wa8_xE%u_un`Z>׉072i'֟@Yo e8a;n9K7͜[?vOֵ̽- 27cgF M֑pNi\}O ``uqlتWNʋBxb=\tWg :B.Й&PHA[g{^ߕ%6Wn<5A$T/Ĺ`zhj%3E  FAWnU٨ͷd4 ħׄ L5ʇrJj$wdฐau/-;MD:IVmݥh7:y]Z\‹c Z<_Apo,wy q̫N^%@fIO։4YGhVt[΋fӯ"yNt{N{~t(ln9q4=j云 EQRAbX`{(9Zsݹ8-p5p܈mgQJ++?P7xW;GAv"m25$H,x 8̛`nfUrŅ=Pb*p itrRS\}- z!8$׫U%4Ȑ fr&T0p䇈 (NydV<]t 'lbȃ s{!)ʓ<+~8hnqKfp MAza|(cͥG,D0ĔՂ4@x8qzL 'c/WΠnAE/}o7J42) `M/E@﯒ ݞ ,! f@=㲡ā0R\uL64>П9کGU;? ot C- ^u+umwwB&0?^k%.o!B7Q%\o-;Ζ>E[WprrapYYFevZ!0-,u"^cN^& p1SF  J*qD7! VotFMb3F#(}IRQd:a߀D3MN$$0{2LUªQ =7Ս{Kg fdiKw}~܂z@qwO9R'@~zM?L(ƋWgbD$0 aܡ^~^ԇŚB aVsԍ%kn'#(re1.!()6='igh t5At6𐠑0Q $y!Tt[\hdtZ=`64ct$(:H{2B$e_w؅˜ < +67!U" 2=!HrD;mhFH6BfEPA 9 t#;='>JA !MYP9˚X Wt  D~׹|̼z>G S R؋f+ha!4h@gs]vdȐ`$/g 9qQ ?(Y$Tek 37 X@d L(n\ɀeAT]cŤsO2xmsL@ڔ #_!&x D[;o(+kHH8.'3@jecY%6߽-,|I99 k|^;KVWhiU6(ʑ$:r Z\vY#^U{D_ӵՕ]0f/JHĶ0IRf(؝2_ =Cj$ր+mYå, X3NeNfɺd)v'ӳ;fAd!. ?B]G`݁i7>XtEŘV#Wi.$W9\1|x$l,^}^wUDu Yg50d} ijMXyk`gY Mp[%&u-h ذ 0T{n5{s#x\P u/{-8 BMRsty sG'HOͳKF4L^fH!bVu2!0I؅:}/  %H*f[Kł.)s47VRKS.k"b aꡭ5\ ĿVQoe/piCܐ &`IZ'1)T]Zey(Ƣe/:Qڵr{5NKU(CMITBp~usby*-ŔAA9)1inS9VT!a*<5iOCn4GHNFeNk݀,iOnDKT\O MtY5_+j=iL~\v/ZK( Wy B*"zv5~Ej¸o I9D°d _x>j5v1LA8=D6[FIb03 xydݻtSd d݄p;DY_x<>pvv|M0Ț*#oŻ(?skWS+UdO*Q]: i̤8 %y&xx-W#ˡ& AO`_IIsymԨiL1Xg+Z,eY8 .{ w@=v@ٵ*pl.(qvo|6J@1j`#2\L1o$vdUL}IeLp S@L,T/}t}~"2d$;~Ɵd!^жpa8u߽r#.['\@bU2f2nS!d[ag2rXT%8{sS-0y-3yQ09mc~\ Q8į]A; ޮ~.}ul`3)CQ 9Y#JĄ=G~`UЋ']:N`bebWhƌ:2rƖԶmoS&8/ O]o߉9&۬2Ío.XȆalm!p6 eϪǙ]JнMaAn=$ZޢO 3~']z D-=z(c]8E1-$ҡE'xb"򮰡 Ψ UL<$$kE$7@N΂ih O2 !,HHk %._[7n,ãg0crZJIaER gaI뇎r^Xt!HӠWFqɠ跎"(MMʥ>~J<e?KZXa;d$/NP,q9|Nfҷ^7 h O+X![C5dCeo9fL诤"c[K W @"mjo@.ۄXO³֋Zl0P(Ze`Uh|,Rc 7*\L'+:kNT4k]y>1kuJt*c~qk18ipӽ+p}y:Q͕RCPD|?Rr^z.QCt(OiE%}Toqt)(h t JK ϊ>߿Jx/>~0P^t L=o޾[=<ĕ}ʼghr=u؝;{ECԬ'u/ ,3Iǻ] jAi^7* @Ndsd9WU[p ]g*wN HMA1ΰH 6:ejjCbevbQOT/AADc~7A&$Y #Ñ ֥֪ ;7 ~ >CuRz,1N|?w 0@Kphو趤s3ڃ&iL\-`NѨdKل`Pb=șpbCIi_ -߾~ ;7:~2N_#,u] }S&\s`{T2DĚ&SOWkvo7?І=hwF'hd8zAR[ɴE.3-(N 햜}z(,M&gg \J-w`ՎR1ܣfZƖXlv чILOU{Wyx;ޑ'c- F؉ &QwN sG#g=Ff$6젟 "ɗ@TFw&1GE~ w/D/J%@LiPS򪖁u<6IJbBnGܖX@L׫{HePf&b'M¸7Zƒ*0&6s fCwXf䬫z q3t?'s鱛M9f԰0:Y6 ~BX `}Yw…> {5r@l!N)@] NjcV_^ Ymt@VjP *eOfFQj{/[ʹFaS7q اPn)=!PX-$L `e7ggDN(y*obj!!:!)dIBV@86PmV_X6"7 dE b!&|2&^Nf R6E߽mA@rȚ_gl:(4%X+ڹPqSU)d/'™.SsD@: SYf W7,f;iu,ΒJ-X'fG3k:-KBpƢO ~\b}S=VhaYqc *)26Ұɡl* !4ƥ<5 ,^ÀֆKb!5M~cqr TmQFPe+v^ԙuJ!IQ#gXPe1\O@iMdn8 t,o)`"sO~G&Hgup3IDa<;;,%A j%&t93wvkKhI[OD{bb\SL +ʔcc4*auvvk;A!ӣ fbRHz,cr؍ xg7:86}8^.&6!>x¡G.Gy]( ?i#AG54-4UÕE?}x2 NQ=jWosv!3YNEʡ3J7?.40OWYzY>z>ĐLIukkWjf},(mlRD棓m`TO"Ze*2@ưBXT=zrS.2lZ :\ -AezdD[,?Wvnߦ*]:%B/*C,QhСdJ_eNp#LM@fd/ov7i" ?"S&(,[/xSssL^c[W̮K NJ[Ӡ ݟJk:Y2֘2˭If{n ӵ.*B@%#܇ĿĈ_{y @NUP>; zw)2+wj@[fYp*(Ua1'ZΕAN1aKd:?Ri;W!I8vUmQjGbX CE:kχQ$IYc CwY( d06jLꀤZ& |Ɗ%4\ݡ4Z7X=I6:.Iіvx0fѰu4᮳Fc_v( y OP8iۿڟ_/p_8gDjr<ZQ)mH?RU"'20:ǎEbbw0#2 u96KRT %qZQ1iΎ-d% NȉC4H؀113 d~ ũu*sʜdѼŻ;bZ2 0*>"dϣCS\\ 1RY歱q*ヂl3o\ӊ\ٗP!4~Jtt>H,`EFy) 5<@x'o0F"ofxc9KR!EFwq9@qa3/" xԎV]OGqytSG4VՔh+-Y{S-9%˽/՗_8~F@+@ GT/CpqDs'NDZg+cW0!i}E3C Ak"O<KCk:{YԩjԣJ*:H~N3_81,G=|"Jޗ^(<1|ok@m 睱(.xO萔ªjIJ]26(U*}f~bSW"*)P.MB.O^)E*"퐈nC5ٓo^ׁ|5WZ Kc'i!(>*jz QHNqF0"Cq_u2djC |m)U$;]*:%:^e[Xx퓬JX%_ XQIa Ri D rb!@N{cD zU.f7==UT)߆bVAi׍:@aHeez& j4R<0L&4eG˩ֲ,™8# #i X/DLW!.O|׭ 3D,ɒZ04XUk%p2xg;'Ñ<گ1xMWaX6ran>6f,q8y?((% 0[VV_uH++E!o*oa|Lџn,SO,]<2,E̤PR\[ }b 2aP;?>qzr02*5Yr6i'\&wd|_Or0bs@oe  3PWxu~UCXEtD*ocf{U_H{ ӊr rtC ![B,ԧuΐY Kۀj,_ݒbڨJnRX^Z{ŖoNc=Ffn"IɑUg~[m1pFT}ki6")~Zg*)i5h/,] >USvmpA!njVu0R;@A~g8hh6Z_߸$-WWQhF.!W3 A⛨زP0y~C 8pc$?C;@t!cQdk i7S8Ib ¡Q Q=T}%ˀqc-9 1Ifp9,nzմjPot>ת|rVDt)hS *3%GF=ʸo/ J IR#!IՑb|g0mVpuײGj>e"N=]|uiHYx%N)!،CVu2k+>K8+{FXqd&ԘLA(j Ɉ";W$rH\ M'$7k(3TAtdeHI3ҫ:Lmqla#>'#KmgB=Pro.1;c62 ddO4S<+ծh٠p#dR/M=]叵X,Zf_-0e9Z,v~ģ7t" /ҏl"A֬)2)N`- ٟ26Q V Ȣi/t^.!zsc^6/BجBCjؒ27f*$ k(On ` jB飮vd6[&9ɑꡃGJ\p86)y[3Fsm0N? 22'ȇv\+Mxt'3і/1>xt/ ''l&AzDJ-pdh3Ւ*ULF QfRhɮ*mjӟ܎x(l$X>{Fmi,,6afu&aS=;7fU#3ଖe*8Z,6 xvK_d@A &٪:+ `9җʙ3b q <7M ~T\piȐMd$CgTMi4.)^4ZۙQ{:3YOÀk/tD!W"oFx \qUULj:+WBp- Y-+Sdc촪NkgGjZ&$KTG=(4%0(1hnW(:>kfcÌcp vʵhM6"q4+KL@sf:.RDYN5!0rS F'Ib#kglE}~>*u4a(q,CM_V[F-SFQڈL8߷1:Ng u*IpU@(ƭ(:!Ug+r?Ftk,n̦VnY,h,4^5*6M/,{_~ I" a6Nt!^{_P!LGj,ih7GZuKniV)զ(K•B[1نy$2j4\yAf#7]&_@S)RiOx0 S~akrҙ&Sqy/iϬFi#_PP8yaWXf'fW$ssÖԠy=bwu`8Ƚ5} ;37tʘbC꥔(&7F:O@gG$/0( `_4 cpɔ-|bߠK\Q(ec&Qrv6njWarL&x%˪#E]8(Iߗ d%:{;3w"cت̐wCu'3hٙ*ԝUJn;UvƼOFJ0k>SnH wFJ;)3Ҳ4nC0Ro*LV,~wW_o%9tqSG?ľ5/Y4=Hheƫe!ٙd:}8[TާSwQ'=ER؂VEm-Ku<K;<8n>c+75#a{eڜj`FjksЃLavFNW_D=dLF tv݃[swc?#a7[tFhx/eFlE$VuPqޱ*:m.| ڴmvt)U=G:mΐq%•6*B[yRvmݩ: g[fӏH & 6e0paWqhԎŇoKhuilI1ŒeI2t#3ݻ4Ké<P?qn5Sau8Bh1ki]%v)Cͤo˱O$u@Xn |O~pr["{4 ]3#2fBpFb\ Bk6֨αlD q>{%W V#\9Elz^6pGOuDEss6T" -NTp;wgý-їAB \<ùpkڍk£a =#b8A(diĢ z<90uPFr488,PZuN~'Wd} 2oݝݤooojDcGCO Gǰ28̞89<<ꚢO u+)g+%|cV:`eC$Ga·;0TY~L#&BB/R* a!&*bkgcw(c$ ۙmP)QSKb 5D$'&H |johu0V&5ȼadAk~NҸ\ȸ J#W(ωMxH>w@;yUd%(y}Ig=ޔ:>h~3%*2Bǻ?Ea ̚]tP!#p|+b5'*Ol&3 %zdi)C $HfYNa3@SU|q|n&s` t|$_+Pxprd)a:; m "Jq@a:Gn&3K8 !KEvZ]1{l}vn#S^R">/WO4d69΀ *!7Sp2X(vEDŽ(0 ,@ RyP{FFwSTrdMT`I?rdF8I+[22{kOj{$-k\,E1)v3n%<\6T{ƒanWH9ƅ(gFk -yNb{(*'s8؈џL_eHa^$%>n+aĚF_i1w hyJMI £?6y%/q!͌Q׆)ɡ}͆m\Rэ8myDh!O ׸;,dNwbydEp+EoT]K EE 3F͇cslh*E˂O; +;mΚ=rttt;|w<յcP YOV.Q #t:EB!*Ol,2VHG'e.ntF'E,W+_7.)=x9bфPx <5 q9vnW2o&R/Entm T\RP74 F;"b WSmm"!-޼Ttipy8}v7t7VڢBctQƆ`1%:\f5uqQ)M ڒA"ǙuE\jzwG{zPp,2ufD"^Ohߛ?5[9P? ./JNk1?/?V94pmZmj={$B[5|3A/m&分cj~x|zr;E2; 3^7yuɗ-#\%qn:2([+>YJ;Kh?/bM=sdca8[CJf\Ìf=rn9㴃5k4 f uHUe[AC*H!'=ZU9R0?C:`̟l(G"F^-ʹmSBdt@mQpA/g7YrT_Fh^ Q5o gk"d P-FMl'1/~q"q)_>CA=3Mp^6n=^hr)ˌj<(̺]5:[jr 8i+DcM$BǛ0̦#·mrOЬO萙o*I?Z GQI9Hz|GԨa$PνDY! tVDj|~~d{G1:N"]p; @LBYr [J8IHtx52*T*5U ǶȪl&CVL7d s䜊PbQ^KAxks˾c }i^QTgHWΑ*u]<'{UP[ g~}{>蜳-4vNL#e;oHɞ#:U^s,?7e!NhTLXi\]D<+e9tcՃ||+qO)8 ѳzXJS۸Vc;Ob.E-LJotC_UC(0\Y»8d4+\}s@ˎ ;ǧ&nX+OIAM&\]qKW.zޮp.Hr8Yak}~etQ)s2)]5Vd\B~O]+҅p u+yݣr>zBA9v%VlSI6wu:ҙSG?ٗ*_66'qG]ʉ`naӘdt>WE32VšxTqvtW2x>LJZV܄fH/+E3q[*ف(f:T筟\_d6'<Ÿ`̄5@Nx!d1<:)`Pi;A2)gk`x-QKVŚDS>I)FjC u2űƁĉֵGTfP^'Rmp8{2 9|Du-k!׼[ZuSlFNFsGB؃= qͽ.F0!zd {Hm譔Vk/O_pVAЌRbж MBu*#)Y€N ]֕8ӭC= [/jW0h9#,ƴo܅ }cl\X?'&MDhvr-E& kJֵ!:d+G`z@Ĩ$4\(PzbL=iD"/ր"*i[BK`rvh+1|hoh|OrkgB:T X3C_w9Odc6dɏ4B2 ڗ3/&QB`R~(:*9`-a#]d9ablOSԼPFTdV3'WFzیIWgSXuC*JŇWA J'aUKEVF2[I`#݃OQJɰVxr2Vh09h뀜*p\:3s_HcxY)99'wZ:3qx~[_.\|c8 yv-ɓ^h^,'&`9ȡ-"@+kia,Vd97E2$M6jxX>ڮfh`B:z]e%Ri)^,YJR` Rcp.aẁ%hH-DEةw̭]wR-o?]!Zas0jN\ֲq0n'<5 hTiA}XZ݆)*5-EÛz42C"4WCݳqeT:QyKN oӝ/@1wzc[>imnh2\+ RәpMQ|­h?C:Xw|]-J}:2u /IlRЖWP=fvkcW+96a\!"z+C)_56MCF):V4 ;3=+;'^Ʀ*>\rhfxd:e:*Ft1;MRdnhvKzUH E:$w&n,93\=G n~=>.K6@X2IG)"nBIJEġt,)LS9DxYrxP<$=ZVҚH8oRT{SXހ.z?OA]By<NGo^H@ttP2_#ח/nCPAҡZx ip.TZ<j|u%ԯ[f RgZMs0xE4m?ִyI}6/v֏h޶pﵛ?µN_\/i 27OxvG^t;烴ug}(}ͳvgg/ߜo$<àR:5=A:ukcf?OǠ \7}@w{)kh6`gel6BNG@%[zvv/Ezz/xHgPLtվݢ b3mlZӗ;ӗ6Tz`uߤ//^NtW& U p{v 1@/zO=Lf:zȔ΁=uN?;H $UO/Y6\Hɭ~30a+׀h5sLZPW0O Р%9~+GzyAo((,Ӈ[$ɟ:fgK k o;^QpuH j$2* kHO/_Lk)^< yEӱwi6o*yd XZ|;H{ߏb"i[fRsLN {6>HM3_sp @_N@nA} = }).e+hi :ק -ț-Zgʶi$7|O %grѐp#zƩ3N%*)/  G{”O{ωwGi,8=g}ҳp􍗾 ,xC]xsϸ=W:940nܤO~r]Vƺ"nsڍB"_,Nqz2?> BI`ey{iV$< 7һP> b=LI}Y='*BRު7ЉPK.ӳp1V6:u v4 U^'7][$-ir@jNEbjHaDxL4&T23 BV|&KT} M'Zj>읂:~l\9nf%KϺl6 ئIʂR9p4u`Ic;?cII/T`vO@ؠ EoV@KGQ-OM Gc9EI.kԵ(S,ԛ 72n_PK ~AKEw )Vyzor-master/doc/javascript/searchdata.jsJ@O1d.4ϟDGH'23)MEQ6E\|ɝp8B{; ?ƅx/^wQGeeg"w=ܩ݅q,J-?!F8Bh!:]1{&8tG8GH.c. a0DA!.WZfr96t@ K1" > $ %@YclLX-Йҹ{JX1Й-oF@%0 XZjﰆ0jR*@ˤd/P0 '#œ^o'5E{IjqPK ~AVyzor-master/doc/search/PK ~A)%Vyzor-master/doc/search/ClassesB.htmlVr0+EilH;=e%# x:J&-8VzoyZ/tn_.|\`qg).>i~x\sWv"=O.ZXiڥij1Bo4w,^-f\;r]\ܵ'Bg1;YQdXV +(240!Jh ,1"hTh50~-Qs[W9ИHTLڲ4a67q2֬</A l"e-&Na cpͳ42$ь$>љ$ tDNa3˭%Qu@0E&T9d2+Ԃi^Ub8evp GC[ςu]di2ILL-YSE)S٦ H8"uyM;Ncۍ'kdĵ-v53)w'" 6@OR81@Xׅ)WbG)~l RMUUU6az^K6A2-5^1WuiVG-p&G.~˻&@9 X6S!: eExw69݄Uޣ T t wri҄> r7qg'uA$-a˛h NY7Cd-Y _ acM\Σak֕PK ~AR V%Vyzor-master/doc/search/ClassesC.htmlTMs0Wl Lc&i>hK'! vzK`Br%t+N0mIRҾㅇ0>t|;қ*)"@B5^`d:&~7HRv:K,f qrp-"[EM$)BYgTn=CMʹE`% H5GcRȒf{ODgA墠 }+:NJҭ`Hu-36jLF*/ :Iš @ EYjL  Ckp҆_L%ufy ,[=5؝Pg_~q}@lz%r -4S9&SǞ[3#+KсU ]sPh:w'%}ʧd,H&u㝾\/8$Ҍ 4qSn>d|Mm}i&v癟D-sUHFX@)n^Iɩvz5,gJiWRBg$9q9sIy_Y:Qţƿ)CuImrfME>={G_pooY@m\fDH|RWTiD v4v Z|;\Z9y^ȥu!oPK ~A'%Vyzor-master/doc/search/ClassesE.htmlTr0+DilH;=e%S! tl'NI[}o]Ubpݟ &7>}BA8=Bc(6OvŞd:]1Vg2),R(MJZ.m0/s OO<$p?PL~E-7)u |!I "kI#qhxnT;a5HqFBADE>T'锛BX3q(y(xp]Y 8ʖYh5\t'SIv[YA!6 v'y+9>fB vt|kj9E cj M Tbaõɔ͉6bdw/P5Ѝ˹j Q;y}Z1ݧj%cH2~Mgqgr78dZJ3$\aSNN{gۡ,h(.̼Lf6^/= SmN4rP"и)*?o-Fϔ6I !4mmnEP'6{j&E2 ZFH*aS="| {A{t ?hNG{\:VciUj~gǿAUPK ~A9h<R%Vyzor-master/doc/search/ClassesF.htmlTr0+6DilH;=e%Sr%+N0mIR jw8ϿOy~y볋QGȷ>!v!1$d1jES2ؤGQId03 ~)  EP_fgƛ9Gշ~g#BS "~"@ڔsX~CF+ Ƥ&vבJrfx鬶iU[ka5Hmd%Dj̋|Ʃ)ׅ0zbC#م,@UutL = YBgFs垥 > ިY~kx -uO[1r n{i3 %)0>5W::nhMLVm:ڍT\*BD޾>AS`1~ MgrsOUb}boBpXHŸ zq!tN#in9e톮BϦ7vp03 }e0i.3O1)jeG&Bbt!E >aw?#ESTstV:\>WBz}]WĿ)cyIMs%4dž,Rk]z{[Ppw<+G9@]\)f-|RTnk C@ 'vvfu/R0T+S|)PK ~A`f%Vyzor-master/doc/search/ClassesG.htmlTr0+6EilH;=e%lBr%+N0mIR jw_p8ϿOy~yQ>ƃv=c(5&f7'T OtR=bSCQtp8k(X1C=!Ka0޼Ȱ; (Lx=GQ3!ҦLZ5Te| "' t'")H/dMfM"ZS k=Ե,$-!DMd^3FTN.Wթ}2(8l ͔{.2.Va 렀f뇿P+S/acmᶗ6=OL0E (aLLҙ{ 51tP5LTra;~}Z1*%HPv MgrsD5"g2 frBiu ]مMo>"amh(*l'qA*8qws`瘨MNmCYZHUIޟ(/KX4NZ+\z q:Si۝S8e:Kh Yl !gx^h5~>tI"a_'>泗& t[ 6AGeJ!W"hw;OPK$,߅Ħ팮I _O,2 ] WA".hd1+}UB̛ 5}e1L$vOA]LNMF=xa ثQ/iA5'qυ2)kyzs t@)mh=:N]֞W7pqF? r >q]EwPK ~Ak&8%Vyzor-master/doc/search/ClassesI.htmlTr0XI4I2ةl9 tl'NI[}o]4,OGyqu ӛGȷ!Ű>!  d)jM32 ؤOQId03 AsB?冂{H6x2  qsb47H6: 0"Ċ1A$I]$u܀ٺk|:}ZEκjXMsD\bSNN{vqj/2Ч;%'HEqs t{ oao%hj5kmO?Xev`e{c_PK ~A%Vyzor-master/doc/search/ClassesL.htmlTr0[XI4!NOX\Ix:JL-X1,Fiy5d<l@p9Oh vxwZG/5q'(A2 h 32-˜!S 7/ N7;gA1 mJtʘA`,Z#H[cRȆ HX܀ٺk|[}ZκjXMsQN%4y # IEaM7˭ p7rT(Sdmz.XA!YvOuVL󩶒%'>jll:jQhO?˨}? abʘIl0,'IRv[l[O'W$oVedEfmU.y W [2tca"9iZE`՚3j2 &;Q,㙹J0z<ü!r%[_rq}qziuϿ)#qEtRÚP_F^mtUnE9Lڨ.UIrFqsF|?I^HP8NXm̏8 ^sZ{KYm4PK ~A/mv2%Vyzor-master/doc/search/ClassesN.html]6W( LEtm_,.a+F;-Wh&:wn"-}g}h|>nt^7ސ #(UNp=.vd h<{3$R4R^b^] 8s(SxXS0+vT(JLV , TɄ1IQ"6GjiZxp%e$RXe"2:Tjg:lx|BQF UdTDɂ*SrScċ[NQ]1\[~LטGU';TtBp9d:g@߾Zj<޳ X6'44CcɗhτLy~޾o1E82Z&^ JdAo8|k;V34E̎ ab6ߞD+C_MІ`"e4g%csN]3^.3vX2їU_jBSܦ)#ЋB6AVQvOPoq*v>XTh}),bt? y$-R̊P2w64jLH4g.n*kCFkj?h&>vIVGw6QuB "!G Un3:;ϸ-!F9CN*bdZCp sf{Lo-m@Hb2w@AsG:Ι=vEEv`i3,F(s^]c6QF QM Nse d 6IcitΐwtDi),pb|`"B̊+:3ϵs9 YL?_ɛ ݤn\JZDmx32uSHmiB HJ.a5*J g5)/\e189Mn*TL‹SYfB ~uO] 2- ~04pu]=g㖅lZO^,|m@?PK ~A%Vyzor-master/doc/search/ClassesO.htmlTr0+DilH;=e`r%+N0`޲z+?6§%Ln..G} c_O :pF{ HbLvKTOtg=J#CcwOǡF=Qef03޼̑@Tb0G<(J nw$E}" ڔuhohˀPj[4.:Rin@lUjVQEVkԽ,d\B$ȼgULQMM@f+}yG: %K~2*v0tRDB=oSXcxx` *1>1t, 1UN#o9ٺMo&D e,.S;X"3 gaU1LMN>xa  jӖWՖaEHbj[ӮM%QT8PkBe am5r&gxQ6up%8NUiT&>sTS( maO05,E j E9 eaÔΤW6bDh'P5LӍ͹Tr A?y{Z1j%KH}j,Er gb6cXd R%L}:4&IuO]߳Knk#aTt'etu.-N/\bVV9U+* C CM׊tm?YL+jp"1B֪}Rmcę3/qEQW L眖v0񩞃 U۫u=:^5^׬?ܿaڷ'q{ZPK ~Aσp/%Vyzor-master/doc/search/ClassesV.htmlTr0[XI4I$2ة\Iq;JL-X1,NGiqyGȗ!Ű>! '( \`d1#K̆6* MNwOC <h ax2c q343>O7PH30fohV˜ .:RifSkVQEVkԽ,e\Bĩ,挪(1s65).$4^UVl: K% ͔K~27v0Pa]B;kaSXcxx DsbSF:٥noR0 }S*uBLEj4JnRnV5Qt8P5zÝ;kJ´8sy1ۨ)q"@B s tӭ`spA Zk6pj|-ݺeҢ~Os.PK ~AMq>0'Vyzor-master/doc/search/FunctionsA.htmlUێ6}߯шts)$f]ǰ}Z"m+HE=hR'29s!9&oǫSxWWc@ !>2YM92!@;k뗄|xޒՂ,dg+|Dea1 SCc%-6Yk YObG6{zTo\dأfǹE` i$HEK'OMڂr-~{6@zL=Dij;B!1b̝4%eMކ` $(70Xku0\ _r]Z>@)+wKÏp;H]%r#̨m40Qy{M$_<ܖn;ƧTw*hӟ_,;[.qwr8dZJ3\SaYM tg/\X{5Vyxʧ$x[!X3ͺ=(=eIODCfpڛruBmMK;y |ZI$;.ozֈWq]sT`X`4ןl?cgQoŻ*ey뚣QⳫqqt<|-Pj)6:_MS=}2S7;nvvোD#7/w~xf4ġcVZc &g~aӧX, a:+氯vӮ/&S}}s gc@!2YO[<"d:Grk{ޒ, x;"jZ ah<>`T|I%C6Y40}^ ~Eq( {Y[Xj \M0&)(kФۊnYU#3:A_1k_<4hbITvTPc"PeUid,5%"4|W $Z ZoҪp[6@awǣthx'S8#|N)p=ߘdZAr9&*5cp%gǶN޹c|@m՘s _@kԡ,Ɍ};+0+s_qHeZR&)il]Iwԫx檫MՇ8Lp*J%CK~2(QQ98͸Q7[W%{_g쓢O\xjh1j 週I-2nUz36&$j观' =6Šz]), V| N6?Iˬ ZȀ¤BX--6@* rYB:+-H^+|͚qMK !~q<֬ࠉ%Rbɍ TU9\LJZ3EiQ< d:O<"[A/jkviÏDU[Y#~m[sqFBҿh#+ϟdzD>BhnE&VK\Fh^7/et*hq5A͕V9TZ5?u(Y\v9]bR!2-HD`Ҕ\{{BR~qWQ[Kč`+{G-Q'v*7C/U/ʟWg׭J~|w}=O]untO[nTp]Cyi{E1nnwH>M2SJ Hi#Wwn LQ#6Džݰz}ڏ3>S+~뭮ѺPK ~AH*M6 'Vyzor-master/doc/search/FunctionsE.htmlVM8ϯhX"_[[ۇLjP@)a ۉ,9 W=B*zZnu;|4z?\35L? b,B(7zEfX,fd6)FIQ|v:k挦qX2C.Ja0b[1I3a_ q Hr43чś/A1!m1X~KKF+Ƥ8ԉ**576OdM !~rmty"J"%ژ[DŽmnւ-TeJVTٔYlwT3RdoTy}>.T|ć@RUGK׍]6 zP&ϣsm ۱;C!t2!@,H}B'q$5Piڀ5]1e"oIr㉄vfoZ~q_mc*֡>]8FHسE9H]S{ "z`A9 )a~lX=kv};5|PK ~A` 'Vyzor-master/doc/search/FunctionsG.htmlTQS1~W LVԻ{Qd.+ 5ɁLPT}d7%]u'߆}4yH.cINc2wjC͌MFlFsGf3G$ۋC4E/q2!]*M]B;ǐ͹i􁤱w0(bZ#:Zf-ۄPj[\ѐIcp |g:fMV|Ļcu/ZZ!ڄ uQc&Ж١&Յ"!Uj_<@G^~ +& ?ʅo ]a"_n^HJ[_n1]B a]i,\+xC߽ ܆510:PjKykJ#V}j\$J}Ux4vcC2t?W#Dj#$PJ[c]v=f4G)!}:0a3(tr,9 j9?MrSp/o<^/ZXxz? >PIKٴJa4=g@_rѦ Ͳ!43e'z'ԗ՗'s"͕6LEn QZ!9~xgKnnPg;Vn9^DY-߶np\y&Yx#_PK ~AY,'Vyzor-master/doc/search/FunctionsH.htmlU]s8}ϯU Xbn~MvN2¾`we+Pf}% &-I#spu:5L?_\_ u6dl5txBd֖nt{F^Ō x;`<4)ONB4 |0 ^ j5^CUZI)nKn4/_^X:Q兗nO?/ܯV~[[Ѵ,/GkDpdh≂v MooCί@?]=KҧuǦinJw.l8O`t{y5 z%7Us!?Dfl6xsS 1ҮyElqbDBᒳ+nx~bn,W6GWYh'^@dpN? PAs!c ͒s:~MA|!I"+&X̂dj5T1B">x"nQ2KbɌ(l™cnriI#HUʒ {7~4<#1LõoK~&i\cF [(Lz`C/w\n].>q5c]VrRf5*$@NQ N:uwY6U3ڵϔazlS59wBհ?ϥ+/_^Bm\Z'dR0<k4 (ײ=s^W7Ͳ߁ߝ[*=ݺ!c PK ~A)\ 'Vyzor-master/doc/search/FunctionsM.htmlUMs0WlC`K4I;!@[:0@)# ˕dd;G9iޓV~;ɏaL0:赁x}?n3֙tʅb; @dk>RdFݶ0Kqbڨ$2461 | 8h88dL ƛl2$5 ZpWOG"IBm60_" ,B)+AlɓבJ21W|\ƴ ҍ xxAT: C#Թ0zh B8 e1j4=@{^2TɵF宥 cK{1t ~kx ;`;#!ih|Cj W;wiST` Б>*G[1vx{i3%+4ZgT81ކ;Gcc9-OyXSJ}foT LQ-PbY㸘եǣ\r }^qkS:Aq$ r*E>5q>r[)f/9 p}Ʌuƕ5Ľ谘 /H.3Z-EgB_O-ţTv].z-ط|gaSVhkSM@$TÊPNڃ-Zm^]nx Rٗ4ihLM@R{miy9!^^5H B{uc﶐ G|EzrqCᮡOPK ~A-~ 'Vyzor-master/doc/search/FunctionsN.htmlr6zijNL²c+IiW($$ݳ irm]-N~.?W'Ϳ\L{nL겹2aZ /dJV γ#,0(2DA4EcW|(4+: BASx- GAƋoH,J3i4ԷeRm%ۄI#"9oD%/5hV4etGMNɸ. F~5uE3H(ΨR!*x`ʴ#Qxv _@3A{ŤY!7q{5 gd![?tF'y^7qKB׬`jͨ$ХcRqQ_oMm[ap9:V52EwHJf`4zҺ$ ;DĖenE}(@uZȄpbe1hڨIRGf z+޾;Z;O}HHӌ ^7C|X"Hպ(NCl2Y[*EU$^VQkci,Wkyd&nLE3˶5OL n|EL2f./d[τ~2.‡<[X""XStD l^Iکjy۷&&f[]t@̋y0E?PK ~A 'Vyzor-master/doc/search/FunctionsO.htmlTr0+6DilC2-R! tlLI[ {?\ߧCr<v'dGpnx{3" ^jGQ<681 | $Pp|,&@L&(s w2G8J3,>zQ .b"@ڔ1X~CF* Ƥ5ױA媠+|:cZΆjXMsl6͍hw*l~1>74 L%L=:4&I;Ig׎͒jFCiTt?KQpɍ' ݠeLSSe/n8/Q&6'4<ߦ-wi >jo4v9vz\g$&N'4ˆL{ˠ{wzgӖ;-/QAe.lsAL2t<1g@ HwrouYoR\SĽXroPK ~A`'Vyzor-master/doc/search/FunctionsP.htmlUMs0+6!0%Nb-0@Br%t+&؝@}ﭤ?v&?=2u#Y[8qZ^l K :Ҭyh(l4|g %q诘%u0LoMȰC%UnB''(͖3d 0_",cRȊ&;OH%N" |k:.lZE9ޚ XAw35,drH)HS-GҁU4][͹+ Ԝi?U8苘=Gcc99'bcXd: fRLm:ŔqKyvtHaU'چ>-+q_QZ&x" Κ;Ian ɏYy]yJ=Tf"&s3]#ʹc-8׳C¶4ʖNwB >AXY%"ڮՒzWGpEjyh@>Sht8P.KB٦ɲO"*:zն7QYeDn$컡ħZ A>^m4Q N!nۺQ/մj_?տNOܨusPK ~A |[Ť]>.507wWhMŨ{߾Ap쥙djrkI9DaäE _XnheLf:ʦ8)1+) %z?P\(y])p P%g2e2@8WM U4M]+Jg3V k.ǥ8M*Rj ^>Ә౷ve1=*پ xM=HL5a/g ksn+*MbN]/6ppp(*Q ɌyoMqpH{ϊW&.&vezIx8vXwR$ncES0n;C04R~$UY[&{/hurM]25eQ ]8fd@:rݢ{t:ܤ?L5IT<4BS[(}2q9ͷ˴{8͕9fq~>G*AiS{A3γn{V۵x <\؝+G!oPK ~AwjEn 'Vyzor-master/doc/search/FunctionsS.htmlUr0MN'}ЖN vzb-Sa tlpZV=ik{әtp ۫~C!i\8mBzC(: drIc2uHy(-@Po4\݈wWLS|ⵇ:",4OyH{M,JŴw;|D'H=tΙW@)d aLJY8vwU T2K}k:)cJ΄JXIUtgEl}>+b[Bol3dC؊Zri jRi 3߀U*4ַqL?P?Ie`V:«Q}7_{68d}G;2)(VZljqfWy?lʾƆXJ̵9\^5Q NٯKV[H o\z\b{mPK ~An-Vyzor-master/doc/search/FunctionsSymbols.htmlU[o0}IhnFۘZn2K;(g'iii<_9wI߽L{qr~ӳ~P@ȗ!I8-Bz(6Gj«cLFd]1VԦ( jfq`{(id3I5e7xbjlt9yEq(dYkZb LaL*YP.߉Ch[T :g'j$] V=T+nP2SAPE>fT'وBX3t!hJxHigmz* UT琲籮Ā-3!HA 1]?]kTMWڝn>K<`G}p]mOƜJZ o~`I~؟r|պG3E }am6|k_/2z S&Θz'-|^TIO W5=ߕ$c$$:iIzIֈ8"\ ՖeO( ݫ]B]%1ӵs'EUg ;)cTC`阁cbe-nS_&T?^ln,GfEa,l\0셮\lUփ5x '+OmӢzJ^4A}5xw9:XzPK ~A1S'Vyzor-master/doc/search/FunctionsV.htmlU]0}_q/0n\?q>,:>&@5$5Iaݤ-KadՑs{ss>]u_F}0t w./*w[B6 ޼J/tLn+Cib1 ''_%,WRuJZ.m0-2 fOХ"QɋK;TTdzԦT0onijM ѤIyǺҾoF=e>Q,] aM/~ëvFpM]}]1`-T-j0KM&h!$Glj9J]S ]t5ڃS@d/+V˭7c`}6R4C' 7o PK ~A \,%Vyzor-master/doc/search/GeneralA.htmlYQS8~W&sh؞!n ͐"vk[>IN$;Dثok:zbt}_]v t,_xk!C!wf3kƢlF7"!.X >tl%u`ߵc"0PoNإ )(7 8Χче0 <"< D@ }aqAȣ- J(ab S"L2b߁9AkbkBAZ5ta0c@?~ :Uಖ8' aX砏EpΨ0ayl c\_>WZ+Wx*1A"uttW{?:w.|sK oBp&kYk <SDO'uBuVÛ<Y{Te/lxPңqJYR NaKq>= s\r&R̤pimC`0@[,e][!+@?PJtX (=$X+1Q&ȶXV;^lkD'^p^ڃ/Vԃ q)ޔ'R Oy pe $M#G\|}8fV UhW=0 e7'y.r/yeLF|/m^┃;PYu.TIm苠&`{@/7%:qc `9e8W T-f5໑Ss8LVN{p)of}, 9m&^eD8%_1NW;TF^E5X u?>ަ7:训}MQ?ž_ǘpOȒXlֺ'Sª>.Ї֭.Q8Ig&z sK{mf:k KUnsxVK%N[,iCU)!={$Ysjq+%7uP['OMZJwʌv3QMT< -^? cPM6THz yDTxN! f Z,{ųu(oyI^c}  ҔJVf9R"./,f m<܁6Ԟ!nn'i&noGbbD%?`^δbY+^]~3緟#i^/wƩi^AWGMsKs~o_]V|;5 {>9m0lk9R^㐏C_cqMx џж?(Ɛm c+0L-dm1 1Z_R&V&L="./ cc8%Q08l*! '1 ֫ TeE` 9@L_ANX60bB>!?MF"bz\Sı-C<(eo#'!L9ƄZ^LI%zALa+7 =9f3.t)K;0 ő`a:>.!WȤ"yWZYBr/)C//tsr-lt:¦ 712$ÛŅ128lDQ'v-o%>L-PDy7moCgI#By7d u90)844 ofुe:CI hlB^(QVVtk,QE;r!Rn_[+끆6R=Ki*9g59Һ|"!U8yG[0$=zD?B IV^?H&(uZ6B̓TD= U=ypwAψ'_y ;Q!uG->rS}~X34jUBZ0ESS=Va8B`ʘ9ۨQ[庱#亱nU"|/Scq䐱w˼l}[un ~KkȰm߼IqېAhja$Dc[Zl&_/]lKZlᒖ 9N'Uut+Y'= 2/U{ECʼ^_lYl#QJ4cK]rf#=CWCz-:oktTǧUD\r;rq# LsQF@w `hx>PW+S((A(bV` " 8gӻsX}u>t+ XcY,╍̹qnN~C2zo= @ A 4|Z.Yv xb9Bx$ hhQ b`\?S(@@вmG 9sƶ G„ƳǪO*}MJL)~zj/S/AJ5Nd Dӈkm_`SF/("",?{^5Ç4T7kdW0># es~ts(F2\Aїay$t3JJ?c<)ãjT&'] yQű͘q*:Ex6m{pрi!Pz\&@ߗVz|3`M*r~3 `)ȹ'pQ m]hs(ӐxOH8q9x9h 8z \Zʏ8$@;Uyr4qssƕI>mdHʶ[d&˺ `jVȷO`h"壇  5??&;$Vdf$zw*斜y>OR9w{\aK&LKH3(E!efqe[S6VwP QʭɥL}Wj)Aohuec,BƋ˸W4u$PE&C0ԭ}^րDPNh] BZ~Iٜ& ҭg IWQ8]c"%H/v78^lxѼʗ L-iܔ S&|kaJ42! fSex/I2ؖ T 6X د]PU&sVݩN\-0HO\8Ք7FF&?;Mf!GZb :tُn#S%ݚC&cgR9V<ɵPH[*"|͂Ժ%р1y Y,X΂wO7M?JDR~O'*\CB@K:ZT f62=X> ykH$Nc)Wd zQž5&&+xkv 1a@Cu6:maC.#;I;W6K )~\ ;h5Ԯl/k11TCXiV,;}a6chwV+ELď:^ĜTh4ERYM&N#8Gyw-xRh1o7)v7cEI0 zmuj`-Wi2HkCB|DZSl<90}M^a7 *;2Y?T j:(DSTmG7tw@l7}ޣzEcZƯV\,į;=:Ka o ]LZGҰD4٩)&Tg<+τ>ASpDժt^f9f>fmHRo[%qT/CvCaH*w>9p#꾄8_|*oV—y90>f ٭Erjiwsge[^&\vy>@V`b̩%ĝ~[ix{bj 46֮k"G܌dşPK ~A a%Vyzor-master/doc/search/GeneralD.htmlX]s8}ϯP i~(nv;[`wm˕lb `$AHGÒW>COn{w(M%]JCpuzMo :y^'IKI]\8F9!g$\3d;2Z'RSݙl2\WM5C&M79q$]&*\c0(|bBhDČxeitd Vl˔gjgcGs 4r.3l3\<2s&e1`j.s^u:fRf[@6ey ;AN~Fea+rt7JQS_S.mАd1 _]*)2E%b\L )̹ ZmuWZKTMի?5(3hv?J^Kq(hzfn0Bn6jog˽R~(m3+N4BQ"UH/ yʷ1:fɗȁI!V, 0ȤŮ/n@BJ#J )3S7!J9tyP͘TdfA @<ꮚ~+4C-B}F[!ы$[_glq-hCq Y.>4اu輼I˲ߝ$;VW#z'L\ 1ʹ/Lq)EDkpXc/s  HO8ڄKƈkp ~ vP,k:ovPk8_ v!߀Ƶjٲ3y:Vz?D;ھ]~6wVy{d(C@E0(.2uq~?JAM6hnľ:@%UY6.N!~ç5]1j(5u*k DsKMo tԫƁZetmEC .|&3( @&K*t?k|xyb+smbPoe9J^/a[/xQ 4]"Зs>mQJ-~|#BE[jP!q{m\EZְ>"XPR5CM{8>衦FG d+fMK*7v,:P4-m?E6lI- Mn.>d@Iij:AQd4Fsa'59Ug)3m枑"( b]({7ۅp`< WHЁ Skc~7N-]w&LU԰-p8gv ۖˎ(2;]R&8]S)XhjXpqkha9HZv>8fA//iaߊKoE:`[v/mI[@ ®e eBЂC)h-*z h7w)l:/x;2:a)ɣTÔtiTtV+1WțfQq'ܷq݅y ,L"sp wj|~XqoA r`@\}pE"[ȸ~R=ldZ=/+6i} ]OF>PK ~A)YN)%Vyzor-master/doc/search/GeneralF.htmlZS8~P} s͵(7@SFEֱ\&7O+9[rCh,~Үe ^?9E.Y}n8㻱xo9鵅EgZ٫w6esֹ=2|^bohu }w$ F'qhh(߭cb!O= <%(#o'  O! B %B?S8Ђeێr8lqcAG'3O*}MJL)~=Gj.3ꯑb· xB0aohtI?ǟa~ x@+NS/] +$g qC~G%adq 3aBv~tCDhF8Iјz z$4BL1:HJ)1Kp;:zaTx-Mlr;IN~۶t ( !!'d|B+?v4%IY4J" G.c*9N؆p횬dKH\iz^hro@ >ڈHW" *\)zl9 g2ؾg0^i9qx13xjN.{Fg7blC}]ɾyHz3ֶׇE+ >Igڪ{$&<Œ.d> l%RP"a)Fc’p9D<@N жҨn$xm[l>~h"Qz5 .mq6 ~4=zC}[Y[A<-  _ob,駢4JWg:LHKj^@;<]]/^ up;G{W ΪWRjihkF j5{m^fśF] kUr[{/ۦFfyl2vV^Vw(&. :Y+Tk:9y鄌By3K)1OU'[idt!\@;/ւ~[rEh3Xɰ/J-0Mxw0<t=,z*Am-s>m|ӮC[ +'3gH@Y>OFM#}.ݨF#LHffR%~l|0?ԗ@4@'ՠ͑;Qdn1rL.pڈ#_X ᭣_8-Ѵ֞X˅9qhRȫH.0ep)U\bWW8" )~f ҵ"-u -1&uy{Vv:JxЊ)݊xv>b* QegUD7ȂAu!)h/_cZ^:,ھT7p!\*kPK ~A_%Vyzor-master/doc/search/GeneralG.htmlWMs6WlCII$d[HJ:=i BRN{~Hْ#`c#v ^w'\wyqo+7hnLj^R%x2£~כڨ46>5Egg[9#4 px}eR&7Yg A\Bd9QEO?6k1X|F0W.DK# NXND%kZ]*J'$]C̉!,ƌx>b:F-5)n$!VD ;K5SrraiT_԰ h? ?CP LLamkc.`Fa1"z2dJR/B4#J{{Uir)\@ڟ•ׂ/Qñhl,FMT$Q[(0d̤L:#fRǣܿ Q@*%nV7eOdpzYlb^$q>%[ߥN\d2'.~*xltfDY9|b]q9#7H͖_C8 ˂ x,*1eR ت,<;}35wC`%"i?]cL9?z#TD(8 sH']i{D;5?*;v}v74SZ2>Djus#^ q#U{jCNQ?AMgJ\3 QXXY()~(pQ\+zeѶ,>d o6aF#4T֛z ߭i UE!jETgC$~<{K`G2riZhr=vVZvYF.`.[ۄȵIPK ~Aۃ9 %Vyzor-master/doc/search/GeneralH.htmlW[s8~ϯPՇ4ضil?h0\'F+,Wt}uqbpm"};:/:~|݂ ?owF0 RWZE\hݶ{R4R(V1 /.|# 8T`=HlLLyuN!SQQB*>zgi/P52TA~I A",a f섾D+H6/Ȝ%:UE=$z|x "F `E>DDɀʂ)얓8ν]5/<"T„ yT,t`J65 a񅊓)41qK}<>ь h k#%XR!S?ПonQq)`Q&Rs_BjyWd(rS@D94|IۧMjgC=LŌN,vDfJCTU9KMQNJGLz T{'@%gIK~&9:bY 1 /p}:z/,C~:r_?c|G>[('E3m/,[JrF+zt5;m,1 fC(sD>F|>gUnŴ|E[A#9r|Uɭէd,ӟ[Zr)6>4Oβؑc-=#u G#BXﬠ <_hoz,'֐ȭ*,H>1>%lwuxTe t EVD'2T%) KFuYn@%ff9ׇ1`,Tnm0>6SP?PK ~A} <f%Vyzor-master/doc/search/GeneralI.html]6W(E`X4I; >% %J2v߫~`6{{^둎4>_>u-}m޴:ymCJ=BۼXJɻ6JHyaxu_~J&E:]a5fPo DZO( I(6!rE@", zr"b<24S l% kPK ~Ab%oP %Vyzor-master/doc/search/GeneralL.htmlVߓ6~BQX~8e8IOl P*$WN9^hZJCdG`vt0>ƃ ,A=cژ-ƻ^#Vx>a?Z (TWW"7b0Th/)y%k45/09Eysה״\k֊. !L :W4Ȋ&ɖ̂LܓXQAba/, DNdY3JTR]q'V5R$)8|Ni"t2%w*.yA; `ۃi=h {񉪋UXAcEǍ\Z `LLW`KfRЏ׎[3#޺] 0MVR O:O3Tϴ?V$wiccXv.L!cLcC2NA&UAU9\$zVgz6]p4廡0jƤ.cA*AsZqyYxم &gN._ |:8@7C.ffu"yf6o,ʖhvn/·' xݣ#[ͺ`ߵ#"0P5 XX fۄ@H)o'40vFBr _" R?S8`ȝ- ! Ԋks!)^oS3Ǚ)#f(=df䇉eA-B̹'4I)[O$44wkpWQpz F70>S/db A;WP#Y3a! ^J"1aX,`Ep.Ǐ0f~t3cb#/:@K1,tz''kTѡs-6 բ~/eY6-"$`AOs<}.ѨU%ëEȻ^u* QPX%܆rFUSfN^ԉȡ*{󫣩5^!9aOʴI)Zk4ɕڿOܥz"V-_&abIhY!~m)x/;{N-tJz>I.<:oA RۮΨ&;׿7=RH5քn2dTfۚw.t}$1teOt(;&u6Zk/S6UݶV2#,,dB.-txsz@1}hnʸ.C>Ϸ~f>طtxX =ϓk@L^ ܃%x jQF'r:4ۿYy\HU[uPK ~Ai%Vyzor-master/doc/search/GeneralN.htmlYMs6W !4"$tbqV :4}{>n1#fgՅޱO0K)l;?ǣ\e}!yK/ F$ VT#L!\\fۂbWK(}WRCI4ߢ %':cx֔׷[G+&KiM|lJ㷿 HOJWyB#ƦwSb\OETy^+(dQ4g<<#W*{ QWیF[^ՙ] TFץeN ϡ)؞h,#5_ Y>j0\;ߋ49f{ނ& ^ Cdswi9,c#^ƦyYd n}|Rj/jϵ@unj]pEt\ k_%[GZk>tEɹE!G47al ?4v>t[,ԞHFbvK"ٚ8 0ۏ!qa #Av%qqPOWuSM]'tGTrl64[QN4ݑ7-c@fH7RVݹrЮdC\.$AOF9Q8;OS Fg oAђ.@':_W]Y,6ԉ 9o;P׈[~Z"$,8*ىc|sVv!#HƂg+]HjQHrG .$w)#),=nDp-H*`b%ND Õ͹ G}őR j( fD.\>+4j,\CYH[X|m}͐S6D^"%фgP\{V}RrQyJnࡧu^"#jV5sB|7COgU@͖Xw:z9p{/6zРPK ~AQy %Vyzor-master/doc/search/GeneralO.htmlV]s8}ϯ>cgP`餄ڝ}bd[wdddK sut? O-L?ՐbTOBhmLnwT)YlnE?i"CЈ3J 3uNciz9Mw(]ﳓϖw:JL.f,*C\^FT3"+xAK_j9V&:U= ˜*{y$kEw?1/fkcj"peDyf"3ާT< [vCz*.XpxV,z,]SҁO+, IiɄnNyi`}XI$F6Kȕ3i_µ {%1{;֥ݏ9e"?PmP&fCh \&k}9ǜ&~F}\Und: nK 6fu {؂xqxլ<ğ.ؕrUN=>qbqoPK ~Au2G%Vyzor-master/doc/search/GeneralP.htmlXMs6W !"\'tbuǖ5NO(&d^K"Q;\{Xr]=Ӈ{0|y7p_]M3G'뵵`1zr@T<1ї[X "x@^sNCTLփ5x -I$z^@3`0?mf8FzzPK ~A"Sڤ-%Vyzor-master/doc/search/GeneralR.htmlX[s8~ϯP eNc$mHwjm˕d(_]lXv>ws:ޫ˻47}{=x0@Je0^Vhq1Ǔ]{ oϰT E*ɉg$ *~~҇}*dQBwCE+l/@ BRO>+4T  PJ>!@8!,EIPL̩YIZ/Z`NN//3A)}8Y)bDe+9ȇ;{}{띰Й TtDS-M_A`T4G'Ơ+׹ԯGRAl D,7-4*:~iJXIԜ' 9;;{DjiDƣ:<4g<(GyX#OYL 4eFB)2EnPGSIsY\_JX;Y4yL;7,cNf<d8'Ouve@WVn"溿Z}hoZJ}Z֤ѱf]e|:M_~tT6:9ivlu/▎DOm9Zo 7#4Kfq,o'o,3")~$ى#BAZx],4N7~2f,eSXeGܰ싸8M U±Dcg$E$:\. ʒvqU,|?K܈extƌ YFUfuV_- kb_ OcѨaDdrSSdzQm?{sU -Q`AqY(;Z,$*:.PĤq_0ա7sPuI*STnkӁ[x ٠v;W,h%Xf9hwa2K/PK ~A6!03+%Vyzor-master/doc/search/GeneralS.htmlYr6+ijv:1ɃeqV4NOD&/@"%K"@!qu\}^O;0rywgJ lz8>r,Bg~">Oޟٌ8VC蝜8R9F1G@?ypa7Ze@ܖ e_F{CI8q!cYSZ9SKx hqtv@ +AaU2*l%ʗ W Hc.,|h=`' 4$#(tsySЙPdiBs11֒wƋGj3)7E OL!#öAW9.b)>b8d%,0e1I/֯ҶeL0:Rj -攒9iv0-,ſ•8toj>6LُәWoYc Mh`0!4=N@o mZYBc?"usPUB}`,Fd6Kpm |BOJmU>eO9%9iRdI0V5 :,< ~@IX&=t j#|cQI\#}5W*{#񱑕O#+f*VtĒx:'pkVp5|]c tyn2AIӜ cF~5KSbY )01fB8%d t *m)pS%-?rt ; JQ[nNe! P+UDx/䆌ҤR%ZJ .QvԢ6c<"ҺD-"=n-ϲ =kkv|QV0rk^/-ڌZYlȌ09>fT\G7ԌѪ3"$EflIU<M[)2*LQtW))3#S6Mlevnf|Q9_jϖhƨҜE[dRd%MZZ#cjQkZ#£kqֈZkD ֈ]UMËo WS ^K_KEMK8<,S|{bjDy8@?X"N_HR5eay--I # 맪Űd@$̼ciPvjM<Uh._'X>^n,V,Kʅzxp={MpA*ժ:pC({qySV!76gG*ޡ햗c.l&PK ~An+Vyzor-master/doc/search/GeneralSymbols.htmlU[o0}IhnFۘZn2K;(g'iii<_9wI߽L{qr~ӳ~P@ȗ!I8-Bz(6Gj«cLFd]1VԦ( jfq`{(id3I5e7xbjlt9yEq(dYkZb LaL*YP.߉Ch[T :g'j$] V=T+nP2SAPE>fT'وBX3t¬'G֗kTJx^#FE42YJ#=p{oV ǹH L谴1]Dd1~E0<+8+!qvC.xݱ X5SU%Z2!7WZԨTLfpKIΩ Tou:WMWؿb986Hdv]# Z/B5Ghp)l7h&TxwG1KzZhLyAXቆJ]OGp=L=ЏevgCH%{obbu@\ og1}߮vWUhd\ V2wж۔>nrm׌n dAk|a»VW3 0Is#z#7PK ~A=|%Vyzor-master/doc/search/GeneralU.htmlX[o6~ϯ`XLfm7 $`s׈ { (ʢJRv}%̓#|<^7? p=ۛ!~?x4ف 1p!ez`!ɇ3,$BBRYPzΒJ4~@ʅCJlQBI$O X.tfߡ$qpPMBłR Tӹ V /I"=9"q&AB('u$+22DVh`}YABpey6{*D2 Ko ]8}6O xΛ$ZP,ȗ*0hcI{ Ֆ * zb/ʏ6tt\RM+RN$ c"sN0b8+ER JŤV_MGF˪ R6-AwvA?J7iHcTu4!+MϑO()w@@Dd$P:[FмMlP׾T _dM1KUq8N )3 i%d[^TI^ϧQW%I,4NyZ;5%Bef:HFt.vnڹA"KFfe&%'Å|S= UU=)|n?fARӒI5:sD超ffNAq,a ʡua46¹. ƽf\vI:Qi`gW!vbۘlլk-im4oZ7Zԅ[ e%Nu6ڸYa3Lf}!QTEҗv&QGvxly^u<䕞-JeϓNE|YN=m`u{*!cvGdP1c(Jg^vTzPx {`qa?"ԎnTīSGԏ})ySG~{n,|PowT[/1PK ~AeĽ%Vyzor-master/doc/search/GeneralV.html]o6+X6VKY C#"G3$i; 0hJFRvܡ}lɚmIqsHG=9?yui8}ݢۛ!ж/{Զ/1s)\.;?ڏ\&S[H dGY=gNI9 )G Y*i*UF1͝%}!N}_ ~ǞGWib!W1sJ%F93[mDxyI4IH?ȂMp_ɸ.L-S!\<Q#y,ƈ.z xΫ$ޔ\5K0?Oa%$a'k4U{V!w}nh0( w !tMSʉ=9'1`x׷J[(*=&5P]i/&b8KPcwzV.% ܛ4^HF4􊿖e96xz$Ә))iSe$vhU3ᑊ#>7+!Eo,{Q*֘aL{^:hLYm96ŒiQ:$c6%1CxGE2`i$TAKş6x#-o8(ѡ͆CKhѰ3é3)Y*=ߚe6OkC=E%) *i,lSV}mJֵab_peZ-c{Ѧ {$X}-DiSE]kPAZpc?h=u[6ͩ\߻%HS=Ce!(.*-66(2|upv "d>~&hkO(UU[o7-?;ޏ7ث-,FGg.{c[?(uPK ~A8j\ %Vyzor-master/doc/search/GeneralW.htmlWKs6W !T'tbKJ뎭hD4H)@1j'=AYbڴ>~>I>ezO^u1{Nu0 [˲D+$Gxz^;Xic04Fh/&=gWLL{u S5ނ8!R1|~ Y@)S cm5,V Dy/ ϐՄ%5HI(ȂLɸ}4"g-;9\fA8yG81UZ 5"{p{_Z ϻsКIQ*&mYo*bi J5kA54 agS cyM/Mx2&f`@t!I z"V`Ť"?77[#9{*+gpΥXBAӹ}Z!O }F٧X4(""|l,C_YLHd1KSO9zڥv}h:a|}?rd;sn'1\dxnK 7` eFȅiNFL31 o6ae6`L2sufQrcIlߋ9h,^nH^^ۤYݴ#er-]%CJ5*+'M9o_B*ot P|݆цކ<>%w=l7$?oJ{i=M)wŜr_{##9ۓ5pS$lxZs$fvm(ϨF>~/Gy8H~ݥNb_V]ni{?Gㄩp @}fX&c rG)ǻ=mzmTrdT>s"$ }71ڽlrW/CVY1WAc]UPK ~As~%Vyzor-master/doc/search/GeneralX.htmlUr0+!fK4I;!@[: ar%+&ؙ@}oW+]7_'W0w8ҝtK)n @K3B6 ޜ`!d2"^]?mejޒ(VLS|ⵏ:",$OH{M,%if/H3dL#І_B,%cRȊ SS &.鸴);c*a%Hi1r9UGCfQ.GLe\ @$F>tzu983)6I{--0[k /j`Cjb|g! vn KE0a@u&)TH=plě(+(P%Lѵ9bnl=C-SG~?}P+l<kQio?NA1A3`&dĤ߆qRLKifmhz[{yJ;5DD,96a m|5<mgD<*y^ŶyfzES|kʅiJmC]`p`pEbI<5=gOOt.RTXM5+뫲mE߅ j+N< ᒩ` ZVkjTczEޏTIp1pG)tx5&k45 g0⠩{}|4o?˳\̬#v~anPK ~AI<%Vyzor-master/doc/search/GeneralY.htmlUr0MN'}ЖNB pb-\Ix:J v$)vJo{ۙL=6u!Y[8qZi\n $:Jy(-@Po4\kﮙ`FuDYI0AfX%+*._ gjŘF J!XIƤ5bl=%8)]2;qaS2IT bE-sfp"I12XJVC =4f44RlZZ'A62Ҭ0R{uY70]x|$g_yKs<,fj<թ"P'aRE"喌bot G0E7&B5{vSj4(qJaXN{Q_K w5ss!C&6s`]B0ClCGiZfKKt\r<[hGg%v^ߋ;Dy^y7` M4KEJۅ;/ŎhfzT Ξ%1Nx[=P6'7eہTū׾s NV:OxMS@@, eW^hN5E8˫6Q)]PaN3ayR7TBMAln6ҚA'? Vث~1^ey|ft=f.sPK ~Ap&Vyzor-master/doc/search/NoResults.htmlQo@ ){jŒ+@%y -˪6xMF+wN .DĀslLn| ӛ>̮b`_c'\cΧ s޶ߞJoxi-/ܐ.$e, 獂E[$G]4!UEXw@>w%\hޥw, ʢːڗhrDb@?`u|"EHA)M-6^F,{ѲxFJe{0&dswKZ 4uIfnS3PL,d䶳 kj j7̔v0~ ! y4#=.r|A)9<>rq{!9a2#%]bB QfMA_)sˀ_ geʽ%pC" ]<r+*bmDcLP`i`_Zei!L?eT[:W1hKUY#1ƭ* Wأ>^u䍺N6p|"jS ݥgaC5:.ϛh_rρg ε `@:|-}Pl.)$75o\Υ8^BHkGK*_PA-ҳ*pk~O"駝{;ڂ6;6wz.d~dv' Ћ>]-uJЊEf~]At)`%w݀7$`LOin!NnY{ܡWO[># t9 o6k¬jYwCj=;PK ~Ak^+E(Vyzor-master/doc/search/PropertiesB.htmlWr6}W C I$,);vIbB 2{IUR ...kƃ 0 K)ӏo6yl'þC #_@нյ,Z;Iiv)ϟ(Vb pAev%T,)H/`,9]8!;߸yJ$HH?ɚLs}U-~8[ `1KtJ *X% ͨ=ƲnxmzZ߀JM Hh * {W1Rʥ<>ӄr"iq-XS."_Я4@T*&]:xn炳xtzwu@ R)Q<$ݺaT*/GIB6V-S1POXW>SJ<թ'"ŰS+w2ONG TwAWE)DA$Ҙiw9 ]j(p@v`;kkQjU^0fƺͰnPK ~A4A(Vyzor-master/doc/search/PropertiesC.htmlYr8}Wڇڳ1ʶݝiNxbwZ_/Ɯ;pH,̼,|(!5žS;Ag X  ҁWoЅ ߄!巔IÂ`,2cpN=~ &77W{T2&);\Q|dt2;7tw_.%'OnEn$Wj$peH"][iL20x$y=o)N]|gE=qO H[6.1R8ŜGggRiˀ,&ZQɜ,?I1n:ZΦ4vW0aز 19zJ> ~@IkΖ q6R%>3˓DSDOaC2Yu{ ^B*=)\ciĤ RjSeS='̚t|"1 碔RdC]*Y%Um>у̰+ָϨ44&$ B^M.Rmaj|*4,!7zDϕnڧgZ3H]Q#; }}rWR>)Qܣi^FQ$1FDH`EWY|6N$U"Lk$( ʀZY-Mߦ`NMߧMYf.whj#<o$1Sc\p#2S8)呚롆jmGlHZ )5dpu  R%ExPe9c;a9etjjtTNËs[`aQښQ3a}Q֤@VMR>>#XI&m'L_H>:̱M: ǧ]qu~*^w,Py娿Q|}-U_D=-Ǿk4K&vu1,p@֒kx Uӣ^H{>79s~޿i"FC]PK ~Aq%] (Vyzor-master/doc/search/PropertiesD.htmlVr0+0%Nbi: aSF ˕d(߻ N VI]{ F7rq}1Xg)c26;cl\)UzF6趽˷-fN"KcwП \X_yH[V2A *gexьk#le@B_&OBؕf&%`_"c̴RV:9ORVBD:,HNs>gftT~t+?Z*^A$1,φh6&JF` 4Z-X7VQ>ǃKX ~,[k9㌄y^*)wm]bx"[x=ns%tTda!IT oIK Ǹԁ«t3|k4ZBJWi,~5a"ƸEwI: _J3-KccDBJ}Y㸘R쨇|M^>qPg%tS)*WMfc%Cg.0WZ6'H3=H*ɜS^L1z.b36j3&}@c烋OUu/ (Vyzor-master/doc/search/PropertiesF.htmlV]s8}ϯ>cgtݝ}b-J2m!9G__>w'_oo@l6-r[tO$SJ}з|&̔: )M#_9k_R)T,~f&.H-sUd1KxOTe ӏnn0N09x)na>%xl% jX\pjhU.M9߮ esطIRw'ul鷓]MD% mrnɸՙz<3{.Э15'´LtwQQJZxΦ Zw3OCD;V =>g[O#͗ iƍ`sG~TDnV痑_G|#OuV*}]wG=W9Gat! =va@q-0J&ԽH}ETCpM"SJڴlh\M@2^qyRW\^@mj=:U].bp{ӽU\PG7W>sk.]?PK ~A (Vyzor-master/doc/search/PropertiesG.htmlUMs0+6Dil4H;=e-lFr%t+Y+ҴzIZ?Gݛǰ_&W0wy|?ҝtn @'B%^b!2Qz24uF÷OC4د2[#f\{UDn 4sR*~ Y W9S)c6) l 98+"rʓ&,JtbJFބ-\"^AS4EYQ:b̵i_ hнF֋#kd3hNX*&mYZ;Q97KiD~-[[ Q|G0ص<>Mܥ9%LRb`@u)i]cX02~b5ccÛ(:PLхќI1RA>zZ1ͯJ%>Cx4ֆ좭~Ɠ C_i`*ddІ*hd0q\=[ SE4`RgL=*/gmH Q$VKm׿Ny+kZļw>;W [Ohx ɈÊ-B5a]<43͕.Ij'QY׌'^˝TqKn;i3󔁸:JMaM`ǽփl^\~/gvxMTw2jp"qSet~9AJPnpS=k=:d?:{ ر&&3Uʕ\zm>vn~PK ~A~f(Vyzor-master/doc/search/PropertiesH.htmlVr6+6!T'tbKj-k$4 H!@)j'^Mʍl\X:~1.>Oaq}ӏWC@!^ -Fa 2 @;Bv޽JbFfaT؍x3 jY''qhf)x~ľV|I-%CYO<0|\Xp7h&d^0S0fXoh1 n1 \b&Ӽ \Wt͒?΃&}q /G-B,+!ԘMUYsFuV̘5S'@+EMF7i"N-VZ >-}7WYq;-8; :`R?h%N' ݥ;{&ÄJS#S2m+~{ S12q/QfijJ7Z3O ϓKoi'lnM}.icLcKWJd”4s櫤y^J{`.}Ӷ"o/5ҺlHTj&n ,KI6&4=E `Ӛ66^~ua})LBׂ^ޫ죇]j\rM ƽʲMڄ״AX4808p1\kGF ؒl?<Ν<ѽY4e6ժdr"nO]xcע8HOC ?^>&> B~S&ڬpy(h i > :}uˋeCM7B}\)sS OtiElj9JR O>:S@~ػr݉phOZCGΧ?PK ~AמPr (Vyzor-master/doc/search/PropertiesI.htmlV[8}_}ĦWv\cz߫!Y?tB#heL!o^ad6!A/Zx!(kMyPp_uzR&L4V Aj 2!xي*Lq.qPH6ۂci`"A"%4֙╁eM,4iyg`Hhe.-d:AcYՔQ&Lׅc+@kI7j@? \ɍf-K2K0xa-|}?4{`[C)j_iԣ%,^({i a9̷0V%\ x߼t܆1"t tm5JP"iu:/߶OP='C鞱dj,GN\,cLcCT9SI2V4湯J}vyldŔLa6..܅e&J -;)va|6A靮u@VTYm9EᰃDŽ[K9m7zqfYf_J"Q &8C=ۂ='in]b1T3Pa߹&;gxڎ}N<ۘ=p}-Pw8EϚrӞv2F}s )CiwS2VIh I4{qP5izaB=gPs]t a]'>(uM\ p {tqЁes /ܥg2I5a!չ"R'fR%"w喌cR7Q:PLѵќK\n~h=C-SA?CX)l2hQvў~.c }MgLȘɠ \e42r8.fuiwVz2.{ЧPUX,8k-SlW3C OYY+}XGb3qy<>7C*bj'C¼JiYhEgL\qPO4rf*E*w ^hoShT8PKB*mkoӋ558ëm?n¨DenBO9H]S 5B9Zkkg4vWH w\qPK ~A (Vyzor-master/doc/search/PropertiesM.htmlW]s6}ϯЪ Xll4nIXv0ʖ+|Lg^&i 4ľ>\{}5ܟ5fwhCof;ңt8/>P^-* $]jЄؿpmwpÐ;<^y/SS̶((+fx[4b&WL %Zqc7[1xmG 4J&(Wzo~L+ġw|7M'Sm/iW !.6ͥ z(B2Y[쳕NXv`dƕnboQ[eT.b;L2BS`2GؑaVXZf)ħd.`T]K䂑t,`pͯjP~q8}A+H~S?ìw'yr< i ~!R=@R>ʯa>i8DO3Vwq;DK_6sB{SZg lkM:}hksq nLF{ZK34WŇ ^]>D>XF,Ds9]( y]x2/hsiZn;}3H!^Om$KUT;b)8J{]&uqH1,ITVjl,`r!|Pp{x ;Zfpk. c p Wsb y(ʵnA%l.Y7v؇n b=xiuzo|PK ~Aj!(Vyzor-master/doc/search/PropertiesN.htmlUr0+qh2`)0I(eڐI l+,INaw$m)!D}V]F1|\\_Gȷ!!ŨvBheLf7X,fd6z+bw_1~ 2[h(axm.@g_w(y&~b<@l9+ c -Je0&54yB_*+ p*Ғ,Dt^۴+ҭ5հxxEK$-Ĝj,bΨW3KnJ#J$@j?yyGz͔>Jd\bFedZ`C!Ꟶ42u+߄=LQ0TH%ҙ 9q܆ѪQq+P5Lӵ\*Cx NVLRɒR$.l%6͍ht4l~1>74 "Čs]b]AuIg7r,چ>m qWPuJB)gF㸏<uB0+WsfJGN;>,T_aELs BơaM&@yn 2MٱfXcnl .и !ġg,e]h Rr pu̷SK3qSHCFr! CH;1m .&6iըgGp@[:w>[g;-G!L'{$ˀ} p`}ֻ_>fw!  -Gn2"@B6 ޼B&d9'Ku 24u«+ZC?e4i /UP[nK ro&xQJb:xXBggH-g*eL#І"=c@$YLHfN kp6%ɘ?Yq3pDS4eU.Q:gZ͌4Q h:Xz Ww=Ao%F1i"r1x#3zȏ5 -yC!ߴ4fSo;n,V0I5a)ՕF"RװfRe_70ZS8Y5]')r$z_'5P81[pIc}b3X 3 bFӼ4뷮;g+?΍hڀɸrOH(IQe1xElx[O,;aT&#x,4ԝ6_ :Ohx Y|hAӜMy"̓&!M ;Xhja%DގjЙk^W':Բ]R$ g;}|lWݖ_TC;?j\ۯ%ldE}m{#?稩]O3g|_jnKѱ溋-aѡ2TG)ST@3lMjC ׆4on8T6@*ts_QJd)P@5 {C1=몛3v]|OytySGK&}PK ~A7 9s(Vyzor-master/doc/search/PropertiesS.htmlX]6}_ڢIdm?,.a0iOvb,G!4} `{}ص9GW]}dè?/ f3!4C#!m[{ҦlfS4HW=a"͍zΚ "x>MI5eP/)"8O9I~$.b" _!YжqBk8 *+776 (M?*2`bYps 'є<|"!š ǃӽ:yfY7tn9ajYkH|-޲Xtx|ޕ8&13ou \oIJ$c3 -c_(l(eLjtJɹdt r^+P?:8tGiHx/$Aq򊿶m;Hzze!an$IxSe8 [쳢s?GT" Ğ*!.3&:W|QĊUtT3Zʳd%91eL7b+>y\0[350{މ~/PZ-^vejL5ل頋 Ml'cxf7TMdv1cuXڔ''R4Wrp+il[,sg,6FgH#b6f)%`ѿvK!&"2b+If$:+,\.JGSo3:üWǼ^\[HrnLDƪ(:YN)skHM@KӈQ{pq"N̵ݶtGrC7:C4[߆ߠ/YM[1pmx o\q2Bq#/8^Mʂ ;aI4␘4T:SE.:<ū.bU6~**:lطM-*0+d;Ue{d>~q@5FQ qgPp|(MR&(s O2G(J3.>xPT|x)9 ci Ql I "MvבJsuA,L7t^*ҽuհxxXe)"NTE>gTEɌ=4dxSY޳IW]*Lg,"[E~nv 'EK S,a;x|$*uc,¶m ݘعL]NTe<|{Q N+hhmѰɲ=Vz~]}Lkjp"1B3oi&m#ΜyY.jzZ_: CljO9JP5;X.:@ [9յV?[[)Wy4ĽTr/PK ~A!DZ|F (Vyzor-master/doc/search/PropertiesW.htmlVߓ6~BQӳD~8 u7yb-Ra9 ]Y08Ixiv?*|Н|[4x}{E8MޤoI#Y[t^NFt]ʷj%Mq|q:ifq!R"U &c]-j#^$cp}~q(E7\F؍&bd_c04GAtDN&MEadd VleF'3<?;XXf*ݠD2c"v㔁c6ɸ ˚PƼ0 nyI[qT SHpWlj9J]1 E(w]ܔ_"V0l/[ѳZ o tzu983)6I{--0[k /j`Cjb|g! vn KE0a@u&)TH=plě(+(P%Lѵ9bnl=C-SG~?}P+l<kQio?NA1A3`&dĤ߆qRLKifmhz[{yJ;5DD,96a m|5<mgD<*y^ŶyfzES|kʅiJmC]`p`pEbI<5=gOOt.RTXM5+뫲mE߅ j+N< ᒩ` ZVkjTczEޏTIp1pG)tx5&k45 g0⠩{}|4o?˳\̬#v~anPK ~AI<(Vyzor-master/doc/search/PropertiesY.htmlUr0MN'}ЖNB pb-\Ix:J v$)vJo{ۙL=6u!Y[8qZi\n $:Jy(-@Po4\kﮙ`FuDYI0AfX%+*._ gjŘF J!XIƤ5bl=%8)]2;qaS2IT bE-sfp"I12XJVC =4f44RlZZ'A62Ҭ0R{uY70]x|$g_yKs<,fj<թ"P'aRE"喌bot G0E7&B5{vSj4(qJaXN{Q_K w5ss!C&6s`]B0ClCGiZfKKt\r<[hGg%v^ߋ;Dy^y7` M4KEJۅ;/ŎhfzT Ξ%1Nx[=P6'7eہTū׾s NV:OxMS@@, eW^hN5E8˫6Q)]PaN3ayR7TBMAln6ҚA'? Vث~1^ey|ft=f.sPK ~A. 'Vyzor-master/doc/search/VariablesA.htmlVQ6~_QӳD/i=s4s! t[gؒ+do8W}ҷڕ5؟3Ÿ0t0M|PM=BcheLf7oT OtV&K6G&FՕﬡb4  P_ Äۜ!hEf&4~WP, 6۔ci`c0&(̈́ T$MX]Ye**A_r_T;,e(Zh""1Ք"5zbH ic9tOn _yRɍfʅ 2*2Qܰc- ?C~uoz11۳xS԰[SS(@FLi.qQh:PzUn-磒* :oiJ)<F"f†tf,FI}.1 }C)T1SA":rW:gG=.R/ Gh(چ>=d#w ,ɥK ]4fŤbG],*ȩmixp 2gR"B ;f{!PRygmi3k)e9rn%9DSDI;z.Ldڲւk9}OO uk\&4puJ{w$IYuu=հr{o.3+uMȏv8v_X0oEB7ُG9X!=G?g<ܽc@a򷔄yR`G =`S@Ieт4[DdЎOų,,&S<{;d(DEm rf,jE7а6 p 5E#)j)嘳α!hf1hikJJ6?4˶C?Fs5QR!@F56+w8 |W~zmFJ2eko PJ߽)cwognzPX{vT${KWG wԫ^5թg癘5ɗȉP_m#û 4fkA{amFww6؜n`Oo/Omˀ̨ 䏹C~. 'ò: [0?=62 (D %xU2Zᠲ$*ٕ[@9rFϪ j){_. _'fsmP> EߧPK ~AqL 2/'Vyzor-master/doc/search/VariablesC.htmlYKs6W !"]'tbKN-k,94 L(@)J'xQ$eM-vowk~8grgw`xy{3p`h6 3۾CCl;Х={g64z''zNQ9+o]8$ ̶)ן\7nK 2s( (]6,ĘC1 Ʌek%{Ē+|(YfhݿMQ_}" H;[Kă 1b̅f#e1g In \8ݫ^6y3DOd0ig+kC#{ u J`B7G?~6 ⢖"<>Sq[0F<(#SƔE$YK[cQDplCkD d4v{ggkLQTI+>LarQf?JkYc Mhc 4=>c"_O)  ,s_*7W [AE3>Ead2ƛG)r(ӈ.ESDErv 96N#BNr$Pb3|F&, vDFsג=>Tdaa/QIVa6+S C[qL>ojILxILMKcK@@}$›l 4Dlꞝb}]KqGv{`9$BH$*|W[3\Ƹ?_M};Ci{~. +e\__sEmFMQ\6Gr]m|ߙzfs-8 9 #1meX{{/q׻0 ^?*\/nM7VkA7ƨ.gnĩwϞ32 ݜvb9_8F5 *^$J, Zuʢ{t*$;%AZOO"w3תh?XX((fՏ$ AmW>XQKa^d`hޟՠ9E[ WwOŘe1C1Gc`ĥvq5A=(tMЃf [Am]M/9hFT.FD沬+*@?ؿ8^ڪ'As5Soގ-'r/?PK ~A3\N 'Vyzor-master/doc/search/VariablesD.htmlVђ6}߯Q_`hf2]nf2@ӎvj,W!$e)lKx=!:poo@~gl0WpD֖?3l%Uzf6ԮW=fK$]4SEm) $~+?[W\iwyV Z1vKJi X7P|[n%MB΋eŗ2z|cF'5|~r8#8ZJl!ɹ1*$HS֌*n nQ`q,.tZmn[UZЍάPd_sh%Ĥ{M)0w߾1Ag" [q[i@%RL#6V>1uis *G^ZJ&BqKt21n~V,R2̌C繄BsSsYɅgtr'dpKPz;zXXCoE1QRxl;=6KkD쨧\>1d<k/v9#+8V}7BkޚD{wӚB#>77OkCЙug!}#1=&S{?wcܐY{=poh ;d>p#Ͱ4&{xqa.ZtH.)sH@9 ]s @;!)h:.Gu0!;)kst韮(d:W|PK ~AɈ= 'Vyzor-master/doc/search/VariablesE.htmlVߓ6~b>g&i u.Ng:{1NJ2d0p\~߷w<|;|swQ>٠x(1kJۭ}KلN}oeUjIHtu(X!K`{OmBҗ 0l#ཡx)&8{JgoPC͎^!kX5eH|VFt2ờ(бr`) VkZ%]*gՊTgYd1gZd,""SjF-5)$KB2|(GD3ϻʖY(ըܵtK"bm/ߪ`IKÏ03M'SX=|J)x[Zޡ@ &B1kؠҙ uGЁҪ2lc9JP-/<ƹu -Jb=.Ȗgԡf)W c9>d$3PG# L;8R54Þt n1U&9ۅDH-'0YebT)U(_RBt@ rdfB_"+`$OK/% 7&El!s_Mv#D<@̈,x=dJ45<$ tѶz ;V Te0h'2E{Oݣ=E3)4|1FN4(SJAX-29 }eb֎^#`l5J ( z'BmX)Y\ [1L4B>W$bD\$TSdAb{I;vu6ԋ*c̓ Ohv5ΕB4RC~:LJveJw7Oon"R}n "t&,|Ls;XR]J= MB*#j%ȦH-Q41]ԃz&nj&j!3d dH@ki\4}yCAC~n5 s?Ie;/4KOB|N+.h*̍j;{羵&JLN?jc婜?NMZ4er/7(uy=,%EJ^~Qtߗ`oR?fO3f`jCQZWiAݬj72M3t{5*ڌ>6%,‹|n{ v`R{4^_}zzmW~awj =:uߞ8rcPK ~A6 'Vyzor-master/doc/search/VariablesG.htmlVr1}W\ mu:-e VC&YpuwGZds9ܛ{!|һN>~rqë.OG]Bz^8BhnmjWGXȨ v!;X&3P|p8sp-<]F")BO Sm&o(E*"B9u`M0&,h*ġItYTr:j$}q["~r}o ]+_@l wtkj9ijsMTbaɵI ϭޥc@`.V ȵZ΋W[%ӽRRIƿǍƣuS9OqH2- SQ.h0SF+v>{g?K8II 2)cCi\ S=s~Qq !tuxXRuE⺰ߦB_^>{ܣ]=w%_3YyKƨ!QLI"k_moԽ`a{҅bhܳ[2wTD65w@]P̹ eM]a\[AllWp_p<-X ՗j0KM&h!&'nK]R idt1ځC@?sX-4Jҽx'PK ~Adl'Vyzor-master/doc/search/VariablesH.htmlUMs0W, (0 } LI3Q,56(ߑ,IBi}{/)~4>p6p>O'}BAXx{ GPnmf7'X%Md؏r{X]d3Pzth眲4^qK#* +iѬ.9,dwK<jm2^4 [ nr---3Au0&DVدtQZT.+{3:kH_\(qPB2AIXU9TgJX3vP%h4lF?HGQtT\Cgp ?ʪхb}vnR=K8EDѶpw.=w\rM-gaDm16x-ccdtohPfi^kJ={a)`ɹd{St2cB.1C a4:Aƅ0%f/KO'W9LJ dvCiutەׅo5Һ3(2p z龃jw7zP"DŽ: nܰVܝ[K-;SXBv[Ҹaߑ}9t#t烇'<ܕ|dIi3ѶGNf97HA;l Pp[Cpu79 A]x'f)$065`v]|{A{t _@Βp`u\|ץw&{e6ʍ5\3c g[7PK ~A%4  'Vyzor-master/doc/search/VariablesI.htmlVݒ6ߧP%NiH:b%[v$B;y~'  ;HG uG}fzFo]J~٥7ՅWCiN-t^KR% Rg:X-K8 ]o8̅e񥒫w etS )V|oP2mO_8̤"l&&bdc0JXDZhΤ"&Ѳ(cjY޲}F' jXMxFe^ J2fLGEYt2kF Q #:eXbJ*,.y=3CuO`t{y5 v%73!?DRsB5^b!d:&~Ou25NtV+(HM`42[+rrO7C]4{/ NTLӏ<d{ɥ'3I5K`!եz"VǰbRe"݉֌\Gҁ `\%^s bO, yMm8g"11(t̄L ;3UAcwMjהvyғgslbY\dKm#ueVӴ٘+4E ]9O3S \4J:ڧ. 5qT4P/kBݛ{d:̛fx.-I N7!Ma}RWTBp 1r<Ԁc@vr^n5α}N[4t}{Eأ]J{^%xC:ᅵ;JWY&J't2~[LPcuY; gqg2Zw\Zo9FQ kK E {7"#En[,kZd F &V T' }4H0,lՙQIG"~qM;ft@zY1u.]\M1-77q /0nr6#qjr6p{RL+HB&ރK݀ #sQZpޜ3pwz$+5AÙ̧n u3PK ~A~8'Vyzor-master/doc/search/VariablesO.htmlUMs0+6Dil4H:=1TH$CN{%|eBriծv7~{qmq"=j3$CƤ_YVxuр :-onIQIdplbj8Pp|ΒeZR&7S *w2Gis+Z5baLJYD` }$5etƂtIM [S +GJ]LdCĩ4Kh>`:FmhR\I׾)VƋ Ւ)'J4SZ7QW*18Y;N;bmᶗ6=K&0ɡGM(1,҉O7v 55^JOB#ѝhoÙ[^ݸD \rHHa&%Uwu xk{\־72( 9zJ>qBTPK ~A'Vyzor-master/doc/search/VariablesP.htmlUw0}__&>x66O;jIjªgI[FQ&%?MzQ>M/at|1Xoګ&NiYcl jc6wYJ"CcwD Gҕ 0޴Ȑ@Tb0G5*H/W[3#*]v%is%W4hu:޴L+$q01ކ cXvnJ,2 3bTA"LSb^KW'Qi"}aT|Wĕb"9_?51W [7WRb5iX|c*0*a)f΄yp 'yxƣ %mI6"g[#&6j-U|抯p7DRYa)%儕yqUwU)CyMD%͚PR#Gw!H\kk/qi2mi,E@Hs t3W!al/k[dB+ˆX-;̵X~seܽPK ~A"JТ 'Vyzor-master/doc/search/VariablesR.htmlV[s8~ϯPXb{il?nv>1>Fr%Jw+YLHU _ >g-#P>xCzG1;J-پ&Ret6a?XuGQ<1$5)/.B'4`r| f0J.W(Y1Dg?p\|A kA FkX5F+B]3.:Q0(g"+Ylæ^UR>[WG.|, P3# эH[l:>Y\'jơaBTC .Xbu]ҴS:;d,i 7Ca.Y݊z}Bf2rܳ{ny!eG墎}]'r]HaM}\A^2/#ί+05/{q>暧𘹩?פTf}@r&DB B@dCE 8 <8 t<6CL?k`cYh 1lJ0"D{#S\KYpe#ZwcI:Ћ^ J {SwG81pK5=J8$as 5.bF/4@*Z5K/&Fq.9KA ՟ %!ȷt2 #^R'"!`xD!IPo"Vy\J <\Ⱡފr3Z%xم{.]$V 4_c/c]!K3FUR}KNcWF?vNY\ͧ>Wꛚg+=ؼh_# ]kҘs%h=hX]-$gҫOʯkHuKRsjSeo!uʷС~ٜ'K Ӆ_V4:IVڌpr5VlTu!K؉X_isJГV"MvW9}am'Gi2>hS;5SueJ Ԟ?%'':Q;܆s@KG bea>A>j*WV\5U]U̶ .lCmtNHPK ~Ag(x 'Vyzor-master/doc/search/VariablesT.htmlV]6}_q>k&iئ% t#laɕd2 2@:H{>\ß[s{30!coƮ5cn_R360XujybijS_\+8\ _o"2T i+>YW6F8,r/hQD]!JK"%Xĩؚ璺84K Y37|mF'5#<?:\x_*ARpc"2QeUj*LUX3AiJ*Fd]-niz5z47ew(rup )@b:3G:r Ľ pgޞ1޵r=n};C^Xۋ{ PK ~AN$1'Vyzor-master/doc/search/VariablesV.htmlUMs0Wl Lc&i:hCH:=e-Sc q;lLd{عjOp1krv&3EHwZYVxuɈm'ԋEqD\Jݐ XfCmhhg_<&x~Ȥڻ|v>"Q$=tsrhïhRBg˜ `Qu/TC̒yʖl\);TJr \"R4KǜI?qZ 4 <4\F{8 S)VK{,M?[+i@n- o63DQqVBq64| L9 $#|uK.U$x[nŨULRM8ʖhΤX@&cjh>A-S^/ =%6(iO?J 402kX7j (f=[&%Z,^72.,8e0 8cfrn6e\Zp/"5K=ĜAÂB;NT陸~i Vc,E"$P_9H_'z{vx.Y=6ߔdհ"T>Y/*]ͤڍ罠gh8TCH8:M|g'u$Ճ _7].Y ^xFʅ]b{m|PK ~A;wC!'Vyzor-master/doc/search/VariablesW.htmlUߓ6~b>g&ip@H2ybJJ2d#iWCѻt -naf(!!!(*! T:W%dk͚,fd6&7b1_\A%,O7Q[mZ9\WAwr#xEI.{#0\fȺ!p kgcȆ &OmaD@Rg-G5EE,?4C!ꪮ朚q[KgV MFUy"I.=VF,7ZEwF8C)3twSx|J$1pK\qCgÄP #]KrcV UNŨhݱtfn=z@5(ƿ泹Z?8%2O]I+m7 .hm]Ekv1ρz>[seW3V󔶕x[&xk{/$/@1oVZ8%~^pE(Bo*|I *5š~Է 5k[ˊ8O]!7?uiNI~'.[@;:3X(ΠqCKCm>n&+fV3BIs@\t (b*\?/6{N4 EOC-) _) <~QտcV(}FH}0),~;ǸH4]04K(6<]?yQŸ^Q&DB6I@KYq<f{˔M5 `#NU}S-L z4KF? o49aϗ\jTo@gA/ 2/}RϊۙCZ&).)>n|?1ؽ/3^g_U!dPZ:PLDkZÕFEϙ2|QY74Ůz(?-b{!G+;1yBbWsAF'l DrrC϶V>)L /V+w*CTy.G/hzM2 k 7hT vy6=[e+"V79:ECjV!cK|hM@<5Z nz؏4ZzózddTd& LN9aЭ\Y?@!k5t[KveYN%'?MCA,G yͪy<r\u;\IkX4 \@YM~w"c|5 qH'\i_m'IpXpk/5"+@rZY\}egpO5whXKNX/t'_& VsAbe '4-vЀh7l_DF=ԀN1:$ ݈MVp&!h x[D !٣i,+1@+" Qy7^(%-f0B <\ j O[=,]C]U%"v2ŰyYln:=QïԢ6Rzf\c#۶%01Rn [ʜ*Rz>t[`YgO s>=@v bGI[[ ͖ex^b3/R$nLv9aZ8H#;iI}xGD:.Rn`H|U6Z1xi4)ԯi[`ravdSgVd74N;V!ctw^Y߬1ҪNMJ `(܋.z蜿 ?Ɨ-ۃ;ueNٛ8lO2GA{ܐ[AѰb%8xlm,m*ZɵFU)eyn }rd\G0\d"Sa9ծXݨ0YSG)M[Aēf$Nƍ Tq7&N{);C:<@gW7-GHuu7i+-pJJgи?(9G\8%N%Ϊ=)Ԭs9 m<3KT"U,@B ;;k$33%oO^Tes޳9#Ih/0Tu뫑J| :/lOC.o]I s~$E;K\7]q+_C,S̈́D?#JYVe2)n=oW;"Aԡho<\J"{Ygͫ5S5qu75hiPG$1& !1>=>o`[偈- Fj 0Ɏ`k4w*GNmJNDkɅ^Hr:6ҷ)< N YScB'O:r&dP">]yP@͕T4tP5MJ3dD͌?`4'Y^T2i9OEK\/z7B-9#+% PmX`q b(Rc)ǚvPalp+G寥x.#A֎y8ay4sӔ죺L]?lP}kNlNpȚ#<)U@}: X^2ȷ=AB4& ܟwtwOW`ktEطۥE)qlSe8;[0w/[(.״tU_ՇXYz9d3-Fln;(}K,"]ܫőLqcgo'0 Sg>19y` $EgЇL=`TLoY5\u2cpn/#'@R̯+vf^,SweE69 ^ߊ!²f5^gJ 5gF̚o2Ff:ۭAAҸFcmZ5;g7g7ݦP$lCPK ~AVyzor-master/enum/PK ~A}5Vyzor-master/enum/alignment.lua]T]k0}~%O @@cMᏛDTWd֕SM&r^#LS(p$˸vBPmSVXJҤ70nc eϕwgm9Y8e84#ghYGrJLG>Y,bz'uԥ0`sJvp V'nnJ}UWs4wo?E9wPK ~ANS Vyzor-master/enum/color_mode.luaKO0JIpi[[UpA&Uߝ$lW=5'g~Nͺoa.:w ~vTU8*&p.0噸S%tP#os}um>n6̶䰝+0RRå8rx̐1L8B9E4sNr`wK".p zmP~}`&DtP>';D)c@MҔ{}%u[Knas Z[vAq+K,TC[9)dlA7+PpP&^^ƭ] ]ÞAeaAJ<گG5ॾXU_$&u ᑢ补Wѐai״֠ }0t3Mqr8DFsPPK ~Ay~}%Vyzor-master/enum/font_decoration.luauAO@ ϙ_aJMp mAB+mjHdDntۂ%>.iُmK^:BUVzy3{1-B^ZԠNϡV>گye}Ent ]n'<'ˏ`/a@z0J`7PK ~A\'ga Vyzor-master/enum/font_style.lua]Ak@_1`b1Ԃ Bm B)1w'w+%˛ofޛ(×x$iV¤"3bMл <#txj9T:vZ#L3Px5Qt>6%Le3-'uKeTPW[]%-2FVö804B|.!SBJjt`JFcsc,D0r0h얷 RIn1'L)eߞc#OK%wBo  uPb8ٿEc>ŽhVoZES?Yinoyy ɕwq݅s'ZY ;BX]PK ~AbfD!Vyzor-master/enum/font_weight.lua]QO0_q'Hئ<.b 3&>bv֮s{;X;ν4 gf*۠VDn9X:}^\ab9Qz^J,R!A#m3IuiC9FnX\<0QF`{O!A '1V}:Nb쐀'\õPX6NhU6;g9 EHA.n@p)LhYx0v7"9I|v՜?N"[-_OIƞ b-)J^I,\s|/PK ~Afdp Vyzor-master/enum/gauge_fill.luamAO@_1 Zcj@bbJ;-nN%hδH{yۙ7 ӷu#x]*.dN x|O0H0xB"] P)iZHDe4Ж,%Z`5fR&YQ` ?kp"}ʓkM#xFywŧ|xgP)oѤUMUdDeۈն,sߵ\{)1љN*%i[T僔ϙKuy{ɓ|KCrH+zMPK ~A#C0#Vyzor-master/enum/gradient_mode.luaR]0}n~ťO;0>WXUv@tݗei/fzZF{әjW ¹÷kp[u ä B`jgfϞ5gx)Q̌[2#Zy7wp)rfDZDQ) `2_s5 \*[Qr֖ЧmxP%>4P+ܑO|\jkׄFط EОX@ƎL&8QNViHN8oӉ| aHf ;{q#p} k?%s L\WSWkG0R+rQӞ~X]̓MrQ626,9>Kc_^-=ѴB:~)vK>EK3I3ȧZzJ)4ZOPK ~ADVyzor-master/enum/init.luaTO0~/K6l6v-u֭S?,)[>*0?[0'Y,|$̻;)} }B|¥6#6]*>F,$`*XWJ9/ Em)P6+5;~+m7AnSҥGyG{Pv4ct d$V'6oHI@3KS_*̦l/w m5`^$*~\&UPK ~AK"tVyzor-master/enum/repeat.luamRMk@=gIǀZ"Rb2NhcﮉQK>f]߇rO ^0tF+20),|FSv܁MFF~#2)e: X;3 Ğ9 nPf *Lu]BQ)b}0YHmhm5p :nd!L1ÈEs!8;GK󆸒s%rBxwUVWa3nP3d4GJA#}OE2U.Ӌ*ɆĶzgb;E}&UZj]& .O:E,ɯ8Kwּ=e˕S6i~'mjc,HM`Z,İRm X_xSY9ְ̢ ^ 9%Ã>yDֵEeqgixXJe_ 6TRYIFc-Ս+|K6N3l3+1' 1A Zm6L$q66.<>VwRЋJ ZB.<uziR҈D!7v1ewF wƁ>-sEFNO^bM|>nG{PK ~AiRRS Vyzor-master/init.luao6ǟ0`@tIh`Iև$3h,qDbCItR){X)t>:" 9'WV4I6B6#r&dy4O=P5RH[e(W;­yW(U/v'D+SHl~x[%TvqݡZʽRd-9,-H!x9?$SEJSujI.$-Xn(#DQtB$2 S2y5m c-[fGV֢J5h~s.%1"?k-ˀLjdRLp{4#cz`%;fR3#c*1Y:5;+>;Yΰ MC,cU8a=8۟D*yĬ?qB$i\!,:otQA0+I0*)4dy<ӐmҌ%=\SNѧ;"W%˾Q]mrjKS >rW%W]MƥEXzv9+ʮ3eauu2C*$ULT$(Vߩ}ke9\0|g8J᫆65Pc3uG_쇯\ C6€KG}/>F*ˬ|$5; 0u#L׏Uq֧.8l JV(\ "EΞŐAi4A WAcFqW72/v0Xtˁ)㲥zՎM D{ˮZoˍq駩`,a>/;vhG kTɜLS 99!t [Q =C=}bCO^ohϗtcsZ3"_0 .o_X9LI6s&e޴QH_"a۾K Uoptր*AQw~}`GZ!盶Jͥ3t  TOtM<ؓ= s퐿9ycTBd HY*'Jf 1]>PK ~AVyzor-master/lib/PK ~AFyVyzor-master/lib/init.luaWmo6,2*+M̀ XbA`mqEEww%NlX8yCz2?_IXIKm)*U p~4j sʒ*4uꮔp{s_m>[Ѝe}}t]c/(*Ģ)*T*QKXX6u-@5,~x+, ~ ~j dqG.PIbjIeMҠɻ [EUaF`>GlWDкaݗ PjKIc)e os 5s[N6Ԃ͆A2#_JYk.*?^VgI+:3uNyJuAOQ0V&ffD%I 2{QSYYymBz]_dߩ* (CG JqD!3վ/kт>Mȍ6 eP[ Dmߑ ~`lK\1e4a6Jiƍ}<:Gci_n-E5ys%cOyb-0"p"!>LƘv~1ʴ"NIHڝ1^OE<;+ĭdb `DU/^Ǔ q?X}*#J`&pc/ͮx<[z7vuF|UMS +6kB3GP3)}rqDAN q`C;?h9mI$jEky|B1Lе$8z %G@m*ZZzSGD$.$Z'>y "i(u1v8R>9G1rj[#žbad6 &gvk{^بL]g_?0. 9𗃗޼ )s+\^\u Fo.\!)>B @wƿPK ~AXN3NVyzor-master/license.txt]QK0W8JѶcoj^rR!1mmL`wJ"{q0_!afly`"c wz{#<3oBeb1V!X7 ovW8fK`o$4N\pюhXD4{ n/78Akmxй|4cl"`im۶m6Oڶm[7oUGc?G)@r;ϮMn "L ;s3FQJ:ql]1fXXc_CQPu4H F&$"Q!b !bvٹ8⼄jv>"bg"t]RYEj!"lKy)e( <Oi.v.F5s zC 7V kKSfs+B`gRuUN4 cQ Я3[Cl2? (ȔEN6//AD&)r/BҳTnrݠ&wOM`Q+rJ@rEm0~1h y`W|,LbTZgD_n Ag}{젿v!fPǘS#sR)bOrVOOJ^&m= ʸPzı5L)QF%x:a:̘3<,JJ迏6D0|h8 Klfjuosj %P,`=o Iǹ$.[f[3C8zbϤ$$p iPo.:B-@ۍ1I 5Gj(q`MfHeG)%l|\~ N}SaM!b2tb& pplIۋ& z"MTМ({=S()mA&mWv+h%g;/Ϝ;#YGP<"o 8rQ9{@Su.7u.HAώdܩL8k)Է3A(:ՆJ+ L*k5w|=x^@0%T' @)< ~؁@0~ ;HڗUo @*Au ۋuB"L3sM@&Hn6ӒsTXYG^4i9dwylWP|:hH(OL z;HKtk9'e=@=J-Tw:Q%”o\k53~`z2Ut[[|g&Zq2mG8C|SQUefn@QdM/eJq+&W%h B) a0{h(>Rw4>'6mSib=r՟2Kٺjjza. !!X~uU|YȆm0chRWmflYKǥ>|.ӾUk1pL? a:]2%A\."=R͐ ϫfΐ3 }v'!>96>U)0Ysa+@Jco`X#@Mq{;~+ͲK|dD |fQޑϩT'}zw7yTT Rq_$%ƨ 2z1W6%}-RhBG$KF*g̮5ePAl0oCHW&5T'˛Y/&|ONO"dԪIDTÈNxtp7i`'`q#u U2L6L{9lzWʸ{~,Hq%l(΀K΀09G\؜ѶmELK\ߺGPj:X|!^Zao6iই ulsvj-YGk7  TMħVGkNt>MnbF+R E9p+s7c>^bn&I 5[U+ĖۏkXm˟[[!,o#g.>ɘ㝹l\Hb=9[:j_~ӹI%h5ކ6i+'CG2ɼ<\5Brf NY#ݷզ5pIyN-cz&)vѷ]IվXF|ijH="*89b̢}fNZ=F bjf{#QX,гfrɽnj8U͓3ޛmJk_~/RfLqhm3 ݇6T1\:ZsR(Ha+Zg挩O[Ҫ50ߙ φ[QXMJTM;tH&G Uj֑sM6>qH*f:8JGڄx.2\ϫDT5QƬ4;)dKll\&I>% =C?Dwrկș2sw,zk ntnnm8uV3?59RY ^xvȇf9bwKG3;M7cՕoFЌqUud}E9ӸPd +IELE#mSo Y|֯Ey\=ǴGt: 03ֱ_]H\8{ L#"œ3~qԵP@߹_=[C#v״ ,8Dl!h3|#C  s?7$(½ˠA'8RrR,#JuCrC51MNHJ^ĬJ>S~``w JgӥqWrRuU-ܝ/?{Z4腬E fbjz67"{lS2=D7| GSPNƎaU[+ez1= ˿678 .Vˆjp9jl W險UOՉQ+ GP/W&5IP|Ebˀ֮E_iW6jn3f4%|BFN.–.Vf#!Cǽsaž* `&bN_= :sʹv0ʢR,e-ZM]SlLB1%jwkYq*D9: xBKfHz)} a{Hݬ_H=('eG7u'R5}| ~NA$]`KƬg}ФĒCpb9`CʕIRQ[?xj,OW1pb)6Ez>.t_+\5J6;cQ@R -g\[\ [wM/'F: R٭s8,GDz3& /PFI<0a 6h@z~I$CQxTVim;U%ʬSrr6ڢ;(^_/vĚ#m -Z8 Czi ʸUv10 /<PDČO48'i+EZ>&T 2 GtԆRM}|ʅ{kXoV.z7C$]nݤ7PY7o,utv.ၗ$B-pCOa5|ٸF5p3Φ2}zN7" wwiAj8IN`8'7&IZZU+!pꆿ2e ȅZ 0q~᪚#b:>o #73'qY쪇XZ0p+$ďEDLXtK :4O}-n[O.n~缚 aUP#Ĥ)qA'(rߋUzGӤgkВg} F'Ѽ_5ukK]JԱ"K^X1&zAcK(0q=`0M\b?.ѵ3K+Nh9LH8 8!jU11/7df̎K;,|%BM|0*zT_ t 0W4d."rl $4g%K'_ktZYݼ1V;bIFx5^V$#7"H[xrPB h*HP/K4GԼXzMXY%8N{pWJh2\QM7=.ͅ| A(?ƼTT\\Îhߪ-~m~6XoET$H'ǣKR2&}4d.ڔ- O+RE "_vc4 G,P)%!zjM];TKhU}Bnj멹 ՂP̟A1 (> O7BxnG/Bќ,KR$--WոIk`D("ATCXŹh ҐĬ /< I kLV7f~AxWh ܤY5di"5;{g ;[ɭX] w[ (@zS6,B2?:"*1z Tٗ[ ^\f'3BO7>K=0\^}T}X&9myDŽz(`($T 솁/f2gopr)Qj3>!Gy!بX:n#p.*07⎺W:+廱2[Ⱦ6SЩ#9؜[>1k(`qp|՜V3vc"Dޅ@@4ܰ2_ѸΘ^fDΕzV5|+Xs/B݊fa }Qݸ.> ;ڪA} jjCI41%"~gЉ4b,T×qW=@ne ͖Y ~]fYnRY(5h2SΜ t*\O D1{Iq|L$Q[G^תv.?2.k^VJvG*I|Դ5* "Ogh`&}Go| X\-&jZ1`B# N9eC}H_ކdģt^^ߢ@n.bzHKLpGQ@{SFX h;TCWO^LEFmudBA`TXI1_?Ttb(A86PX Ӿ6"iFxK c˼hULvF9T6aK@4d8OҩV 'b0v-6kFx8gIܢPԒ/fhrq( MsڥAˋ\@=\wwedэި*Y&_vAWN=02SٻfB1ї& װ-QԑX!0PoHAC*k&I);YK~@wY-W#;{;[[_"O[XQUgh`dehb_li"밯-@y6Sӿ?ݮ)\] Gz:OxNyB6B0P= SB[*v 6{4i x<_P?'``aeMSl'^OO߹%7+Ibgw.^e~爃 ~a4;IYe5hOX$:yg{kH  ^~v{xeB2"խ oӺϒr,u,B{@gGE46rԦV(@d:h Dgf"2w1Pe MFxm/;.sra;e!_v"`{!+J͋p̪/PhS)6J#~=a/S&stz4KJX譺W#^Y޳/Y$*P #5lnw@)V7"Da&fd[xsKhq-l+}A]$sŨM~E(% } ؘ?1]vZ_nsYDZP"r(dof6E*{,Z1-R`/N KW^VQ s. yftf)@aH.e*D{/M hYވjb2tFK.AR ZͷѺ&?orfC;ڞy.[نA8t}[f"WXfc',B_D]~VOɘ19 `0~] ~F嘍ܑ%aG1lYJ/D⨖ KMry}(]9Qx߽>B+ye C҂p[M{ $VK}}eY@`d?^URuc.f5\Tf*B42'JƘ'}׶sX4i6uc? 4%84j3.kCl2 Sut-i=z GHFsK$3%<0#(mb}K/ uӋts +3 fU5)A lB />^_n~N:Gŗס@/xcG~:@w')R%SpK-zy{4cs1uՑnMbE~^˫݂#|ˋހv-VnxО]bn\BѴ<]5IS$4(%E̺ 'vo_>Ɔ뺔[Lk\{&ҮG++Rtf{ӉM? m9 ]*n3^0()Xӟpw9KNvߝHEq2 `:mlgѰ?2>Q#%*W*D°pLٮ~;o(:\|;3N'kuv;oLc=Sɦh-+`A+sM֌8 fr9|Fv]zy(HPAuf{6Mxۛ"p+HT)Lj[*9 jg#ґ틆Tҏa}T֢)TҰbq[P̎ [I8(<=HMpZ6Y/^zTca}[e|!]@dU:TNgT3.өI˄NtO`xFLW! )g~H\^DnpN)(x74GFOQK9"4ᑫv8 gUJwi*vj4){DJϠDD.0 &^U֨TEsNFb[*sJ`[1cQ 5.dGAx"6͵fL(̀nWK !~$/9ۍ-0*:ۏueC,lyҲ"@(PhƔhOnyJt~5Μ{tѤ+ $aOsDirju|En9覙CSP9+1aBGNeEiMKfx`kc2NyMn]GҼKΫoVKp+!MzE+ ]ڟ:lެSeInôz QņХO[&A KlԧUm!DZOa%!W,"vfo;w(A0U#!fgFNaj\f6_p' blg#h E["j5O.4!*F9xCR, &_)tCȑKijenB%?9lY,@k`f!g:ilzB-Xaȗ@"/$J=qZa_ց+ufC-V"mZrnNfP[{AesڭL95 4x; cڪ\4Ҷ 46v=gX@q]VL0yIN+:˳aud畣ǎY*=Ν0F3 O୭efzp~8Zݾ?=@K澖(7fJWÞ%R`OɄfA!urQOֹםV@\-~LWcsnI{$ef'0o:8{"c.Ȼ3Gfn}eI.ÜFARٓ30R#/'Q2\3aU˲[&9;RٍU=!aT_8']-w4a\zҹIQ:*!Y'hi(IoC7 d:dm5d{ۏ7C=Ǎ چ E%c1R>S0[S-u=jnڿ ]"6d"H}Rh*Z^(Z-k:?ӓ8'e$N>;ڝA |!N ʌYDSf*o<̈F4q#2GTJN QZk'<ݽpX-+~Y8vƁ * IA;l%W<W]X(*Z<]JC0 Ight R{$¢P3<IvvB/.bPghڝ)X6;1Ic UC fPs`_ q{w6"J\*Wz)*ĺs]!1C _S<ٲ6W֮NJ8XG*Ҙʬ<`au%OS~xA)JAX>Sem>eQSL}^Q0C%'K"-,muĠiq3ވ1<4_ji@751ɪ>zdRŏgT}".\-.bQJL1kR5RpN<bw Z}WcMXp0?JƑQ*F#5[Dcnlu' MbuPeo͐7/"«VjQZ-TEI56W(_U݊cS|Tc՛wcˬV]U>*?A6yEPՑ+pno$}%H\}NqGs֨6*qM86|k\$p:Z]RymJ\3-0zi!!ż$vƨ@ZV)Ͱ^t(AԢ]֟QVaG{۽R0HU-7rǣJ(c11 Ae.OcN[x@KR/p7 /ܙ{=Bu# Ii!ΠxYͣLc<8\VԼuqu_5;Ɲ DػʂB/3aJhY!j>o=Rj| 4AerWi@]r]CIsU[b5V,K>*yjU qHi0e mvԅ`r#t&.lZaH͊Laiy@ # ?)_4#KXaP+;V(Mst}L{ͨΟӁ E4; bL#DN/._Z\a5PP{DN޹ԡ𕐠0̀[݉\8;udUYZuPt w)peS^p<-id&E.\dAxB4dFz3 ~lR^+^uc@r[}pO&eēIʯvKQ ZCE!ѽ;U{*9kD7s=&MIa*C[XSؚ22^[!S8'" p¼C2 r%rQÐX!#ĸ/ lm1TJJap"w1foe}"&%B{'n..f6R FZ%%v!pAiLx~ OWp>KyjEK;DVǝV٬= ;RL eKfFί>0ޫ^I W{Ώ;^Wp& lnb6mNa@-gdFA k? ̄&#o{1fg2(8@1jH6װAt˪&R)IJﭫD.2R "z|-;IKvµ x$*\tY7 xvF؂XFoU'mWer|T.{tF+/Bb2t#Xb 1=JfVf2H(u0/9[)g1qn%?D H4okFs1SQY$Qf:¹ flpśç|5X́Q. )=D1O?H[ۤYCEPF䞿NQ[)^{DČa?嶱 ngۚM0@\T<]wuʆOAVpSn>z<XU2R}|1nj o:_Mtlbf[yƏpT#BO4"[pdd9,B[M;XP:ai5&7lV5 _Pfe^J) W*J_#GJcx}be&HMW,g䡟( 0 ?dm@uϑ$#v3š5#;F$gSi-fm۶m۶mҶm۶Jۨ<}.1{+5gĢ}쁼#(#͛H-}8ͤ [(SR1@2wʝ g]<8?-l<1_+x8=>ۑImH58A)L3QSNZ>P@Ogd0_2ΐƹq@eaM)󆅕8?WV)^WʡQc3|nݜ 2$B - n 8"` fdfBФ`mM 6Z9jY}>rF(Y:G-$靨R]:Wkd a0^}Q_\S9n#m3v*oL#U75i_ %m+alfՔ= L xGx\mL+c['7b&^?P,G)%Θ>#b;58$"wŮJeClֵ[a؎1G,|AiBɦDqWF ^Lf[X S' e4:݄#(i~Y$uiݹݡXH BvX17){Ҧ!CyQ񐠭ΟΏ_olFfND2\n 1FQN-64(Q^eHW 8o^EC0Z}tγJ#nD߃J 2טc mV}HX&jDde@WjxvV޽-vUN8E\ '&ɺ^|ߙL8]CE[mz 'k72{bxVcb`!iy"iggSϹ]prK6#KAyAѾqmXzfj@?lf-1D-ztX<\"xq"=$b@|F]Z= XutZ6'n.ooz{=KF"ƙB'/q9*wR3J;C=ɵUۍu+^B5M3j{ظm[=_ڰ.Ʉ<\XSGKF(!qt-6f#O+jr yRfcd,=zʆ|~Wz`7biO'YJ5ip<L< |G!vCefT(͢F⹜l2qTի(tg=征6sS)hC,d]8{H$Kw2՘x0t %ʇBF:[^LPJ!t({uQt,DM&YV<Q%aQp cEBwNwt ̘3BתkJqLyNe.QoOk>JSm)z%gҁ/ӷ/J@E#zaLpP D U 0_i dkr/p#-4Jd.G ![Q@قXg(` O5f Żp3@YA[i0]ZZ՝JI)3q@pیa `r 4W}"H ,3U/݅r}v19r^@;M' *3zjSB-]]|7_$UpJA^^bGI_)0c4"&%1I5m ak y ͭN9FIe'Z-u}Q7=?:KeYOG}L|՞6:;EMMXO,7F=x(&XE\V+oXۑC5aB.\["ـ=>̢Drޣ[>,lž %wlPh ӗi T-Kd/xcď"P{P40BQ7j? \pP9sq[ .mx5"FF}ŏ/Ȯ4csÇZS<8n^`a'XCn/R_*7`IqeG&Di;&b֝rPpmj& :Q ɚ_?į^e/G &vo7H/g _h]xjOz6(~8bC&A4̩ۏ? v*u80L0ta1}}My1̬[0Lh!>cDOF󴎐VK][^SHaG ]{o-VeZjx|!UNo쮋 OJA^3 ſu%AĿ?C:.ctumʭ3zrG7h?],MR e\yEH?A*T͚204&f)w>U8!']?@p)&)T-I\$'b!}W3wkeè+Zk9 :Gd&euR޳.emZj9~?s= ;G[EkSCitVu'2x8*ިej(yJ8A<\Hץj(`hY۔hBo'綄 ^6Y<<˾ĭutɏcCʡoqh$t`y(ߣ)z3 AAP iL!K@i8 lZёdlyvs^COXFMM3kݚws4^WZ\2N%~  W5sDKkt8f6K.|: C4=k<&ex{>"5o?A,e=WlDqT&Bi&am:c:h>{@='3-Yy]`]+jL tzn?9|TxYh~?Ά_cg?ʳS[QyDzC:\N)%袎7&}E=}t6căZ>N-w.)b&:޶mʹ1#Q~SX_&C8Vj [aAze9gu9&&FҔĹ !R^EiUv\~GS0*C-rLEd775 &,<ݑ*8WyJmEh`;>6\.,èۧ,WS?)4[]duPAߙ3AX; :7"F̶~[ONɬ5 ør ica]EI҅t }]}ZA ٫&2F[zT fQeLQy{20e$DMY,%{Oq"|Y{U9'SeTs1^Ll6EsVYFIZ_D'en[}NM*q5~>'Q:]B}Ӯ<2aY^7}\:.JDYb *ǸMKp}yMQ.mn ` *xKg#ѱ#/-vʹGP .^*T?Upޝv1 H/՞;;q1W^wZptY"yL C]sċsپJ~j JqdEU>+B%k2{B _~.*猚WGuNR(07<[ށ1E1w սӿ'5q?{7r/hJ rH,I8A9:H]ŽQZ &L}ǰ }8u>l!H xbs@oj~_ 6[>,< [zz~~4"wۅ|}ΒR<ͽK[PYw7d[C/9cc^" ܬ^Q\Xt励qqq HH6{g>~x_]%KZ D߂aeoe```/m^]bDG5$"Ҧ4*4& Njg'p9cd5%`MPC#`NKARäqyEܖjR j_4sR0q1MF8TV"%d!&3gkc&?4o(ꖂ+ת0O~3:<3ҍ꘿AbC/%Yݠ8'#p2vHJݝ;iC|+b5H狱RdBƽ[UGD+OCOQ7F9fz5ԹQaWY3} 7\B>v8'Apop[YpAВГp\>;?G䜜ܑr`q\!v~3cmNBղ[ V>>do^'o\9`S[E0+g Ԙߺx;H=2 W/Bjl(I:ڳ`m7y܉pi.MuH,/iwmTH8Zspoh_:=uUB{ o:>;Y4JTvБSjSt^𨥈A(~[I6k|:@3.U} E;>(k0u|3/QR.fLekir@s0..@z^WbS@/^ (MNiQdNC LGQ2FVY$`>p)j m+r&{-yB? ͣV1dJ.r}  %2Ҁ'Q0usiO%cq|pf62@GW!8/: j8v@4ZH ٟ1wm;|!:1k 5aCqUF[Τ^@"NYKT7܁]J7[lIxAOR5С[;O`lS% ^_G6"HnTFrG$]`WgD?^I")[WvEf.rv{ΨD@+-1n gx[Fԙ-[;ӓOa0H;Dw7B;$NrU%ft ?C"Z;;x ި X&4fܟ};nu)cJ;έNW\ )WT ~)@To|!YukJ)g($g^ċP.묺Z0¥_et9nEɤ+[8>3gw]=/i2lB6W=>կ hQ'H.OR#MߨB{;|4~φBCP\-jm )ԝ3G'*U[]j,qN8q{|P{Br.-~~w,g8A&X ,Q z䝁-q|gj7+VSJ`2 f":ߕc3ey?辯qh?_%m +b$ZOɂtv^1rpؤbݘoD9>7)sSTyiϟpu)c'l胩jW"q'UFX}xvh(⻄"0#}9"҂92#Sl$]g;`_ޚi G/`Bmx(R!~iL'EG9WZ>Gr>ynHr?#W 4؟˪TVP7-ƵSW&-pg,}꾂|倡^E9ͺߚι b[YUb8>gqLF/hdjjeooN޲DkaĔ?aC>v`mam;s@:;[K~5JO<3=;?G EYfOk]# Yl_02=8^8Bja"'h-@H}{:9mN]E7mԯ#QO<!̄»t%#$L$D^b eH.K{<:R35P'Z{p!pd=K#lPYUӣT"ɯphW7 !k*ğXsK1=O˺Gk-\+2XDJ>*$A`p)M[qfXu {U.y_a(q.[ZXE&*(V?N%#韊\6KV&;EWlm)7ָ2 (JSv͛:u1pU"ٔWdWUTbYQUg3Bpêj`ݚEȑ]dR\mp*c bns Czy>z+/01mbҘ ֢BVcFޥj ,yNe\q MީHHDy}0 2S@o S[ēTЩz|kuvu?]`,{ OmLmu]{/]SI5`de'J7$pUT/Khv3⧯ppe,CS#ChjΏ#L]uwOH^$Oq?|Ӿ4Pж6Ј>kWL"|kiQ}I4~· ċe"#m}?Z6mBR&џlމ¯[.Vy]:Qp&B1ww &&_:mLr#U%7OQ5•Feyh3z_hL0fVVT^tlںiaY#_`f3,ٖlcԹhY]G,(Qu?+H0I,u%F`Hc)qQ:k7!݁o'%fpy!Tqm$eѶLLʆA*f 8ABpM Bth&͛*HGi oxňH+$hM/ 9OMU!) T,UU*q9HU+EcyMVM 5[Y>`i@Ѫ]hv\W Mu%w%y)_~ v/ [RBJVL{S!Ę}x)R /Xt~ \["Rls%8Nv8Ck٨{OYe~B0L3. sR3qLJIl+4\ØSYy^"-eÂڭ'[y ;fh,-Q$?#(obr(I '_^x88'Lig"im1dM]=+{~͒q4!ͩg/;w~ɑc`yzR )Pwom`Ni~e6 t[eabcWA>Ûp^hWN㪛ø1\s ;Ws !EZi}.8Y̜zThOe5x;+L^L#e4 ejZ;d݌cd-ªɭG)},Ivrofi iv GF] A&>:ԗ1BGxL324YGZNzbͅLQeLS=B~xnHjGB+k- wK3DZv. 65egd˖q&_WlO屲 U&*)3H(#:.kqGמ2㇇/VزCBl~Ix/%l-M> S+}{#Xx=| E멒fǾsP=QWm[/06;8ʹ>KDN=&ݡqZJGiiANL|o~'hM րD[']6 &F;8P c;/ pA#WR7䉉dd 8sFǸXB Q(]GV﷡gV KR&&6XB|OB_σBԄTa47XV[U]Py91Pt+S()BKS!ǎ "Mϡ6"bߔG-CJqR+~(՝#AܣDiϢW'C$maiW)Y[~TV&f)ݫ2 8 ɭG@Bb_#Yp eBxXvǀxJԆ bxݭMVPC.4_$`Sdސ]]t'U:ʔ~RcbIR7屙 c9E Vʇw0\]=НĴ!ʠF5=/O)`=dRLexåa4 RKqzz`DQUp]sXоޞ(k/QpiH$"E5"U, EdYk}$c! rh(شL Rquہ*G*f4j= YuLC6=ovz0O܈@F9n`c=߰>ۯ|__&QH;p 'q(A~-n!aO-XQ%U.KɣZ%\ n *ᗴ̺@!VlETGgb iO,眬\_LRdEMWt4X w!wW 0O$MSRwR Ţ3*XCSr<LCR6)$X-LX~q'4+ ^9wwo\YEJ%G+K-b v 2,2>cgL&ڷ Am j ˠ`{dGWkõHnhîn+;C>)N9:f8h?.mi^,S,$e@5CEƘCS&ՙlR5? nB}%4-hu\~.eILd!Io_ ڙ'5i|!CgpVq8(Eǟ&"Bm{TL!$e[`Df+q=.q[{_i7#ZDWV gj4yq ٳ7,"˞5s ުGy™JwDjlDؐ\F4C`$P%zv-Ƶ78~=Ax7G4FD$pwU˧p;b9_oP:d rO^{$m0c~Sc:xNؒtRQdoG]۶Mj )RGG0T*bEF]zgkǭztiv]Fu_J^2Es )ӧaq~k-g5=bj- DŽ1Keșl˽D{AaVaP =䍀kCQ0sb*`u wFNQOgѭOx~xU >)Jؼ3p\u&ߧe+Tt Xgj-=|I{ՊP!mklw5ͮ- ˸HSx]±bYF 57[D8=6F0^v9^);}U20!g\*FSҟbV!ANTQ[lGa5jRސ:E']2)v$`9uGtuxO(&?} u!KH6U:St@PcvIP=Jjl֣N}GPOئbGUnf߄j R1)cX\bw)-ĕzJ!Mj5@3\>K,t5l GF$_ k=- Щ@UKM[?H`ԳZD1νޮĜq{+ԉeOEhhgR21/_2&{F/HRUGmĂ7{ߧOJ{ՖJc *?n|wkoMxh2*Փb^ӂs@EcXyk&#w(O h&ǕiS3{1|W[,bPڔL{ L!wT:CqVSH!F,^#ʛ|b6/pʾv0=W1dtEb-WF{w䞀E,(_:FxlwN˗ɠ bF$ˈu)xNmL`՞:{XĎv3*D pNYu`DT4-+xU@Dri&֋,Nv#:^6:L+)}gc?P+̳ xǏpşB0ZϪ1]Ra % DPW|u*!Fg`B 9X0kTnA%vIɇE.#@]sIΐ(Q>7ey5xըsFkԦT K$F=eSvOPJկN^1>3]HϾtCMlT%5l~@:ZP`t>g)JXzY^trGPM@,bG9As,$Moԃ50ALBv…d îS(Vh3Yz`aOضm۶mǶm۶m۶m۾>3GӹR_}uV0Å^Ʋ,$ wwsbe2FЌW065cխSc8~ʨNlYx p ,QR"F󣽓J'"?^ eH&ՓI[{{ 3B3)sɷ* Ӕ~NՊQw ۡ<ڊA~ 0ZJ@Fҷ<}d;<~/ek!\+pL`{U -^qϠS> G{ԀE) 4b#^iLӳKՒz5x Ō 7#TO* LʵQA,\ yB;ca gb&`J:Ĝh[!T)񾵺k2LL• 9 fɑg*㟫#{J |5U&茚:cMx mAq&p[ ֮pU$pC.ȯ7"bid_2`e_ Uir[L(bx*|0ޛ~?JX3r+5\=JN4xzg ۦ@-H×xU3P)P?0iTWV ϯ-qbSq{Լ_zlɯV4,JBul?r<-fLŘg, Pf GѐQ*t{0uMW$ |E6_/ij8[m/4G㟽9AZ lf#T֟tfy,B!0M0^, l@∿12čo_k1œK(|A_Pn=ѾOIT ŀldON|4 Zl8)36[Wu (k%,sw |:[ ųw{[@sd|Êc ܘNd@hs8!xkO&Aн0:v2~t{ #S.۪Vrsrq.dE>! JUКXC+qL =29jRݎ> ߃Wx0 m1콵qU*SZQ6 -Y4j#qJZb"ѣrc yk&JRzKzo4JIYCJ_qŕ XbqTioew Naqix֦ PN)ÓO',g‘FI*NP J]^M:\+ ɅlͫꭽAnCO9CuHގuGm>@sv ;r_uCD[|ޡO u85P7X=.༶Iw (\Fyk8 G]1eZ.w'-,4n W^DŐpU WQ!7sW߸aew`m ; `Xw*~Ce1= ٵM]TŜa6u؂%Zva?qt;1 TA1>b#6$2[}}˩m, mIgՏ ^f k)C88hl`]ß\nUft_v%831e$;cJm9؜ZdD.iuREd`tE1kۋFehTs\ެpmcZp6128UwL*ByލBY4;C>]eң76%+S t67 9 gU!2F̑e9g׆BJkPY~I=d 9 b!b-31$e9n"9A(cw0(X./7}kM# sQ1-:Ѯg&,wB5OpІZ Q&5E}0Pټ煢͇zɸj|r}eܰ!gI!r$p5Pęۘc(+<Â>|"]:㼑Fhl23 ,GQJ7.O\-cؓ[bѵUjdIzaCepN0G1ɑöYӉ,q-D ;l^r2Z$LzQ`2H%s(S?l\}χsd`dja K;6kCJF齒f(g wqm- |"^\'Bf朄lOs&F0W>`-QSC.{4eYj^>g",u'y.%«HvH}.ᨋ2,JDr9םY蘱I#۟.3fwRV6cc҇C}/3Ddu m*Eb &"l\!fP]qk^0ӿ9]]1592=(Ze34z0C]7=BHJza,)=WS[έ|,gnIQ8{T!]]x>2]Us/A))Y-\wgq*Iy0Xճ4yԛAN =[ws ~ovCҴ/B"u)*K&~/p=;2KZ&yU U 0["x_o)\[237?"e#iU+;0׻MI܃ָ'}J%4ia)sԄEC"!>)}9~=!( sv/ω ET{g3VX<"ϸ\eb0B,Qlܸ@Rn'$F Mi{IcōgЎRGI[UM*V`L@ E6믺рxTk2v{on1 VX>q6~֚~cvఋ|6gQ@*O9u..@KvH_9b\_72$I/ۑ%cd1Oj4!Feqe+1ybƵ[f.Ae&=SafIdƝ·9y7Oo <_>% 060T )us u@WFiE2 4,-(R 0 }M ME,*ZxK)H?ơ7>C6^~P40M]s4z#YIXvA.ߛ}DD-%U דlpAF󢰓$AkQr8w0Gy 7 Fݿl݄/_7lM-,M$mM ? z7^ 0(X)FB .\" ZҜ%ALΈ&u;ᨽ$D+G','{yF>5wC휕bmeK;hr!tCY+kI~uʓQV ȻT/@(, $D3bciBʜag Qd,_;ך29B$TpE>W+Xe:h#|ej>S^F}2wD; l2U9}ءx<ʄ.K-%.Q/V"pͷqg\F3ߝ G]tyN Uܪ6(x#o~Vt NدJ7B7Z0F8-M~߉+|6˹ (ol)/HC3| & nљ\'u@7xʰ/;im)4D ?)g 4 BwRB~|y[9h1M:oēL'g:5'Ђ?X4"zJ/ ]:)4$%Juݞe|ـ 3:־ e \SՉ#F\78sgfsl`ivq{` w _3Nx&@w.}k.Tt>g7aDsZo6lbУT]*`}tm.P8e,L'\zL??dbjhbkdb`hm?;= 56q?߷' =+x *Ծ&՚2DPBC Ga,@՜j.n7hZ%+Zߘ;(̪d ^¥DoFݽ5?t Vphja$kbll#Ȝ&h23'˲6戀&)}8SDU`ϫ囶)1@6`6?~K@EKrM]&q5#W-J}F̔+'ik(@B! vc[Ł Szn1ۍK|SE*w  :sXr9XU z#ҕp{f dSHcl>P2&rx|+lO8U)!w܃f"DHjŸW0<:(\NQHh!>3!%PmN,α`5ô;B$*<ʔڅss!$ipהz /+!ζ=.Ij3*UhyfڛdȖݭNv*9K +"”E0t?EwvMr}wG5Cܚ|@$_ ) S~ͧ)__¸ܩxϤfKN-`D !gr]KL0BQdogCK*o}bq6׶X[T9g%Q:e ɘpb3_^.1ct-]iP as9ڌ& ?B-騠=Dn ŤH,p- J4xޅS}̛pPllakKD r!jZHD #sw_``E +[IV9 <݉p57Gt~>D?D}rv2yU9eC;jqUU҆! c`bd%$dF[Zn,]a~yyn]{ d<7ryWtֺO9S,P?,jŷj}Δ(%U k:*{tcj:uI{o ۏ}ōz y>GjoK9ռt@1m?S jV"ZJiƁ? bCƺ` #R?mA/j\.sҵ \*فe8v="_T^!Yx\hQH s9>*.M)D NA5Aj荿#rO1I] *$A]9jٕ˝ktAmX!hr=-뜱*9C}p 3]LvWmrB IU +Č`nrSvMXtq:"@N1g"QÚ2sT8jm9e̵r ϳ yb!OX:bO~=G>k^,.QԺ9qI|MT#iD=$IJrV󕢕 ى zz;uO?ea_1f#5-Ϧ<֚kGRɘ 4x^ rq(,ݑVȓJiHeW!AKy:fKcEBһ>aGc4t3;Ƹ^J7> HIɌr~. LH_'= \R4"eڠV3oC P263%Zo~3</8v(pZ|;r\۰uZff3-W4×ewikz{\B[fƒ /lы:.=s|Y`t0IFoySoBܽ$uIZ*ԞV1he.2^ֈU;~3vWF8pag#`  WA5@Gko?7K7o Qz;e|J[}|o9rz6c^67uQr *""ܜ&`'`-We[z[=]|P=)+~uWJ#$ 3XQe%{<#+ ӢRxT!%ֶ]'wQWէ蠿' U~yĎ9H+WE+MĞHvPPiPwO@Eyt2%ٴlx_N6ٙǫhW{IjrvIH.u QJF;;|s׼K<|e)֌<`Mkq*1ƚ0š~E; -*@!]$Z>Hg68 :|כf>q|>fהnB]AUv:҂YKHY4R8]p-m(z0g7w7ԇB%]zWyE]`=v +v)&UW NE(Ir$]p K~ÙC0PvtI߮%ucJ}I IyK d5C:vE9Oo*nv~.^>[zL݌74{8$4F!@pιPhx oJ8;G>i}}{UVͣT2+n>92£n8&8?.G0im"rp5,h+\,YM5xJ~ jG/[G̀?,-|gac2*LܐpD2 @`v;!:1[z>V&BMt~&fS~- r06U]j@.`oT8dyU|X<4'frJ%NSZ @¢*Տ%al)SMW>jXO合<׋o!u06+*}Imm:-T]#yrKG`^o5J1*uWh5(K-'DoT8ę5f߯U)$A``u&V8R4qɍE7xC:S.ve3Q̒S*ƥwkuƕa =QWbM%3a Q$hLQmF^08ջ̛d"$wd}ыs,0`T8v΂?o{L)>P ScɇQ7mI prF'EjrŌH;wZp20dIXՑozm>'!ӻ_`woJxt2 N\. k&LL#Ad2>M5%Z }P'qntoZc)0="~l4{]e5? mRl^cRL~9c +jcwKq^5 Do@ĪdG.Sk-҄xHC% -==u'10 |tNi%J&N ұUT)5Sؖ*Q$M$p5ͰaʅiId`KRS 5Mâym-aN:ڂP0B]CZx )r`4ksO Ė9W__g36>ves,8yS.3ʖ *lӏ{#k̤ lgļx *3k42QGϧ~=LpLJpզwL1\sQ`j^2TEy{>*C85"fZHvtCۜH&=5ݳK#(2SDzn 4աYwaA=CZhLj;ʹqsҰ@3Gl~JWL bv[)F[c zR3++֑rϹu]/VpUɁI>=yDP I]EZ=@6d1(M˩R$=Βĵ3`3/clebԭx^tpq{~b]؃gY >\ yVCh ؆v~#T{噬9}"VdP@1||k+q#KLp{*Q7xgɥqA2O"7rlZ>RҸWzJY/DU0R|X:5D߳4/?|)Ea5K'mWXp;~÷0 a${/Jn+mWH<<oQVvJ ۦcy.2~nUU݌5w :&nbhU'6ɰ$Pǔ\'qu`9nleX] &׏_ȎgҝՋ>zl%}=X+:tH ̭QQAWv|ó$\d1&W{8Zo;rG)f).Gf-fIC L$/*]ea&X5f%rRA8ZC+?i/WWR_ "ٿa"DFx~ Y1&KaU?kJc?ɗJ[婽$bnKS)#ؐ':MXn@-(t:a>D`WL~}d(z wbEphPabc"#X6iIԇ 8ʴ>*E穲y=>cDC/'Y _0 N@!2#qpL f,t*',(޵D&<Գ/#/~f-NLA3ow'zW䁲C󍿳sϣ0=5WhF>qg[dw;R1[eESV1ץ*)y ai w'SH6B @ۘRT S{VyXK.H3e"v5 4BI i_LU=sG'UKaZy-v*·gE41|\M޲d}վ#1X>Hn]?r,#"Fv ;2ȵ*]yq3&wjX:" (m)~+ xppSn;{U4<^cᵞ:V¥࢖[\ώe:Nv %T+%í N >?֥&C1B 1@M{%A⢋OF3+tQ84zbÿXYz1Y Z%R#ͬeUX GO0\YKtT3F/{o?80+ R8״=ϕ4d\k)LGOUJSnxgaSV 4FU‡>)xQ;fc3 I`"'#Mw2> 0C @4H=Z8cxK۩VRt蛾7bOٜ5}%=D }?YmXr#DXh+v6Kʸ("cU0ZAd3@6 =D7M|mL=n|CNk[K_V'Qal )Dވ]lVu 7 DuYBEE":M1'oL(n^p0q3CLޡ/yN ;=QAЎ5̋,Q!$GyaNd׿?"wߪPidp%K͛|[ـL8mNק5LIBH0g.b*J1ˌ~UHK< :X7ζ<1 ba\v",/Q(W+(Zf#\d}J$t__C:Y=0@7q m =N)7-j[y` -Xh2Jq1W8f zI-t۽*vc7hKJIjT{5i <( 6 kDfRѕ*_;{E3^F*L:$S\3]dhޱ%Ψs|<*HϤ?oyQk\NOx@ř GoЂ|x'>[ o,M4 E:p6=Q<xO9TW<aYTz&B`!Q0OZK/6^«cw(*M?p2'wE"-J+K**)%ܢ85 ڮ'8;f~1{39Pl_[=)VG} 'Ep(c;KdU'>p|[̨ZJ YF5Z$U;[ѡqAHbq 2E(M#$@ cXY</؃nq7Oϣn5ƛoh {>Y:Q03&}[F5$!HJU=@S VI/?4AQXagCz}#6}܉"ؐ?7O{4#S4改87'~XThK"8:UM,y'~2r#SCC*-W.֢Q־YC5.RD|'q@/qJ`uCeS5%6D VEQ@ď9 B; +9,',D=S0VhTVziz?vߘK]RwE@Gx u`c%s^܋Ed=Eb[-8!V!|_Y-|3`2!bTF󣇅'uM vsݤ&X.sS;zg;26RY`E];xw:p n2m|v 8Ԇl1ۇJ6TVh ƀl5L)J*MV9j8PP.1 oc:a͚it*]*1ݯ[ۖxtC vvq5RBeLܟMͥXaYLxP\FXւm]&Nww+DcHO w5jg1WUȉf Վ+vԇy/JY1.,x(7O,{w!St7~Chrs@b<<7L4+҂[1ԒFt2.pė ǃY]YLuYtE-ڦ*a\*LmhW >H @~(XM p%n;_VߧKvY`L"2Ս_\00ƛ:fFv/1ўUFk?0a4]t$F=w2iIeG?kUh-avޡwصt&ηz~"֏!W{iK?m zJo/.t"2ޅ7,]xsibvhnL R!`|X}c7z/|Is^uRWWs3jxO]O[nSfQwh;߸d #(VhY93wa .jG60ji'W;X.,TKBg Q[JhLnٱ[f(M||ٿv=!]7Nk&\_C:W?<ȸQ)@8ueޟT*W7$ '%(fucNR2j̇`F] ;M͚}}~౷ҍ kM(a]A6Z=n$ܾ@ ;9.ښQ.YfimډbE,7t5Vj(p֟aH>L?6/ /K+ACٯ(6b :['}?7o%{3v+ㄖQG7/bDGV5sX(aSge 2SUs * )dadn ("s(uOMxmps:d&N*39Esz,&.$[꠴CVA*h(j**%]'WL0HJX[tʷ$S23ΕݿZH`)38+k2/XW(Zk"p{;. 2Zi|c~;8Zqkv%Ah7k?Ι@Bo< S p@5_O]WNexΉ$3Y>fu췾aWUv>^hiMyAi\!-RjC/Ȼ@d3& z1]^tAX $]Zij J8Q?nM aeKCЅP.8 `$/)DaOY4!܂[@]dGYN {B$=L$9^aI2b}wRFSy:(}O'Yƅ]2aTҩpbQ(N4G3M ]v]>l!=ΰ?9׋PMO y{7d0DC#7ke_4wM+oqH{(%έp/$dBb0haDm`Xm .3;W6GFKkўR Qb~-[;_0/h&B` =̽xYpؿ6e_'β?L6E><~f|4b^YqRGMvצtW˫e"j/*v@#kB2Ϟ,#|mVNe6<@W75zaF|H=9: -^F0ٱ5zǒ_1b"q[!lkްEKSZkۃ#$}0%JW`~*a,\d}40otUx,>M T!.}\I05bma1.R6ZJm 8O^u~㟜="Xu3 P1U}::h/ۢ+CQtP* UN:;[Q~NCe(Y5_jԆNJOY.໫ĉXl A qMP `当U84_audY\G~+qr̒8 #cA@AOԙ;c$!yoFYR5J%;BuBR)t ga%@\ i!̈́,IZg*ݘ<6p+U&7Ay.kC;m"Q(`O>Pp2e|6A3a!ʛA=VҲNQO@nӣ/0JvQrbՂA*3I Nn?&FSW[*:$E尭.NtPv> )~կǏeP@ۑ<8P ~+ѻmXGCTx5~v=Wdq6'Z׷͘x>yV4X拃ȺS)QN*ZʗC*4JctIJ4&B'^[M}zTĚ1>y1uj,T"O5gzS۞bǂ(*)vu%t#UrRWs9nUܵJ$Z^o񼼭J K3?Dy(B5OcՇrlngVPSZZ-0L EcZܧiB"?X6S x3婁6Lb?ae]*F4U6L߅n'z5A#rӇ#/kIӱEk,9/V,qkISM搾o'$V 6`Yژ: _zFΦcU7 *:@-)! 1˳;2Zep1m`K$ޠ}ϿѸж`t>=5{-n_Ov}4[}/ܴkk,ZhZ&qĕk=pޱ׹~ VC j\n:t)k3ƕA3sĿӧ/k{sY3掱yXy snU/-4#')ٓ$BNjKE92YNk ݨcmL e!˻ٟzo?/D>oRPc)qޣÃ&/rv* l& #!Gܘr[$ ] h71{>'ǘ% (͸e}; G,ea{eay\ׯEOqf6AAzd}_!4o^;w^s>Z|y|c/ 978xn qRU7 n#:sC[~^SPœ'RWڋ#BaQ/е] LY ج!$"e&HUŭ.-$Po5(h5^[N0j}~쎎^~>3CC4脥NPc8<(]&jT^y-df/]00glec1*s~CQ"TD 3>Hʿ8c]b&isc7S3X ^ e;(iyw:aMmH=ѕC"h$ً=V`PwS EP=~nk4?w:a\JD"\BD8 \֠kb!>2sgG'ng"a)$!F%+QHTfb5Jw:]Cw8]ӀZclvTfENjHk-ē.+09Z{<QƠqA"\ӂc{]L}Kݦ:=?>9sa!;ڍ_*+b0|:e{u^?8IgZum*SFM x$ڸ<[HKӀ ffipwԝ{ L[X7ɇjמoJ=Y2-GJin \Nc{ OzRi/Ԧ/)8ΊD\QA o%j"=NM`(U7ke%JWLn͗818avUZ0!LUG'|> ml.BBpkWqCtD-$`7I7^>A'\;d YK bJB1.-z=h[xƪx˕1w6*T>לy,]RYJr,qYY:5^GRX" fJʾvmL`ձJ6^AN,5 RkO>z6ISY$Z]89 d$ۑ`=i*c0q/ OX RJ@xZ%3αZxrδRcSdk=6g(\k:5[kcAmj%s{k1`wk>eÍK$3WMyUJ[+]Э! s?k;= mKWmZ#7f O6X*R]Q:Eі ?툍fn{ VMfN0f]eOfZݞJ3,9OQ)f:PZϏ4 UڱEXۅUc2$TxQ$hWc!|ȓw Bb/v"qFym҂zYTz}&9hN16#nb"@'`!H+؉,Б)25RCkW*wjŎN0G\hArW!rl[^riQi:Ҷ"YWIЌiPzrةJL#LHfP9118RaRVSF ۣE\/8.RN~ൡтևy+\,) pdE$O&4 }݁ƣx3t8/?2bR|'6dI>9j@IeB%{:j%U鯓"WԖ{zVykq͐)f5iF[;%@6`*~ ((һ-dC y $iga*,)J"YiLO)J&1AXɋ,[ 0p$OG1I9[%^:4e čkv9 B~L_o~S,,Q 1ڑw"&]xEn`5R|_4?f8Ka̷~hDA>?PA_ޒ}|%;CoO\N"_&G\s2y6r§ܩ[L$y /4:۷=y.o1@a Fh H n=dfS.)JP `X&OaN awCVR?Mq ;޴T蹛>`LVzeۚ>_nj7jۨ'հ$&˻fۈzp[)&V` KGNXbth`lx|M(4d!M;IF e٢aѨal N J GkSSh8idrEbSxZ3}V:mXWT wKBn_9 79;G@c qPt:_R3u FMS '$h d- cgwYD; C Qlsj9{GghdRR,tM*x ϓJx\ &+ J΢eEZ"k:68waH{4!SLGjj qRK uUU$ru"bgb>:+DR_0 n1RƒeϯĢŦ+x9|*x3˗>_1`B*>O=y;?ǚv? 02'łw Y"|ૐkv a9(BAhRQ.R'[DjA-Ec-1X/QDHz; UcmvӒb5wqm6b7A)vaY=I t^cD c9̽o)oA棔ް;_ưϜL5U2si#_(O b( 7AKA$,'uO$]R*qj[h҆}0@^Ӂ餹% 9޻i͞'t^ϦUr@g6{Ο/}]|}X_z Veu`9ms%ջSy.ܦ"e`M 2ٓ$O2&hNïz)iߑd}콵f7X8Q;m5UWeyy8g5虨YfO!Dǔv0 Unփq`o@wouG|ruivc\v[׃`j[".:أI̹2(Lm]٭K>uEgɊ$C\]"W֞oϱr:7XvD;c5jĂ*D Tjr'R/Х7PXgʇh㪹 .5j>/J! Raa6ޏ2Cɺ} CH,fЅkp[[uni:i{PiWS=1ݚW7[5;}:lТd[J4Q q,̳293DXMMwe0pO:NC\0~5Ұ/SV-]O/Rh-\Mo5}?倷@oz`m Z@ 1,iHLױ?ID#5V8$F ޱ=D!_v[n3/;ܷJ`Odi\͚?}WL~pvc%s»k9YI{}o>ߪCqV&bT: ҋMibtH< =(z^^uv>Ӯ]VCN,D^r 9~!$YqܚMѡL 3ʑE>oy5m___߯V LyaH'J9:vX4pAO՘a-p%^wiϜAa6N\V6-i%_/^7J<k\<p M\Uܪn1z-0Kfϑ$[ef1m^_Uڿ@olңkcؾZ>z/wgb?! RYcq^-.X^J_0sMP݇%axtHSպeSm&5J[T\]g:#@ή=xلݻuE׼oN r"'JeW/z !WZCSC DTb,ucм\>\`3H!\ĶU qx L]n .Dط70"$oof %C>fJi(nCX3O=n7x~Z[?O R#iȍh DޕY 9*i(<_Q^kF /"BX$. V/̋Fvʥ <5$v-~EܳB3?$?zK16yB÷ Z V$ 3/|ka3]UbXl lՋ!^X8:fpKtN~ ˪%ҠU]m|S@*!UTogȾ|H'U!,-?nvuc[a.&SP[~lyK\jx-%uQ4 ..],˸aY9sdlJ(g^ܾ"ULi&3v-0z(J;7%mVUJ6{kMo-o#۶ IBBIl*uc+at\6WĆc5_@u&oQ K"A.%VZU|s*L6D@WQi m'Oyn<)YV]{~8l;3G]2&]6ZQIl8e"jv"z_d0$z$r^r-_S!=̻Aʈm nC g [SVG)߁qt7x{ =.3bs}7uD]Tn:oK3S4Oԇo0cN#N8"ˤE 0j. .[ ;~v6-6㴙|X3_&_1Ȟ޹˧LϬ>p*y8rzx/ߌ. *DZ?o*=<ۉd|r[ FDI%gp? I\s, ?S.d [mcpG]g^ξ//߄3at-oe_; хpkF֦H4 'vGۜǭ eܻ ;=n|b[J.guێzx]wlVWrIߺl9лzNRʋ3}; 9mp (u9O!+ߒ KvPTBK./13S#$ ?@rbb@FY(F9F;-!_gzV_v䝪) Fr şt:4@Iԫ'8rH:7iL79VjIr%S͘_>V]B r=/@2Xrr~5 O[rĴ}< *y @rHPB"nYl7ϢL?,%ܣ*L ~ɯ9khgn%}h]IF:lKBZBorEZ#|lE @յyDSA {!pu$"{ `*B9x=)2)p^^0$7;ƒeW[zs_ }^y,aM|aC7$,5ZŇ"Çi1] <ɘMZBb~7p$)af_OT0aa"Q8 N?"{/^X"9'}0?ү1sq}'XvtQ# tћ}_*szLA9_!Aнtn61˿E$+kQb㌆LG6ŔͿ?Ih$QI]SX0byH)QwljE{vMTXTK2ث"nW9?j /|$6a!̐\x|=d1MrX jyȔ0(]B!dmy(%C؞Me{yl"mLDzgo$lO)([ekuKJ4EځX LW8F}Jn8kKsy'K֠;i|ɥG^xjhT Tn=h$-ׯ5+FȼZ8[$DOvi)Q%zzwRdlQjg g}yh|i $>,7(Xٳ/Dޓl5c"]o7M^#e& dq]^myc~UFeݕ<u.!5qpW%>j^^Q*('jlEE808sZR=|pfm?ٚ%F]DPXúVF"!a#4Յ9['l:@BanhL }/ ̦ᬯPF5Vڅ{x3_/`cCȄ<ry_#EC†NEj-=Y2HbJZ׌|_Aj4)VzW6M608J+̯ز;p 3wg o$m04eJR9Jr9^ ZBW[De`6bsNRE(XNr&53^ vGҘԀq"F涙:\:DX}fJ7*)P[t0 [oriN<-S&uDt<5[`%||32w0R(deTݐtcsO< \<]AZ:ğ*RV0]noP w!8J?J%vc.NZC(+3x"'ԲYhwD1YW&(y'u3IOSq\RC%ʷ%J,[6WPlp_Rs&WV%L7F[L H<p|s`m@ e9b0 uZ tY|Ҁc&@0e& .NOp!p&O[=&SUw|/s $H|$%DDw, G3F&Igo3-űZB+ >YXjH(̕wxTcUC >r҆pfTZ(xE+ٜ%nJ `cLg3%K&E,,!dM]T 2;kL^=hA2dӓf¢rCfn(ӵb, SpNY@ "SC ED3-8Nl84 EbʰMaG3kzUi Kôf-(mX8|>7ڇ瞒N'@gq> ;v(~p39_樾-4^0 rtQ̮NL.wL8}!8x1q"< jýydJҠ\ ɕ(u5nQ}^7Y~FYdvPblm?c<:8?=qx֕_2ie8>E wЍ[߸9^b삒լPF[3̍"i%xKSrEU{ܐ2y_R_f`@a/;z19ŗ43o}'O>$J^9F\IҔ ңQGso7/eSzƐ!М6'$]deIb=҅r0.!~#.?a%M0ܻ2Vz沸>"T_ث,rgIz<$IFbo"e/v>>Sc$R$ &Y2)vV\x֘B) uFI3]YmJIS nXPc- 9n 7ȃDT!3[ɺHKm. !ET+_{_ 4UEw@|5{Iw`ǂ#Vn G}1,7/NR)ڡ&*=>ĝ ZTð !& `,~xZ%@(;Ѫ>%Rjl~GP8j!"@B¢A#a)3`>wB;ٶ`(l'o+< *br/E]TPZ+#8h 0`Je"L`9ڴ\.b4xYf(m6K0!lT"8S$H |IXʯM=kG{]NJ8E^b|A !+ Ag#u j;KYe[`QR/_#U]YQsw7`T>YW6o\4[| |iۢR 8!YAC%}y*=js `XP~˛,;{zOqu \ ^^ߦoɂŖ%ːSV bYw2z*F+_p%e!C~0"|h0WɈ TVڙAX & |K : ":}vR|j-/&xqmL3Slh^T) DpDl[ slv&O8]_O;!DV_8>tg|Q*5D)q wo$1 yQk7Pω*u-Ț5="3mCoJUFM[Ov5ʪ",]/I B[N[N[XjK ̕ xיP"J<_bkdF b5b"iCry(n)(n @N3gQs;:۔7f̃m2w. 3k/3$}H}cm㳎MMщ;[BZuHtvۥnm&šZZG4~)9ڤIJ#+|o'V?ю*qwtw/V͎pۇؐ^:0EP8.s=b@3R(XujV070<ҶaKBZDO}/yO a2>P*0&``Ix{cHIzX;A1~`W{gΪ{siP8*\qG%=#i 7_ e2qT'1.M8%C?!' wQ)g~#GlM+1,Ț^'lENͧjJ졛pb`6<~y=]Mlmj R24P"PI8UVJLIyT[=L_&aB[$?4ZވJ%(Ive0A:HRo!NB҂N>hfcn5|k(c#9FQQE݌!^AEQ p6wHh=0fWg| +<S u0rtΑAaE/upJ I7姮,>9۷(sCfa@9f(̾xUb/IbqFdd>%Ql!a=xm_Ks;@JĮha©$ipRJTđ˖9 N SNDiO}^}+r.|J?)Ŏz{m=bgi%޼ HHI-,mm|]/x%gp7{"סÙ8H/ ؘ7u{k2m;ꃜw}js][WAE_SWT8HJ⎢9{wɏ\f)v@^;G##rN4e jU^*;gIf Ȉ px쌁`obKCs <ѴhyH0Vʎy D()u5EGXY-RV)pj&({!lrЉ`!Kp(؊ ƷݣVyp5ek}X \x*@hQ<]WYۊʐq*H"Уo}ҪiLڤ; QKd)⹚XrԔ@r2<,i/t[p g Ϧ#6Iw{#zH|_&{ĎFmT}9~>3/췖S톕;J#H33mw&:6E;V Aロ'J3WuáICAMl Xc|s:+B|+/B!PhyA'1 Lކ;= ]qm}֤>s"q(B w.$z]4˾ʘOw21u. ~BJr@M8SVU@Gztƫ\qj|`k/Gnf.|mMPvmGy^u׆e$Çpۛ*6,W#c+fp]h>ףL)DbvWR0D$z`8``$k0OB)ٶxr~kxL `5z20>XD]co{GiGe1sx|W#hp0%`漅'߰l zk\Lur֗7>m#HMr+W~XzDȣ~z[%/rXϿJ\eYgGg8&,cQES=J0>@&w ;6 6EgMgҦҌS= 1/w-2 Vx+p-n]|>XK@V&gR.Uo `5H./Ѩ`/(AN~C*I 5 {\ya#.Pm=Ջ7!T?BK8Lk!MnC\4-̓a!BPYFF 5tiWN'a(4K?(M@BNR{5'~@貊efA4䆭;pCJMKR.ű x) 2ܭy_/>u1ӯ%)Daf40EYW-:L8d R[Q J>I-5Bc]PC5a֨Ot DP=F?+MGװ\l;>% (G\nvitxAAܡ9n#&s4Ujtet7Cdv~<>*TWm,e)&fZz?S,// mAπ`x bx}sS:9QpPoK{-w5m1Tzl&IHݤ*`HUQڞ!B S3!IĎmR*$-U⃂-Ȋln"egH|@|0>'.Šʓ* A N! b!d*$ ",J* V2ӭ,aU-߆T\+a'NjsrƜtd6cmbNG4!P؆=׫BE 8Yf+è0S <8|]>$6 ya, 93WE4f+ ,ܙPNnM|w =Y"PJK)JOpW*ĉ=^5G"c_r( { VSxȽSq{zeWѵ, ,XrzH>q,iGy%*e) )OTK9.q΅P鹙(uLq2Uz%iyN]HUO21HO#uݐ-DHiP{?V53Pe&3Q (#kQ*)#;Q:()XadV)JM'vo߅<\Re ^PL/,EMe4ZngeVv8Z rIcdyR#Y" ?Zp)E :A#*u_8^ X/ ~) ,?=JF_p}9}QO $A@P220FQg#:JQsJBWN"'N܆*鹬XXt$6^$pBVׅ~Z(b\ $FYCHrٝȱXߥҋhȹL ߀|wßXuc`]N_RR A4n QyqeFq#´7b2tE#h|EmIѭ獧O]G v C^ n<9آg[Se²jMsķx*0OP$6u_|Ϝ?ѽ›iRԕTST;PsG+p]vee^4 `gSN#ZQT-6ǏB3/̗77,G3on#;ڦ Ay/rw,yeʃڍMJC[AZj|zm_ِ*^ mAg5ʠC3  $)u o+ydBq{0aplS:^e o+,/S-MLf%7$[C-Zt!JGfX66o1\Ne&.v5 _ٓg,eֵnr pkZWj[wZٲfGmreͪE&W-ֿZ9yM/ٚE,p`E?Wl,uO4KItpmCd,yVW]5Rt3=,* DUA?׎g'CW[?YU ++X}j52Zs2ڽ ec=/]D_oog ʓY0x+{ȗ@Jd! sx 8Km}můyf[Z;j!)›>qxz ד̔+ 0? LZZڛ_2[5!??]j©R"aBH'gx:]\e#Ob/i)!`6G ^9Qլ }0dQHjg/kc ҽL-ʺlyk C`8@W2L'$ yXse&s<]J4t jYnF.zᾟȢ_ַyA&¦chʬ_DvRoNaza0] zpdU`#X >}{r{16CYr텫,>BL]ӝvl@#@?-/ÁQrK[478,>wSM%/{ͷw X&@S80@`ýz^@E!Bڧ2# (k$щ@cX+ ,=/gd((\b;9R8FQ2X4s,v]v=bv7PI65?1ɜPf ^IјK@|eD0ՙóaGΰ10.pJJGg8mkBS,gE ;e%=b91cy{9'%.ȘEo’XQ0e> >ak%d4b#Fȉ` o */]&k2:Q16cJc!>C!SKёDu<"|EoJ>ab !yCƣFWN)oӍFv)=>O=tg4=b2XOS:<(rˡһOxuv_jJQG)!F<9y}<]}2$j_E%Mܙ.)6 VYH4SRD&&_X!@DFOBK4fo(tB^3  H/B< lⱤz,-EƺX޼#Fںs?W@j{*~rI%_gNRݮ0Цд%95<捱V ]:>DeKz5ClZ-Tox,]*xzDЇd &qv#Lz i!UR!)Ś$6-T(8ιA% "Zh: 3;ӛ r 7ɻl}?;gF\4^W-t{uL,NԢ|!/&Q1^;4?A:^7H6%zFT>*1zݘA,Ov-^v6_[Qhdك!&CC-n:\ UI 4[l3;Dah$?k)V!+FuJHl J%ݗER5Jx¥-v/L^Pme OǨcǃpΒy9'B"/Fc\+?>V07D-O-WAP uY  ZwP[VAy4L5 KvtI= n1?']qxՓed:YuF $_-2BRfDPK|l2jq?\d e,m}2`Ե?NJ xcHV_ԡGY#T%暈* C3O=y{0_f1ci$?bAuK\1]IPImI QъZ $Dbm|N2pmETCӴyB!ڪ l*] ]‚l@ #AWTbnP 㨮 P nK>~* ݎ`Vʫ .RuR>@~0xZ(kSPʴ0YO.Q{쥝v%+^p@&S<*A)&y飡w 9~zIM"DShb`-KpBWôBkkܠV#wTJo(T?Ľ@]hy6O `Cv%EdBKJGʑ'b2T t_ՌMIlQymh 4ނ-2I`Zz59xA^yؔhYqP+`d8FA"oVEF㰀Fq3+4mtR~PH)xBw;P:Bn)c$XPPBpjB2#Ax5*5Fx7>AP4sSQ$6DVccɔ݂T*^7HZiMwv&<ýUޛx8E4$E};)`*d}S [?^i߃hB^F]Qn'(r2K%6Uy%ƆZN@waBjx.Etlz_sJkEm_ˀ>7'v=/D7'Wg6mOEHZAhB֐-%Ny)A/[ors-/ߤjun~a4{l™ซ<7a?z-Y]񖀹LfdЪc޴uy_@c y]hԕ6#v9-dD F9'l)q){6kϘY1luv}-/yc.D(q03\4&G7MO [v!g1F%g^]MtEoֺrPxVcC+C 63O;&}~dy6<|T5I~2SП>ոLjX*_25h܎,#eNiu<, ODS',A^: rCb$fÚ2uјe!dqghi*:_˧KNCJ3FQַlltHf뛔 k}暫Љ7Ae`۬,Ƈ|?Pd/H!n/AlkƗzse?3_}.3VMB+N|DRV!vM1vadDZNzt<+GSOdv 1:P~R_(Stü;$o{BG3aN+Bv75k ~5|m6:7`j;)Df匸ћvn. 9[17995h.>$|2>C< Gi<^!i'KvqZ0H^|}hӥBR95@v nqhk+&,3Ot$ؐDB\ctXtc2?YQCW X[讠ۭ, <-h5OFX8jU ̄_]~Жo,9ӍdL"bN =>y.gL3 O^r|s$:Hr>й>B+JBt8btޱ_"f8p L[& =cb@q ,*$@)&%ɾ+QkYwEg{pO\ݒE3WjPkY~,TM2DLFĖa'߳oƻ^iƕ$ĻB]`٤Ҫb3for[9[JA؋%zn"oG_;Vu?@.T9H?UMڔnG%۴b}icUn:Wam|u'|HNO͖OXA[$w G٠FfIR08V6XsϖmKޣ@!ՓjKvLU#`8XǜVJy1h!6$H;A K7+a#;/gdj&̏7=j^3l!^5oX&OLd -)X V2YG}KoZ8F7}hR;w(H),rh8_ !Do0D/o\@ڊA~/ Bx/`zvg ;`+_Ae:C 1tj]"tw `: "dg$JpB $YL{_Sh4(ތc;.nGo9Uk$|cq?1ȵZЊ (k,WU͆RrxQ%C_7BsCy>$,Ң2ynt2lrLT UpuU.tIo.?ػ:E6ԪCOyy8lZ R҃f=ʸ9qpzŒ~]Mգgk׿Á} }2]_/6WtًVFw-i]e~e }Ov].*#N}7fAŮNlњBv+DLz(B"gP5rdL[h4>JrBWGÞ;{O`y Ywm@ηӫ+Gx=>h ƥmi-TeV X# ۵n.9\>\m֍HWWޡoŷdw.˯cohLӴZpTnF#EKS/+ ڇDL 5o2nMB9{ Mܶm۶W۶m۶m۶mm矙'>sQUVlQ92 \#@;1p+Y Dɫ/ iCcP5q[ZxLR5Q.kw`iêPG$-~cnliowpa(8'N te1)i =׏~/O+Ap@C2u$@ӋLjiG ϺEB/`GFL:i7$[=/ hdW?<{^C_#&)2qKa..cw`k']/aXYHv8\-ugxZPtuƊS(o i-Zk@FYk"v)Ns \5^._!Lb*l#OZߓ $LGw[1$PIl[6IdM.ɮ[? cf_JP۔Ҟ Z0_u>#~e%&_ xFb"X^H0bb@L8=bt%/i,@bwS 4L%Kŀ (S"S|oCpq)A1d K*IJ~ XKHrftA( Mߏ.? 檬t-pڝQ]W覜ي22#IFPIW ٠!okpf`oWǤUO^v U&Lq<?Ӷi4A٭o`ǃw~xƫ2$E[K6Z4JޒϷzr\s)Lۀ.ܲO|q4hVjGWnB8q%2fL:DC$h=~T P*5Ƚ#[ (4 뫚"?쪲2 ZQ룵8ol`wYnیP x5~څ /y80#(Y8Bt!P/VU"sOŦN%J haqBWmϊ1vݞ@?rPAlaNFԇ ϥ>,̞JU*V'nLz.)|Nj0i[4'gpI4pDm̞ N jx%)GEO~-Ɏs_zNWЋ>\,~P7 6IC%gzn:P-Cl X nJH^,0c;P_yx,<fҭЊ/ᡅcfǸ<땷٭ UX4, X0^8&lG⃃z ao*7'`Ȩ(V8b]xM=3-R;-FPB7P,A麝58rىѴqv6E1b跽Prbׯo.}7Tp蝏8K@-[7͜ c%iJi0?X=@ƁXw>QoCߥpIR,sMs 4/\[*ة *c=ih̨cܴby4h)0(x=z~Kt> -B+fOOCwQ́L4`> t4FSCHp@DyT}1-TYATi)Ts.Yjx1,Dw5 YK*0ǘ戠Vjhڹa|.4ɹr9#.Oy=J F?*-*SێoK1G4i'. *[uyƘ.ttB*&(F!H<%;BaȜD Qq dkm* &^S7}b$aǟ]}n:zx9YxcN^DMONnonJ_zGc::`܏i?e+L|8V;]k,W[7Wo=Hs?Mfx)ZPtO$rHFR3U"[6Љ:?@x5ސI\P~D:c:,#, i%ByHCOt|#tWFHuӗ߸7>mUxsH9bS;G{pzÍ-~Uk_@ +7|̆bJR.62_막Rz-א%*pI,&!'*SY3P6"{`ldshg # kG񅝭̲[5}% Y_p]ڰbmiV .dkBMO*4f~ >m!AD+ TL_S }M!ΨV,#:NU)D`(cma}ba^\{<fqo\`c"loncьgM؈sɶl^/7yךBa1j !_Ju>-i4=}gUue+qGq`͛e'\1ާS?bK/TˎA"Ya1l7E CSbYd# 0O%(ӼS!˜wz B2=^aN$|0o{og7)FByT+S@Eˎ=(?^J3\o0 9Mu5}zݧ:78MV!5[ >mƫqOqQtsOP lJî,#!l'Fϸ/RS8JH~K1,2ť,301͡^H-+WȮN#XysAލh ኽz٫UsԮU4ЍSqu]"՗hv()|@#nd”CF6!09/3;X:e`Y욲2WNг4Ib6GZYS(?8If#ieG|u p 5b%%._@2i$Ta!C|cp8MoGHNjFCH|ƒc-B-L-teh𣚹  C^23` w ^jS\vܗ4Z CO Gd4sRRYmM;y+5x+ ;Hfʫ'}4waLeEYXovWhA H^3}m&݆T(퉱>w*&$sףaT^4 5w;:5sn!#w|}< J)&' ^IX:(ai9 # >51,47([ Ntt~ŜtĢ6DH6,]4y:PwL1Y|:70orKCoVy>?%zm/8f8q.{U*v)c-`~2.*jt@֪uNXqmR6_c\뫡3o<Pn<$KK>ԥF#>5yMv+TDZԢH~w,2嶏Bb`P#ETPǮPyX)XKG<.i%o 42\ږl+y{8+{#MC(BtY׍":i6tfCKɦUH&%4QpcZ{pǤ)LmP^NSLy %|ٿt(]n| Nha a u u=,)ܵ!f-M$ ^nd ~ Mu"n1ć Ӷ97#:'ںK~kKtv0FϽ˥f6rݮ=*b>W Bx5[̚:>Չp*&lay>bf445/<ҁ :1#Xs]3>FM8r`D|3? <i ,ٙpu۹Mlw 7I:ŘʖBX}',5|¢kHi ?6@Q=%pvPN֜OEE^T !}Qwx(ϹNZʼnQ+Z<_;HmD000nzr,bLcjvIw&-/uLܟ:@ z`ŒlV fd>a] _<5DnI ";>gx25kT3تhޣ[VҋqhܾHGD٢9))i4Ц&Űp-оcd6 gra" K8Z+>Keu],"wduU.ՐCA>N-v0+E Tk!VG؉`]$).5 nBdk|WF~Rk>:A'wGiE9/A2 .?esc ʨgi$Zf EAg x* QIFn,"_,cc,a{@m Pp)tD$ܐibGO;jZ߸O(j+d[EӨ3NYD)uzԆt78̋dI'Љ$pďy{\ ir[1Gh\|9ʐ-&PiTQm hǫ1WN:"0$E 0Cĉ[̐S28v"ks܌Ze:L>P5ݿ>N!9+zћtcޖѶV2\q0.ZJN=|V0Yݟ9Y:,xpǃ%bR4FнFLvC }>blU~Z=m0NK-͉,NRvbki.̣^TFv>ԣZ( 5‰g=ڴ:pV@Qn)0&<{UZL МwZT+@ץsJT>]%UjEsR8RMDku`3(ݤuJfZp_Ќ&Q*KիpyÅ|PkYr}Qs%9!hͤN67٦zuq;s7Th`ꝁlԩ믐+SǍ٤7PzO:^ETZCԼO6fԆvy]Az:;OU9tꈁ4aIJIxoQ?7w^{F[<8uW~5BI^2hᩮ*] z0#Kn#9z:MP pc+1Z*_2+:nTN"I x%9B qpSڐh| & <{"'C/T$Zҽ` ∤?as BTWIƟ瀎0-UǁBo[{MW}oBg޺|eF΁\6JcuKd4:notsa91:Jl=]9\Ġ_!Der.S.NV<ŎDs.7Eek9 *{^ }l"H/Ql\ 047zuC^+Gv"vdXc.J^hMX_LyaMLٛ$0g/P;[k[UW#yT$vl&UR gUOMX=_;hh@6@| s-8H͛q'\OC.[X[$ϛ6E e818%Գ89Ÿ8=>w֛ gí0)LZ,2 3)Ζ ux0&K=(AJPR`(@nu>h/|'mFiҬ3 %-ٴ*=dfpL8t҆uPPr3>W iڧI!1BP&AjHOκq#J"+B&kewγ}3|R<9u(]JJIt(^+Gheb/Åp ƛVWiA^48"y ֛ *G\Uw+[)li $ha*z܉Dk 'YݤkKY:Y 5O:䂷 /Np@IZ)[24?7 rȮצbnD8..cc@em#hcUk//<Ot_6ݗ#',Fs''?@7L@08Ji9G=L?~y#/ƟַG0E ރs=vfF &Rv^(/( w8CdGQ%|oyeIf$ej"||)op*Z¤s:%80KZs1^4 S$ d>k6+cNb^2$xlJ ]ZҞF {~aWֲYx* C4YHN=H$$# tqcL4NABqA5!=k8heڞ(RPcՅ"xvyj|+7nճ<)Td'#¾9#΍|:-˥B`uL )Ъwz(bfؒ6-*uԠM2LFԚѼ) iKԐ՝z(9X.-*]+4s9jg'*c"<t=}ۻV~Q3]xq󝦴s.#|3iM.O~m&LTZ@J=hz@FW..y>H;]@1!OpMTL4jx٭Z>,(m/lF-()VZ0vFgp֐)({4n~Ή#9g h #2LzkCُ?y[ޔ&ovCEΙt`)f&'C!ͨ2A9 Vi_ 9MhXa<_x~:W7 oR uDR=\&Q?T1z/%?S||\Tg Q =o?*YxĿ6}\{o~$KvQր%<f}G0-^n#})TU>=.Э5O.س>x;{ `R'pHܒIR2a^uExنSj-'y nsR;_TøG78:V&*f&4xJo@&n FEd4^C csThqA3}hSV<02We]I..}`Pi2$ׄi_ӯ+gUjR]P5SR;m0*5PC ?s\AvAfTa$⺭0aD< *w7_Pֵ`qPn!IjF["0:HocDAaiаU H%@V*A6Nesoנa8[k% %c ʌIsδ# YWr;.p^9AB-QAsŭ뢇.Jalp7X! = 9 W_dQjGpJ DLDijnnzX Ԕ 斮d$4ƶ@@&.&3Ϻtע":&¬c*aVs@j;ug4w{R?k9c&^Ublrp"ڜn]Z EYg;A ,oa;+":yHmхm] #N0"Eɩ0L(Lo9;&_;x&a_'d+jv]l*k-n@ Gؽk+@.Ņm7Ir1!+&ˏĢ8˔˿+ЀQ7|76ŀTLuuMMc2ab'!D37'=G!EG"Z Е(*B Q R.H$e[ahhŋ(+~͸t,y='x|vud`&ђE /9ml,{I"j.1jB2ݣ*eGxymmnR~ʷ4L}~e8zopf;zU~]#K{U047+s$S[d=EKMwor8-j*X*tfaO]*pt.+. 8 F]T $:5rV@0.S (ρ 1%GZ/4 &=d[L UmH[3i&D,l g׆!]oJHL00LVUR!E"%nYx$ʱT5& }&&\Sӄک + ^KJuV.o,Vo{K1};n]UX Z,G ØH^jT&b(b<ɮӒe 1` 9b^j&m 8^QocMlb'> \|zk[8RňA:iF81,"s'oc|?k:ѡ~:@tȀKxN/ynkkL(dGo' X?&`Ggyk]]&¼߯VR8,$H4G9`[:)Y:4p݂e8m_?7qW)7~8s!,둠cgrcg- k[ `r(a Pw$zWt0=8\U sn΅__*ݝ>jL.HKSHl8 H׼WOKN.∷_ 4#*1Vb *V j:Qt<d 7t:ۛg?ϟe$|"9sRf/΋όӂU;ÆhC,NmG&c߱~.}ap}L;{wZA߰ 띏hktB|MbU+_tա]e=GB= +Iu0XJðHkWhm!r_ؖv("&c/R@Ż4KRHH̞&RV78 >4,οǗp)ĵ( Z.fBc吿z?yתYhhi2uQ9EHErdY 7.ZUuQeҁ'ǙxDy*ЎNvʹ$o|C/VSs z rmj1J}Ba˓m*Y & UT8(>K>;MF@!2VSK< . D ׵9|pYHn{z˩czqQ]OYCtb=pMwEe)2ScYǝ/@>s [)l (7fl dCx-_ظUV&-\q :(8CD+6zVLz(>P>K5FG$r8M܄2灖>awh:|T/IH'i``7pbOd/Gd(I*V .(>RU(4q†c L!>sE)!*JuՑ8r!E$#z1NUl&:?0d}G$ϊ l3"J^ISg[N]W?i)-oc,4$5 fpZ[#UAsՎE*yW| 3y(e[ &g,~70ueѵr6r k?"2"vw{>c]ݳ#0`@o QtuŁ`ӜAqaуPa?]WK@:{V}Wk# I dni ߚK4ߙK$>,*e: k~#K(t&mYjK'/e lM2f XbҩHQMvN^F2|I q74jB8',oJ ;"Ù%Zyt qXsfXxjicI&PJ 2p?k=)Ja WeyTNG!%WNю>L|w{}x@)RɭX:Q[Hc$/2nָs+F3(z9&T]^KҖ*Ol'Z۾ek=?REu {/7Y0Er0u (XJ;(4ȳItc5rak2)Z3t$'c&@}-ɬ5#V _)9{!ͦ!D#orar\[skн\eC )&A8uw+ް{y3S+ĂL` Nr`ۑ`8 YAP"8FM_`KEul:j+YLO6H!GCdwU .1ݢ81/`ߒa|QbeE DK-پZ|]^\۳tG?\< +@ݧ'Mz@ܑD !"=Lx_5x_ Me$kJRi#B&A-zb*d]↘.<.@Đj1 \+ڻLyR]DE(Ǜ`b㤲s 4E2)!/:t5:⹫~ C&\2ߗW,n!'p1KDB(? C;3H x݆[̴LH/E#,? \qͮN.>Onhl A1A3k|ՍK~toUYx_e+]0R3&K0 }-upZ9[5aqkU]VZPCfV^x%y4/e qՓKaWaE9!xۯsWwk|.Ӛ-}4>k}eub  Džq՟=}r )iNZ᫧[{<2ubY!Z68k?ƒ3/HV{>θUBWW_Ya]H>.DW,%=owӑΐ8^yoW#Ns}N^ĕDoyշ׷uԛS~c}׋K7lRsn>a݁>ԔR"w+S믚#fb߅s#i]y eeݓ}+q['Njs1KLK6'#|2vx\BX6HyL27pY6vOvJaUBχLCszG=-uˋ}^7=4l$5(7Lg^tq3*unuuZ$ l6^2 I8Q45-K))CCC*]5FX@FE1fةpwɮJrw^_"  &ȣ%aLڛ\jUOdbn-LM(+Z-mi #1NdYE=~eǂ+A4~!6 ˢ9A%R9na>4lSvxu2#kmfҦ%Bw5$?cQbQRE `Jl9L-\ӣ4$$"Q>K"]obQRI]mmz-c44?"mSh]QI;Lup }X25DP&ٳm)Ao6Cٯbޜ3Y$%SA&QpePMNx17T,hCiTR9lQ4[k1st1q3W$6ό`T}U@>b]i\M7SV:1MgF"Ɓ{Hɺ'B}dꬢtpPS@;!z|NOꢀۖUrn|U qҿK1T8h L'[8RXQ |1+)}$}y} f[˧0Xegc'kq<ܨMbXA(BnE [8.8L[T#P ey,|۪!BݚT I蠋q2Ӱܐrh$h_0B$N0TZ=uZXCUpǽ&=×dCcn]l9yq4dun= ;$}k+jo 1@~Awo6O=Zk$xfj*!8)&Iτi͎m85Z_1Rjد5Sg)8 nl P[A&$=b>#f>,\T_ RnIp-ԫGpM LNE[!q6 = "$$P5S1f?;tiYmPJpP0\Bv7=tc!.-ZsB9VJݸZx"P9:~m~ 7NW<ɑ S. 7ҕo35/NJHgrB5$ 0)҂q&uy3ܑ$'n,-L?0R@4K~h9<5jmN"h2?} N?VSaI=N5[X4+mtjFɠ!ns43L+" H@Dn*"APMߧ@A_+H&w=5g-c7's*1jY!P!"i^{h"YKB,BQl۩8LF1Vm0/2w$ݣKmfqѴq !{偲9ªZxX@ks^j}{wtÞ[p;uO趸Oo'clH(ucczi8Dqŏ4 1@T!yڛlu0KՏ=^\BSY609i$mB[+]ʔ6~v5uN3ݎMWMbjLmtI=g{Vb<3KAi99|=G,m7M 3 ]zP^dF7ÌI)6BK;ҍJLσC"AjSCC#1MǕmxDZ3 VJq[mSl;j)dڻ kd}I+g0NJw;`~u#G&^j]QZPo[ &}XA.eiض|~q]xݿ:ڃ -|1V~8luTxc1"a7VV7wśt57_.i//wU#m( 1+T}J1=Q` . N(' 262 #YH wfia+hn_f 0s|d/z-vFKt5VSh /KB PRlaCq#JZ/pI t.x4; ;Kq\`/=rv?32OlzxY8< ޘ0V-t#*L@,jnqowF+ ai՞Ȱ9 g0ugNQ4Bԉۅ(Qlh6ɛ@ O䀠NC eMtT (Dp%LcU'745\aV2?~cI~F^lh۫XWM6H~KP犧ȩMmh6LURr? 0Av$iQRmhR8pL ǫCˇr]]멧j յ3)9gO>gɇ[Y7: 2úU%U!~!7Nю^ ~S b7;*)CI?&$b7kfc9P_b`p053m2%Q8+C=(7)nr8oto s!VD<o"iCVtMNk17DȕkUMu FQ9Ǒuyy| E C4ѳ+ e;C}G}+Neʇ"8_4HI VW{~YƒϏUn!;)! T;h[A)kqDK64g;hSM\2Fkj1kh^w x>lzʙ^B!X J$~M4](yءݫR`Ѷ ?SA_M&]iϩNgS}_JT40VcUf&64F̒ІFL'N5ŀuO}l0pa6:6 mvLWyFכ|@LםsL=r񎨠Fħt+U jJy䘪b vY9S4`XD3@rw|d4yT@;4mGAiΊUnsBs~6oYYS !aynzBfG` [ R6Ao9Uzm"&Wu JYQDC٤6ѩNkR?ĥGʤṘqt͗g$qRh'G?~m_;`r\-6ދR_:V#*9I3:`ÞOO3eӔ[a0d=n$ѭh5>s+[nM fOꉵI_IJ '/7U2Z?E >Zc,; ipc5/CoC;bh(O%͕>L^f\~.ejM.uD`72%ivvzQ* tIawt% Z:*E%)=y` k]/0*9 &~v,EMX  ^؍Dz_vrU`d)B>BQN p=`L˃v*Y^ 5;mFnIu: "5+A4T#e͈u-M+D{ ͹G鵱x`/7Q UM=IԝmMMLQ5 30&k aKi*ۄ 1B}f,DB:WGH|gRo%-|Z_P 楤HhwV[!/x670:v˾x4ՌUK_cHG/VUb-px25fUf RɭwED@q*,<nrs0xJ^r%5B|Ҷby7Y.@$#P#ƣI6=꽰"ţ[5P2]׌ @LsdO]w'꼵5z]UkJ5a@9v>%~5ww>UCH_{ФτeSW[%]2 7(Lz Y>TajBvf@+'Ws;JeˢBY"\5(L5ڞMŽﻦVBcIw'A _B67+6*;]}=5.<>5Lj;x>3ISSP7r0ާPW a=-@PX]>~}%&؏ȇ7ӯzgo1wZ$ |dz<"rYjeE_a^9YF^uʍo|w4Uk^v^l_?V:# \5o3o಴Ի)urX7w*=^nW}|6 Q62A /Ư^W׊1Jhf`ߘ;z7V5C0ԛ\,6H.HSbTBS,zpcе1͉q xvW l:~\m76!_yf Ϟ ȾRRt^~%ݧ|n.cQ>#}{Wxu䃿a 2Af_k)k6>;S \Oeڽ)[А7w8e#͍c%%0@P]fr0t{R%ms4 X<֊;V6V6?A7 ߑw-O/Zn8Ba.Y=n_yK˂O.fϕ&6s6zt |_z{*Ac?MnФeŞ հx-h@BѬ UϓI`DMM d`h@C|l_ӛZ B7rD-Y7 VuӞ R-KHU"͔!ȔR5Y9 =YĪp(D.s=Rt3!ZtsBDUN*+7s֜vjGr =e !oo!#zA*+@N|+kj VP5Ӗ;+'DSnJŠ LkppSLz.!tye(xԕfFb@|[HƐ;Ch$PޗW5wyj&"ts7խDD^ToVUMip౮|F:"g=\!f۲$Ҡ7Ɖȉ#-TSwYqp< qy9D:'j?. a%;} i%]|28n4>esRoܓHt+ wNZZYi5}cmc)fW+nFn&:\qb@_jGG+/ӮPټ%f0?4. "55I )z͜˂9V@;:0Ujq؜{ɌzeFMu[@?vo># [M zi qW=ەPjAhs*9D9L^Gh0&CNssmpձĂ*J~LXQ]ߟ+a^ $uXcLB R/J;ՆR9em>~nY@6ȖN hLȰDfF 5_4wGuǫ/\SXPH8ZB?L,bAxB-MX _{{{ "I;'9"?J?Y1^kj?"@1.^pX v-\{ B8"X2-ƓoJh!hbVֳ4KSڙ-"RhgL{`l O,v*~8"\vZFE7o0;0~^: ?W(6C-Nv#'qgEotΠ6FMu]:TAx!ߎ7kSX1Ο+@/"L*Α/}H_g[^Ts"HÕ0vc%|:9L`-`~t7['F%Ɖ&#-%K=zJovDS%:[Krn(pdq6 Ik9{3ͽw9{uw\=:sy>*:Sπ*c$͌Sю'xNL9c35)Ĺet*RfbJ|0UJFc88)CR.u)1@~M"̬ ̯^'oȗ=tPGguՊbU iDh~6{9P'f24F6Q39r;UUDݕk PO HX#Z%HRT`@{&y$WmK=?;gu^XYGfxݲW%i ;5ts[M͋=2L}՞{C4vѦ5}͖G=JB8(mz.51PoWȘ;Wn?Po?dg1,#ZC']rZ@״CRKhK!l&ɦ]CTZ: 2S2 Y":.R<NV,#9EK;ѥoIJHvM5Wҥ CN’]WhR"MWA\떛 ԟ7c9 +R  Wp _ Q)I%,;_Q\Pg^4cƩPSq@Ev(kv~ lOSAM1?gB4i JvSLj[ q S>BU%dhK pe4uVK`/?=(-գbsؐw (ܶ1D6 PLuc_x@ |`\Г| vھP 6;;~Qcypy>50 5˱.kؖ#8$J]Kw0}>cwnmm]D%QvMNcDlV)yC႗FUum[@e~' ]s:Tjbvqe:zqfxZ51Ÿ^]'?YZ,ށvr2ʳ5$ t]RH*:;.!mb>Wsb(t'Q.ѱK- Ax L=a=x /rc _.boN37]I"h!σ׉/{Lj4, |QO@SkkDo:qN?3@0-NT"] ˞L;W}}ܣ}l .Wǟx𴯖,>W.â. G,o-X@u?a ]UA3;ݖ]9FCb^<}kιmJ6/vd :N"VH6l m Digh=*L̀G 5;in}.#,,O4Uuށ?. ON$vQ;0>aP`32{YlCqUb<$be;0y/yKq ]~ȃHJXg{gInizz6.L o>R5س5 V!B<]a`Ju :Q#qIyN(/9cū13YH>Ts}&ɘ>_]|*խ#CI7OYZbQ^_uJEq+UӒ{~$Z={*?GC("y6UUqםBM "r{6uoF|o/Ҵo! HYƥdw^/ GӮ|j[6 [g24P IL$IqA=A`j9mj;״#t(Zmdy\tI=S^6@O!N_ VOIK:>`܇P ?N) -lWtزkY\^ir!;"¦8PdqfXtZ}>Kֻ*z)}"\l}=Y+K; Y: }c5B^ǃ&F!Ԫ6M|?]=؈֭Fc8 v KocҼ(DAA͸^jȅpN- __`2Jl:@-Qq2:H1`<`MQA? #1j}Lv{_j+#_p \x,SlHDXLIJ^?u[6#Z(3vcF>(gk$āj}Sea+ g7fb{41l~!CBz[N%EICGk$S}Iw. \.ī1Gd}<)5nm3 3B]] Y݉zQTʹ~v'T{XvKއ]IR/_Oݗ[Cť#Ddx(pb^w|wfd ]r\V({ibP5ROj^y3\6c= 9R1= 00I-m*j˹,lw$>y2@ѓ!@. `\jPιʡDɬGHM97+ 7#C&PaV? 7XjrOÅvZKlW5rn¸R*y~`Ut2I/ 8QJ wvc|q"#T.!~'nȕd * hN\?C4r<KrU7rTƣ-V0 3 ʴ!eb"%LX새Rk6򗬪uk rP7oF;rCbS@bWYIUO0/f>.HWB-wr&7F { XWu6?qx;W%'QA)}.MXX&X8TmkTa._L\d=zkYY k,5y?jP_.1UHθ-_[,~"I Aa pj'"g( b5{AVxK#3cI7@WY0 Ɠ4@v6yR}XS} qlE`ժ'#Yy~ej3e(/1 ΛD̫cI V >B#G|M9Wi0U>DC9] kA?5Li12`/Uu&$Dx/[ Bdz \/v,z=I^%n'PP[BdԴs ^,)PaD$1n@oZ,/2CKٰGV  Uf 3)Wl_ú]U ꩰmHN;q]Jr}b WbyOyC}l UINtd0&@tBs߉3(–3/i`pg,|+`>yGwm3tR +}0꯸-{]%'%`TL cdv.G_\Up8r^+doLbWTk:pO:>Fndt_̩郩ۈ{YO#f֥5:g5]"hLh082B'ˀsz "d8wSwF%~'HeLKJi!B*%67 `0kmKuG *bQ̅ݩi o;\́8Ƣx`j_9ֆd:ƒ%NLXJQW$rF^lM4aG]ctU釨ʛJP]HQru !YljtGsؔMNB52 ɷAX&j6n1vYN84J]]xAWd$ViJv 'bB2T'XQ+ z;ȭ[8xx' X+ &GZS;-%`#1`6z ܵU352ka+QdPix*H2BwyX$'MVv &+\Z=C |Qw% [Sq+o}̿&J}z]blT*E8 !RBw@6OwSOR'wNWM>) c$dc ZO 5>8畚X =%ITԽ;/nnяR&=O<CYy'ajhU{"M?ǦMTw!Y츷g\hDb$CB"Sɑ Qz**08j8[jZVvHiZ bq{-=kŁ@oQ{oڹ_ BR}[U'9VPPCFER.}iA oNĉWX^Ja$bPzSTx=E{y]:c » ߌJ[ 's9Y8[_-Wk .0뮓!)(H $RF?B<ٲZТW2Ǐm%f^8 })?tkf___ ~~l?cGO \7qG! yڰXz?JelfEd.",_?;A {@`'k`߃,q'9^kr5ˢF̝p֩VƆz,z|ydYRD2XIFzL$?O`BR0r%`F}ߴY&r2F!| i#KR7gJMt 7 <!h,*44 =H"bE@pGFYQuklHcWjqA(eƲܽ{Ii88U7>QEowJKnϢƥ;F\۽ɍ$! 0kZ|͙d}ne19 ?]u˚!mO? 9aӖs~/4 'MXoYvd4_ B LѬEq@qT]S\/Bn,L:dkf:&3"?f"+V43. A.R SI@u@ ybRaM:]kNp־<@2O$vx7Cab{iYۺOj.Ѝ?*1DD;vE2 )e K>I|8nnUY r+nsvX^?q"(_*7L 3x,<><>%"]Vw9abxK)+|.|B.0knh=t4V~p$_:plj D i4_4_M`eОLI' 0rkxZF8*:e0ya s"D&{աx]-Y >g*k+34J 7m99Fuҁ=QfymҁYf|= C"|`EN1ߍl3S =^wznɑ9=RWXXщb,$Ec͙EABr$ȣZȼE\E(Pmd$2h cܶG#)ֆ،X?}Ԑ ,8>WK&δO_1'3r^#"mA.Agx!k yA6)CƮDAiN˓8ַ,h{0$ԉiIL1kZKnB6smӼ 0=YSl3G/`2JN] Ֆ.bt,8TcºZypK3.BYaGMmxV󑖑JYUV%ctdD嬮B%c"5 >Tز}0Y YrVK0T0+b?xF OO-4F0+l龚,dn)Ǟ}ԇNJKr_эr"z*LF d2L|`w^kG&=UȟB) ȦՍ )@a/fClCEշUԫdO`36C=р_6t=d \_xt~ׄKW+,}Pv#@e %8PWGjw^ChN!& s1 Ye9D%FJ<8R?Y/`i ljW8k3M膱eۈx r n+RD~7,٬5h1Itt=&gHgyΎWm<)3LŐJA@f&7.'WF#"}l!B^N1k'!†{bI,;lϮ&b͗ %K*7eaO! &' fĬ<+39Vyx-(be'0sp|-RD{~u{3Wv:h"Q */CCO~fn5i6}6%ab~H rY8㸷c[:9ͭ-k_&tnq@'GCf&\*%ðҩOx1ڽi)e9G ^[2?YHmوH8ۖݿ.>݂-Z=]mM;e+_xv+OpΛ7/sT%@~ 4͗ eW9ruR%?„w75BuB_Ʒbį i>~'ž*_9ȑ_ _Or׋Y#.b0}`F ya bK緹/r~;P f8Fog3tpeG4~w*̟Hp|3mV<D@v4{$7ZZR-h gZkѰ5+hoM(\sB=_C-,u!{v/T+|Yw>du+؇zō7, :V<8L Gدuet/54o}b=_0snEL3!r|)CLt 4ռKI\[(8Xv9ZKٷl7\v܍dtu]Pl}5 bPM,`n՟x}Ɇצ ׆,oI(!-Q+ϫM$z* dWbW4>*ĨIBQY#Ac*砊/NPGEWd5X] G =f,߬|&*ld-r[,`ۮe#lU踄ZۖуE&v /_>OyJ {oIl2Mir|а~Ke.48;/f|W{E)\G!WƂAjXQ J]T3D3 .X$uy0d]< E//UcѧBYLhD9v7-?(B^|@(+!K2QdX`ˑ{l/&  <:֜8^#Hc5(+;QG ̮aNd[nTSwh$mz5&n*u K,Ө~+޾:e6^ 3^ zw%b+!&)m"r}F_{nlBTY+<%I)MXAC!$l5pd 隝ݼ̰G uOZ9OuYC~|/.IV>'9thժM=!9y)o@Q~ڝdLEC~C$ ]Ҝ) 6濰wTعFuK8 ,7߂zV&[b [QzLKbrXJ;M#}/Zj5QP| .bNj?hE"\"#/gdnU5ӊ I)J.Hls2r/Xht7e{ASV<͈̈;jYywb؝׹ݯ&Z ͺ_Pɘ8lF8b \FKA&qDn[؋!h#EUR=Ff-Mj=n*F+՟℡ȎBQn( +Kzd01<7'/S1_ R fӑ fMrUELw'9{ۮ)R韔Sˇk>#>k򆫗8*.ϘO[[`ldK^B3,NiJ.V. 5ƹ hFΡ)X빑,8Ǧ D$)m}۲eÓ)+(%֯@`*c@[]OԶMŸ%~b ɴ+Ih?$>g]t )a淂$o}2v¤|pfѷ_ًkr!#nwB`#cR9RWdUCk.x:(M. 4SwN{̒nf}.58ڱ)P/'PݬKdyZoЖ-|ZŜ2ס)Ak~ʳF4RG&1k+9,{'X􉄊V\\ݧDv0h(~ F*C+U )kޠGY99`ײ/#)F S+i)FH}YElaծMsn1-o饬t8XRl(ih.k6WKnPU4PKSfY-6pvچfF(ySӭ!|lSYU!Ya[* l[ j,$dlY"rRJeC#u6?jjsGΉRE^:dj`qd8]ga=l 0|Sr_ҊUi(Y@S^V&XtMZVp&xjcbD gC;# iЁiD-&'~; 7WS!!YNSY) E#&Md2)E SB)5HGV~:53o}&Ƕ,iX.?Nj8CӸ{)]NބC#T3MCD)a_nO6!RhRQĤn1*n Ԗnu jc=Z?Tj9#͠t5YWjU˰ Pn0S~7yY#qKK{ 3vJop(joGg[b0mڹO1jfmů4s@#Ǩi3׬HA~_FZJ k'Q1mWͬM|=?qKuW/\ pS6] q{ܯf5W_l6dKqb|*c?x3cf |&s~eb}4$;\V^VM<%e>?k1+?~w'xA0~88!dQQ-|fr WB'8bn}z^eF*J>:0,+3z06qVȓ!HN1y|y<[vUŞU 5{ y4Z!5;2d$GeY|kXgV#_9TQ S;,s141X G~SE+!s:=8Ϣ!\O }(Y덩%/9#jur1Y1/-SR1PW ?}+9GH%~CIBcW&God߰NP!q0sHF@xk:7[6=7.;[ig(K$0Zpf,xK& aM9˛Ct|qRA.9Ј ;Ȳs:te}akir8t">&.3_[7~ eV9"A cNHMrF:` aJAr)u{Fz,PXxW `Nrت|6Na{ycUELIQ>eCɼ~g{k?esz5k 3$].̼JcA=I;FJL!Q>A^CoNA?t/n(Mm!`1F nU*&0vאx']J/!C:۫ `#wE0qۡ-#Webs'IHN=Ecr#?>TX { AT<ݦ;/7wtXpH”I3BBe4Sq\oSGay똲# c&ZkM\ra`8</N[Pu4Q`YR9Hl*4uFLQ:Hq Djb?NnB؂Kq;UĄ]Lg~GaO6}*nV"c=%L Mq6_p ?B5 ,z$ohʼnDiDV3"ܳjc@CpԺ~[}p8oCJLEǕ:49eK* ):FqHC!C1/Jǽjw8(#mϸmeD  m(O 4N1SX3Y@oN0I52Qg% vS\RcEn{O~1T+n)xiw7ա Up V.8JeTteP/VRC;Ԡ9|(x0 !e~.9j՚*U ܩ\Nyb HZ޴x3﫹خMqj=yۍȜK"VEg}Y~^b31`]٥L,7񌤵yQwLkEbџG2S=K| H i?Lx~2"giANJĞks+hgQLu\yP@.L4NUΟMSQm_+J+|QtMح-S䂚jҐA6r G-UجY8:b%TvKsMzyt{H\[wPŖ1 ӋYmj!zJڬQ K&w^N.d(5t8B똲 +S|q&ky*BSؚuBbFw%7JV8+:{q#a58k_!kJ\ YQZLXOF!vZ!+C\tS xBbcj.t3Q }*42}&Mv({ʒCbƮQQĄ /( %18OXhy>/(, q#eciPXguiLm}>=yhaF~_p)L12ҙ5E`j+dj썸]tcʒcQ "[&a SϤ{P^fJ}fg.H92!篣,RP  xh}fv;ξYQIE #6ZșLtܧZND=4?tA"NiQYo@пۻʘ+܍9lt$zZSv#|77=v;ͳSj* NHQ-++]\k9}{>@O5lg;4|uo/$M^=R$L_}'u=+|5Z(}H_2k=ܣ$ʐ2 -K*&k@0PCn3fV*tea:%TMD=g43;ggHaʞ MLNj6y? ?U{727_$>;!hi;VmAqdXY]-H)yخ|w<]8.d\rvRs^tew\<{tǖ>u m3{.]2V.Y2ki I>kֲɢll3\\k;6XH e+^k''6-N2l_N1Ur͞/MaHgqqEX8>v6ܙr5d|3 .g!nF#=c$$@"!H8ѢHOep4ęggZ"8v4#}WJ(4@D1H ?Tc]z[_.99|h_O4RKޖGξ }@\UEz~<̬Y?#/@ I|q`%%4lo\5 ><2lC v?7E=]vouϓ1"闧a(#׼eK}eAY=g,SNj7h] F!e o1^1YKD{1K+;CFu9,"x|*2 å*8+٬ 9(_ p>/h~10+F~' Acp5nŖvζvOO+s3KC` ;b}$+v^ʅ*/`OVTX&4]R [,i8ZzҺ5 CF< ZF$}ߦhj0Ҁ1j9uPz $*2A2`|G3:NPO3Y#v)_Iu h'"#`-(M{ գF&0:*lV0:aE2ҶD{pRRMJ@~Xy-QI'fC@u_cs Jf͉) (RMQV13#{S{uR)Sln 8dipMmqa>N @ <;]rc3W!<ϑ-u;O þs*qOrņ,kZJkE?|NcXebzb'3d'5#QHr2mo[q#al6)~:sauOR,jk12#&s^3p:R ݴo>ۻ jTHBN?V︎3dx5}ǫl-Y)9ai5e";bs`9Wڿ [QrLi\+|&_!Z=IH23Ҙ*N'),k2Xq+>5~J0ND?)x$q,TD}L/ߞqˉƁgpd2Sk`V5;p5:LK[ kL } #?>$xv"1 ơwq^"_zAk(w1Y(d$:HGQgzJ<zR{X~ plY? s'49EK¬{,$vêT3QSB5 QOH*3C~sWvN S*rfjl_9@ѽVd~T7i8x] Di?* x$T]"Y fTҖl;Z&OfǡW6*WFDNU]{L_Gt#PLƩiF%"W,0et?!p|LBlrFǃ1@OʵТHNFެ(dec KII+SܸCHAf(-L)4%/8R7+skS6lEx H-\DDpJUrDžt8hN%X|*>6g烷.dkSbhGj~aA#/feY)[Zf !,taY&3ɏŐMp'(8zj^Ø_ncFL|ølSH5y|JMo$iIv-]*+!ʙMfhIFB[ /Ncc> _pyZqnM"iu!Y)k0NW$N*Q*.htAx+(;21[ }p8wE+0 {+4E&' R]".\k&PR2  _=aWxDAw0L/I]6*bDBQo~c,|3w Fi E}A`nY&\V)\ ?Q\gҞ~%O9UaиsHm\e "%/S= f'OtٸFws%-é چB{ւo4wǬB:G*U{3`@]tqqM DvB-SOW2`@-0⌾_9n$1I걉zP[7ʀJmIw MrceSʕbΚ6#qr xӵkyP|X@t%7$Q=Xt4ǐ^i$X@i7ϛ/H ccP NDBz@hRtdl,n[JH(!hNudRP fz]AU} }O9of?ɾ̶ڂdmcY6v[#jHnu)m*c^ rԧ38&HCY. e+4 ͩ7p"40,Sld Fʨ;zZPc<XxiӀ\P&:sFAIo$Rw'yi{` 'q_EZ JC'Ǿ2V0 <52D_fO,M3%)$%ewWIסaW'[ܮLU@ؤ"5V{W2|,W'%lQxB1}λ\s~19u2߳JYN Խ[x-,~qL}[Nuh\@f5}5` LfE/Zw{]"Gmq410yOP]9&ʎՉUa@]uSw Cc?wuZx}h+5Ӑz*pnq+Iޟe,iya!ʰŵD̟9&VyλvGݰɅPwkϱ| [԰H $ɤ]~6,_OW@mxϦ(?WdS#q%8 ,ٓMU_ŝY9Ʃ%n]pHR0+ǫcvZ?/yk$'Nڄڟԝ]/W7SKf فw~F~գ(L}Zi|yvp#3ߧpl4ϓe8Wu@0:̎ZOod >1\gN |ZߣgOuc+~Z1O?SXuc_]'t'&uOp3}; /z|tyx%~gxIl|'))hzžq.miV'6l\3%HEt|x&>mwKiJYy C`n q/c&Xo0.OLZ%&[&u{!1nL,49jnQ?xi0$ Lӡ#u<6=3%zMxD?;,U2\Pk*+&{'A&BVNb.^ Jzϖݒpߵn HUӘqS^:Ћ~-Bhs67%{l(Me]A}WAyT5rA^aV[3xsĆëiJw|-8+{n7:(pf58HXezW[J~<|P3T/ƫg]&*3_%nr^d4YT8 \L)qwrjBѠ_-sW?7;j|>Z;"7m8e~}l!]ʂj-_qS}rPWZ̛w3BUR[6XL!NeSq~c Q]8G{ /#yD}lhjYXsS:nXRc\KUEk>B(KZIDum3h&lňI@xj-GD%R*`|O~%Չnм^"80nt 0z/o>/7ы7vFm5G CPƌO*;>RY?(y,GKa?/#aMXWȓBU3@WsLqne toB0/fiCP{M vT0TG4(_ hD%hR8 Lc_Ik򰒢w\ "O.i' XFAD/ngT)^OO 7Nk+6=n@!!m7_,_ (1ƤO#QwpCZٚz6]cg V6|<fB:_56{C~niHMN$NӡBEU_{fL(sO vm+I`N Wo^$!$Ⱦ]sh0 ]g܄wog`BpB46u7d[]rxuǭA΅\P{< X$i?!򍱊 ~&0@TI6TMNѭ3 SaqiHy4å g'z7ƹgZG _LQ!($Wv>t1S !DHQV!ܖ8k,N{,9M TmϝD4H[A!yEDKnƩm0ni?5M87Á^vdL5Me}Q;Up;"I\p<N፦1X9Z|1Zncόqq5lV]e|^0M)2֚q޿?tk܎Ԉ<睓nPuԒc=k&xBa[9-%%S@/.k4JA$d%ȏim T:,l~+@/F6D[_tz?VSA<.r=ZY 1QQajYӧFe&4r aH*؍&oPd UD%W)\?ٜB7V(ĺv>ǨĤN[=i A0&iTE>4 zH#c;e_D؊$x&LD %H,? 'XVW@-IXǰh%ukBzR3fE;AvEIe⡜ E$. sЪgn+A7M>~L}3$EDz\CANQuLPU{Oiϼ8TUb,/J" _nacSt= AZE6Q0n? 68pCȫ'`g]4gacS_d0D}~\/Վ[חAO`왒%s#2tĦ?5cϙˈ^klңٜ>,%^TF>u̝,4Z_uQj#>e8Rj+]K3R Zo4R8jd(!XM%Zd&SՇ5G_|i'N]~.-/HM7GDg@րWSHb`nJ{:oX6\pHl/Jb݋W'ȣ/_Vtލ< իmtnUPh0"޻F;S!u +DzҖ)GP ,3wR8ɅPBZ6rpxl| ꒏+/Э\6~IBdzO_;kQAzy#)K9e0wF?>-AWi* of:@%`њ %٩Ml_ I=آ9IW65[oAJOOɑovws#Sӷ~ע)^~arQa60zDr&T[,v߷WXסRqܳgEQsdR%h-q}KƒA'ҍdLAьIڨ$|`uxMe})g7SApϼ>|!Je ]0оMHt쌧._'u4oZkxZ7L &u8%Uҫ +S/p iŞn S4]P{d!!t@y?CdVWW|>pu3"띂iv2l[]m۶m6l۶m۶qc9wyy#9w84C)躚+ʾYwiQQviNLzx7~6m1Aڤ`q#䞨{Eq}[ + K-bhn^qx7*4d8#FbtphnHSJ-#=s7 }ѯ_ \yJwgo.[<į4%KXyD3.54>U^ILi;6 Uyڂܝ8$#>"oNH98,_OɿL`PώS˕^TBC(Pr 8sp4#Wy@4tB_4R2n6H4݅>r)^( Yv=>YK׊·\ު=Y/yg9g;o>PݾXG*7˾lD$uWaZ^("@$S.Жh1Bc3)lR yc "¸ߟגʍ?.y5?J5 BoZtb+y/UҲkYLIf''{xd6jSn%:JJ̺8zS/u- ?%n|SJ}~}CM$ s=ge3còE{6bq<Ȩfqf㕽Mh$bz6Nd5w\R-H#db3/p1~`:7=wXH*[ZQAgj 9kH'p:/\/1YZlHr;]-B·3/a 4$M'ң E@ m}`I:!NX3h#"ڊ 8jJBf2b|`qJpJaGpND) y h  _Am #O֌l;n9I?Veb.=/@,gLK]ds7G/ddOɿԥ6dpLSG>l!~hOWkəH "Fma8`p1iʢG -8bw{ pY2Z<_xڛ|20'y3%$s:g"2:X{plz>(|R'JpP"%L\H5qWq įz4ⵁ\`^hSkjf]X-wkm< hTM8$h;7,S+xnyz'͹,N79;7w?}}AsXJq'KBRXImfŃK^!)j\N,񔐁Ѭ#t7s/Mnɍk˨7=jҰC.vZtݧA Њ~o)?EI3)/Y+}?v8 +1y^Ovzk"DQdh\|}%t2A0Sܯp$%U`cPyٝwߡE /N>Rw'wG*1?5ZBo` E645D3D>4 V>" Gq (҉*2ԫɵXMgU[PtR8 c=?Α}p5/]9eܼUTG Qcbqd妰"G>Pe !{6>H8Oa(~.¦«3OPʫ/uv۬R1oUPUt=b;@q^B(k@880/ok]F`UJޜ͢?,vfSSfDV ׻]]RDqwhQ(]`i=, Ge *J7pB :\*L:!r )d橑?:CN˱eƐ -5 $2 (~,=4Ě9^%g>РŇř RigDX4bNgYLZm~^MoQ@~i͏^ g\%6gaU$e[SMl)aIG6{L-]ڪ}ڨKʈ)H=S6H!Z" #  Z_ EDjn5nac\k8 ]Qz&Xwƚ݂5rz\Up ٚaぁ[}z S!QXWd 2RG8c&(w5Pb*.g1250Ap3-EGr٭Yf˲Ǣ7pUYIb:I7|N>{1a'N^)b>eUSBH=߫%ysHbOQp\sq9ptb{)WY#oϫ`v-'`Y;ujJ58wHC;P%|̀.Y ;ؐawuʻ)20m-伭FS5!@qk٤$‹nw=AoM0(a A:94?8 ~vhn =Z@5q7nt4:̂| AN;fMպ@L"uȠZERA?,yGBl[{^VBGρ]Qigs`| @˔_1i ڳ`^WCvDlytߪ˨ cK"Z18;6ȏ5`5^p'+]f)[Iɛƀ١[>NB"u?u(秸+E{Hbm66槔Ѷ_gEp)u>Wp8syݻ vC Je@*%^{k@丈8toeG$F m'@RAӥecKC :'傜U=-L枓ije8xrj":_2modsL, % Kk *KCеAevW~)kus>%Fm\[̾jǯ++he'c /M{ pyk"NӔ KC@,d1V,6`L435kgR1hġЬM8~V"^͟Ej7 ٨GGon{CCZ5y<93R3%E-f{_GVܚ̢Ʀ D6KŰ11#T:?Nwv\`Q$=8(]*ܦ͈L 쇊Ȁ* ZΨ0!R2y[yx*OhAw0"@qJ Ӝӱ1?9{s;7+l|c:u,b ^%]s <繱+#zfsEmk }A,,#ܛղͺ|Edk߄aɤ^Yiz*=6D*6ýLbl}),Ez=*2"ulӬN6^V>uh,zxˀ&BiR&s(?J5FINjS:4! .Or7)Tج"ITڵCޱEG(R``lFIO.F[\dJ c׽`dp^tlua[aCFۭP%bjӳ* _v@p -uBP)0j 7hpr'N2FL-ߋ9HK}&b*ޒC%8̴qe2C? $< 2Yr}yũ PMf0WdJG?\Nu6< P4,L{ΗҰU~Zr~kKfX(@;Ûr>BćOx+FU-Qsf%Yce*N# agѐC }EXMAK|;M Z7 cc%+eվpV. _gu 2—N\z5#M1H*.0⇙(~_P/+㕤t4,wЀXOn %̃aR ?CȞT 8KRbR"dYTajtגnwt-o KENC "'EWA[z)`IԚjj%q :DL%G|0ӞjdQFCQO: ?(I_,7A 0[ azfل? -XQyE5 `7[_h ɑMBLp%k0,4߇Y ӢumYH v·BoE!R/oFfRf#ax?JV}M%6Ik }%p6c~V5S3}l2 V1J-y]Uz~b.St 5)]jW"##HJg tʼng3Z2ɗM xb`1u­`;T ^?+/(mt:I+Ya}^IIMQA'Ҩi9'3L ]6_y]hckAr98Run ΍/[W^[.[ V5 1tI>t(b&dْd@'Wxp >s':1]혆x `i"9) &Ł]M 1%nډ.m3C e.8 /.=gÔm] {BZ8#Г喭"d @Lo'R#ծETxŎ18IUlc Rz8A"T@*6+ȹVlN`?n&"BD`uy['7쳈Cdnh )@42Q!Bj{yEoxNTpX13rbq hKNhw"-.n{*|+HBu0m4gJ!嚅ʵ=$N/+CX^#˜:CUʖqA&4,tXѦkt6i[7@ZH D 18,-q )׏蒇סg/LPB;=|sBH> }@pv`+3>^u=9zݢvOC R&+|+;}&ge(kRUP-g{,'x9( y5Vo!jaOf<6%kTËjɪo) V+by0a!t9:<<+;BX+ӑ>MPk.R-IEK,lE hI'J)K\geu-g(-O=k{\le4̌UGHOöWl6].pH%g~yrL`iF~r|oʵs)4=Ϥ2WfbyX ܩqEE%KnnKXڴZeDE,7YkY.H7~I\Emkq?B a.OğS㗈Ao <ɔD<;Jo?\9m=WQgkvB^bC *{O_dmhWk1WfG (L {prnhY+M\7;4!MY!->Q4OG<;N/}.`g%ӕ,~%L'a=ၦ-6 %"'rѸ0vu;˹1Tc?tEeUnvL;[9d;rĐsy.ްerեײl 1h43W!13q9:[ccC'S*f&vM3WL|[wia_}.J2Uk涜̧lG? M=squY"=FB;Ϣ{& JAXcL@-&azpa`^\'BkVŚ?)k%׸唬͙޿~p ƒ^54q?`嘙%g hܹ<^+Pd6f'@fw66NDu '+z0!Ǻ_TɁxT3 XDngR>j}ЀUÎa6`5n0U/9 d )zZw=ޜb=de EOl!GS1n)AKUfeNNcr5=5*ɌQ9ʊlC{_s,|2 gzPIsL+Pkm=Bd”;gcCpѪ!rl 6$y0+F=ф-)A1tyT"<<1-- 8fvᒛNv5l)J7RoEPXB ߿m: *C [> at㈝R1{USg)pu <`=8s*B%A *+sN9~l06xe]L'rOn& 4>85Vk/vH\G{8x" Fmn6#p,9-^Ob]5xYH }͑K+5M:Q9`;-[b Q $8 %ٓB0&&oM]:p|uX\D;;Gb,1>vY/.A9?voJZD%00#c=of]}8P?2!$Nv̬Suԕ5g팗9 7.aÉ dDy '-R51Zbzi{r] :T25/-ar6Ydi ꪑbվ{ݑv3bߤ#Sbs*+;$єNUv?4% [ĀNB+7!x^?8Ʉ.DF$o:M&RA\&(x>;ۯޗ8 h~L/@5QAPX%>>@` "9v((;FPƭ+m+JYbw%'#T$S&hT,I<ڡA#>`=r!zݻ?,2M29˔mr1lQ:C&$ H6EP2[nn,l}?+e1  <Ss]TICJ&9|IjZM*Rc&^n8WL ojnrz-2 E8!٘Mbiy&`@9F&T#_&.vB̽֗rXvknNT0t2 >ZJnO'u=ĵhrӀG`0 un ( )L9VӦlyfz`?!JUJv$⼂1mXsdiȻ^w>U# arჸMH9+ghNK)ٲ<4 gL>%>Xۖ |PNsinƾ;ddXA-~d**n*֥G~3|\~ex{~9[mX}'lP%zvlv>D mq vqTeБ,GA,o$~E#{9TT~p8S1Uk0v-_P7GDM_"W.BiRlvlvs~a@BL%ZL[ʩ87 pr5yvR0a׹ybQI /4R {cjje83^!7X7h~c}+;pmZ}k7m%jj8_)p)wdJo L=d72X;I_ }own6vR%VʣqB7uc6^^^׍kmܑ3㣶*ZVrM YW+-6dŨu}Mꕘ`wKs<6" "U:bŇЄ!ƛJdjc5$bm 9 OU3s2mBYQAK*lƋ{¶kyE/8gkvuW%sFvG{9漣R\+\WK*)Tz [[Uw`5d[-^XkTXiw2<;͙q1Ϭ| wzbf%+ dpgcRJQ(Ч9UpLt z{oRޓ3F;Gpu0s%68ۗSA;NykA-;|y~^{Mvi(^IggؠAȡGtKm[5v@ 5wd{xEٳ8}8ZY/"CmxIY~頉xMH2fH){ `WbtD\>攐#{B Vm!$=h պx0qQ0p gqwARo"L#&1:.̍CF7QC!6/rp-*LMc0iO;96Ɯ8\敟UWe5AڒžWZ)#Ɩj,}ײጣeS:;f!mZGI@9n5 >I6l_7ώ}G٢HL ;8 UAIOJꚤgy3C2Du.$A`[uB)!DQup8sslvɍDؓ܃ARBk8$MU臤@И5r|J) +-vkAMjcb7&^wZ>V9%sH_3tfP-Oc| J`gՐHNWOD_<70G"[- Zn )l[ow!ˆQamd ‹ỹ'**{ǪY6h۬<&_//xLzxcAn/La{J˒uR@tZȦ#cM1DPik?Ms3zY9 g,V pLB&C3x(q5S2J}'RRfrK=4(g`C/WjHږqȯ6#!MVpzRN$Ԩl8Q$mǽ>m4 YϤ i8Tmɋ]ϪXy $ 13xXON)ccQ$mW3L7" ֡B:%)A'"A7em,%Wy1c ڬLvC@55@IMt ;cZp!@"q~G8MIo91+>@W=|hLNdmvF_9"ᄚJljjǦ`}>jGͯôSӿV%|OG⿬ e2%m \ ra CJ F%%\L tZ%n~61FDaQgAՉk5A bӇX= Eg}Bu5XL7!5gX'm[†'l'ff1֋e*9]Z1kL8הGF56[ jː͝$ iͦiQZH/LTq[fZ[f "jo5Ȇ+: DNf-77J>i(ܨ uYPfǃbڽ 6_e6?#[UÖSL7PA^5Zv^'=2j^H7\3heτ~'̃7wӿƶٸqVc۶m۶4m7vIûf\ ;#QZLr-$'y'smKG6O515U SZTRS(ԣ]wxsrWm"Toq!ߓ' -`yͯNaZzJ8t&S&5m&Sm\. D1FHi2U' hbn"}~Lg.AT'F5ۍ%+$m-)!_p%3G= P /pi&]Vta;IG9z'._8BXXAVBB4qA fOژgVRKJoiBemo{:-FIl: \[ ?Ԑ$ {Gb F Cp{<Ѱv1[Vq yy{rYZoX h=OO ]Nݮ w;le5š.$<Fe|Ftc&Z#RmN–_ 6cT2hx029F +?~ۅɮG#E4Ǐ FڢnJvxKcsԞF:)>g `&.7O;[Q_u#2'9GI"&-{S`SO)ѬCȄyZJh];TWԝkԊ$Ӳ **l5:c=vyGlGVˎNJicN F0r.i7ڹ 7 $=G(Cs VǡAT&#e z001Rx.ژ)'hA`a!AZ;ՄFVC-J媀'jM&3]DPAG qB)y5McP$C&~sN]beέ Nkapk<=ljcQ،)_ Y5Qk0?$s}=Uy*x6 #+p54QK~5.#T+ƃx%&Y B L IH<$u*H"Bn2 : TEyu/X-%^e^p#((n oiL[ij<ˍ\]=Ev_ޘzDR\g .&-o(b\"4Ka-\oIwJx%9l(8NUŔzAGlg 5ر g͙o v8/~}ES_9g'qޜM,` #YoΪ;ʕ\oM,,us1(rd#*kP`CX:PU>x?pt~X |!~9Pġ(_B &:lb1zިf~֖ukkiN{҈A{ٵgeL3`nsge:Q t 42N5B$VoAY} Gl}+|('CΔ`-y%wcPEuouRsQ%U ~b?qjhD;e~ld7T]}H@P_|yUUb'&??koXc:ֻ>AJC1V7}YEO}gVq%``@8IE^ۆܲ".E(_² z u'7{+-3n7uѵI_L8:L0CȰ.sxϤjs ~S}Gu݆؆=C 3|!yX$rq${,d$Db\3>vԜ\\!ֵ XaN|,E9("'P܆In` #ČqS"uRhH?]DZ6gT*RBTbltTWGnTtHf=ܟK_rQ:O9nHQCԔn( LRnY Ck߾=qG\ &cL~֋6/M4HnU æO|S8˓V2Gy5=VFzDJi JՅnЪrO q]Pť~ )J5eY=4+,Vd?Ψ9A* ', t)fjqjqn}uu4EJ=I[#F}Jɺ"rGA:Rf}:|-O4ReÉE_%3X]#Bɉk)laҬa*ran֖z~hF< պh ZpNٚ{5))ڝ (RP$ [i+%cM fc9Su4)9>@(K|=^?3;w5"iŃȤM/NxϧեV3-0#EvZ QUZI3ۤ\(ܴ"e-L?+)]'yGz (JvwPrއ$;X[F[a zM;r:؀n: ;噾 s=;4 eGnlcdzj0|J(FgOTo,Y,[ ^rIG"Aռ $D@h"s7!^Z޳y9k,OM̒@ rY2qI5z]t+5G$z<=HPr0†~ASDۜEe8Ggkb_´E0 rw(H0c͆j)bIeo]3(PAr>6wD" ZN1eACI/*LwUii kFF FI> ) ŚJϯl&#8E`RZP;n!ӮiFbk ĭ0u@sϻ=>Ύy|36 2ua Sz|U{w5|< >OHh%\O{)0-xlYP!=?֗rޥ!M.|/QLXhӽmFmv7&zfF֎o,O|K3UxḒaksl+2.S2֓ ^C.p >;J}DQ䵕+ M  : ?0-?Ni_Vb " A42бDd",ѱc]q/[tgЅ+ tn) \.|jx|yŖӷذuYQ>ǁj4a{^`C`$;]g_E~k,ڟ:1jHypҠD .e?羗ϵϯϠ+ & W.{Y+g9πVS95C`\@xzyUX.đӛc'}ϒ9a Nö=qWTd湪C8zTSfq W9 SN5G&}b6~s5Vz$ k&lvit"ƨ{8* rGGڜ eOCP枷vVL,{F&Zfӽ%z[iI}#7ɥ)|Vg.>e }Vjs~"8Km1Iͱ.Pzx%&91Ozu+/sf-ziBm֪'e҇$c~>Q4ˌ4|T >4ZbI^ʗs쀮łJ;ۡm% AY$IEXŢ*is}{TyUB&u)waEguBХfaeMR-T0Iu~&<ɠ ˱v\ñP,idPS|Y: #HcW`KPYH?I}7`uenvm F”jԈR3:MkR0Ht0s_D/XSęp&ܢv*~XMzBF5c歑'[M4mgn,e*}M[_V ̼c|g/$[ZWtLfmWs~q?Dgp66 ~buaWǞGBF@+ʝ?Z07(I\cX2y}&=nWv =u`(ϞiԘ {+e٘_`9TÈ#*'0<򖿗p6 QKƩh$BT4+ ЉY VgD!0؆!wĘDd iTU;FSBG ز 5WCSY 8#I->ٶ$030! ZNOU).pR"#c@C%# Rp5MhV**RQxN+>6(R?kDAYV=ƪY7rQr-q8̴Oa|"q6drf NC$1SU t{{nF=9=k)]B+X))>i~V*=2%w>-i.{^gyҘJy,5V zb8Q&Ru9xĚt*\3j@c+jQ+2Qb~ z 48h=w02:CW9aI3T4t:CY-G? /f!*Bs7Yr:γҹr,ϥͬ@ËQH;gq_w̷V)Wm'E DIQرQO/D.%RuA5 &`E*)G- @aCgj}mP EJ"z}NlfC ~9q|$z&::_O.3_ca$0y9Z[rH1A慨M>(};{"y ɹvG9BPnbԼnx; OĝuBwݯo'e-SU _ yOU\|$SC!S B6YdpE Uw[A!#`0M|jTI*EҳD u4{ Ȕ (3k5b1D\&A%CGkyQ U'&k~=B(`0?=T=cN-nZ5'S-k4MyݧH[ ̛ h.隲9Zc1 y~tkL锭B%%@vpw؄p@]N̝YG:n< @ABCITwu{X2}}) fjGPފxTfɃ*AmFvɮZm[؈3k>P5 I Xnk`3f2xIQ}b<#2ߡr.H SAUUv~|LٷU: ȃG!&ȐU, wV "\aٯPֲbs$.;{*}e0ѥh,\)C8 TBsKS3 v^q*;9mQPhͪ#k:2 -rF@j[}N4A4a6b"GߏMvGdT8va_užò Q'; PBy92f8@>N k F-뼟@p ܪ\S͊ȷWo%uj:iY/D h0fuw4vQđĪq&NJ 'Ig#)G11d =-iT G]7ӺhЙm )oo5ompL:Wu4ݮv >o_iרnE^|0\*WN|n_lt1z R~Kˆee*M{>h oʈX٧28.i蟸"RŅjSaGVǽdUG˿;)DH r -ļ&?D :FksWȼQ^guv[[uuՅK.N:kǩշ#cn):o q*oV[wM5v[12QI9O8r<(M.[E48DTшH/_D?D#(/]Z뭍&S{T_z~*61aQȐ?lvN-y10#"ri6Y׀wfJu\u·14z}_lHW 6=ИɌo@!җ ދg8YG"$@rN"$O1Tg@Wa!b\ gjHv1u xR9Z`[&`N-PD:T &=@rqm)59E|r'Of_FI\=:u|0cJH0lOwm8bG<H.i <6i*5QTg+ě*(N.ha[Sh٠G:CbZ$c1:Nt'68I.p/0)ZuEVFTs5u=6C;zAЎrf[75f^Ўn$hwe/'.6!~!fPzs+@v.M=e.//jq~~;oukc$#"/ \_>>`V r n|y[8-J"ָ<)SQoH&^U^n+:#QeU?;,~}l ,4!ooݿZ=:X17|" V L6t?%/T`0{QXVud1Hkm-`B+c,p8/}4%PlI^u"XGl A4cڕ_m>*뉳і}XGڭbQ'~/uDאrښnꨨ%*S?öNJ^uҧ>pU`2tL)DP-^gvLW_H́ȬQH2#Gbi]abo= +F~lS*JKV5`"_X9P%z$E. R .,ض[zD~VX(fX.cG,~rR1FRti-FܟpaGJҏRhi*j9+籁& N H!bU6Jmc:w">qCNGmΉ6!$Bg*Ǚw_Q_O4sgqç/:⿠C?Bb?6 Nb\c@G Uʔuyh[r]Q|. Ua) ad8x|VNNb_9Ҍv3Nk W_7 C(J/^!?tZ:N;r8;m2(@OmjLB DNn_cw^RB?!ϣ<'FHv  |:X8T̰%*Q63N8d,F<+_n *9T^oz|y ?8XdoR*t!fLG&md2n{33Wlb]r&j&/2“j|(梽u!NYt p6 6A6ZD bz7Vj^'ux uA{1AEKV6[E RH :Mzd@1X\Xy3f'$b=Epea2 Cx* oxLo ! |lD#w[c0wypA*rJY8]e(* ~Z,l0;KLv0sHі/;72JBͪd L ;ڞI߸MKMijA ^aߐZ JvSod_4F|]2VoBֿa7C_zncFA|B ع6kr9OקQ@/[Q>\b1&C"1-|!Dz0eDzS1`,M\"l(ll7Zeɩvm6Tk^m~ :-W1ؒ2_ByE݅;JZ_%d4Ý= C0W*b X'Z=f6_;`RjƧD!$LLԿlt"vG#C+1)j7x)%>"CQςlad?R?u(6q*prd 7vyJеLW-*$P<E߉j )$pzמ"RK56DkaKuwYd}2Srs[H@y`*b%kAs2qW4w rJZ&|< CQWkՂЯG 3EkKn#\#`9^VG-8#wnoG:^cqI8z*lgT婜wfjO+*`/R*6~؏piyVv}9'3t9Y?#%'~lF׳1PPh,Ri.Eeɷd ʓ95nW:* ـ0M["7alޣ|LYM55|@ 3d\ W36geVziuW_YY86߆_cq= ex4]lJ//qB,s^f۸؉^XUyrnmAa޿p*Q¿dp3MeSF r?z;θݹQ/}п]᩠9ӿEː#  j'n59W#ۗ0Gπ +Ɔ%dʨ^q*}s~Vrz TG%< rlBxɁvRj'tE=%*rEOy*}bBзRPb86+"6?T˃5=Ce/CR~zf[Zv~4C"BmiRggE7x;AkWu Hla3XǕY@)~vhM8~*/U_9,|<`"<|}Ar N*FK.F R":C3:''V/ÅB<-%Jybx4̗Íи:߿rt”E]t|55Bdw,TsYB&6!@m]'TQt9dSbuEzo<@2εq:u8H-{z,~i(f&>!;AO M;]{}yӲ聵Ut~)Q&#q$ F;RG >k5!K|=A.R):ﮒ E;M3}آl\ @*)F|'yEgh@Y>HKPvDwWc"V_8q=/ kiobL%]"ȵ^:`m,8_Z\MF~ҭe3|m#A?z…!4r5C^Rg8Hhf2B|^+XcʓQ,!tǗ՚Irvr߯2O~QED(!g:}-ܬYhYξ{ j@((yq*kz&FaA{ע~Q׌o=-62,ٓ8sr{Z:I.а= ~W/x+^3vAg_N`:mUbx5zA_)Rf [4'jlB(>%-[&͈w$o' XU'%Z湂K],Ϧb+MFT;Ύ~1nOq)e.%kn\՜ife u3Qin%i-Xf]u݆2uĀ{ț#f$6鉬dz2M'_ÎVR3\RNgzDgcrX(+hhXh-IE:ͷ֛ $j%=6m;̺DlDmiٌ+Ea!0MybsLHW<=hex^\>z7Բ—#ʧ^er*3'^kV¶-.Wrc6A8b`a(S5:463[w\$R<靨Ɗm]hYXA_IT< |;>VW֗'CǙv}fM;E (&H/~ͣX3Mzٮ ';>~I1eY֩B7cY $%?ŘS,jO! 9*s{%]W͌•+WP~tM$bD:ڜhQb8vna"]mvE7kk*$2(!9|HOPRj+弎ӥMh̵es;iP]F(䑒Tɡdx,FNUf>W}ˆu6'AcfPR.'' o&*`I5sXf?EP?EbU&cJOf"cezx- =wWX_-7ͱ0}ġ<L#-L)s瞍&0hJ'r?g} $niCᆬ F,09.s ʺ{߼SOITy1tSf_bMH8/uMYclt'a'Fռ-)uhFlPjQLZ _hO:e|A|&&XqAm ߖm!];MpӲVِχ'3fLxeTTّ0J$tGta+E8bdXYm-@$4YX$ktR,N˵Rԛ+ Nh MڢgJrLp?`\ZGActJ,`)1ɃZ*א^jC.^dKk*xL1C$M2=yqUը,AƮ3G㳜i#=dGV ,Ι꺉볏(cDɻ4@[+H>LA%]9+{3Hj(}Zg_7+U\> Oݿ3pĿN}{QyP1nm [kajb=jZ ˃ ΅/C`d2Y/[uv`'uR#*58N(|vu6w6u6JV?պmp!qD}nUO(S`3~纇9JcoW1ćrqhSWvp"A-*wd$o^%/FCȖU~ f@Є]#NПn{ٗn)+<+ߓ89_7<+XuA#6h˰JMףU^p55kn}9 ~N!Q')6Mm] @/ާ4f9~ޜ}(UmO^+Xsqkۯ/IUխel-BKXiW Fֵ$a%xp. GvʹÖmm8v2"ϝ0x>he]%mC38#RށYإ ͐\&D.5'L];:N\vLX4MV`-poŪL͖{WK6R O͙DQt(<s}IaAi70P=TjX,{<>fCw_9X@~ Mԑ9ERF*m)z MT՝ #B}L>{{dHO2卆%qZz #Ula,RJ8v˹+UR ˆDq[13 4 $c췙+4SZc0ٮxh Q"SIl+Zۅְ܀{VFT]!$< 듌1D\CӃA,ISvϐ(H` =c05mslju@˹o]'M]]=]7ioV#IH3onVCI.<.\[u-u~wB"Sjw ,wn"zLńK|ڴclQb>xPs!1u봬4xd,*L8wپMDIlSdu@ϘR09ƻwn*YX;-M9Ɉ2 #V=.R T[2Ⱥf|@NK6_ &,˭)ͅId B <ґf15 LZb[/Nȁ"([\Ooѐ۽Л Wjf-2LZkv`c5@:G^|WNYG }$a(6M7Ic))|F\tdPγl nsbLxȈ^痺RqԈ{Ihe7}Y0qf\}HZ_$ƹ)C[mqT/ }p}a$;Z'!;Odwga~>iN2 7 V'R%PqD')kD",-3"KG77>G :+Qp%& ?{хw #+N%VBn|W=V |FݒpJ㠯IZ%E7sהxʣ\Y.LbVj2ieE@ Jk\4m-JUG7qU?̶!N#0S!1"PJF5lhi:wa0 rb;YPR Nw~4-GևML.Zw!Vu/lAwr9AF/θ/Y|e#BX 9!|  >9Q r<^a~6()Dg}LJc غ`RWo/CkCbϨq;[OF[@|sWIYDtg||CO"d` l0+vÅד'c U%D `ـ\<ٖo$t#^PU`B]Pe${ }Nmh"x-IqL[OS1"ohJ]1/"fM󩺀gS,O\P9U?5(cfoeO哗by F'Nȧ^'7,i+{zpg*mv;nnu ~ԏDF]1"Y a߀3^9}Rm Bj$p^=Ş&1'͓w ~13kȪcbhnpJ}w*A'daNȷNpEWU y a|ب*izq>55™Ș<krqR//oq.I.^/`#W6SeI)Jmef%^1n~^qH"H}'wdyBTkJjfskx5xfbA}KYb!-6?Sܙs(<1ndRGl&d/b!OmEwtfπW~^"a|gi]JW'7?eOS='> (R^@?HyL;$ Q`2ʶ~(~9$_7H2)AnQ Qܝ M3Ye`vJ0??h\s=vczk(.3bĎ2]V5޿VA=7>sMy%w4V`yʲm#2xԎbAjHgqj Vo|R#qY)1;O(+^!;fk眳+:;ȉyCm7788E4Z1"1mUvN{7嶲:3GU]w91VI%&9j!upr*K[4kX݄ou uV}Iag`gflI>ky8>\}/_m`]{`0H75?ԁbTV_vK@ ! 6Dz\wm.V>*EIsm n= Ȑ}My}ٯ#F$Oһ: %< @7D#%ao%r_zǪɘR0+diIEʪ⠏v*+}5ݴfb_^b@dei62Nn /.^Sb_5~1o޸iSr'_*ߝh5xcq^S k 7ݟi(H^Ϥ?@5<טsBSGU}2!("@R;i( ۅ'}pAಱt]'BO-8Ә oQsߞQ7{1(XÂ)= ǃPUro0z,Wr:gE:2kx~(obE0.ke]/AI\z[Լs7;Ά[Q>ip1^5j[/ydžUU$/=¶E(z8FO||n4^^df) >OdZ LXʷws<|wϑۭSBv+Eo3!Hih=ķQ(A/ڗv:FvN^&c_}XJK[%cQg~/f^[cg b _^ZvJUf^ju[cgŔh)G%ui՗Z~H3fLvB6o Py8ewF=\F/S_hTl) CMU$ ' n-q|8 îտu<ZC&/DJ>9+9s|b];G+Eq0k CY_1H} ^B-%)yAA$ ҡxiv'wWVkNDP&UXZ!S/K P۾䗬^ϔ8i{ZY*@fݩݝ9k-|AOK 3n(  򭋋-t-<f saէ)GqC!Oϡ=wPkTY/Q;S+M?=MWZn5wn{2햮^5]'+s&Zʦ <#m]Z-(U͓w-V۵E^h -д$}e1P MQ1k x t慬8N$WUVM`e4l3Ggfx:i MjbӴj QxR[KS g9ɵa߀qRgS$JCWW;j+a]@pS6ȶMW G / *߹)k\(RxC4H&5,1[ܥBKH&V,]qFU,JaL"=2s,U-e ˌZ+BbLu t bFT)1>֩iN`Vrh(JH]5j>MlKh.♝hE3Q~Dw$27ys8+q PLK&VIO,NQGz ́oRf(}룯0s($MCn7h.O/Jy3i@[(%%Հh ㄳOt !EceZ}ߢثr&/yj`ˠ%J:NLRc|8 RPjkՒURw(~z63h.Gg;ur {ýS˳ = h:"u/|EW[( <@qx_JڣrpH'o)Xp@/ޫ%99ѽ6-exFWs yk Ou迅ko AD8pz b8xA*uf㪕{SXQ~u8U/3wxKê{+vM05ܾ? Gܮy-M[ H^ `>] kЕ"ê j MƘq~$[QIiqzvj]K[MwC3vj 4M Kzl:z.ڏ]{q|]/gln "Q>T&Z:6M{]UVjK3?.[q_H.< |0QU4bv-Vn6g9dmHgƿ2ĘE-<حNlG {Ԗ*b/־*bqȒ~Rs!IvȄEݧ8At}UH5SٲalIz3)kUw~dUH8щ= ޷^3/~W+;&(w@LTGOzk;S:g<7<KS1bm# RH`AR#nlQ i_aDoiyzWԑ^!oKhkSJ~evF r#!EELb сj]Xve1]l{6ﴝ6J}?7.;k WFZυ0 ?3iidfA!X]nO:hC~m]H<,Lmͱܸv#L`ո7]8Yxx; ,ȧQĆuX.i`+jɝ)N|V:٤p7&Kɖ^)ߠ,1gSj k5e B 5"[RsfRYDžE $RvݚqD}kuNZΠ;i݈e.cRp `OOA.}.$12͑$'`HaP`rQ4Oq5krt7_ҙWUe` z$JEhiCi8\{HEH%*voztuz7G#P@Ø39\8(ݦf7hrNX~ՂZꔠ``x\IOC:\Ncol# Z۲qwқ0'S~A~%Yxm4 OD2}{2 G<Ϛ|ňהfKܟ]Xzщ@nru]" OR B ?HSr?@jXC?.N]//}tF1rκZ58W׿\j5s[HPN?ic8ubǭQ$ ;rYxL'pKt `jDd݁"p%D0o j _pJUHEARM`JyO(v}M3RdD )ZMԕPY5 7~XJ N>ʅ35b*y u)*` p_Stds淚Q F[˥`ϩN53LtXFTyI l%&/XbX hpp%h&6:O5&\b'RGZKīҘ*K.'lH C(xζgS[=u [jr?~גI4mxD.+7>l==uԠ9}[mX߼xl(0yx}|lz۬ޚ/Ǿگ7˾>\Q{ DH'T`>;IVd5RJcu1ٯ42qvgonQc:3ޜfm󯺗`|~[=rK% ~q0`c ).HQIw\:+b]l5S7tWܞ`[UJPGpo!tZVr~Ojץt(-0%@96ZG{.;\E"_٨b^>CIXcQ1{Vs8)Z.vaM{m=]L35&4^*" ]X~?tvoWC|PƳD/%|׾ri[X=a$)t+blYuܶ]d^]zHGAƾ:䥫X:ѺbUѶ*Sl\ʅ-hg-2Ygu>hK9B6g9 yhA#|B-2&|CGq$P *~hC`2Js]=#''o;lY[j@\sɆ uufS͆E[=NPEQ/ OeC =q0UYwn1tXWAڔd35z/^ǾR'hscgp OM!5JIi#u:,gX9sBk EϤ}3nD%?1AZx /dNҮ?Xe?ed$KHxV==SXSyϔf'G0ǖ+4i@x{l`4rkg f:Q {Տ` !l;ZVSe:;VM(*d+<4-,[.E k̦ )dH5KdIgRy= chQw%o1̶aj 0,o3<>$*fase$DDaeO`%0%<mj 7yb;wyDbz29)GX,LX:oVY)1Xl0h(cMH;.{a9GՊWb]΢ѥ~ -[ Mcٕ[05F\ͳS:J=P=*eQI܀\@MG>~\Dk%[*DzކȖ/{ B)Pf梠 u,Vj@ʦ {D!=,֭N/ĩSb`btQJ88)QJ~£00)> l:JfY[e݊9?EL횖a(F–sp.XLZ0 .)aX]TÑ^}n( n躳tPTjx*,q ELth,j,( rP@*&s&DfAJ_-:`\ D*g IbRol/vU,BhP&B!WӸ +^>Sv[ 0۔&^1Sa(|Z>@C?P8hT}q|GC+F@R5( Hw8Q`VdjX>toQo`0rCљ?&hBdžPBEC'(ng?EEM#¤d u-}-4Р/>BѕiEJaE#: is@(!J]Y=]j>\riܮReL|^cɁ]0W̭|?\mݾjw;PQ~Lnοa6k( PJ! `-n!6ʄ3NgAN62FlQ)a:9<%qLjA0QS9e\9ٖ"]%brY}o_Â1Nj+ɷ7=3#,C#=.,W\k\=HZ'-z2U2dGJ%ȕ+l2,fSEa`3Pdc91gT,ya Ag :JcԽK齢PݦNƭBS3Q2 @IWa fn>%]`<{= fRXxybkQJ*16gVJ` [bb Ux8 KjוiE0x`A?p,; (u<{2TڻkjUM,EZ5.rt-P>C{Fƃ|<0`6;T#r|]#hDؑnU9M6˺,3پ;Z:Zw\+7Gw.S6 rݞ(W%FG XA2W@?e-EwhuߋV}WiO{'?7AbZ 9ԢZjWo``_Ʋ'°hk%Bۺ=wWĎHHO`RMPp&ifcvN!9 *VKTqdz h _vbR- ڡ+FZ楊r0I6>\mu53̕|t< Jpw]Ad%U4&8L:._ nSqբ F ,ș1ذjo#6_;^/= اB~d% e3.4%$D,A\mDu6 H-D>#!n1~' T'q H&覌 e .X>(:cccmojYpc$yTAW)OM2^l٪-%Ӄp_t(.ljMyaeB^taر;ޥ9 [0z'ν MO[oF%/#v!H4Ѩ4i׎4uI8W,aHqLE}a3PBkRmƟZ\p2ո⩚(z%ƀbLbwP0̀!{\8vϛ3)IԮVp9X#xͽAi6)۹بв9r⻘M7xY'I MG3­/K{1ucJsZzB$m- F d_Lm0t\/F :~ "Vpaan֯ҹİ?|W7ڀ2E &X6 P@t+jm*Ѓ-E^\M w\Lp| =]1@cd Gf{` byAvd=;3kjJY03]$Tb,y>Ν>Kj3*Yߒm'}dhy錱١M~lȁ՟[#evOf6UYVm 4ܸ:OHp+.VJ^k~+Ah^ЌL@m$qV&Lai6M[L ϊvuTTF͌RA6\u+ou;-OU6DEAxYo v_L \\tgKT6MlH5*a8$*Ea\4:M$Y)LUJ5^4Cˀ2J ~Cg޶]vCOc*d+\73DbJf:7_f\GN-[*IAe#`+Ϗ$kpGI#>c~Oood=[EWLN 6"o7b0Uc˅g+8J}¶t@jmR]+un\ 8&Ȑv ^nZb+W耘 ._QS ұ'΄ 8<-"zhdM *ZZ MscMN-gXӼ3vF!?lܢƶ]Tah0?c^LR,Tڳ}_'hgiZԽ~(=Ds#wAR?e>>Z8&*mcv3n43# AjqOBz.n5BTG?[OwGS#? tsZqu5~;,p)G&plA6ѷT*NuF]1zyy\2?Z@ALUi]Vņ"KwJA_ ݹՁ#+R#(e.U.l\Jw0Z'A( QIQs j'u jwud2؁Eu"G{O!|{UlTzi'S+!e0(Wr+=ܕszȕd7 k%Sx$U[<4Ax+z~N@[,;m:*WNlL~)ユMUeGwTb~&a 3[dޗ^~oƎ^??5^aJr>O:zs*N5[:u~xɠKtZjՀW R$$3]{XP\@|hFwq^IBRjB`FW!B>Y+џsTr'77'PĬdQaNL2V YB74jz6jC$8h($+6N.'h<ݯ`mL"e*fg&z:+֠|LvIau{YA!]2o

    -3 ؎+FOut_9s8N+ }P0YFv#z!):8r|/E@ִTvwJm$SFYIa1RS^ώvy aN7'q.,}՛gAsX6=gFO>}xHl6XI|2ì Z-qs rOf;}0vYrk>p}6|Qؓ@>tTU_%2Cى{ti W(+-dQm 10VV,i#a3@WɔĸX̐ճp4 x "0FI=ViKQ Գ+s{G#re0❭[@}!~R|B*GŶiV9 Be|[;-Fi8)x Ӥ{$׬dU'`)ar5?uNiOr~ -y ) =JV^g:?I CgSIW e]:~FL*`{EٸӞ/,ل $I(oTIYR&ս(Pz8, szm±Vn٢M6N48nY1ﬞ պr`j=;1=#5kE{Me^r?Y:cSWzV]% snB 6?N.SR8 #~X$"u'}wRaۇC+¯vX-Gm7(x}!Ԥz6{K@Degk}@œԞ=!CA/JÛٽG; a͈VS[ uVxzS?fH. J=1P`8ytCp q&Rt8[Hk. Nr)uf|xDpF#jw2~ؽGQtYa/V#aEz*6˓֓Lc~qq.bd,֚Za݈EVj_GOA;kX~e뎒yLƔ 8oIҳSY, GXAj=p#g^}ʎhYʖKb>MTʼDRUUӊmh"h ޙx{oș#?%p2*DdG1§s`)yj*2HxY+2ٳR7B 3T4o7{8.bD'ivo! ³K=_Y} GgQelRgk:ֲe<~ KS _3ry3wv|11g㑽 WE{oYff+:5?9,ajgdh# yҺTv~7: R5r4vV|;԰}sɪCڋK-\\BÂ:U[|UƦM.xWM5~1ϚS3synF<=aE| . ] ~0S<3 kxň6fCfQq(c :BċG*'d߬mVߤ ÷GwRw.'25ӽfF .02wF@0Td'ˀzw{?_Bݦ%?oQ"[՗`n=-G}7 $!~T0HF dv?i8>’G S*[Mj[`=kWFio4d}ZwAcVVeUPd?#mn?#^o6~>]r? |=f\r uGsp z#hjd,_J<56$_5ĔV}ZyդO>`PYLϏJN{XbwWscؓ {Zh)Rs ٣>Jw Yg5^۟:F)O:'Vl\3ζ@h&--΋S=An^Wzۛ+&!H-n|g+}&84;4K (Xfۃ=B~-_ & |{<ø8>9ʘ͓~*{kz-'oawm@d_'Gʴ}h%dU;鶳yugO׻eOlI=.`4H`"  Hk)Bև@^H>hg5DW1EgmnIMSu~ٓ VBRJ:шF6uoRk3k:g5;{|F}%/ٟd&iF“pI˘e#cXllTYv Kؿb4LPk`~/,R_C_?,^V[RetU6k]/QZ62eh[mIm;}aܨpހ8^>qy]w'r!FKkNYKmHIdW[a_Ib;\b m5Sh<b@fYm(|K=2s^:8AhI.367$<VajɆX*Z$Jv.Qbo!k u?)ż5H. x& {49I{-1"PT{̽șHiRpȨդ;)­&3+&ō=REfpe=/ZUk/Q6\g$\po j랪&H@&QK>Ws^qbeyEd cʲ4IyiyO֛RQKt> ̍ƹJQw6⋉O@E4ڥ>C}eaUc-nr#Cؒ`ԂGm9ZlU3kPjTB(%lLHEl ۳xi.&1n2]i]WC i#͌ZRܩ͍k')  9j`n`(SՔ'vHa5Y[W L /L ̟[ DTs xj2#ϦXӎX]XTšɜ&HyKIQcUUUmm&fff% pC[H@tl<3WӰH.J6MMQ%>+FHV,w$?t7Ť ᙆն`7Ffz0{)z3%@EiZPaaV>8ݣxYR=9휐Y9+˶GRҰK  4×}e8@u@`%莥v44FZMRZG!jw048?Q譊~Q"r҃V޳Ż r}9EObc $ރ 睏34*Tl UGRKDŽh[b$x.+55P\t󇰧HTrҕfެ'y 'r7!3=XV|xG@NI~ObYSc"_q᪏[ob[*+e7 ._rn4d_e{ݸ*Rt&Nړd^_T*JnOލ5+_H_f9Gɸ%ϭ<!oв!=m c 12Pd,І+'Uj7x";AAP w8EOԥ8 (LXe3#0|Â%r_!d_*c653A0N$TXqc֐wQ0>L¦@=5ҝn#}%DmK+_LVB2nT>DY/]8F"g' J8'Qh ,1bߚ34s VA)#RZMVSL1 1QC`j!-&Kf2N,IudSQKd$lz O`JqdUAc;2!NtJD* Jxr ]EԛK]u@5&C?7^~gԹP%_)"pwAax͙~\P!QLD'<~k4edYj~n;SL^l ż Xf#37 az7#jozf痤%AsAtPM mM9܎6Uo4C#? *%L&0!$/ΰQQmn$ ˮ*Qgv Kjo/z_D9 fe4ӘHokp^ j ԍ+WL@П\y5fEqv*^7?5mLV|ר-%dGayNy/=`ɠ;⥩][Ç3=^w+Zn賃w!EV`ѡ!\1&$C Q|A?ehJ78[ ,-q{걄ӲYCMB0P63fIà'#s]NF;~[cuè=ˠ<̝+j!ř^9tW|HnT(?mZ1he*.ƄI=GWc&WH| ;G8\&.Y{'eV6z;|D =x{n[+ʩAUzT]q(+*ۭů@CSr^B`ȳ*G)ɹ ?󮥴O]ڣ\z/מ;$;ӯ Ny1wM05֒[tor{m~1` G lWPT?ɧ؞ADWc![. &_&|dRw=3Hu0bJgϠҖʐ#SN龐;&D=y[@ H+͍`=vJRTdl cng",̛KL [IDStıFnNn:2FNן PG\G./*O zrbĺl)m\'b_< h j6%TG>DEz?p(}9vMNC&d)d%M-$BxY@QU8\rJ@1Ȱk%㯶5.\F& ,A W[xJ#,)cQ$6pAdoZi1%LDUsRUb4JًˆuedeSg ]+T~GMLhGRi4,!_3~fެK5XCч[Sd[k&nYSz~:庎Iw)w =fYs,KP/qkx.e@dY?"Sza?E/?-ø`Ty 9V$VĹz;FsI\Ɖ(ϜwP,_HGÂߒ}1̠3DG #@$?K)T&|e+%ϝ/>s/ 1M |phE2Z.YׂW&{+eͲq :2'"&Z*[1$Q 0ꇧ2ɔR$ B {U!e,w0;k'tFe.&SHSvʣ,yIx OO/W.Č8,F'#Jǔk|jV$rXʣFz[ؕ#Z(4tAW GfhJIC꿁d7Zb2Pd![kN嬏 +f<}RDT !$Eabf͔2d0Ӭ҇ 9%_@I992T i<~2 hikҨDk>d>I%I&ç+S"Y \2ɌҸ:BBw scy QSY PP0 .7 D %![k*7\ %3H@M %CBT 6ơ(жP0Ԛ.к==R3:BNGGC`ohWPҺk `Nv;8A)0w _pULZNWGkD+nEP+a^mh8vew qq_pMv:y!>\{K9F$9h$D<.O%7g -W:a l59ŕqdX.vFsflH;t4;1o?8Jњw b(*n>q@GCiԜ2 շ1^]+#OJ'^teB8uMir _e2.qJS'9_3n"<6Rٕ rް o,[z 5:~t7ߧe7|TdA;/[ JE(67u*1̡wK5$6Zk-q>=Sscv*6BǺ̧#q F,a;Z^wYN{a5` n ͩ4Oqm#OɃ /ݖ6FР wPA);'l<1\XMmV#007>|.4בKX|+Ɣ .ݠ 7#ۇW-79E R{=$- P!c`B vlH>RY,$+Gwx\z9"f0$)^A3, UȨi[B8ҀU\nԭ."RI+vjkQSc/8ܒ=qw=k|c;2{"OT&1NVyhQqW 'F."p>Gb%DRS3sΑ󒫘1NP| F^F)/+ApdeǰGIƌ泖hm4qULi0z<17P_u?MZz )kbP6! eSiU!5cH{`v|dE77mxs(NF@{ڪ:EɟHhѕ3$/s@e`JjZ{ag[<~F U1{4߲lьQ]rQoH ǣoAIimk5B40B;=[{M^{i&_s_& ^t厼d[##F=,D|XMhs9G@hQl)yEO,婹-e(dE1q~v`҅ULGzA#Fm j6k|ֽT u8:M smk==oYws G8" o5QEM P3\JI8 h\fUQ~8B=RO+mơNT[4zvY8^? IAUrD|*?prrxXd(INe^[nr. Xk P:1>jEcM$2RT_:Y+T9sZ n/(aK W&D`F #>%{EmG_F+Ygbj=|RD(\ˠ{ڕ&pL<-ǿR.{mpi%AׂXM0ErGU ^>(e>5@qzy CQ##h!xV+ oJ no ݎ}/Ju'ͨ.7{zVfr`gn&T_.>^OWR|]clT]+v=HKfNE#x&p i HhCkkom?Xx P@6jT0fIlim#.c[f8KclSogWp:^v1ffȩZQ>d]A OezN A18n[=Yt%'q/HlvH&OBmqg 1=w> j;R=ƢQ_0"Vs̝KNT!56K8 rM+O궉ru;$ho4xCAĜCZ~FӷV#/)Dȁ ,^v-5k`\ Ko;S@ P~V":vz/iIx4ф-Y&_H#IȠ|DN OͩX|{ccMZm3x%=ɂd/Y~(Vγt?YZuMv8Jxx<>lS/4zbwHCT.)dBK v:\kD cXb"#]c?кGbHK gRwfnqagN2}U>!O3ӻ)F&'e4# sF=7QИ0x '8z{\$8vbHNh`Rz-LPs-4/1} {6aOk% uԭ}vxoc`Bp;_Dt8;*wH 2cM_Υ2ÈVȢ uVHNdIUǘM1uiͥfbtG f}j|Hn_7;'yGeyh,_/cH.؋zYPmllU3[fu"m,v'ב7dFL1/9w+\P,&530rK"6qpaqfwS a10%@+P@|QHZم\ZT)*7e;r~˾٨PI/}:)bM`Iw_^^y5;e~}}wm'`ߢE~di.S,(oTjO>2K1+H[` %luG} ˌoRƚ]*b1%cѱHt\/bRT\('@y'_;E?R0X?v||;؞,X.MYsB\rDmar!`qw#Jt+`L;YQtw aecWiuS{snZx+Y{3޴asBuǎ~MRۺw}+[Tn&Di/Ƒc+F9 NO<'fa7iYgC!dq=4hi/awA:Zz=Wcf,1Mh)*K #v5iU/[q8J^ԟ#v:m1 >:s&'B;O>+Xˀ$E:=g>>pe؉Ʈ7FGOD3~m4uUoOdh PE NԶC7YJp#$БF-me?&/::|xCcD򝱰y25YSbx座+wmÖ~ok¿Y##^k0 |&5K!K0lou;e3#cFͿ2N]= Aޥ=ej B̗no3DKB)^C]5S R_:p˾XK"F>fDq sMfoҏ|F9zݵڶmvm۶mcmv'f%dLKWzȚ@8mp?櫼FpX࡮P}kH>%o&O`#ȧ+cP,R-KKHd3^za7jjBT a tdhS7WQoX?aFKTXװfgCkb$Gz3Qd99U 9?|\NX![r?7XMgfߣa,t8YDy{+)e0C o H1F ĆB M΋\TWĬ DzEƩPaA)TBo`] 1I| AK| @/xx7ذ1t2gZBL6vg Bd  }LN"3P?1]TX뤄?kJxehZJAK'l?\)NDkk fPrMpeEe @JFb= :ohS{4gMϯRo?iiZ9/<8.JghўնTچ/,4_cwrL03#!v>.s)s\"hp%WVI<Ѹ +G# +Z٣t-t0f8WнE$EMBY0TM?SlY <]h~ajz)aI|>VY/Wx5倏Ε‰K[:2 *࢓cWD\*k)* uզ>ϩ3k[bTQxkD8 ې>ìз:ѓLTIz%9M+zh! xE@[QƩ@/M9_qcVECT~=;H5S셴L2(tMJZhjNH( Kfsbz%?m[bM6qRP/z12ؼ7tqҰ&VO0aeSYl1XtJYF}qT*s="[$Ԑkwz-Oh O c(QU'2p>WΑ= %` DfzH|)8A,6Mf;@C_f@x*/T-Y,k2YYpWUD9 R\D6s7_IM.~b`7k| :ܾ4)q^Z? }iwn"(qfނךf`0@׸S ٙm&@H+t i_u ĉނ]>HU 72PWY%؜M63uEjmEv 5߂]9H} ARSys@,7C'Y4WڎhcTc_jzGscg>Qr;L VՐjJaRn6y@0^Qsyٓdh[*~F|JǻGswa͐e b Z;ӻ~F;@Abu9N/iR5|W2n"hDGpaWRY6 &.wt@e 5b2}۟+9v(IO9z -An'z{qDYe3c+<`b[X>9h&ƹyXLl*>mV!r\4,YK~  cwvkD0P=Vv+Vn,'V٪T y?v=%橾sXY*64s.F}Q}"4c+IfX#a'^bTCvvV>\eLĘ}&:VqF-/-*om,8ʍ77_st8?"KH ,29mPWв23<{oq裣ڭmconwV[G_L| SW q4u@_ڎē6zDi4N3pk8,-;b\W4]J4S<~xqRG'ϥ1jѱ:hC4~Nk2T|VKKg@h\yjP]ڻqS^1O畫 =7|q~nm6JYJV3&;,+Q APԒQ'YӤ7,bf=N9 XؓTo2h x߇s4W#-;q ?” JӴ J"KhdBWR+TQk'uwg.1ey\O 7boI8MZrVw8:8iL".!kgˬ3r\6' 7r7Slsw-ϙ&[% Q"ѝq_zw"K\KUYi88*::-2vҤjQ} BV|0I7!K`|ܬzL3z'ϝsQK8W9^n-2d@-AUȏɰv@E@Pٰq+R38Ep;8jKtB*ZTcztT~$Pi,^ m2sP\)SZPϊZ̎)lt~ĵfj#hZU>VlWC输j~N9޹Q$-2ՆA(KK'(() *)K#uljU_ XgVK=T\e؟Bg]ȝLb+4uifu32''媚I(T5^E-R.F$5-\uw..%ufWf@Sd^[I:OB(lw߻Ψɶ4o'Goi1t>5F43h]I 'Jʔ nE?-cQ771׬<)눭)KM3*~'>\}?R).+o.553ᾂ}b'ULNΉk/;zt`㕋'xpp)RM9'^%fP=Z|&[!)\ڼ@}9{vX+:KMf̗ld%y s+23[|87P$;onR6e d5 4P0țnxhٙPjF%ڇH`n~ z]V" ;*ږ2U^FVmçaook×.~t*?Jhp3v"/V<2BFxQbk9MCO7޾hpJJmWD%© ss(K4T&0Ư.ѩ|[ea8ENCn@-rarDJILkt q?j8!;bNJtFuWc` Uj +GԢ7}:»;Ȝx2 SW#cb$;}񘈟v}0?mA'ŧlLA~n[ZN*zrAL>9ǝcX7fNuhV;r;Nx!CqNQ7qH#5@ ,AcLLI5u'>r&SJ" tKm'9˫ 5ea;w"QY-YL4DS8::,$/%0*+0 #t8Uqf9 !vpXխM]M+>X /5o7z{wwx ? U(%O4԰CuPj﹮fMٛL54Ia EhK4ZX[Ѩw؊snǞUaj.mwDNNa[$3= J\3îmSCUvdo%hc&YZ!L],kL;Nb= 6`>TwɩKJFP^4(Q3ww=}phNHɈLxjUO>\R'ե<.5-K 1b@YDI,$VL-&EL.&WOU)Ykܮ-w[ PȤg xcW%%r=-UO(#Uuemo]߽2g\D1Q&$1xrBMԏig$}Y9 C1-6Tumʔ\5P9RP7y/:CCS\4mmEWcl9asEzjEi1d(y[z#C#Z!:Qj%zĪG|9cS]oLy<-8٥t>C?e ]L\9 F<(ȿCE+m2S+k;)_E6 :DA 0qi=[ogx_D}S5~V>!~ ͔;~l>Sפ*-G ASm?g58a}=>Obn_KWmQwed$o3Q x# ,bFfF)7pJ\tR/EsRL(ш? $4edC&F{Ne'ne{|8N%x;olyѷ^pQ,ymnʲK}[p+^mذo-k\u8Qy1E$9?C |M~4zBT5ۢ/rR+c:̛l㶅Ca p3OI>zX=Q1}}5d[٦մsk׃ ߐ!;Z5ӌ&wTw ?f/a.uJ R."29iNK#0`)π2= b+x1[ldd<:qƨ 9nKюòr7S'ѳm=̬.Zl0os&\1[^й}|Oz$yCnfsNT@0<(tV JYQ >4L4@HN2mgZ-{q1y wy5&b'e"]ͷ>|ؕ킞X㴟Ý] 1&{n>~q Y8wz1 ^hvl=/a䦷Zۊc,5Y{tc7r,L|Gj%2+þkrhɀ>"}ֳC1#ɒ$­Ky jň`''ĿO#Ǧ(^Xl?Qj&QKྶF+hC~8*X=X(8ص%|'22Qd^93oՅK*GOU*xָGX #^lf6 h(ˬ:ES:^ @'mIV܇ "(:َƈ %ݛfs@'ϯpHyp~:`)~E,M0;W` 4zh0:Qk} d{<7ibdSgj bEX_.bm'D)W {;̤Rg\=Z^mLgi< |<&}UFāu3~{iOY5aqU V4Vè s-V>5jw U Mw:'n+;:te.*w , ܓ^'3ok/ZKrʱ .kӢ>V$_X>GB&R cYAݏ&/{௓ ")\О?,(٧պ+CE=^!v_XThcuH @v-^SV:ni_/h253_BRTq_: Jr@}Y m:\ r WJն3s#6-]r rv;])xN >a8mY7 T?cvB7B~i(Q#1ϋPJ\Ur.֢(pͳb\ %=qA ))c׏$lkܞ_)64}6u4 V".:9}`ƃX_]{֕olny9=Mprr, wvB:)i-kjFZgpj+٦5~G*]f@@rTl娦G'T~ӂwn(Sf[vUڥTf!4хMZsƈ~+_ I3'м[nl\8GjLBo3{k|TpR惢8! W:|u i{L)v`}LbDUt{&PTTZ啅i{>✜RE9E6J5PDfdTE[z9U8ȡvjWvL#W ,<+H_2-eΣv3h-;VmSh; 6Ps +;#t!0IV+t0!Ufr5}[-:R gQԶl&׼J_ChgKR![%ttPNs]⯔F +( Co:_䔯:7mռnܽ/NtmyXd>m$5f c!cD-Գ(JM"l?hP:wd67RSゥ=13gJ^m[P:g\Z}V˓sP0 +âS"1R7ߨ셔]d:cqѓO@ ]8>SqqKm}gJ.+"5_6TLrI5ܱh5tTW+Tڦm$'}e(l.ɧk͵ڻUy]tSUw#&#[ۻ]\LޑLFR0H,.К!|M]Ș\{%Ǣ}TC PUmmgE=Oϱ*7 _J OP&颦QTt/{#R#sPUJ'MJLKg_+5e彇q_kL_\+@(f~T _pIqshN':4 9!C¯PXv1玘!DF^$ n4VѵT0`3sITZJi-Ţjy![|S OyA4cݶÆ BuX=Wժ@ާ|Luknbp%L<' 31VLJ]1^Ks= TR.tG㭱NJLeȳnz怿q|5@*E.e@n0Dӆ# !&!dY#WH򚞲eeTh<)]D7J"'ƮKZ2)WW J>jRU/)(LC]vK0Oz7B!'6[*e\.w\`&^;YkD$-h_XRy OꙔMC{N \,{lC&k1|'_*"{N !/2nz]nOlTci4:$Kfo<~ӉYDlvhBW@c{n{@gs;kh\i)A3Yq_k*OU UwIcu}riG[qk{ێD p=aѪ)8՘Bu"I+m:GMl*x/r&Y*](2^􏿷(˹EV-< bzۣ-Êp Kw%4[Ĭ!\;i]վL1_ OΫCFiv>g^'Z`N_] pTs\:Ϟn_Ejm=QLb$jS3`N믎}<v on*U y]K+EڤQM 0uqruv~~7ηއ0aUjg|)!+sn-(,43~t_CT=ZJc&wOt2ys'U:uhz SˇdY~p2ݲr5l4,(e 4&{0!c"X22?|Kf@;4o!ͪhK6WzDN=P/8|!cM,BcX# bkqpNݩ栽eU:7I ^𽐲'p$[GYm,6E;f ͊x6#m ^u]rקՐmHD }/ % R*("*kpb=33F>WϜקZ;.稺zOU 2qMjV,#ԸOyQܪV8pq Y;b +5yڝ>HErK<˽ 0|{ ߙ)}m:ҲQJi !XB-YJB*P"humNhl+[a501>47+HJɱ>_ rt8 YOʼn9GțPÚ<ТKƌdU^9gwSkk3O?hZ v.it/Lq1OI?2*"t+rdk s_x@:>'_P*t<@N^}tW)`O*=;쇐^_OѮ2Eh*Ί5;%c-=6<[wo(I> RFJԷqVݟiN ޽6}0-JGUx)1c TL"v膑?WhpXֲk_Ydېpc;׀BWŵITos_)~ K Bə1FxjOx޺DHu+Q _+ҭP( 3(ż7dd,RE6 3DF/-*?(0ycE^>lZf^MbQzҶg:KH,ͯNr"#/~H9=@'ߪwRv8_y'aM1o}g\}m')$^V\WX-*ZW)w:4Th]ͤؗo1B <$CCn/x螹O{irq{½62Y~u7}il͏;u/p=_Wo~OVc7..Z*pھ8j@.,3ag}k~Gֵ{X=RAYU@F <;gBUvn" X Pa@@Byo֋vK; v O!PanϋQ!(9]X$^I }{VL`FnspVe'ֿjy2HuX)~#yLYs)ɪ #aLSb4)ZŦօ/k"v> k.ʁYp8"DlS=xyB q% &z;[h2,{\.^iS[ aKH-gnW$&1v bP/|Mq~LȹØE9mUi 4}Cedtqa*MؤG8K\9oMr +!򛏑RG=?qbxק`WEU/A & ZE'2݀5rt,C2n<1wWr@9*1VtcLrzB%bgOWȽA[j6l1V+X;U)g_xW+_ǛV &y=Q5[sp;i_7ڳ 4>f~2|&ijmɝȴ[|'MCxy`7e #Fm^!M"٧ilROyUz7P/+Ϸy]ϥY;]vWKny^Sɑ0xMZQXS#`bPfٛ,K6U63СJdP7QHAy8X!EՒn5*ݮ&s d[huWKV*+ $jr>"&T?;sw+[9a<Mmo̐6)Tee⣶$$]{zr2Zl)[kOs^7Uǣ }?XFAJUDx3egMeO`XW9I,<0ՐKR^c%pS˒O #keUnD"gp]V)_8p*ʬ(wDav O.ru? ̅bfUHi4o j^]PJcRl+ryx$P?)lSf> uT[lh4ҎJEaH7zީZ#d Ĭ`C!+,Cь`įS ]Mcv}z(oVڵ9\\pvSV!yè!hYj;:s2wMje{KR{wVNi8:26wX r$o='Ab[l]\\̚N@"Q\`aLJW"z1d5Y1QN^BI_mk!ǻUE9Q4^eTy6稯~̒-\7 BX,k$.a>~ L?зOg:؏q4d@ 8tg=?f3N&ٽ-TL-(ACw)lqHډE}1njk/o,'7K$q_gL`^!9(]kVs;Xa`I9zvsNZe?Hn";\kL/v$w( ^ff'V,$"XZKČ8ξdŌd):~5ΥϜ|8npnpwzqG_zmDNx^omDYl(y,D5vCy+assA*x0X=[ـQÍ7{?` >K&O3R[% BP$6RU~}!Y:} J/bCґv1@b9Fb\.Z0JBʼ dX CV}GXAHk/v>|2mXש a]GYDy2׫3x+F`I%c֐@y^Ibv[yG}ĉ%n@h/ju TT nb EOBTbm4 lZoz)!Oc+(y=VjQ_jM~ }HI |p5!pPUm(J)ptDWGUj#S(jׂ@y cb`B@3>j-ƶP-bcJ`7tb'{0*l8U82Exz$!@dZŸ -۳F~=0~=qˋV 6Z`yx#͖y65XN#3̐*pLBHu2 b5oRGEuh8ɯځa\VkLǭK7uY~=Fh`O7hIǕ[)CȒ;wSLԻ_4@6%+llR zGu\ּÁV,Nc 25"*WzR\bE54£}ԖbX[Ǯӟ=BL7,'|Tq W{VNTy6vS\W]ڠ9=CNT1; Oypѐ:!RO1,7d$ۦ4/R QrީDڤẓF ݋0. XuT@;):\ZXJ+Rnn)_fFiĨ"SEi6ӺB3 :6:IUI6pV9{w̮4Mg#2@"M/U㸘;| Rԣ:.b2?.@:NFW3,3Z.,VS)]ܪ%vU)$P@&ٱF Db=ţ Mx؃Г,dM¼Z!Uw&$`1hqFPN|h`c{;K8^Ⱥ HiR}i{NTvdR.&[aUD=VuzTeR;e;$R'rS{%̈=ƶ{1Dj'z}vV2|wH#6aQ7-k0 N&ХAXBpcGZk@\%:9t_ptt/z >n;<<(5ZӭF}9DoL)"n M" P{/n <(Xq=qY/؊!R{aFظo5酫 NA%&2@7*[sR8s? -4ZJ ,:iMe=eyˆϨitO jŁ<4e\^$ّc(elZGP:80>?7'(˺NLcm\粒ԞpQsA,PO7! _8;0[I N' J.;CS΀$3Piс/jY HlN/6>t9y^OQf\YT|o $c,"CobJJ!o-!Dj]l-hꢡgiwO^C ,)!S!vo%G~xgy\1TY"r[a mF*#h}D}1E@Y^%N.O#k"$!X*mؕ @DxPJLs E<%ʡsn0y܇Rkfg&בh,G&ցȒA)N~nkUrS>aYX!y>L;AqP JNKET{_7?69B[=*RNkq{洛JHZ3K"1Y œ>ɶLRrkcMwţAs'dv7_儈 OYřa]w7`^IUYyfN.7&!xO}lX7k cnT*eՇnN 8U潢+ӽ80C`oVV%UrBOafF .t9Wm'9Of[YR}@HCy~vN#kЫ/ecB6BQ(uue5xj+WǾ룹nuЦJߥZM׵"㎞NwA{0cj q-:6]W܆)2"vxe.вY5[q btnû6 YwL;_#lckSPQ:~9d$YF/67`e}\ީ)3޻Q #|+=El;nfl3~/U|ѬCu8ɷ ~im- %Znv_{giN=٥{jիYq;#^2%(ƠGBxl.zsvi[8EB,"N|Opɤ1蒆pt_X,J1{W[9(Z'/nZ'}ROn.vi>jyi5[O/\w=H> vctwby'9KKݬ@ٯ~ƪC v"@+S'[Wa.hJQRr$?<|>X?ɮ~o։/s/Utrr*u"u 5TBz0UL%TLQOK8`J8^+Rf1>45|/~1|[5}Q|əh'G%hV1_'3k׉tZ}mZM~OtlfB]VegaA&7@Tgaif9},13wQO^NӵO nJv@2ɢôs0$[n e8E MXk sJFGLn@92}YO|:QI|W~7) )PO\/K~L~UL6h}On"F =?^=/F(/FW݉W8##YƹoG07^5 G6U#(,3!B8Gf`o^]zK|U#cX7䗒^ P}Ż snNVǙ IY^jX$p0x JnƁ֌ꧡ 9u/)sv?L+lFAo8]tpYPA}ȱc@>UIՊmHn #zO[ M̦A@д(rm*:E*@[2;@ѪP 9>5`tn8:[)zNDyg4*T~1Yr^*gw/&ł%1h!{ ,1ߗOwD?ދ CwT~|$BoF!qqUP0^do`RV al`SĆq&^L3{Ɋ%ϲ\69dYj(D @RO/jjy}(8y~'KVbd'ai rT4UZQ%2a,/ӈ1ar׎S\ƭ{`f"EsahFL4h0/=g)ђK \mCctZ1g֪LO=QKCBlaZ1~gW`;)hI sZ}M4(E?g㈑hk4KԑFϕ =j1g =AywSZww W.Y}L]{;U'O.ϪeҠ߉Kr<*FEh%]hRqXpݽr%xN,Cy݆r_~) {MwJPyhhgsz M&EcuKM)~_A?OwsJ6\Rlj="24fq~_%E*}Cr+=t&%\؇ 3݋IϪB %y#X^_Pp.I-px?}2q쓱XP |QF̘p&ɋv\8jY𞰝BZE^r)m:C|T|.%k9>񾺿ļws9kiIRNpe~)+plgFp*gÄ܋sHc+i_ԉYnta 6'x!H^vҍ)Y7nuzAm\Ҥi=f1z 葀fM2N"&6"a щ8wu%;|cJN Qr$ L-m7" ̙~5o#p<*%-jDr*G%J$WE,Ǭ*E 2p2M%uήW*אI8c߈ŭۍ!#Ѫۢ+؍v/,nAdMTS'WH\☨w1_bSl_$C3=]w`\LMC$[hZFi,|GÛymB N ̄y""Gn &؈R~,9c;E/#?׋0fkB!A2PxR/ C˪WDb5Z.0ђ6VIcuv4Z5/_m1s &ֶ8t6T:rjs Y“N0j}ƉyxĈR:x b}ǯ$v5V6Qhw4?)ĺ}3<:,AԹG%x)6kl*2M=ht&V}]eX'!I3)Y5 elvW!u/}+p¥ч4p 4T+mZI^m5:M5pl#WYĞC^ώg+x5 xLpx8F#!P*ݒG4V ӝ =վ J6hkV)PcS6HP~V}*,1Ira tpPꤾfK%{NO;u)W*bM5k\Děio^Z8l_J(M|pڭuyF>0 ˽?X۵ ߎDI %{dk!抋 1 |>V#?lM3B o_aј1 &^sl!וf{ˬ|+f̫zߦdDC(%)7ABkʢ>=m?Dو׵a}T5Oz^+_)bOu?o2b i4CsK9*hCF2;k6;:kó1nh]7%}HfN(ݕ*%9ڨQ,5ȲbȂ! z8) c;^)j;Rx,DȐ>/DP/QfU1,zet."KW6 '{*;eHo;{^88!8pa\O9 ]KdkзS>]ITd&*(oN[M9^w9ӬłMC{_o2B7~d| {d vҝ5P`c݈16:`/211Ud5N+㘹fڮF=TJLfʙ=)wIoMP}tvqݫя~y?NeL\@Mآ x}?|sL$ya$*.ۣטGGS5pNͷ|㣻zԅGmndL/vQuԎuRL~_*u+d!!A632 5cABc#oη3緩>vb3t+7eY^L$ޮ@E:cNkqPI"8p-0eYg< /t-*;l}fp˗BbODRc avQhoBH"g1 𯓦u)N!uHb~jI"~afIR# CVUXҮ.J! "v+*%ďZ0Td"H @Bvq=~,؇ evn˕ i;νJP5ѳ:v?2fAR!yi0UnXSVڽ_uՐFb(J~pB .DYWCJv6hZ|DU9IL*{..N&. -;V|cD3_( w;RzX :M.|l}zx(1m=;#?7B6(UQ}HX6a :ٿot[O&n<'V=s2]N8{<.~a RU9 /C嚜nED7;7W96?ձ T7U:Ӌow}6MD,L84w-g,2,$8]pK_˔^[VVħ/!0 4ډ-Г8zVXs#/X^BKP/Eb7-Tڡm]hl>iD#wrW:Ɗ]Bx~k iտ}u7^`M%ԟ/kwdgNG䝟!AC]nPޤky*-:'CO/:kcs%7ME]!^DCiXVIcK(#Gܭ-+EZ}mK 1#2?ξ ?ħu+Vbq7m5K|aE[::I%dwl;RUgml%i/vE)xEK$~ bɿg}0'5A@ZG2GOU6}z3 e ^p ќ icO9-yԙʇ$)@?x"\eA{R[C%y@lX ptD[}}H1ep`EH]awʢ;p ^"=5 !0$S7gX؜6/~bZUiZjYnTPJ;a>o>>}dz)5?Te:qS|ke>XF"͖S 鞉t6xMfw o+{}աX~|.Dɱ1o^Đ;V~ZCmnd]x5gT*,:vnUVÁmT#m4Ӟ.i?L::P<9oX^[Nk1"M-fD9?m3,DAݖfٙDtw&P>3Tz艕t>GX{Gc bG,M<"GWЇ%?v}l5(2V^7]|x sx5}I $GH*ن3C,Kv 蓑w]{fg:d_ vjLDpj# UIwYۭEupq34`Zj%'etth'K_W}-4t՟<\a)b;/Ɉ=_$C_ѿrbC3ǡtB-ʙ]WX󋍦ډXa]_^@7:[n%=}}kN8FF6`w/p6w7'.gTUbY^CJt}@v͂!+9~cxCH0kk×PRz#:{wp#1Fq@-l))p7yLFgnw3N?g&Xd`ъ.rHi\n+CQ݆W)$-^ܑVLp]TW-y  w%nOk M.0A_"k{Tķ0©TZ[ YnywDrtf C klPտ1}k&Υ{ KlC>&[믯ekz)Q ]z弐fI^h%\Iκ" ok>F鄘r?CK߰aԨ_Gƨޮж\APw}e@.RUO9uzp;>.[Sa.>JxB FXhYw[hz&~g tzvkࢤv,ٔPb'v?cU.!/tGt_W`e}h=>Wȯ/ r7BY뵸 ՑG}Q=߂46["@ (ExaιLQ߱DgqwT'07I眫x4'pwWX`8qt_MmD۴Na#Apэ ˍ2`i(Fy3mSDG}*s~BY]x?Y&N 5*[$ 򇞴tw Ʊ=BԶ?\Ncӄ +GK3 ƕpځG6:fgGfKR KD䌑S#4#]y !Pg(yWNMiQ=~>&6*\(Dkԅs:g2U7jDBtfI^%u+%t)ͦa2Sa$q_k4xJz})}(TQ^+|\6i°Z2zы\\(Fg$l# -Jړ:* @B幹6y؝:?ldfΛx{* huӞTOHP6OW\TܷKb␛Tf5yiT4$&7}TT2CUST: aj"r"5Czdax`^aib9w[0"W(sAZ^#Rc<q¿2W9cq4 2SBCGtd}e~tZhμgVP(X kPvfǚL-.d5TҞE͘>YN/qcWde1y)M+osK0\HȒ%5uȡ\JOJ0Hwevbt$2wA!$fHOË5;Pxҫ k3bḲX%(Kj!f1/g>T)-5+ǚT+V!%!_JRܱV,.)8gqjp\ IV739P1Ayq Y%\ Jf׀H*Ug-x6)SʉFi7n_hQƶ.FANDl\.qv$2*{ܪs%%ޞrN*r.lD]@h Ի[7o/Өuq6 cLXPmD2bZ6uZ^QVd \SrJU)} ^ED +C]M|kyJSBۙPml4Mh{Tk@do^{{;)mW`|4KF-b%>Tnț"2~Hh΂uEփZQ8[˝f4oZ ujLp)BvԆZ9K\'YσO ~>TO#l~gl~L5BeV/mE;@I4E,yEcumN0Vj(/CaU03;kPj>"lm :/-N췗TvT65ӊC8(U-&E%块[KTV62[ 'kQNSHRJXάQbq_2Yr\>{rh yOq8<ޚ㻂%\pv1eU)[ak䎊ض2= yo#Ub>HJ^%>K6kzllFcbx<2L^%zS9_.A r"^䶲r]7|p-Iv9e|*>J+C&:+0[bՏk3W$SAj@Ltz`ZjWD5\IfZ6A8*BZSφ q|L3涒B%K7FZ!ׄ1ZI0%5xس7**;Os6Ͼpiq/< ?+GX#pX)50پbx%*>"#.KnZb_xJqnvH*ud ; `Vo&Be/&&5枈&#|$vt\sіn]jLC J:{Syd!<ҌƧl, E䫺ٟvͅ6<ϲoJvvГ11<^_'3;̯4 35]jcYY*a{XK=|{&7p*.)4qN=d<~+Ћr-#|{`N6W8}Bw `*{%yҸ'?0QP/ुUb @i}h E#*p7ZAta-pkhM_<+ƞ/`4:H'#Ovi+*Wpc ];&}_ϵN\om]2hW N5ABY腐V 5Sa0.™P!o$= WNq )tTĦfD~z 1X\+5S?z|IRplGQW &7`^JIG6b = V4HX[nPAJ+?h`ZΫJ`֨g"!,lwyq\ۄDC :hn`e++:Z |zA?%kxT!bPJ$E=ns,\A73`ݶple%&*i(H7/䶢^#l{AJp42ہE-7Yy *s7??A{@~8(i=!6]vG5rZ5zJ6z(a4 )^mb+mD'\" _Ph]qG̷WvMUlL &=Τ/f}B&eAw0-/sKs [ 'u8;N}9!d._ܪ0?S}^Ij0D3$r:N>gomQE)2C6U=GU&u%ߏCz.Ά$W3 Dk~¾1)) סa%ڽ2S|N$9QE-8x|UϯeǦ&SSR1|]ȯj{ DGMȐ(_"GضPqJSCtQ3: - oO0TV2]5r|P~I,\xʀVEfcP?`M(Y]nyV0ݐBoQOkm$6I,zf?M!No9c{=@pz[;LĒC,gz|)**˟;X׾Q/=ޚ$j RaSղ]R7 ] qW:_4276=+|m"o/ ㉡s30ߑE.Q qz+Wk*- D7]c[%qOoN>g] ^Ŭ >,:'!¡>ΒHp lϦ갯uWWaPQ(49ںqp O.}9Z9߭|,Bg4V{ΥJYQJ$[tg'IA&g@1[l+;=R)MӞ0(߀|P$<5BHD ]P*540nTa-68G{M H"Z-V9k>Opc#*~9+,fn88ƴ& _诒B<|Zxlrҿ,[{nRz-[6c[q9Y)pF7y\.uѾ(XuB0y!1+y\藹vcÌwj/S(}\WiE+"}C6 Vt3d[QJk(jh $Jԃ]@ "t|$0 <ɾC`HZlM\3}s԰j: Bъj6֡0~=,u-~8P~$4{mbC;_h忂^aw),AP",+w'ႳU儲ټ[bB\M҉bvr/|EqT/FsE ZFZʟ {.;Ux9WUW"095ՏBg*{G)_lQ@MuC*r)N~ )VѷQ$u0bW!S3b鵤&jg ji`04/'E]&X ∈ "Nys}ȦyyH>;$YmőKAUþocڕ-W Q?9]EQFN2^''Ww`IXXέE&[B TF c Údp+f)uF6w:/A/'i˕ D^;YlĵթҊY\`=ۊ_ .>%p3j/h#yhsp# ʝ=+2P"l S)Ծzz+>z-Ywil{ `-VM;]$W[:Kpor>ZO3w}~{Gy{ݵ葧Eio!ä"#?<\|6eޢ +J )5VD`CuQZi=k0r?[h߹?i3=<ֹ|k<ܖp"bseT&]1y+8-8N7Pf !rszMtKzK>0z}?/@iIu53N'wxQz\F .0zXxB ShL!(#2BU69-HSTӀnQN`OnϺ%M=(drC\=e)KN&|~9EP8ɦ@Em],[PS  ZYя U/oĖu@,C- .ͺ>& Fu2kfwQW?Λ+>E6bɩ6Z#xAkʕy&>!%o{{h5/N=9y _dfRo[غg[ֶU 5jXF;x\m`XD{Y5h߹3.}svbbw3b+# ۘNXF-tϥGwY.RvZ騡㙁QQGHMjY%졉J!4Y é9@`ᎧXB%f!0X ۞ix&燼PӇeNG UܹS-3k)'y1S0LUCa˒9f!T6>JRH^Z JjI+_RGKM}K%mJ!G L^#1ʥeq*(,0!Rܱ]m|$QiJ-',OR S;z|J{GhdVR-'۶k~3m;m҄R})cL̿nɆ8ΐig.X6xqJ4~vRg݈8_Wz'cwi:=wG+-MWfgɈ fl}䪋cǥ Eif*%̂YGnË#\_CgE&h4ka^\h"ʱS9í'ScuqdyoVQB(" uA7yJ"av#l{Gqd..GbIm8FTНg$~.aKt( :$V'Lad0|%jmFw*{v,Tv\eQ׎g 7nUKg$O_Җ6%!69Ȯ ۰^+Z`5.!"W eTV!HmxL Y׈c* (@|xOԛ|X T+a=k^.nBn02l *Jg@~IҍPΰŊO1pn.ٰU's,-B {cw%e>qd(Bc.ׇ9P$^\:y:\ pm{rQ©(Ѝ*0;W[&1歾!QOnAF2VMN%lLv~U+}4T]X=9bK4\6 IS?È~ɘ4sfFBAT*D +u|(LE 2bo ,ޟY˖h&wlMRDŽ Mw_*)}΍В5P͋5heO`d ڊ AUgH;UD:#a^)q Z:/|/rkyf00j6#^iC"MaO y6u')A\6] p_Lx);D(X#C+r?,*\?Kd?U[cD|bB[#L7!s_#+[ Y9W֬in~H=BM.Hơ1 vܽ˅{GXt~F]򟡁YنdPȎ?Df¦QO +c_BblhwMgo \%F?aR5Y?Jl%GCV /k^^F%̪o#q#K߇\0O~o4s ^0k -jrI<'#CQƽrX($> V 쩿_6Xc/Q{J_B_@RyM`V 7;:1ٹfnqܳwGZulw5&yǔRXNZ gNQL=&C,(2/Xq}3XR|)z#{ ߎįB;2*bS{ܼoӽYmc֌ $MbE6 b 4٬ȊHϐ{ٓ^FA),%9"¾~%0;Z9Pb[E+4U{TQpS5rDMЁWezCj{f;t^\ XC"["R7?*ϑ,#ڽGe$ցT}_Т_m@e\Bl-kxI e71p;RMO=Chqo wLD: !#nvbiK&ޑ@0tGkn3lPLة_L~y0.H<b)>f`>b3|R+gP7YW\y9eӛ3!:U*\zݵ|KCIfҤ#+L,IR hR _A 4?0?`li=Һ5JR xh~dNh[G}8yBM}вKF]~둥}J٪gnX.gO r>W_ ŒIۑX%Ahls WLXsiFGm@w ..6[Vz\f8ՙƿFq0N>}Fxd Fxl)jd^,q +]ӷ3\}gulo;EYIfuסq,QR\$WWO pO?vFUS3|D&0rSCo.A ApU~o39,i4E >Sfǘ?7uiHl-Bp49=t֜LOrбJJuGSaNj7:·hAZoQ8vDRa O+U]m7-Z3ƪt8} a 39aڟkbt{gIMlŚGW ;T-Ig>ɸxSj5w +<E=Cرk""buQ_0VcuGl:h<3ǐ&rM(X~@ҟBcEcc"SV*!xsZ("R6S[}++ E%R鶷w-ڋhOm-٩4֕9m ] 3W3&K<2 KofwQQ6#5.L{D~6qA]P۪ sY`Pk-w-RI@;v*[/"7ȯoʥ iXKj5,Ne .mns^B:?gH@œv  H_ "tCP,bDa1709-YäI缡 X~@F*PcqԀfk4 )E&Ev9me?c3}v8f?pIr}))ׯt|;渑D\OP?hV&%#x(o<]wiC0?{txrZD=3mQ k"qWCjKp72[|bDȋS3.D)'e/]k@^Iz91TEx{Btf>:TOP&&,w>5qiC)[p4bQq9FZɀzёWNnBC-5hJ:Bka-< 40eޯKUT90;5ApǏUF,'hF>1m,hƒSm( 5s\uWqi2*sV/b{0E4AqC?`B"*p mrʅ-}D@u̚Dfh5>}I B8^gxωgK,J'B܂͂KRc0gcF$+DoV30C c[;~lE*=lBtZLK5gJ fgt!XU^PSO݋1]M$;վ(yg1 .PBS;eF$.-/bV4ppn 8 l֘a SJJIup(>9fy%V1^ w@ǥuD`,?2}2$qO?аQ-U"zZ8:*LVU)8PwhCxY*|>w?E?}Uy;yrϮ?(1;UU^=ŏQG6QF˹-i?uwp߈C$Y۴^nfF\dh,rI (P C9M/Zk#;ȌPyGL+*dϳWZ%erch/*,B(u:poG˿ [Oް=ѕT@_鎓ufBՔCF0ۂ ^TUPhD،~5(7JMmd"]run_mbPBҪHtJKvFt?)TC:Qi':grj<:BsqpmJJ{ҧu^IXuݪArzʥF g#HP8yFɲFwTo[݋E{y ?h}lȲn20zDKxso7,$U}ސ`1G]ޏ cZE]_Μ}R>a}uΧ7ʨmbQ/vi^8GPwrEh=)7<7c}# h#  sz#^UHGu]?[FIA:%bڹ_bRʭ/f9x?SIWuHE½cj}q^UpxꓜI^h 2N7` Tsç'Uź歖z3K:ϛW;z;>B8QZibU 1WNٷN:7~Y4, ~@(*NQRmK!R~J: y Uphg S0ʦG~W_IІC4 hŗ& 2 ik3<@| E@9 G+B 8G*4{VAd[ݷmw7һc'Lsͬ,FPs1KAFg >w($wwEV>Lvnӆ~[ZŊ֡n} ħPְU(ϳ ~ Sdr2{Yoe͆ݳ&4$~rJ/X!U,0])Uez@d*V=PhPC)bV+Wv|Fم݁ QxZT4KϾCZm=e*+ny݃1U%ZEQ]x`l7f T}H@%ǺGww%N_/g?{>\ ֚TZ=QYVX2l! ,Z]oLHmZ^Y1]PN\,U7ܾ϶hSm}K=gsɌ \nCs>DXUI)"R.ѭ<؂[!oNr(<}@%24 S\#Dҩz'ƚfNzF C$ȲTe nvn~ hE͠N 2RMܨ"!M'$o˕;WB]63uTFM? CAdnɚ"Q؆;[[5uo`w#xj;w2o:+t>؍j} }q_>ՆD(`-2?\B5cu ̛ IT9Y/1gxޯkY‘o*R.<%R?d :"*)QrtB y0&5E~ujcϛ4/>sBԞw{l;XLZI93DEܩ<I3a.7cIg= z*GjS$T(N2mN73@ S:e` _x kYM`.9*hnD!6 /zYéQȖ2p" zVVn#Ǫy"g˴)b q*mixſq(i}?M&yPs3q!rQ]+̰ KO C/H.=?Z:3;d(Rbmg#2hOݘCEK|Cd .6pATmlHb!cC q.MT55 IJJpk_f~Ҍ?r < kx})Ma*rSv?ZܕF\ų@˽Dj!1s+ ln_Z/Lزl la(LU4al]Th{U 8%-DUOJx)> sm%'/(L</ikN+D {} UяOWŅ5kh7#QyMzlȬRD'̖|5u+EA!:a>>5~_`p4sp|2le{jra^d_^K =IsځR 8X_N.e^:lȺVS31[8|zGE1]|(:Vf?X@$Zx ™a _XQĂ8-oH9C 2+2!FZSV**gcAT$᭵ʈy?~7ŠdR9H 8! It9A,]HkHੈд?Kfi[T~sU<7XWtz ^UgӍ',ro/"99ZxԊBZVr& VX˃o4a:Q~k0%qSQ֭I9Y+ȫE5(, G75y'@Qq"(81TAGɪ畅=¯HJ@ٸ+Ч`cV(frK2͎b[^V1b'H;@<tbU0I/8]RȱTfLɕ9&WlxJ/]pÃ#~6@j"tħ&(~^}c{^12x hNC G‘?s'h4#И69>(qG(S,R''.FGKZ"Vf a vNޢry$gwI8U/聚-cFh[Z]Y&2bh6& /Ďh\`@ n9{{2F[QRйP:<^}E4BsAAHܺ/[`O4MfqT@<>96#e]UbU90/^ aُ{"BL|8 PM J򌨆YE,QM'^iX0!-?MQvuEH ;\E9w:QCD-,Äg(FEcEØp60/5q;zD^*Fe}zX11O6b&Q賾4 d@$,YxI&9< 1 D6|F,+1**+$i+M0$y0EX!a9aЖǃpN8MsşQfRkVmsMQP mz5} f^WN#̥E9+Ԗr)سj,7nH~pebz'zwRZ!=KcW =6z(qy>J4viw> t%eTde-c8TRMDFZ7hq j Am-o kKW9F;CEpjҺ0/ Howgpa|8bjx=z~0'ȻִI0&C6Q, EYE]o23%)B,h$Rˋ9ᕛWjRN,j[K!xBF uк rٽqwJ(wYG/0YGx JW'~˻`0.(.ƣƉ4q7;#:Cq&54WU*FD-ѧ}^')M0BTE 'R\AR뮠W)L`YO+\bҚr j 0 I @"I-:"|a^s0)aD8<&੠ dpku B?/Q[ ևhLjaM?9=Oޞ@bI{\[~ǖ|SQt*W: M޶ `ZۜaMI_J!Pbn6ݦ))_~my͟~Ƿq}Cl<ˏc[9ߗA^tߙ{mֹM YoegY$)D#ɭh~Q^ÔKfpY,iLbի<ٺ 6i=z#X]-*`k-qh2»ީ_^kt[vX5tKepn7[mfRsZU1`|44] `|m^FĘMչ<{PNc+chØqf)iv 8(bs*hv,9Kq ?jP߁Q >`ەא͑2Ɍ"Wl_?V10u&&H|WhuUʜDcپe[^]2BhlD@) Yx v"AD[Jcvf3%^U:d$穟'''C㪿X h,E#sa_rz齻w;l2^+ŋN<'d+6#-=B G Tco8`>FaĀ- |Q_UK9}oW*ne{heVsRLI n$ܡT}rUH y!:TiNģ3Hf"5ȊBq9yz:= uU%)fJdWS%i$)fnLq 5!+d^DJ>"bA)ysgS̲wBґ<;g%vh(ky -SYw%c`r:D;>%`&V:3WR&o5Xk4m=&R )$F>..My".BYltb%֞{ <}Jݼ0:> לZ[/VOҘvrFIN(4lIx]7BxLH3vm~J>,t -r/j&DJ߮JamyU0`(1!9EUyR*3!AfN԰i3E ʟ7|AtI0GÂPPlݐ4"1wѝv9kpF:śob`'!P! p1Z`!ؙJэDܙt6VBz!̀ )%䟐[nJFPm|VhiƓ&2c놔'AL6^r QPh40i(i : 0E]gFM2#ܯg,Hܳ?6:{\@y9JI35PrrVa )W=fJuJdQ]j[Ce<=z! :]۴wa_.#ҡP!1ՓX9EG$ܝݎP*kdʆW[*LeP2t@M 7u`\]}_{ PH3[FWidHtjytДrJJP{Ta@jayԙ2k&X0ev+lq a&^e6a[)l &"\W*nߋD܅ikϖ`2뷩(tlOl ioO2>ؿ^<$EԒ g!DxtE ?,4|qZ)1Xx(!tvrvdKmos3 h ~&uF{BN;xuغ۽5?ϋ7[q1hK ܂$C;]=3Xy='eMpDޓݳ(K^F2ؙnG~m]F!-i.%6mXLnꠘ:uSR鶶nA0Kxt,8ۦ~qЂ-@y}JWtՂ@$,m}ag{/|a6oz?>k.&9ʁnWުzyEzfWV(:`MTuL6^\< [2v`MR [ʊnEm朼(F|K2E`s5<ﯟ9ٔB`|HJ&%o >_cxA2e\\^3+?}M?}oz= -@elNۨ ?EF$|ZA_ "SOGu&7iwS#!2V8$JM޽FlTɷ]5csViz]j}S?4*}ZXҰ,•uK1Z~"xk%f5nM6T}M{T,:gzQxY2dt'HK1K+;PԳ Ow)F>Vqz827Nn7FkivrnOzap4.2~u֐-k*d^ך7C_ |ӈ~:B[q$ HGx@*Fڮ%'鋄aY7PG=OkZ&Y^ tم(8I%UE"CHHOu>7eۇ]PUs )1NS:!v@DhKֻݝ'[RPzt܍Hl!9Q24q!tH9,B)I#{@T$!60(ˋe0ߤ O\ؙj'e ʥXP?鑎Flri:@fS!!y`ISrJrmlQE-שN INϺ>`7:ͬhSn63H klmvWQ5=N,u]✭] "iՅWK,`bQ,\;-5zW?!E _zsˡZA,tÅ[tuK=(* Na+%B x"3[*a{Ђ2aZ#9ȿZ6JWL}-s-Rh}+ ,aP59ZoZ )̍LxCmd'JN嬍PfeY a*g@6,UAuuA77,DLzDtJ:\-i *9=jq|+h<]@81sF}4_&YDwz,pYĪ%s}9p캘9Sm*/3"{Ho%N/vm/cx7v[RQkBE@ 6vC4[P6І(+FV-i,5TrN+?g@yOJ;tF?p -A&Ld H5*Љ9iʝ2awJ)P::F5Qg xECǨx{FHDq'  "B¨FҼ@ 9RPk|L-8-n@$lzPd)Q)2gutH/5X~8]&ٶʎ}T^.zb 7^9GQ:~:F9!UD42eGKWY\+c5dB0<vvⷹ'ܐ'";*E{+ )!^+}cmJ&~nܫ eWk}ѧ(~-p|mwo39 t닅7Qq",_Q*X"ᥧB6vY*O6pαFw|ęu/:ia %u!׮/Am?|a~>Edn #~yMrFi!QJ8Z.֙k [\GK#ĭ`gZVv?bup*k,gʊ2ۭ)rJ(w|h0YB5,m6"'eřU s'%SѯAHL&;yn73b<8i emذ%U ii\$  [ӦO@ɐeF8G:-1!yJN!VRף}62 M1QU B"{dxM$ SDɜtr\C`;30'!Z5 x)]ʴ^~Fg&ҕJi1*5f$c|8)Q{*d/KSB\PK]|La's5[;ZUKB@ mbU6Gd3cNwe;b] q\8Cj[XbMvlj)lr\=#inT[ۢDh/ EiD|F6q}3-'e") ;±9Y1HW(ն`?Z܉qIqrcFh şSf+K}= WGe#ۏ кhz2ܻ8 _cTFd1_b":%TƀW8 {9@q)ؾH5 ;_5Tߞh]*OY{ڀu r.e.k\sm^6Ug}/+QH|D?b׻a-ۻߖY=XX=O_JE moqPGplDĮSs- G sORѣy%:TEJ&3<9 9(*G8wO.XG>m©dZ2l`3Zs3`Kp;|,xj^^ݷmnG등L/ zUn5\ +ğ$*sJ`B bW>^0tSy/Yb-ӃYSobDNzA֚:weֱnAeHW^^W OÁ)s Gha"z52LF):-.ѕ˚x#6f@Qwr`lJe1AU F1R߽zUX<3t#U:R I5KQ Rd?sG H A:h_sA&*@IX{z(uJa^Cɒq8s̶\g֤%5ء^%d#ӉgŴꬆti[flJw6:B["S{ i+G7Sҙ; =D G7]ػ8ElNYo.V8 tqKzJ~aD,@.BPQ3UrmL8wMDY) t=UEʴ*]:uHX+Jۀml/* yM*y}!:>Sv+׸K0}hb}f"Sy_^f[ n>o5pb,?a^Am4z{hh[lZ@icMr!{hk:XugE1.GlR K:ec-F,hP*N2lJR䁺0C4 hwE:UkQtk 汊+3Sr9NKV ` H%Kɋ }.`*fwM]H?^UjKNWG5y2΂|FW_j1ld!>:)W +j(>Yl H^5]/-3 u]z*; k#Ԅ3\_juXd;f٫ÒkDE[6U=5cN3h/&\\ :&8kHS"/L\.8k!7ƹLKu/l-n"K=d/υvvo)[0c62 }Ʒy>Xqn;n Żv9OlmsX|OWkMoF !_,`A%QN /Kg,H*DIjToBǍ Zp,[6(P6^~ (N%[C׊ m^탡ߋIbѩK9N",U+@0UL}f`,5Sr T;el2قXxdEP0J51;l]:~IX5bF mvQ(3ؕNd(R&.tPT~K>s +Ro-gֻQq s xmVbi4)dxRf 4fqLJI^M:z[i@57dfwP("#%P]:c1ٴޏ'fjv`wQ'|_{+:i7!4;r% ;3iᝐ~P*'djBaС#0ENe6eDm3FDc Sa!O ;WuP/NlfelJL.U*ze{XZO EM" z ZƝ٢N-E s)Fn J>c[rC35Qb?8Cjw( VL  _p) Jv*kqz[h:}Ev>[  W$~QNK/mb[MwRLCK6 lY~۷e29XjJ &c+aw>¸ujhKP5/1Et=," uRˮx4@oXв }nӴRcSf)5tkMrcN7#S2G 0/1ÔYa>ۊ1:957*%t䱱ؑnz!7+2} ɋT4$>8>^}X t!HH-?jvґ sIV\Btߞ,x eD;IAad=(ڪ8ycwXf;7f's2LZJQsՉ9sS^ D`wlX2Sћsquı%D}~G`_GD 4uk@ɷЩ +L8?=rQV]W1UL`<^ѽjշoP݇*y/Wۯ\oo 1IB(GB(`+Kݼ{E'O _Y4j(;P4iԱa_!%Z oivxEO僪XѠ镤0TLܹ<У L׬q^xWґ-JC텊źZ. PX55f ֜oXȆ6=5v6J須wY;e-(:nvj,Z bYWV}&YBG4MJ`Wh)Q/׵">;{~fFKn _0ܛŭsx")w J+x Yɶisf|MU*S,tVh ڪ˔o<ȡ}㦦 M0"S"|W XQf1Xa$+N,K ?=`t+{x/9𳩃JQ/=-zSA.w"h-~6EsIJ0:%7 %ŸF5YeQ2ڬeڬF$xm PS 7ֶ]d189.TtqIK }BB$(u1E_p%5S,1YWS7ߛy@yƜ|y-AP_tL.Œ2јkYT(׮hL]JP2fEEhU(F50 b$& k@ J 坰3# !gf_OSujk`f1l9>-++-h)(- eC'귽C OJ?h|9F5Z,;hach8c-xz !Ko\O:xxψ8N e\A[Q(l^.rxKh`̮'[v Dć08suL[aPz\dv>v_峎 {Dq|6b:qjVBTE`Ak>`2pND#ig=J@zKWnV&eF]3c +o\Ey#ҍ5"߹a ) ٖCou&ʈTCͲ ܩm]h³ 4WJҿ2  q[MEr2q.)O qD:TZkc 헢;-S׵vw4pԆ#W=Ybn8̀MF'؂lXުQu}}} ӛr0y=y©rQ(2?>|p 9;Yf~|glնu20cԝGt*,QSE;;9 K 8Qh )8RSr :c$]!v`DLQ |8$RhC*6V 9S#П6hUz| Of~d[UN!UYRڋ K|$U˼ +h*q0WqR/Ey[hdL} t'Eh圢P1^^w.3Qj<9!X]$sG=,;CiU2!THFT0/[G*f\aJcua6: o`cpOa"/^e!{tzIQj58 I~{!=R 'uU{];1JްD"./.ۈ-\W$/Kw4ݽuH"V_zgd~'wuA[XPP!Xޘs|to`hTv$Z hwmDٛ:궼_[$"x(q,3"ԷSVOX_x~z`' 97/~ӛcO}&ᶪP8;.JWS/BƍbБ|V@5*S'  p(pj LE ,NPkⓩc`ѺSgM/ vU}oVпѿ;8P3d]qk/abH{ Ӱ]z@XHtPY-Tq}v/x<; 1y84=kCHAp8b 3KWBi4>:[(DrqCY! UBp ;'TeQzrxǢ 3t.]-N8#mzP5T;&]NN<ׄ9',rO r@g H.pbYpx͌PI*7G%|5Ўa״XPY3 q_#qyyNyLπɟ_:Hy9js?עQ-aͭ! N_Mgho%' OE]oMNr<-I _wtgwʱkjl] 9XT~jwtB7KCS5Cd i7y 9&l|0\Đ3cvOy9ivP̓>ut0y4>'α&ѕND1%Iʀ(L3дmi^7^h#P]l1:|P;ze' ח_*^Q5o&~.3>}mm8O\ބJ$W=N?˧LS*D4 r^F=uOT8zRAUT,y4 ~o-=`eA* ꜰ_@T /宐z csOɞcp]\Ň|Hڑ&e=VΩ7Xɣ/HRlUT^w&[6+T׶TdOP]Q@7$Gh?ɜ4t Ff7QgR#eD(Іt%'7CvӜsc}]0Ҷ'2MB=vTL*b*{`5?>?<[T, vN=3q~֫KJTJuM5rF aQYvi\ TZN54rH[F֧^U)) 㨜SqR.ѐ9+o!\/S `#*pԆT,4a zGw}I˝+N)Zq.S/7Y)\铯t 4ʶY]o*;=$DZi 78/'muϻ||֏~a5(LG-uq8OC ; 5 j.A95 +iTш`!ʃ< Ͻ!Ep xb{Hj+8"]cNXUJseZbU:4̥m S(J٭חʰm?P ӣ0S,1<+,jViQN}  Dʮn\]Plj*q NF0Nu.=Rpa) ֌P΀չ7\?s x ODqtZareon[ uF8eGxˍ^8?Û ~t`SZa^lVi_ų7-qs}ՉHcz HZTQs[[ޣl,s3<y8WNQRc?N_te #n|-Q4Gyz)?N?"TJmMփ*yRxSdUg!;xȩ3_g?aWB{Ɨ~IxbE}v Gu(ƻe7,ݺ @ 2g0'Af?{|2_eQtouyH<ꧤ gzAkb~R񅢗@=|yc2L@=$yh̉x46@(L\"qBL"ހ8Us >d&ZѭH4oLv:G)24^ܦgEǨOB2x tNr<%|Ry!2؁,{aY  t+thڍ 7xvicX ̳\svG3Ƶ[jwӟ@k]6B6 e2'dSVnP7Yv! jC.:-0y I!*EVY+AI!-^44OB A~CleO喸ۘoEh2'6˦!SǸPVh?ƭ~Ѵ:/KI0VBjdX7^YonWpW*yz/2DsV4P^|oKDFY~ x΄]PפPNkvֺVE’?$>56n!y#:Ԍc8r~LLEh lsEi(0f̨1x8ZR!-/E&]RpyjQ%.^/GRTw4g>BEe(qpHU998!0̂x*HP"I`m^Ђ\x| `mEsYI iL+EC> nJ̵4@T8Еw4LK/>Z o&RVU fg@l9j oNQFQs. 铛9=WšqFUq){@"O f20_4kzlpzDR/+f- pϳkL$*L7$$*Z k~HxiJ};2=\$!CL"g(>PaHMIj-ZV' /&2`늩n (ՊЫBU{=w; V;3g u6\)+l#qƪoѾcy1@s'w$h"aOo/nT liL!Qu0FMg%X=1+5 HAI]PG?"y0&DؾcI e9YrDNW/!m?y| 8nhfk'ZAGʞ$'RrJ[T ^9֍֥ؐ0>ς<67Iwoi5$QsƖYkjêl(Qy[Br68(˰Mpgm2v35ٲO QMH<3\ڣh~_0';{ѱa0k)\m83pǦx9;$z'{v/ο})ʗQ}V\TuAxBqw xo{^SP`w`go`jGkp6&Cup>VyVE)ƉԱRmL ~ğV}|geY+9A;"-#u$FX'jנbM<&oaɈ{a{DOQZ!7[PIB0F!V/cK$Hkdbzd..!5#6' C3 }6Cn$4zy|6IZZE/~:P1(y\hZ[P*ikrTLcuU2ƅ\4(ƕk԰4$EjIy`}I -JW C~%V<43޳A\մ:v'Oh.` ! ]HY89:86E#xlAFm@!9GnR &xMVSAUҙZ{3 ~z~QR2)} ֐ÆzբgQ7 %_]16*L4Tl1 }NXf{ JYVT6s 6K7\};7?p SʤI amg7AEc،yA1^W8oLvj",H) "k3t\X\Ȼ+p\JQ#X+ iu\x-Љ,ԫ){x91DZX߉MAX}t^C .8Գ ;~rn0TE`l&5xv+L*gmAhž -\;)7 ӃdM@E~)/XXE0f7 JAzb Kn(*G3# ;4p kN1(9rNh݃Shm$`ΧBT&-mT閖ƙ[2IXc8Q|]rܑbckJg5sM3V@~QW)O<¢85lmu-rRKm0 H[ŻOźJL(("yH$UM* @(2^F2|!!B 'P~҅5y$at$H6~\XJ}l3'aqcb);~W_sU@_iiĦ@8sƷ$K+ ϔ B`Q';vDŊn8UR̈́8~e@0Ϲ?EX̤"]@?!q?צ)sNl:dRBH[z6K+3 fݾغL>p$B:N5:0ÔqS`&oPe)1{hQJBcE/WƣlIU[p;Dz]iΨE{\Nx~SU(zBB.MOaҥ [,$jHD QG}F C?~]xxPjӕ8iB찱2qyaԦ#ൊi6څboK& w.e0s("N-9I2wS+~fo̒VɞD^D3,N":tBjdP h} "\󣭙 =p`OtEKTgR9Ap̧ &1\)l^P Z)E m`Vɾi :yZ)Nβv5}QCB=Q^^];w}3UP,Ǵ>4?!8ϜC?z/]0âm } ԒnA uV Z4%5|l㒤LPXrۗϑYq'5G>qKŁ5?hS5Q[f+oP1ڒU D" !@~{0Ϛ*L迢HE*؂@,iM,3lQc=ϸYjrqZ%~͉\ =(3`f'X=MA`sS/S2!f_5Y 5tMDiC$/Px"=\^eYb "xȣ6[$QD<6T&[ (`v"C]u!XaB|fq'sf6 -( }ȯhޔ c9GW+pLYs^-ݴ(O{C#' pS?lxgrD( . tM]TX}Nj[ROe\K2ߚa喤)f^ QLGa $hBԒJ3z84X=fQ@I.&—JF8tuln^Y ME!7\9?C"q*[  Q:NdY3M1$)/˰}<)v\ `dW͗qv>V^nuǼAX׆8RQ7C%>֦ J~S6RYI*$ (/\)cXSs * "H+ev HfMLȲD|RLSX(4a]熠FP7sįc;F`ML"O;q< 9OJ|sSc-Ê^rXb-6< uk9} |dli {BzJPuiT,-Ȋ,yObady9{[a\ jF@ N^D=_{D򘙮v.I'dd#DYL8 Ftf+ Q/v proF~%R-^%*pe,^dQaK7DM~2b0,\ 9i(hN7lPvh/g4Lllq7뱡׳!,]fڹڎ lBwVVMW҅~MI3!I/O"ǓzLX@ixX˖ ! ̼Mgًگ2=N5H(e-B{c ĦAbFa <>QVҾr?YʯÕ 6m RB:҄תhԠ}F ĹT Iǩ%-4?W#g]:RijE޲DKqck.GL˹֒!7hR"=| IR -PU6|6љTcJvNtx ϚJ">` ʅ" +wnqcFTE;<(w-o)hfH39M_?/})wSz4TqB"H{'_qPJ}d v2u5E,}BID]s޷؀ܹPI &^YQIrTR]TrQe0zIFoPtv;C$,zh(I43_@M=)ԘeҰ=lB6`6FS.cU@Z'ULc*˓;>#b:s{ƻ'&fJ.;JnxqQ 7e$wɈ [FHtZ$^",yaBLj8C5q9+tg3˪#$# &b}B&n+>+SB {BX|@AMS%}H@/[ǟxȫB%x0y"pf3Yh'/;4HAgR_gY-Oh!Bq`DTꙨ7L5FvEkM֓wdR2x`W`j1=.bWoK>7?/?k ⤔{hIp5w֭3x=Ru'Aw~4,;D1}=%'tpEE^(2JuQVϢj2Uu2jփG\ao9pz "M =b47qcϋqlD9?@j.bCWDG֯kVF$'# x!_yzEug"Y.1,) A}~?9I9JOԑ@ @T{+CklErl!+((d-8𖟇ڞ7x#B9;C/Y' R Ra8Ba "=@-~{VaVR;ن%mCKQ$Ő[蝼ͦFRurKC*] aO!w8Q dyy"u[皴Ƨ'RXr[eWICdM `T?ͻ0񩛂E.E, ppbW?6#FPppK/'Я.}h?/oÿw6יRWϧ켋Rg[?AD:Vwj-׵4u]ѽ鯦jn^?E'~ E75->/$i%{zӯ㌨ )ȅ(ve갑@Żkr>σ7p E(˗aͪ)W*s@i o6T(;XI@u$ cNU,BBa/:*%#.>[{}3tJq <ڜ9>縥ԧ`Ɨa xFT3XNR/b%ETQ R;dbNL^a&Ʃi͸r_?j_Bli=kO?h}0ۻ֯xit͕et[n"4 FTFP#-Y^H4Cbc:FGp7 puQF!V+!S|I 34>[&lIR#cg0Es@j-7&"s!hVōOW3:u%ݏ0qf_1xqfc7z}4om&a"O X?Z9׫;n-IϸhVvddI*њLg u֣Eݡ<8 *E]P@w*蕰du ҳZB wTOVzcHXϿ/*zKN5[MBUF;]I]Nr|/ )1sB 6*lD^^ P؉ u.ŏsYvWNAY[4mey|*,zE4?e᳨/TZ k|l5 98 |d>Rʺt<;H֗:k;ዼ,wGp{p3Dk߷#4m?}#k2R=J#Hloh?W]t&|?+$h>F*&+&͌cWD} IGI_pbyopqZve,@V4rP|G8Ր# @]bCaACAkqbRn p!Ik4Tr r }HLeUsr,m:ie rS4uC!zWeF).r%P\juL_&k]3'; T E!$[a64"fO]ݘ9XDm z \+<_Wmoٳ~;xҬ| /)C1t<=~nF1LT\ݡ2NK,KJ٩ikn'$c:DgOv?0D]'Jxs+wSbJ̈,zNPmr|c_t l8TuU32rȸF`"0Y.7Vۚ~VI^ߔV/2̶w1 n%ⰈG8iWX+`ϏZ"Sc}{9Ѓ=+fh; H&^;_t۵_Jvd\V/J>ݸ93ςF.F>N;H;K%j^fHa`ںeB eYOOP>t4I>eԽ n/u7\eP=Lp?j1 .=(űJ#8$})]ϹG)e~f, Q!j*;ψ&'j=z]ShPo]`a?n)M7yW;TQ3tC#i!wT"eoRuMy!W>d^ ºձjuŤ!P̩ PLȔ=p rqgmDlӤL\4#L'M2ϗ\,wqO>9]9CE\fMF uۏTNūڍcbLo*9$[mu!ѧ'X "0}SvJ(,ke'84,fLfrKTpeBҥd>B_./jqaJnڀmm.ZyKk:[ h(??"e$=Dҕ'S&)!C>!Ǧ7G-GԌhqƯ#4Rv+/g{jhu(\맭+wqCnFӮ$I+9kحC<܏Lg "ŅU7MaݠꄺEICu_I_T$H ;9ۤ  $CKǘA7dkRD/D\ G,[[(AUw 5UIPTPhܣW8G/ۈ6&L1ZP-QA(Klo=t2G, D*gӂ՟Nֆc0ڋ0UŘ[a5I.JF]83iv;m1!*UJAir#Ze&ʡ壯NQMȭ1E@X#95YnH| szJ?'?]Q^ XL@TJ31yF8sSşWИrC-Ah9܆lpua`Hz -vZIZG@ !w;Koa|.N?ž 'g}+ hS/%')dV[+HMW33hכzwL׎,1e'4"DZMm39 0Sd\EC$C:ޘh* o|"qabiJλ$]i$J۷>h'Hv?ҠzuV\:6J qVP)Rúo{:f=nPzk[/yj8Z@y"/b -Wԝ%\-R9<[erL2RFGO7蟪lOGó?=M\3+I*d?JU"Cv~yKVvy!K~D D+$Q+0,(i/Ö8RPQW!Dڼq-x~pBI}B `L#< "BcQ-y(` $ZwLZ+&n ~1ѬBkTdİHrp"4 aEC>ij!y ʼLHkR+wÉkr[8(u/l~d#Zh"4_Q7B ZQݻ5UIj4Fsֳmuڼ;-xoiwqS&Ml*UO`TA̹dڬ 2L^719#9R袕xhf3Hu!'ɝE;[tߐ0ߋM5 J17[[|;=$l(](GZY|*D I[S= sQqPP4 "-@L M3B ջpTq<}h\iwvغ`L$bNpPu"%$Ug7އs.5[jb-1 $Tҝ{L}ΠJ<'H B/ lM41$*ʐPWEKm)5NG)dxgM]0(dIN~Zb+mGMw#οW _)C;>ȇ&_S=d>9Ky9иyW$'#"ؓEj"K+a;hA(cV!b[}nQ&h0fVY*P]CŠw;/M>}y'_0+|%mb .,;!XD*'K򖢢ettsQC`@iUC(ₕRKd V%fi>ٽLNnLJ١:of~RVeYN."}i69A>S>qd4 b* )OM 3,S:1вtϜT6ܼ%[Gauxꖨ`S_NI|AN[J4\;e n [^*RNz$;#}=:!iBB[o[iq7 oؓ#=ٻE?.BQ/}]AѿTO*/T6*,%9l#WAB?>*p/az`\۠n.H'z~_nc0&jrZ-!Awy)%VȤ=CY) u&ַڈ L}0>oz/rS\@b[i$MX.}~tPbQd\ y{e4HWߠ.o@נ?3v0 jMN.oa7~_njK-qT(G+7e%|Kp =tpIBnIaU*8uITg%EIkM8QL0Kc")6Q["6T]ƁRϲu9? ಻*ǻ)`rW)VCN 񒞰s67й5O{>M[%8ZӒ H<^6.}K`wp j;Q3o C\c]\dS\L6K ..h[諑ٖYSՏ_aMWjlo0P՘FoDL1TlڃUv']F{vvC.;qx(GTTvq (L?bi6 G8 (C[|3+LUG[ӛۗPyM (,~#\{zHNo.~ޓX@rjzѝ$.bRn57D#uPq8?Jŧ-FVk 󻕬ZX'MCtr2Q$2d@kbt)d"7\qEwQ˫P7R߽\jq<@Ņ޽+*S M`@[AݓW⏗OS/pylIݯ)%jҿД 1Gs u]`'dgvLrHks^h9>ZFC-nحl]8>PN {:y}BddF-&-+S ʪ*&tY4&|ThhƗ*繡rEYs4#bR1؀ *oܢ+69Y eD$y[k}cw_7A#DոY@pԊ(m"\ᤝչ~|]OtBѳs3?m3SZ`*̿c/dmhfcBzOm<^*~K$e4Y֧pM3Ƈ~cjig،3ݸt!gnl$ƴhD\,|ޖ9+^=O3"XZʔ7bNȘf pvҬaCDmd:eҐc.hew-Ja-ɤ&b&*aM4nr$4錐lKQaڸa}tL_OaVȳ) RJJ*LNI: EҘq&au R6Jާgr7µ[)B`6z}Amm8roWY'Ҁd yR/X@q}HgӠKGWYdwEf#a@/;}sr-f й]HíU(v) =.48-r]IgWM߇2D Bw2pbңa)%;ȟ0к8RU2XNlJlQXDriJFM"o5~s9cS:)-3ZqMxO=8|$\טY'̊/7*Oqp{H^.6SEoom*ox{{ lC#y`&l\2u]n>5;:L_)Odc/|vՆbpVh[~aTH[-@=# Hp ~[0eIݬӹUkqgt@%Ir7-+Nx}(ʉ+zǏ?@Σ~ʾJeZw]9jmEL0Pf\sȸv ~^?^`nw~gqEZ ~Q;@YMߴdyyxhԃ9D[xS0&BNfY;RJHor:aN"Ѝ (r6AXH戸'!Ŋ6`$ fXq5Zj!hUFࡹ-m4GҠ^ܟm<k5-&@\]i-23+- =V^l,R"$r\4rAQ6B#Σ>)^t sg215JeВ^!=2/ȵ-.I| $=BcM# }噮~ C)˭xY*Pj˰I. 4^\Efs67\k=y} j@(Qh ~*qw%m4sLXᙶYplvtlwlNǶ:m66̻;3>Ϳj0Дs$H!6y \|6M39Xq^zam}g,k}b`QF4o+H H48XsOu]egB ! KɧLˉ-!g#ހهd߈7~.)^d%ڜA#tRj+3Ǽء6-^47vMhὉUxxBO^jK-ts>¾$qmI%kF.v;33tb0X3J?B$'0_2Ptq3ЉiRw Mt~5qTIpD|Ci() ҆V@O3AƆ˕yP l67pv:Ꙕʟn-Cs2e?>1H3Y ܏֝5vr ҆8GTΚ(Wd#]*o|r!ҬBSTݾk>vwMB|Ebٜc(!igF N*a"('PK̪C6Y|båpe*oЁ-mz@&X=NmȄ;7ʰ8}=vil#7Xء놑Y:v9{p toB8 l8AQ10i2:WF]Ŭ~T;cK*{,KY3Ʊ[:αApX6p͂iXK$ބlYtlZJu<^28,j }y{P|?vRywTwIJT1&}Ҫ4 6g]p@/Hix`K5?4;1Bd[%Elِg|,.["ğM2-bֈ'B'd2NvsX+;l2880ROSLSy~\Wy̰f(j+<:Ğ$mbq]A}̸uM\+tdg .ӑkѤ39Ja8쯺0j@uS\h fL^v"ApFuެdlequì 8q2_zdqg~kVp߃oh 4 IX:}*tV A#z+Z?T $Xc)?@6ហo*`3H Mw+Uy:XHa57kr>  +9^F󬾇Ѓ`A=NN8U~F㽠~v,@j#RYQ݀`++Hyo?xfDcc($tj[PST{wZ퉻Rӭ3UNj y=w|5b+pqZOՓ )H?^pLT\ݟͩsG/ng\*l4/*% ,G=WHOL:$_WSK(d\ϭ#hػڥ\9k%Iؗ r%(CH-#j(䥎P m<qVu ̨`%@W[L#<&ulY RйU=6%{F tĻ*r y"Tj_?ttKO]: OOS:S;^T*v{v˥aT0+n'1緛IU^Pѱ{p`xWBZglA3ArU.:] `V6-uxvf:MRaCıAԳ&VfKp?pۻX2~s}8z;hus|:/' A/O^h98),U:~R:u`,SXDEdlS⁐ȍ"f0O4M\Peƺ1,Q0=)~;@R0om)2v\h ?+}N)[|*mrl3RFNG-Um*e.?|f{2>2w$y=xt&UK=+$U+h=ש&-]xH`xf(g{ oR<8SKb'$d׋Yba!u ,8p&G!YE~ mQ90Uz{⮕0ڳhX0"!go[DuaÑ|0 F٪PwkpΞj5b -%p:Ao*AHjdvW~I(@,W{ lj~>ܚpTaDO!)=~#53NZy{6uL_r,Ԛ4+!Ď!=c:f>N[&=F܋S#Qk>؟rXT鷩x"/rߘ2K$?Xojw4XJ˺)O:V'@-Xi!29{g@n?~:9'B/e׏T98@=oϑf H\#yLU9JxY5S-O^BZNX̚XƸ* ㉢\*aQ*<7cTIO/XZ@OT0M5SE{~htk']mDb TSȏ6FW)xߋ#}w0Wjlۦ7fk LhZZEɱc4 /cTO$ 1O$A/cԌ|oct57x^@zQŹQΒÏ'N o֏ҏ3=M1hZJu+ԃR^Y(mPƄ}89WkU "sC\=ۨf @ldz%9TC;xeGY[ۘcTᤆ\:;zYWQbSo6ύY3F*{.ZHb1AW r}y6(N-@]Ay[i2KI_>}`/'r Ċ~mCzuzz])ΘsqdL|D}MjFh'NP2T'W; (4֋qc2AF8B1xE뙮NQ}Ssl%k~¡Y_9[h 7!uF֌ݶ?}/7Ey} GEP&dI'}ЂS&ҥ, SGM Pf9Pk%}*t >Nys4Li}- aG-u<,B['s 3HJE:AbÁ"{Н ,,9(˞mU)9h[۾LP~#GKl5]\&*t̩PoH%x/xߗ/ϡTv$~:]V76(+%=\]DY0eFDUR &G횦ke泫2Иl~tcm=njv6\uWw('Ckc!]EkBBρAO)TydOugY z"Zf3qiłUwbDN>,dƛZ} >2햟4Y{V05Qu}%5%>:˺nd.ŹqaEi[U NmM UoiuD׈ܳf?:ArEB k%B6MGʨGO3)>3[v[uY*<~b'?c9mUFsD?XD"\ ,|`"rxuPWXXZ8|2bļY+:wLf"pצOQl:{PD]3勹(|\RQ=-ɆD 0 =|5Y'+HHk}*]&@k twWAq:FN_lXRb~p[&0U:>?|S5 vXЪc(Bx7 V{w}BO"Yp#.5- _7X+FxAYTTyma 78ur$|l> a\ T,dcCm䅈 V?%xOy)3OJ!Ú;igjD]ցs榞Y rH4 YH[$cX9p울Ԯ+4^QB wVn~.]YF?/8/ッЏaH4Yڤ č@J?q&C噎y|k*s*S{1vh9KwMO xQǪ4-5;TjcPsx89]q(`yB&YBqvF!07Uٺ,Z<>A@9 qg_ܿC0␶ YGCo1M cq6cKbJXļ{j6Cm4rk /eANZIbX.Ը۰UL.ѧa2*؉ƚi?2:@^tc/+!>4G2C-NAt1Khqo~Tx%O߰⁈Y$Oye h)2.wi2f-p!Zt\u߈-ى-0A7bR2հГ'O>(b"<)1KW6%QYY\X\sFq)<9hlvoZګDH'cUn?%fdE䡼9uv.ß z[E4ߧ,ņs^@@ƹlN.tRt8G-g]iBYaz w?G44ŨfQGL3FP3^%!PLt\(<|Дk0ki_Iq Kd3<䎒rQǶG-͕R0"b h/L s-2Ǘyj'K] Լ7]"^s7uy .6e?WDT8h} bty-yBz xEv˘j-T=*zM'c֦) 22)ol%n A@0Gen~o;SmJ)GK6OQIѢƿYN1 ]Ĕk}V 2xvs:~9 |@Yjǧ;#33KN*1 BV)xzUȔ[{5%)MOWN XՉtE)% W1z5@LFԪ-a^Di$ڡ@O  hژI WWJY3i#?3*}j6DjV[`1?Hl?%cs7EDV>'dR!F[8 s%x{~xz2^˻QЃXae<㽘E3j+˶ޮݰ)д.z R]bM3[:n-*p ؼrbD@{F7Dz݃Ltz_+2+CaNsp$>2I ?Fu}Sā}Z;9z5kakf%z\~㬴RD's*?R.^s;?^N9ԥ4_=Z|^.a Wa EWa I !֭QݕX(+&|_6:ǾJ^?Km{I@ GDA6%N(B-[7z|%g!@cJt~SǹM;J%βLo #ܡ#zKS;i16H(T(mqnD_ C eC񈦨 DN/)lX@? C~d[3*^F/RRub̡7;:#I(& _J8 Loŝ,9&qk=8Wz].@ Ppv rGsn ;Omv'N <д7ZhYZ)ߢve~mG" ѳǕ01't$ꮩN9睂01 +mҏP!߭ RX /u8/noW{nهγn@'2'Ù,&Vpjvh"&xxJ.*\t>Oz;z{0TJZu<!'N I9U(BIgyo 5 >R$I 7/e𗺵8^⟞J#Ԯ1 B2O>FyA Eܟ]Oq- Z JPmv; ©܁ԩG>ɎGr{Ϯڂ:m~>q/Tn/ f忱f7 ޣ|A˳]Q, Cdӛܷ Y%͕_ڼ<ZxeMy 6tzi= P(sKΝNFGE| 9{Vݍ'Gbtjob٣fڧ;ޠ6 DF$`w;CdOށk#t|3v7?Q[Tsˬ Q*#n_ ^XOP*W)7ȹ${53Y;-8H'6^= q + m-y{?ꏼy"&anO蠬k psum<'c2drzQLm !!4MdC"j^TgPK wi㻆̃#V)LaևiH)璉wPtJ9bSׯl~">PR741:dCj?O6.N:Rr|I'2|)\%0oNf̱ NJ炻'&QTxYgPk GA6™E:bڐ..R_O cʰ4W Z_~~1l\ oҨ]|A |npC AL;y؁EE.Vf7Dptcs yVriBTnTO[t◟')4)cQD%0bAgK[|p_ fj|+Dp Y]etkjSq@i-e| RYMk|==a.mL_#DE9JmqV֘'&ײ-g$ā-Wl>ٽqVzVpno@89GD/| ~Z;61GR}X90;Dcr€ae[,!U53s-ᵲmMn Û ZԘ\A7۫' {QJV~/)rR R_4Y#W־7agVL!Я୑1H#kpr!cV9VC(ki{ȅꪢR)2wqٗV].|޶)>,rT{2VG?^sc(9=WXVOX[ӫXLy(B( w f`e$h?CIm;Xд'fSq6kMQ/yLrm%I$;GL$T ]8U1Aul="MUe&A@5z1R~yN>̐6ontfPPcİxZL=hkq2vdmDMO@E %E1aNI@1I3]S5r(Ɛ1 x^{YCf)=ݫ܎ZM UOhtӃu[3Y^[ρ٥2TAjQQU[Ԏ`%@ò8!4-rΒyJϛyC/6S%}'ܜnN@ ~Be &V6dߏ}(n^Q ۜihAZ8twn6ɩ4RAa)>ox%-oŽ#@XM2K"YqG#&Y1 795 U]^PB 蜑kps@k@qM%ž]/abhHc)_*K39=)xEQᜩu/܋xc "/FdGa ]%(i GOQ)[8i}R&ő T64t_.+~;4[pF.GuI.IU P-(h7ab).u)>aq("< ; Ӥ+v^eM&)#B<@vΓrF[2!C AL9lo\Zc𐵛&,&ݖ@h,y,rAnz/Kq3t$jsvhHL-Ѭ$e(3J5C1w|W|ٴ8}M5.A?MDKX\Pn7eЪ֞6my_Q2 COq/afXogmeڮ#ЬQPi4#󵞠ڦ$ k+fhF"ݠ Է|y_plXZ4KPp(u@ +zV =fB>U Ihtpf99x-6?hM=TӢ<}jmQmLwݒ!a5=na"i!9}b}F>H7&w^}7])Hʚ;1(91 ץo9?m9Qr;FP9>Oc&MHO<8NsQh(`"Iz\5#8֑rNPÚzJwt%4/ʗ;;l*(CyW ~͵7*+ (\ѝݯGZ\jf.'q?#Nb2W9JI6裴ĒA)[^EEKgޜd/0u;`s –>6r*G_X-mfhhAo;'YP}WdˇMi%;Ǵ5XbIv罾Zem&TP pù D`~_ZnR>Hk&bae=@aʬ 0#)t N2%t7V?}czuoybeҗGGTVDnPVʔDIR15=ozBa˔u/aiq[uǛ#v𡓟t-k9aS>y:vqvޓ=boM8Q[A? Ķ EVXjh(gpz8Bܮ<#^LTS/c7k<ȅvQ)LqY6 (@`dạCݠV"Xr]أ h}!5 aIPSXջ|$z:|T˝!O52&q]J꦳bAtnf.dFM^k=l`HSgCNʈҨ#yDiL&MTȒSBFLTWLD4 DI40U\ o/Y g061DQX0E(dgnڋުqfR W1^hSTXǭZ?N2WSqa\K$>N!t҈b"ŏ„ k(@\ޟW3L+"ޑoX`+R[[*yyHmL+-N* OɐNcF#*8U&gp]nlƤZ_+cٹΩ$~pvXG/FK qIR%#+7ki+np*-ijJ6'gA~]5 PC tGeVY\]+̀8! qB~!bR_aF"ύk _PJ f+MkTI8's ӽylNVkJyU~ILj&:OΨ4'XgO(!ӔQCzEInc-x0-ם~m4w&!GqXo+I6eEzev H#gDI[O~ EPy6G&y=Maܧ +2L3ˉ,̠[$_3 @TV W9\{MR"{Hq"5nUb`p8bdQG+g2ur`]SҼ |(7\0?HB*2 ;qi/NN4>EXgj'G*M̝EFԙ]U8j+tɾLNpVkx:wze$0蜷$Gj0<5,èD:ȘSZ4s뢫 +m5[U-_ 4t!?~r~I;3`Ӌ11e: Έb&K@*L 8zTU|SHwJ,G|7rȇA[HA;&`;γVPQj({ݤmg5J9yYYh}{upX(/z\9ȾGߠޞ pO/= ֯Y Pf039&ן k]_C?+á'Oaz3u V,WDrv c1p \"vKȔFR8DU ^%a#4cJ:Q0%IBӁ\zwذ 3H&>Zg0a8( <;@5:TBwxX[[ʻȖ;"jQd3&K$ةC~ۑX)DcG!oe's2dbyg4RoEJorT~̿Ȉ 2,W b4zY#47 AJ"ZH3 Xۘ2#U];J-b'dVnd(M#H .WV6(Rtf&ЏQ4֨ Ht+OՠkÕO2W[FJ5w=E 2q5%8.ب={A{2?-I8D߰1fjw f^RH ?- lfk(F)-2*wZ_x/ֺ3>V?+t ͹PGH[K҇4Y=vZ١Z!Q9r r9t&KJTzw=i eH,n}՝od UVxq7"Ú!ĸ>%~>FL4ߋ}Iܓ4lN ,inT*5,dʖb+aAu+M^=VFK pBlF8}%&u溄ULСun҂XJ A{L?9]`~Ы:o WWx|ŔcD=nS-) JʶtO QSM'ԤbZXo#PB)])/'0Ҩ_͑ f߽Z6*6i8X۵ 'TrvDAafo0a۵g-Ϟ1΁ݪVMLDp站H"?[iEM\,v6xF2\G5H$&P@Q}^MsCr@3JxGZ}+:);gʁ[ag&~wIC36I_0yUnjun{ s!?.Up쎩'v V3/eCKXpciVS 7V#;lp(%Bfn,v~zo=6NUUxm JABx0(a–}$S'9S~U9#G0"$&֛Bc )51tW-ߟ"=FN~*fymBl"AY^a1 _<9P~b!Y=1e`+hTi}V| ^>E1>(Q#i!Ū(x0bӖlY1wgeQkL@Dg6<7F4h j1K ) fV\ b]-5͍dQ}bÄkǰ'1s+{{wP,X?ޱKӭ ۶m[m۶#2l۶#ömf؎ ̵u޷:UZ}ig9c ^E ᡳ1Ȃ0_:(K~KغfȪ...M+̀Wx0XWI3HcQe$J);br|õcu~+4闊^:} ƭ;)1~hJl wo)oQ`+MY#GrAT[o^li RcH=b,dFDJ@CPP3 '9 x/!yB1zZ=u۴/;<:<;wE#CǃAחWwzq8e9M[ ;0[GUKÐWIPu- ur.ZO#U@/H! R[{ dr}C=n'[=V_:>* Ś7vïXL6]<}]Rw_H>nU?)Y :CD3U+osv\ge;Kp2ϟv;Mmrwoͥyr{Nwsq_mv)g!KChTN EEэlWpC-_j=oq_ӥ;hzM !-aV+*=TiޒB)tdPƀD,q:N棉iו~(hp0 . L10chGрtD/OP6{ɣ8Pf*$ EXy߱E &j E'q 4;x|ɒ5s^of7ы$SJqo(ZӴpDsoY6,`E Γ=wl2DVGY6P!3䉃Mļmrױ%7I!T!$B'Zeg֥ڬs(%l2Žj:8P(E|"ISs)y7A6Y}y.D`ʅy"UOJk.]l;n<- |~5wyBF eB-@}sUI}h%* G`Iђ@U_V,8/b@ƈsHqp+^iQ{~$#:~`;.lO!2q8NB _`]WƑ$ka 0QGLl6:3[j"y,R*5-vA{g5d=0#*1L|`!.3wzMs?d$e;/o>a Z8 5r@a}D,{ZU9a\b#њ>jfʐo?/Z:\:| _IP0Y/eڽ.:a?da|P`쮲,Ƹ0vPIn I>|p:霮\@ 0oJ+ymadZfy90zd$2*{QQۡ?h{x@p<倐>m@w;ylŗ:F600z,qXkI6kovy{bdCS6]Lc5%4؈d+VVӖ;|_`:Ӕ^W&Ep|Y:Wa~cm&=Mݹ-pMqEian1L=2f{ > % (Xb IT&]TC8t%<‾RϪWXH(: fs2+s0he%:AO^ONp.haO :Ib@1-{8YIԋói3|nI13P97Ǻ[k\ BH+_B6r`ON!=BuY/^B8s[&qp#U-D{"艪ܽ1lwwg׫MRV k/?Q[MzAq=\C:$(P1 u$'nN#ki w 8دngu%l{ʲKf%o_ձD;8g`YrJ@Ɋl;HK|nR1m6'T E镵1 XǺ(+_늰bSlҵJ u4{%qe\Z3&&/"2إ7ߡ]jcsA;4nⶂ?S֩q\ZlO \>>Xgh>SbJrAhaN)P-]xf3tr}"NMs(uQ|ԁhfr&!VƦ\^\}a2b H.n #BΥ T ^\6.P3/%m TB}>\z, =O" hdR.%v$ˋ_ ty rğnkhD#^ n)gw)TB邧!(y:X=8 "xJEcU`$ҏMJپ>M)!1tÿ (;oeʅ*6"8UN@m~u7ljo+8$~!rGT vLCyH Bf{aa85m 0D3!'ʨLYַG\/f$pFov?W(/>rI%%5s[#I=cy1tD'Z@ ed3%keJx Jf07/eζ/桵(KW,ZJJ+M69{ EFvOhD2xE1ވ9x8YŁ{AECa( |/fMNnH%o} $ ۔74VaGe\L7;df2ԛ7I0휯T1R6\1Vul,$R.d,svqs+,ݠ]17š^OdN)٪MBS8Q)d0',p!G))O!>n4&rkAX`"{ik1%S㴱؎!x=sWjiCt:֍_+П ݳ©0ҟk(|Vi`_ n΢\O]g V}هlvE6œZEENR K^^9W#U4vJy»+ifCpfNu^WZ%OY#ޑhG՜ePR_,l'h_,[.=2H 4UZ@_H3ˈl 34z#s.eD12K3?:H(>AhFΦx 4 |#-RQ_[\4uUY^^6׃Ϟ|YSUD t]<@ l^#=W睘 ?lnxZ@%l?[t76t *{'$H`˰ }hD[g-`Aڂ0EYִ 1m+H2u0JWAyl GAnbw Yd+Vi:v&=8Z$ *'FpK/g߮&b`FҼX-kkU~`mKE Or) U@? Ci-%@TCM{Ffv^.zɉEK<s|pz>$f ۈ#u~ seE9H0ENIs"'}')]8u%axXӢ؇̚ 9kc^X8$a)}6835FM+EZu-ZPS&Ԓbjk*BF׷¬\HH}ݢMykӘ}2'd=} 6QOZfAx7 qt^T}+U?ϋxTZY#(3@ޗ#(O2~h>R.=kkivws25w6 y|p I3wGWfif?zyDQ\sڋ-S4%FO lfںrbfOsgQ0sL)"ֻپ:ZQ-c頌һKF2q_ǰԺ%C8GRL8JDB!;\3 JБZc1RyV_y)p 2PKJ l"e8G[ 3i+9sR @fNܺxD>ҽ"yp=^& IZu^ h. VcTiب g" JxqtDk^eD ^`%&/bq$LFrh\笉уjn0Hw_[VYkVVlЬ6鰉 Ilk4FQ@T{DGIWCAw otI 2ٴ iS?ź;DI7!Ll~ث ` KUV?`u|C2՘ޗHtjN_Sp{B\iJK>ď'%Ԅ ֦ye$SRt<Xڝ:F Lp?- C FDQ*}^.qڻ8:Ymv@ fw<͡"%ax,\u];<D, i``%A_הWzn)SšeI`ը>pdQеJ P?X/I$S2u`]I56DDh,U7#29&Q\4U5Uj=93+Wy.b3l+IQCE *aKa[V00; SDQFܻ̊<3݉Ђ6xbQq9#4:WjÉSj 'CP~d7@hGIv1HzĔ2տyfb,&˫N-'KÁHzor ?jA&}*֧6V]Ls!tf8UC?lHyEjG8YKNנL(Z*OJdު ْ]%OvV6w(.inKX}Wj1\'&?YL n٧dKD#i9Pn/ Ll5Tuɀ J_MLQk%&9Ѫ%9S{Xѧs 2 c:q(C%:鉱͋:ZdW0ELx(1[b84L` 89p$DA sB D9= FпMGpůq _}DEzbxB~VA\snBqWQ6;g|Aϴ`$XnÝw.9':[qZȺrie=Qo ] P,ED/4 WL*~HJm%xTb? P@DzÞѾ QP+Bwm|`6^υap2lw mlzi%@ȥ"Q"U7qa8B;2] VvQW!,ɱm}k/5uڻ`hn435f~s:( ,>2pܚA6OBx+bAG^'@_Lev=EdM,5]f.JTxJ>7ں1g|'J[J{Xw8xmrNnƤ뼅U/T?e /"J.j_wԅV_#}\tD+SwҭׂVU.},ulL 74\4:!9HĿ H7"y u˜%'eɬ; ^E^4C6#F_8R'^]];r8ZDDpAܠ7=bhdZxMSIpG$5ռ|>(ZU7& <ЂWq:8N'C~X2{5>$`bxne6QR%~T`tAn.IK X(|ǀK1d~%B3?(/I(V mDR lI֏vlD 2J 054_< aNꖍұܢ=/OƥD<9gV ; e \y0Jm2/;h$aΏC(7ބXq\_0!< 6-G2?.dEc8(RQ;&AuPU Vl}x!srda}-O])٪KX_&.q _\[2Qaը2K[ LT'TQwD70\UR`[9$VtBաKA-rE^]9Ow>6h7Lvm77 ,g8-׽XQac"D$gJ T5 ~N9nvЂFc=B}v\dOz,=q׀-n4eW9^]n:iRS9M&;2XS/XI嫆Z}q(EboZ$[wPfJ갯///ڸ"g DqճͦiXKb1'.֢c0UqZxzDgp- B)a!*yX=92"870*Q6s- D[PfjDa)wK-)d7/Sr]^_ -Z&< $)|+\!VFbgpFRty9sݫInG_1B':Su jAVt cI,TtrSV8֙Rj~.Kax74J@';Yl |B}K(֌V:.7 ԲPrBV"Q}m}/;{|}IIx1G8r`q;ItXCMlܮ5 ̄'Qˬp&N*U|7#IY$^NO!-4J%yxX Y]/XFf:M^UϮEJ 1%'ymF h= <~Z+7eEas#H:[}rtN{?mN˸ ĮqķaGdY`` uR*dԙ@H;^7ݞyN*w8 LR]qÖNTh\F*.Zdxo.G?{b!=uDJ6)($-Ju̱CZ1eHUuS44W۳fLxx,XQ<5uggU\SCé{m$[R3ZF}2Q:c+`D#aH8X!9tG*p{6[s:=9Tdpe ,jy8`QV)?PfO~UD-K1,EUN@iexu%$TgI79=e#KٿtvyuyFz(㊊Wkd{MإE`vΚ2CQT b~<3 񪁝PS%~+6ak|JL 6"eX/T,qzEzin:ljHhb:@^xcUz/r=4Yx"3yD>?Io."kMufϕO|4Ӹ)-J-L}Ȼ][%MKcjy|Nҟ'?2+;Yfll Ț/-ު h03FZ :F1bLcn3.O}_[ؘuk.S]>qd %le槙+lH̕]CL/ž|6.vEqt ͗ +UpӦ*o㧬ΉrH ʣAM\KbuJ-q >w]>[ƻ2ԅ/+`*ܔc&&H=iRWyVuw-Bt-GZ 6p5hh^X=1~u[Z7`YI mDUoQڧꂕ肹i2\23\(Hv:Xf5[pFk%S]9 ANml)ml:^aџ0a1 3HC Y:߯c]zUm<1m%UՖW)E!/zMaWkp܈#/>X XQ]T. NaY uLV=Y+[^*[S5'M>/@Yx=4?(w(~n^̵q⨌5VK@-_LO᜚>^ڦLw]| ]D:<WGq'~l'=K_>L #-^90h+X* 9 ,xt%Fi yNrNndTfKscY![,aNՉ@ۨ:ߜupHF88ҍ[3=_QX̮Q"m&o4j+Hџ;U~'O]WXF)Rȩdp#2GE3E# ^ߦO#u }GhVM! Sf4~Jb7K"Y!vS/A p0avDEYu|NH{ptX2(.IJ@8P{ƘbĨR(*)$i(PU<"Ѫ +?_:Ͻhqqh+ʪki| Vic^<^};u?DD-gm X_qx(Vja P+v-=d8ix)p!eʯ_ Z˖ mTJ#d}?6ʿq,nз.o]+mq&*MTQ>Ľ!ͷIo_/IUN}\}"_685vx-򤽁ӄ0 "tŚ&7>u1P4M~11GmۇL+*`;#-9-9L܁xCz7iAi-T?g؍09ѫnP%vs9|J ޻l֞T}2MS53FGM!5(OH=עa'_GRѥ=,)PŔn+'>?2-d^gmq003yWM"$)VgV 7X:&򧯳:wSj0Wg!/>/tOii|3 3T_|33g>ϰ3@'UW>Cؐ0|Db~*|ikTClHx$p>Iw.Jlj9|%uV.fF9Z1qp h'ITߠuT:4Xx"aWNhX<}H{ l@D1yf:jG񸖿p.F]ͫ|ΌO9Fq#Oa& *b]b=sP˷ ~MG//0kCMRrU M[= e%}]Y@E]fHf`-&W.Siߋ6ݩ5&c6]XqK3NbF+Bm ncb*> mhk878 ӯgetY7ګpEq˒EY87Y^ӊ1U7gfآN% 63"Ab,R3!y3LshX*mo>CxS"+Ѷ݊UY]msŶm۶mbFŶs޽>jzc9zTîkJ`L1ߝͳ/<5L͜q;lʤ3r}5d x`y/i1fHpNƷtL_x\w!4cer;_O+^)9KW2IBI1_MT sg)Y~mcd(⊑j~_եF>2MlR)#OPȆ/9XeN>N٤g-2ѤW3<&[>R;\ܘ7eymxZJxqN*`+Yy0oWgĢ6ZAyd4:/˝Yy}`$]eb _.59\đS+JpQoa("Fz% 蟃آp9u 6n;^7%&m @Ƅ !G?%VZ{6f(ihl2|`!"=e Y#(d0!n ܖh~{ݾȲv>o@u7d[Tx}֍3JgXCQ=.}MVLieBGd/"&BƙBGn ɹCdН~'3_)A׃0EG֭Kp2ߺ5_bM3pR+MY4P|͇f ku$Me%:V@$g+J5ۛK+=^9|G;}x]};;O fY4i tZLADl [Uřo 2[[b/s9e^aɶ|o!$ ពbisF uid.B<>B+ҍZ,Oq/ h#ydLUG^-.>p<#tOSxtd%$X`!4{. s0(YHDd=|Š &|Ru{rDc;Y@Y&*Rr*M':'\-4'w2@u+XLYMDuh[}()/>o EecY"-!>Q%MB4NmK`5w1PkP:k('>ን=`)VuVӭ7;bR\YJ'ǨVQ#UjWԤq\5AJ\&Dr ATc^9%~m?48dǔi$" xn s.rXGdIfqDgXQT&skk̽/E\c=[ZE#nןDZzL엹G7_t@Kvz~dRQ @e8n(|>?wG]e'#+VVL\cc}eQR6dK>(/!<'(AFs^E'}ja;vvYx ,#~VYȌa~bgK4u0x}"2`nzbq>`,7<@JP?F&c Xd&;n2 0-ߞ/$Zۂđ޳ VP+#>I F.̍z+U6;.@k…πG`yLaWl[& O= -%)XVg\W%huhNΘXV[|Qu@RY GUcK'_ 9 z:E ShaJV/L^j9@wWu@$L[,Pc/ 3u mq6@0o#)*j>ʯKݝONJ00i :6jn_Bxy(!1ۙuC/µkbĘ| $-z iDҀ7fQ(fGc'si~E'g ` T/9&m0~>]4"~t 9P_{yid>ڹKLL WUcTp䟮`썆1z1Osa5]ٱ\`zFdyr\Xd9՜1:{$QxF߽Ě\5+DZlwߏO7=`BLiDim]Lu#=ތ-HnJ:ƩM;0LPP_47CuJqXNeDGF#n34V9'S+ي~k̓B/ um6ĭJ(98Y:5NJڢ\FJF8i+jnIW6崖R+ܷ|8NΈQtg[{9Gb7R@2B';rn߈'Ċ7#mɣ* c/Zom< /z`b!7)#N8M MuGÀ>|釙т#DPM{ ۖ՗MarsXf0pDFzI<&LMoޤ;)(dn1Lb8^\rr?E!S翩P1p'[Vn@҆V'־ײz- <߃9i]-uju܀RG\Q.ƍK.o+?Έ+Ū\!OV7U`: X-RAʉO@CS5j4KcryѻDg| "rEbؖ  9{[#{G3#O=5L0%4_fd+,)4i$NA.I[Z;?7Y|du~ z`<_}ubST@U|ruEiMW%un8T ;C}!ғ~p-4-s"m æ|Q]Oz7zEPο䛞V@sH"Ma4q6 #b<}%G^ mY7ZzlC67~]"퀗(Hf6k ^:q\JNt+:l$ic6"I͠5r5SW䂬H蔕Jy_ε|9 _ q`AOHH u1*+d3sK'[w)Q?ߘOG(оp6 ;Y;@r{?#c06gIH}N`w~ >tUZڞOdk@A)WenH# O  k2L7ɥx|mKtkeT;r'&N;%~a$I;>K,v]{utbrAAtFg@R(.31o `'fa(1Mt&Q~S&AF,%YzS>MVe\TѢ(t2ԫ*cl9bca yy4=O*6R}L; Ǚ=·2 %9xyAqsv[C?xMeUSYM2\ uܜZzu>̽Zs Ʈ՟,Nnn#tŽ,vNSoHkMLKA ]śD:Zt+}esH ^)M<Y dI}N6~$8I ;_JDp7pKba{)W9vCܮ. 7? zQ_X] pO\fRگ j$7\TgLVn}Jw?^a;$MKtu/W_?v\#lVZ-Gf%)Q8Bn'u9Rg`sU΂8<1tsn w`r ##ڽS$AvKc9(h?NkBtyvC!Uf0`xA+uSR1KdP5bRm#փTX6s^Zj8Ip8:?I :a`X""dh(x_f;+VZe%nӸZ-TNK^ .?ط&&'c2 {gK>8}co[1x8<?*[fFFM:u͙D{B/􄌇 ­hCY&w}is %(JaZ6II}Ge}%Kf|»΄rG!LwTýsiC(.5{~U-x*sN.r>Xc_=HOqf5,S尧K߸e'*׆:">Q0NC柮`7QTvhMb1ӄ p8+`'r )2ބ<4,I#1-1" Y}jemӜu=w'F`PP F-6J0L7Ŗ0wdzsjN>Mh.Ӣr(3a3Lyٹ%c&av@5ȐDC%yR;۫<7\g}t^?кC]#qD9bB]H%ӏ׌a@yW D {gPޤ7 oX6`~^E@|kISwGf(AThYtmIN`b7Z[^zFHn֫(4ve7@'`[VDR1iUT'PM>fkM32l@뼐0KD`蒋jVR_VXn}{d 7ۓ;G)ҁy"n @#QV!^CiEʮS[b4j3.a`l}"o&:Z Qvn_UI&6snx%86F(#q^ 0jX]C >y/3~zʠ68͢7wH)(u'bM49%7, ZN0(uLښ_p0ݻ=ָșs䌘UX:dq54ZVg)KX;mS3Y|>y&d!QՒ7cGmmZZa5 2nA P!Xzd>:w tѠ抙&#ӭYr$Ee୸]a`i6o9!{/M4ڬ׊jl{'eaw~8s\|n{-\.+.Vfq!HljM̶P9ۤ}Uy*2w$y/,<_}iLSPۯXA|!A{_`OX;?V)Ѳ2 J[]S4jy8MOԯt0]F\\Dnuz,B ?\:n!76.7e(ehFV< O똚(l69~iBgH F-qF7vEvۍpIDojr"C4( %{I 1EuStPшItB`un1rnvRswƕڂ Uդ@FnRԿSTblwsl`ڀN`p|b1uzJ+/GtQ#:rm+ qys0 g HJI";-6k΃;gSi2HN՛xV"F̞#:v-HB/4 3e(Q4Daz¶vf ;ߟ|%{ϯ/OhX4ehYz0=u@y9W'4aUY_ZOO2 D\jdVw ˯g/Ŀ@.K^v7俋M vi\%FAkմF%O/Y%D@Lh$wZi_ً>o.]ENޣ[KUk>O!\Uk$GZG00c刭Ui_wY/ >~;<2o|#ك̾t_&3 !:lu1y rŒL4H+\[ muBvpNGv+*e\ y>QjմӟzpEl!xenʔL^0Tc =A__߲*Uf/ ܜf d.h{_s!?1>1GO*N;LK/8PEgR0H7:"1^е>SBMphn) Ջ0 ;6Su3|5*\Z+E1*<~/`~>% F1 /̑L/YlZIEĨ;_U> vL͎Ii2 RCLH&nT/ 7\G5kѓBv'gOms21䋜ϐ?^k}5igʴ&)6"`#o, K43N3&.S=]_X?/qrM1ǣJ52W)AhD\ߜA3 Z1IHA:_;u2Z&F6ějojC~t ƈmhޮMF5h.nc*aOmNQSY˼¦'|Am8e4zJ;Y5c&\=ggw*7z52̭d+rAuYlCU:#|G)* )n)v6GcQ(g3N?\95*Π#^>5ׂqځIdsrGrp5'mƃx<*tH`ˋǜPGfR^nhl {];k(gW {oE/wE47!hi㌉v"gCs#{:TurcEQDt> 9ͅ9<1ٹLAoP  넵[ӌ9dH|vsGd5G2?SgԤ_΂x=𠈪;Q TeVnpY'ʼnn >sD^UP6:͚X4_\m p=! ι~yvȔkKӘЯJP~whBvebC*߃GEƹT+q(^1+ǚD!9g2 # sLOhf1>hI;욝o 7w'1 Lpb֔Jjlmů,dذidR.+D@& {pdQ~ay>RZUS2XB^Vl(TD@if<b`LrAoGv֊~Ӎ.7hmPPPvH`}rDY߷JUJAJ$xP SI(5džzyM>\G̷zö_Yo+w/#VJsB8I V0fe!,^hWiĂ#7(Kz&] +6*O2W\f$4L<'2 _t?AEuu;. <~,xMZsiK iexι€DqIA\gvff5F=4GυCѡMKºe6w{$a(_Nq@0MOCr~y hgA$d8>xN6:E*T*/xvŝSBfwY k᡾Řvã `UYDR${!P^)lLxD?[^sKSS#.+ѥ|qGdr5؂ɰXZ DԴ7I/f,3oE0\c,<"5ΜݳJH&v<,|sxB/ā(~&LL) d'K;%ډ :A}q쪤;mؐ~CͰ>cE?Y47aD,8V@O*}DesbI2 !JJ>f)xoGhm6-qJm;+KoCEkSx["DdTڧ-ћpC?E;{+l"ar*; )W\A#gFcZcՎNEڣ蔎1.f1 ªcI(RSjrWpuZtC-z›y&L$܈sy2XFZ1?΄yOJ $*hr >_y&*eJ&CK$azuJ1Mp`"P7+zVCa^yoRl!!M`' g v<?ҍm3J, ~]ւ^sGқ8]fM4k+sup?c N1I쉡%vU&A-27Q5z9#v~}~JVNoĴ9|@ N=,sYu{U{d%ø 8[ SOFo+ (q>O=?#ocN%Y"\=$W=k?gԲ2ۼ yɒdZR:͆>ݰHEo@-7_"R ST@4Z0 /Moe.\5lwĕ Vn3D߅̀%cF ʴ_sA].aԫ`.4_TwF-7䵫؉"t\& +nuSxn+{4R7B*PCr}W /ĉO}_$+ yt CqW" `=!4"rI'.H=dꩵ}1WKMbSs{Uq@eGfqSv-O<| 4IrOQ`0plͼ} 8Oa|IƉ?OqqT.>c})U-TCE˓dXH3OpCuPJ7Ef4tiJKgcyܾDE;JEԕ{ ޵ov8d^.jb f]y|'\Be.N\m~5u]Jrre5z\P'WU%"s0qgg&}IΠw/G::>A,pP ,8V,mnRMjx E#dY0Aļ}ٴq\Zy{(Ho)wM*blolMY)Q/FE+U|m"E$VI値 $~na7'BxAk&iy5t]ɐvJJzDd$1ʫv|fvx&iGJ(_9![,V)tç+HO՟S/Hmqv@.t^Տ@?3ʙe*W3_6JĐ1𰠈4:+3TQ&{^XEô=6~#n#r 47) 1C&HzQ| |V01fjI$<]->AI;肿YdDLg0[*a}>)Uk=31XQY9Gc\ou4DcƎe4nqNBw;Vj\ywi8=+r.i#alI4 wt1na GpN<_swwo^CX 4f5b(%6{f L.ɃaX ~kޖ Q'#3Lw)-(Iwb\3>w^NogS*rij!%hUϚrzl~67E캔pwqP Ocp/U=LlxX7a, _mrXfr3.*?=Dk 8mx Ϭ.Jt" m̷T2ˑ$Z7^/Dn3 56+s [&cfA"n>2ȊC LX !Ҩ5n2H w>#z4$M0#v3#U#Qu hQR|Ѱ fB_0xrhᴗxsÍ*l(@R8 ?9t4I\+)A3IHK.){%;t'KO)p,$1YWIm?ahee>褰|8C }n&ON=) VǴ4ORfrcI+._ͲL 0:iU[]Y Xwsrx)iC#ۙEcm\ BaK[FH"|Un8ML?ڟ b+xx'mӖomL?a;[hYμdyb0̡OD0=\cNm'[KWorB)C^_42Ojd90~Ⱦ k6Nλ{Zk&GRB%iMY"KvI:m۶m۶mtl۶m'NϹsk=_׫ꬪ1fVGF0z!6,n-y>;f0m워w]ŏ@@LM(k^JF3]T @$s  i<$ԊeI* 6HeHkC.dReӠJjD" F(wi}1K@/yNv??sڕ5 E@45$~_wq`gE1;ͶT;>!|OPcz*f< } $3n{"Xc8;Vΰą-J:gߴ 2w*1Mƨ"ΈF#$]Ga(5ztta"Q &G:sƁ|l>(D<*ah)5.XBi-*#^̈M( :9qcQmafC[TWHM{COlbaKܻ!˲6ZʛQ(-l(˅r xe Ȩ!] 3o Ĭ'jVy2rq4題H"kHfRğ/=\f+st1<*=1rKj_0Qk9:Ƕ壆  E x;BSMC-G--鈑.0=yxm_l^v] }4-M"]H=a&?/zxu{\ndl#Le(IJJ~ۋ揲2nLW{,OO$'N<0^Vן GM>”<[>/4iGiRo |3 P\h,tMaWmH*IGXm&mR8V&{myJRw N֍h.}XVK;zc|3d!`];)R?J(ԃ8Uag%Ѹdq+ցB7i*읞6ڼ3^ ~\uXP4#1~!1q6|x WA@^ifټa]r`o) '=j]AgZc?:R]'&^HJ%NOzjS3T/Ebj9۱m$sLP`9J7xT«ǚ?v'z}$N^'_/W8N<9W+F Ds=o2mr5jO~cd$;sc` VaQx2DDn)hw_0+_=nyCi1V窾M" :2&' X#'X.Sl7fX_niOC{J zK#GO-vk9c#w z/ BqLsb4~đ#FRiMk3ۍ ^ڂynի,h!Yt0x$% iRpMUK%/T- -~cw 5u=T(eh&DxZjUx :E A& G Kkg}2J1a0Ow9& ˷2q <14un"3{#aIɁF?d4<ӷtS{?^|a>Lf%<K XU18r5vһݳGnpyLq\#šir[u{eJӮ R3__lnXЎ_r\wk0^SM"R<ȧ/:~t0!k$>`{0J |^;歔B&XGvg-pB ؟9?QܨlF+HΌ4?ٔ"FLnQސm}N&UQ34Z&*Nb&Vt>qN9,l[ -P{p='*`bym,t \j ;4n΄]93s:MA G%۫6YJ^QCQ#\FX<2Ɔq)"sIW԰4m; dUiN#:$^IdpLJ+5ΓHcr'.bKj~X9B蕤Z?ZTv:IV339uJ5H/XX9.i{\Yl-!M07bW-22*{\1>WT9zCgcNHP\HE] 6C[.z!1Zei5 {B5WͩYcqtdW ߉MFA8Iz8Ц@zJ+3$Ή`L"lB 4roaߥIda5f}g8W6`USiJ^-#FM,xx*@j=-ߺG,ml/m3Ki擟ۚBUjt`티jv'e.1bSOp1qmtD;`t` oL='ѧY(*| ~JAӁ2OYo}e^^N^HolZCS@,r >8"dhb*J&?]IJ z Jk7}B%d e %Q-9=5Olwl87,MeK#TőFNQj Z"f\e23v^Թi{i%c@V ~&Mm\fJKa=H*:M7=Uw ܴ?Lz| & ZmH Qq5WEtV[z~$Q"1O.]]Ԇ& ""2JAPRMgT_ǪlMECV#&@i]}M2^U82ʋ>@lKyRbg~yqj>8 B˻6pr1D ncjΕ |LPљG[ݸ[hѡwL>;~s0@n|0h; kE!VE)N2ӡoxM1-XßQڟ٤@[KhD[k(0Z{nlw+׮ߵ mXXU >35 <!UC`*<=jdZfYfD^S'8P]_yv5&RbQ!M"1zT"Eݘ4.CҦ?3ԑB2PhTPfU^ Šw9<' `U+ f¡N`_-v6lU Z2iFkE^?6to` c"X"K .Xz(F 2#j)>2V@4bFkoʅhV̈́q'dF%J/Su{zo?hOèZKl92EhLp-%=#K b*P{\c 6?~%v f>6C k޲mBG*(ZkEE J 80[vLp=+:.)e\V(iLk1ꝨWCM؂ޮdk=s72QZfEXo7&g*-t?LĊey=zc_q5⬻C`U^B﮻y_G`wzt9Yݜ *Bv )Dj٠Tʱ" K(?u~}`ZlA RoZ}H53o3~r&*[87@+{\eb @X-]:LJ"$ [HC\ tYC\ ? -]iO@[RYUAAQ 'F6D2ckdV<^;߉ːUsT~+Oޗ{OnWm2_^ |K^~>|H+X55&Cl EP  ärJ2qgsoH!ыnD>[Hk'd|i]u([?@Z/̔`lF?*nuUk/UFPl}08947@:RJ?yg~Kʖe5ЅuY:|\/⣚O4-_9one=ڹ.2d"hK79ʒ[k@fϻDZ=q OОhS%U2OJ17 V{9Ϻ?0hwO1Sd܁5ՆeҢ ;"HS t )AVu/W-GXE3mLiVM{+u{ko /۝~&gߥ* X=H<;Dpd۝y(u]2OP[0/¾z' xc&(&OfVHN՘Saqo{,9y|R0/$q^HLjc#eRPzz.9@Ė^Y(L"pEAMw;"(c忶I ;?eO e^P~pΠ'7gRpz\Va+ݩ.x}H/-ƼOQJU&}X݈0xB yw. = f}Lf++7eރf"06YtVz\-It:6# BN)0VI#bvXR%l We πH]9m bI[Y2QYY7?SCU1Z?)BAy(ʄD!2]*3A/PcY^ȅZ@܆ÐX⮜bR3KzG.?9 bK{TU)koݚ9/ؙsUvqM+O8B)AcaXHv jo~r]jQ҉/S&W 5Wf[M_C-Bߍs/Sgz˶V;S FSzsR\,-ɹ#qya[-P4t=ڰ\wpRStuM=PDp46hÒaH;g"nztt|`C|X\<rf'gM+Jb  ȡk N" Q;iN|Ki(Qq?<uQm\x%q,f,@>J)\I1Xq2f>fzbaLꧏ؝ɈL0?ab-HI=IO*9RSܔLB5&(2tOUMoj8 yJ>Kr#pqRC+.)i ܱhID1/H_.VB85(oZ ݏj+vy^+?>fYH)ͽ"\싸/\F$cx~*Cv$u+8.~zHlCS@F~SOj7j0ֱ խ# 4}XNWtΓeM ñuE2tը)זh(QԤ]}s r{,'Q[㽯Ͼ);ZHY.p<'c^,WΖoઇ̦̋X@'jY8O8$E#W:'WKs/4.@2}ҍ=C/̎4VK3AS(f=EO{qH<^{sZ2 $Ḇ=Z`rPkm0~|^dvt òk *omsy)AWP7ݼH'VQ{sM~(Ң ,LPJOoinn&k 0> QMvnN_tY3gf'@AA^lxFl#f: F_CӼpE* x>l{Q3;dhX>($@P`t,va@<$/L{ с:hB*0_vFMjQ$sSuar;jwd8: F)}`ƴb,KlvMZIGsHptS(, JÛ46F,YSwE)XlEN:&m$̺K25:EBekID)Y\bW,5b8,&X6 }"E}#DG ]'T빫?X!ra3iV W)U?x^pSN;_cT=Sxl"W2HG )kBUkr3B8q%bNwi-kT<<8)Gٳ^?1d9G~Wё4S|Z{mb{&X{+l3)Z}^xR&j~pmT3V6#[]qFy/b&Gt^nq?]6F'I3;鎫3grvGMixkXlY#V(q|O5X(RTOӝbjLۦ?B2FJNM}tBNY_!/Tr/:v6t 5qKhH9p|Ns`bEm}8&,'R쩄>\&z?:'誀dgwиG=ԳuX,@.u:.-iz_ECW,\<95G nxwW,!m g8͋HfBV ض-H ls[4Bs(]0:9:! x2.ƎeE!ZC?JFw?$JŐ RIDzٖ=535\by~,[ZN(@8Ν?FKglkPn :;” WoJM\}tܰռ<b~|HHySmjF/ cM['t_Ky/lnNW˄xd v_nLl_7`ʰ Ȓ?hV%ǰ֕8 R,z>c{{Rx&K6W||Ϡԏ]j'jsQVk_"\$eYUc[}<)Qʰ=سH]Aodb yM92}G~C nX:cׂyLW9x>w##nAޓLML’"@a4[9;< ח`tMpLML eT`89-O⍻>;I&ILM) <ąTOss~1Rdidcp EOiͮ]A5"HԱ"NΥlwV.?Z<$gYW&;oCPkGx,i'n _ D!J'2{-(aoE7\Notgf,PK=*=SZ/Jd(LGӌ~i';`ϺiMb!JJ H9FBCK5P[rh%<,ZjL=WXUUϥDr<2o.OHo,RoW1S6(d&!a_$|lZ$'IZ=,yctiuq9+oMhGkÚZdQDD57ׂVpYcʝ?Q`-6Wh& ;sh^i.^iz"o4ɷ2UVkMcK=ƢtcA?9C`. qV^a[ADcʯ]Fo:jӑphz} Q"J?J_`ۿvG]~K+2.k).&3V9ء($.Zَre^q|8CnV xrbj^c=Dlc-UkK|׃ N RC޺޺VJ~ 䏪|V_i?^ƲAb:/;8gh'=&Sd<7#7D7HF#0.|,91GBpтH#W_aTSfR#%?I/Tx x oO "U-1ְ8 SJ)`ɔl.u'{A SNNEsZYvn~汆Dԙ;P!hJ];هd]1]UL6+Jz.`o%^,nZnui?ѽ˚anNӌyB]m@78AW[/ Q1* 3 0W[*Ŧ_kE9 `QN9`eRUnI.PN/h;Q>!*Uhtt>;H?$lz: R$;ja%HyA5hMk#S vǚ MT|nNV7hLq#iP_*?(@c ߕ!4~ILVռQG7L:`㱊aߗ%h7hD LyW3 n}<RN!dkδRP!'jE JQ|AKK.fWlM^Cr3= vc#tKCDO/r G5YT`/J>o )uH3pa%]8+] z_>%uُc5lCy"o{2m$L@DO5͓ d:G ^/0m*C]#@ʝ4^c2G;I[w-ʹf F!șP9տTevA_Z^9'-1tH'J['FFx}3p1- Q@ MRLa鑗.q(nB3ت_O˨wF^GonZLr[u'K|HYQ"M?SդW{C *@8ˢ.GKfc|q5onz½ڭћ=c^TM퇡 ;j u?\̌ y x|-9(DPyjhqk?K_FM\҇QJjW69-`WZiT;lfw -Wǝe歷E22t-S Q>0 txO44$`XJbZ`%x<'p=>3vH4<ћ?XyHC&֬_S?-lId* UÞq#NƔ/Ǚ3J 5/>'>{P-`'m52uJ 8-9Ma,P23{vSf&dl~o4Ak h$Rt:GP }p~F2I&$ؾ0i>,I|q Oc4Is;+knn^h\7peWFIX+ءV 6}w~(h=թQ6=hi#E. GLP9K)TH)8miC?BˣmXVοnoHTV-{ju-rImZ땬>_ ݿ)sT4?G+J}3[tFMq2M'ao;~6@Rzvv̂IA}m{*-fb@&b$1F.+6rn5ax/n7졪7[/r U'\KmHzJm>sgx=Kv=J t˨Y:06Y'CB!78DX)K'rٍ+oFZ9+Y XS1ze}>p@ZrbqJ" Avfw'񔪹;5:f ~EhX1-fO#_0\jH)󚋥 SZƢ&,du>cF]h+[S\F|oFrel) )i&& y9 qܳӞkPsF:6Z]>'aT7g1S{Bd̓#\WQf2 z)aW9jUͶ?dus1=!~T/4w93X5iwkhAkq8r9!ӹ ˇYXFyKw΃T&*y?!kf+%SVfmﺸ_O/Hw/WYdx6gZ,GOkˤ7 [WBit|O=?Kn@~cm恫ר>eVBߎ:tr qӜ(/0WZn'-"p?y[cpg/$H)&38#閽"@&]IPQnhN&г 1Y܉&Z+ #Wd(1:́%r)'pxn0wrc0n}x ٖ2>迀9ٸE WEY _PU_s-}a{qen+ l**A(Z//!ɴ\ܨ^LxIw/԰/a֎ 44Dƚ[٥MpK3W\!qtVRn[ʼ̝RDxk8n'MXI{WGav[V_@oU, mR`US 戟A^ TUK<[,E 4f޼Z|r~[݉zQ38p{(_0mꗾzԮa3]0ql!VCdy| hĬTǡOoVF7.oWF$: KJ6mxl=\a >.jMZtZL]UDOSѷ-CmbY3P]"DoWm64(lUPfEB&@"Uv:efqgΐY=LkEdp~Eop@Dt9o8X5cʩtmmM{䢻IYm@jV3yxS#8:zdA/4R&No8L4πL(43VԀgOԌ!*{ْ 2FHZ6}?S9,Ů6@v= @%a`&ĶQT8k;2)On#7V`@R.v[U6r-\ VefibŪ^nyw-#.D#yna}Kۄ+0L6TQ=HTlf=[; NEER\w%h[6J1{cn'EKAJ|B]} 9 IKe7즀S\cP_ 6j=͔.Zt9^uMᘶ^Zv_&nv-e+p]БD1̘R$Y,ѣmNRGIA )}Lإĵ cbw[`GxIT{x2IKV8夫ŷ\*mLs"߃ &|eepEڶf+q5 /O<@s>JFbS6cqwYm_c]Alܨs@A7ޭi~Xڴp0-'WCÙ~%ƈzBBR{)Y?G:v#f x*e&-\ {{17s`V?${s&z4gX!V$;_- V71ezGHȍ/AW-4I> b/f , F5rMQl%`%3P {_gB竬>H1BD Bys$ ΗUd\AG B*ASc bdwf_v+"?y+MV5̀EK&)l~HΨ-Jy( ]BQب$ں4i(43 \DԬmz}:z:8LJX(So P(t_ÙO[b1<݊BaL ٣ TUCl{ $EUl%n1RPLQjIBqAeK5q:8"ϵ&f=?B^g&YJ]Lսrt-rf}OZƳ4G$is"b2ͨ'SX0ׯ/7Un5xQx%%|JS*!. b hK~ ̐tzIjDS"3.'E%E/UB_ݽ_?;)nx,;pP;$B(a T{N-/աf[/;1Ȳ-:m۶m۶m[Fm6+m۶3+]vvĉ8s5җ/^į1i&C.< yxensEO͂ǡe"G\3P|?@ڟOY܄Q8 zQ=VjH9h/BoZsS*3į2uMOV ߳f` 75=JjI1-Qҁ'\C lArhK)p=r}xQ-%^(_ z;oDςzUx3m]-X'nҝ[:{P<T9¯V#:LoD G{5[6JOfXbɱn>`6]G? 9%K?/#[MIcZ~za6(Neخ2O1 oVS;y3͛/tV UVY4F"ؕҧx '$qL!C +0>*t?3JToRܓ_w#jk #ۋ +박m`Dx2Dt| Z \#S%jd?y;C_#Sۧ\;` )fpȾ^ј͏8>K.0Oa{F=4$(QhT,4*ρ##4e`a\|$kzD읬Zʔ3+Ԇ뭴08uГqFǒeI[YӔXLf57};z>V1p8=Yǟ42uڢ˱6x?(}Tu8@Q<B4Hӌu6"ҤjGABA{s;y< ۭ }''oZ'm3=ȣT8`|=ϣcU =T\5vxim~8okKu@3/lpqZv/c?V.=~ psT?VBFק;lZcZK m  ^ن3?G߿맲SU?F4,v(ߜ^:D$q}#cK$GoTÜ1D3H!lP>Ct3ƓKEMsC'Ճ0slU.;ws8h¤|_O5nD&ޟj\Dwؾo)"TK a+~*y8?VX@Ef:sa)'x|.HgS9aT,)!r.%Y۹ZV%-&T=Cቑyt:,&a)3Nx$D3}P9%Kʙ8IRet).bKU:?rxYR0V5'>v!\9JJQ!s+^2} ~^( :} *GOɎqKv#Ē{fį*QSx2ʽC.5q7u"/t'_4W]NdZ^*oqlJ=IB:mGW넮dZ.f%lDHĢ9;nSM`Dq"7q)XtHM\v|F,'q[}3^>x$U+M|ӓZn%i P9R~4z&yrϘB2%g\g'{wÍ:xğzxn>H}˯Bjz'&LD+DŦH,{1I!Pj}&y5,3M1Nx(mpt] $J:d#8W V$(A epX$:$K5z \>%EQG91wEC %)HVٯh²!FN,RNn~ؒ4͐WY՗J?=l4ie [R.MMך° 隽,?s`5m.4E]wDJcZK5%KPUv:?:]!@tvޞM4n&/ۂhc !ө SWpŒ ]Z*F7XMiYP h蘉!"C3d{m8<-STRWQI .`lm>b'[n Iwa|u^q$\2gt{mq}.q{Tٕ9 zwof%FRI^\Pa?Og9ttt @o]?O=,]ALO%L+dgX?bT~-I+ \45CcCy h0J k`.Pi;+(R6=[&=5;%6َ:6 *r6v*lAIr1.S?%M^T hG,BTƩYBԟcڌ{ozFkrl]WԷvݕ'0*h=挘*[.6"Q~e& LZz,Jt9z uLz'&/ixA Q3[: Q*҆q G2q?k`_jfBk!s-,8&ע{gP괎0fMr~W7 G;n7UtlbT^xw!=oo2x?X1EQV+- u80Ȟ*yQd5"ylV,bZTtM*׿d c/T^u96~{2L7]`QXg7~.4F^@oFm(;$TS7! &BuQh+;3>H`|7I҈\˅NʘԍXy6TRo T7C6hCi) &6ZAL||Ĕ˗cI-MACM=t2:Cnz;lA:t8hpJuYeW\oK+4̄kHpx۷7T%DO^G=4t?F(cT=sm R׶C rd} QWc`[3AJ7u6<8d.%,:X$ܭ8x`s6 O{orBW `FMq1vQz@ޮR35Y +6}cTX`ЍcMt&Vv!{6ǽ7)t"$Y gZ#m]뤔@䒷ls2 `e͐MWH>c`I662Xͤ=qsm 'g6Zbܦic[a \OҜJHnȩi 0RŶjz=/?/"+'ZW\35<+_~S4O|88kc+}@r nΥZp/>k z J,'LDj A(?aJDe{lbLJ] otX&sEI b5z eiYzB Zl>:Ib&p9HQI$jeCdP/]r-Ji]g-sH)1좁c$c(ޮOGȠ6xZy˳* noF"ֈ'}ڽY\ұC|zfޜ.@6:sT/z(>x='97.ƅ&@ >XȌ*dl]Ut9_evcM?ac'%}67^/V8Q~@[%_HDk(lyYKK98 Ě:L5Fl篔Ph=@x_^tZڝt.vَ Gfx nz].%G*-ai:=: ]:\O.X;jTa(f_ ]'mo=QYݮX莮=Pw) ewhW(iVPt=iHt,,ISdؔQ+pP0~鳇D t#&~w`i*nCu_Cm8&HqH}k6Yp[8ʮ &P!j =s/3Au i |Õȧ\ 3b(\`zD`;݀wTeӁii{i0/;X`'y^)u~>@"IN;DM^뻿8"j7ebBWj5% JHy*e-Apg%IRH.79 ͘3V#J{c Z #10felcG?(諺eMx>8˭'TC_r M%σROH2OM Ejt$te]~A!QL p5mTgd jؙUVyBRu~p)Æ(=ϻ&@}V<8^"2H:̦붳 [B"#AjDMڼUr(҅fR >R?+k8/ΐ\ll) % maOI 3q2yrj "ۊg|-cL^~qbDo6׹Cwo-# [_^,u} ʿbJ<å3u 7:PXӗp6}h%\M1-Iy:]IC BwUPs&&ahU*Fewt>]]v̕`sv;(؂Q$x\\%2E" '0:iLWä2&p9QWIؙåYm,1 -!u6S-!Jimt^`ډk?zͻj]M TAjUF-PQT:?><בvͰ1.5TX-ٛ%z6JN `YAzImMjeg#eQٕ%$T6à,/zFc@h|*ĕ" "!\ s72R=L;yIRC.ÄSS*'\i>vQ/r/0)N ֲQ  < i<E!EX !>yoe\uކn3[}L8Bj).WNբ\B*|+_Fe6VcATE1Qq̺Qe<Ҍdm؊_򐭸]LȺz\0P%su lMh7^"BV44V^TwyVOBфE~!tq8uL5'|LEjB2^~F[%U *v+r5-HJm 1U{ܓ?G6Q2? t*@$cÜzi=\FNI^)ļrAwc< )!`S:\9n!}׫+վsWe EIi! T}xz6Խ9odڱr˓XA&% &T[aiE4ˆaץCpÓ01R/)fM!A !?Q$3IVփVz YT'=|%xe ʯݠaz!)ֻ8MgspuHgY(%m%)nVJt+E? vBv7LnpP(Qu83qNrWboR=jb<B@0G-6vv.t6*}V،}_ /(6X^[(0IÔI^6jCϓɗ/M7gчk0ٟΰ֫Tylun彦eHO!?$ O'giP"WRU(onp-5Sr8oxa"K ԑL* JT| l2RgN,U;ֽj?>ADWj婕[5~#@r2urߝO"B1@s@xGQ^[4F]1j RB^-H 6\aG$͈;ZwI ^nSXv<#yZv\R{E;:cJ; 0#_AKZګƠ`"AB%v''UT߿p]%,<ɒ~|'r c;4\JBwW.oA¨ G7a# a'eIՠ#e`ZfӺ![Kj,^ >PLp!:|ӴB ǡjg?6g⸹ ˇ<5.j@efiũ&ȫ52``bTwzXuKcZ>i KxF%4پ!gSYIPhqWh^2/iW5 Pc(gߒָKIW؏.~weVvGl'aG#U9#? L?%Y_1tlLc< r;ګQiC Ť )%M`E&$@Uƻ"" $" ީ_6֜v#43`/, mpUXvQoُǾy} l?jgbigokoD l3I"Y$} XU7jc3Q,dtcZV#3㢎70/Q8 In:Ɂ5-9jjK䴊e= gVtGR^iN_g oC^_̗ɡ83ExYG`҇Ia>C!s}W+XDƇއ"?$OM"I]>X͒aσ 1jLߓL.] hJsPUd2}MϽ2K&:Y⳩-R4ujF/߽In}Gvh7扢Ur (]=n-!;֖.Mp6'!aj Ƚ7(Uojd<>`;wܖ çvOSuϳTf/`L! W-wn" vv L/IPV4GѪ E ]ŒڧLuҭM6 Unr6E׈?mk~4R' Aalocr$0 T/~1K}a\$i@"d- D3 aI^_ݻ*#0X?药^C5< KH/$lCyʖ-)+]FriuY>zFq-ηAueM|2~"c+L˵$$ꢄm/hz 0?hձYt4:axNc1[Y9|+9{󙮰`_.m#$|^t](@pvGt~~_N7󒁧旇"ӛ'V.wn0\гxikSl_esV:(Ə$=cŷڄqozp *#7>7 DEltBH" cp+K~X O&+N ~P( ĵc9W(ux\(뱱!V h>E( 6dx-.5^h^E3-"p^s 5=Oaҗvr;yuuޠ켖O*g =٢^ڥ5!ڹ3?q/ [l]%OBYxddҿ?q74+эPȌ‰8 cu@6N悻܍PO=ۓW{ղz *b3'A+DwCGNxDl!kѣ8Š:-Ԧ1C=9uK"yLU4VX0~+:d_EINpȨQ174T6m Αb 'UmA7{4B6GC8EK h)-c,3*WaYў$miCv޵> 9ף|U28K.BjS^f]ޛ_g񫀘͂~/anjnoficWg9K{=Z b MbVm`VΗ-*uf?b{|1D;NR~hc?9˅1pr (W>]."UW!1{Rxf +>l`4(m +~)mgIv`{V,y$W@G}2j9<}Ѯ::xZlً9낖Y8 )O\ !=ɋn/qlQcLG6 U?4ċ3W.";f{Dtp.+ ]\< ZMtb:mw)W`Դ2RԴyJefEbn930^ y}:OS+m+xQ*[~CwBIzᯬsM|M(#EM* IHXӻLIi9ɉ1; Bq7{!&mO-%a*pcƔo?:!ĽF0_FO0V f9:0~5c?ubY\`QG6QCۭ{3# )ײBt)55Sx&]k^aI*~4P^ۍ]^0H:0l F.78TUE iBEe OTqu+Z!ʵO9Ԟl`õC3UGR1:AkP bpӳ~d5d&$kIyC`#f:@ך\X{M$!e~9 9;č?a=,h\ )Wr H[Y U6`x>NMvIcN;(PI5vĥhp"v}Lx{c8ۂ`*[*œj2/&w>”k8-k4hVR9`WN` r>q4ufڹXKeY5 p6YTRZP|Zh\H!R:\v-9䯋s:j-׻,ܝ~dQbɋii[*ꓮJ@omJ$@fI7i;95%-ei, )J.6!cHdwV xzZ[P%-|)r.e K٤D4'f IK.f6?зc' ;{-7=D!FN?i;ޙ1}0|A t[S+KjGXwo SJv ' v]Se[ĖyYs=,؋e)NY*`yz X,T&4躔5rgƱ9*! [Y5 ֈI[XzVf$'pY,l ARޘN>xRLlb@j)ThmaK#o<NW zn3ylsn@S]V;:8"d-#sE<"Ĺ?A;7[-q""gpeբƅW~af^Lr_sEnStp2u05=ޟ̖L`Q6B"|"̬ S2 ?M{$ <~ߪ'k,SķfZ6Daj paڞ]tQ>%T,BQ'W _ .g-b݊(/HT[r!h,˕`vBP)} Ѻh^W?{%Y4l#4lfdxiw16 KDS>On"Fv OM)΅PuyLA(9}PM9F~b%χZUO7*di8z"UqWF=Dy^g3-3blcR5nHt\my̋W8P0Pqb[-Hh{Va: Öe ) Qǥ Qz"ӫ b<`Z\aW[ qHYV/@G=4+4j֑Nqy/XÙb$4%yACMo2?e0ՋHT$ Ў[R/cRXdֳwQRÍ=Gwr|3b-.IzVYws 煯Rv0EA?e|إ;O5қ?I ?zqg(\5ڝ%COpT雷0;i _`A f4Vk)ƚQ '{2vc-@s ;D+Ȟ >"ߢ)3Tv7Rݞ{漏BuH{΃h+ &rd qbrp>lfh//|XPefEq]>}|7:l=RN`7jo_l{Y4("czٴ%[2\FLĎ0_dDcݻtӪ? .о!h TPBʻOӘl_W[TZ]xmHC5ZXu! @2P7۳&=̔sT#ⓤOQ=ao&}v3=tfo`ci^'kNLdQ(W]k콖mh" 6F&@` r j/"|OYm"- e_q^Иmt^Za( ױlOV׉$T8(<ͳ0:5ãsOpaGeە+Շ9ϐ؊VUKj򽽽ͥ̊p6+*]KKEdfV#2'D答dze|0(xBW%_:Kz=aǧGzf=A5I2\Q6(HY}&&4 +۔4c'gz@?0|yR@|sjr5Ӈܡg2(YROVblݜJ2# Ɯ;Bm=^i yitRj`KlNbȥr2A͐Yn?, uӜh>B,M,Ŵ$\ f^N8'Y:sJp|ƴ46΄jX0vK",gaK!5uU\3]D2Z5')iGby׉\Yr&5SUC)Wt4..{ߺbQRsDŇiwC>msfV޴]9mvrD\'Uy䁧.2qvݸz9>D KEq3"DT:L˃lV8 S/El~2w;k[O.ZM..nz-߮24m͊SN/Jԏ+82F*( {UP%P37)=.F[f:6S*ı޹9}(!a%M|#6%^ C=>\7UyfqՄ|i,.ZsXw|^ `&v|U|>.}G/dRUF RGu}+rSrj 2%RP D1%+1B^y\x{~[x&ޤ20彺Rg<7M7{q yenD]]J: \ON Ih^^79AP$ޖ֢Z *ҩr)f+ z8yFuzY\}M %NzN%4.;>jK;sT$'B'^OQ`#9ӑHseg$ȳ𓢄 Nu&m 1 =t/u=[;_g圳/_8s sy'}{<{')wI6ou&loa&ߝpvyF~'ɯЛ*$b yV}̬MaKwv beNi}ỤΎ6p8 =)bYLĦLkOs]m\h7qqWov̕U޺)(Xh2q='k3_f%jP\l4uw/u<+cR:bdPSGv?/Fotۊ{}[yr.9A"<5FofNB)VjkBx!py]0;81I$"Y$T灛1 4J.[|>[lZnʼnw,Btv[Z{kK:mtUsX?RxUnh"ݡW)To?tdkbU9%(VՉךQ,'G6Տ_*Osz%<_}#2,{+榯JX?\g a i[}P*y*):g"u 777@M;|9>9IgАXoܤgKxY\;٭F fvEV|NH114/\$ 8[yúO̍m+Ս?N䉺'TJX|?.Sۗ_N]5:W7 R]WALwc ]<6Ǹa8) ;;I]|ЗC{8+q'm%[{w<$_G |$/f͓ef @R,@K1> 2 q-!p2QQ)[J-fxaEbg?q#[a}iOR JԼLDs+7ŢN;l0M`rMv5w'Ǎ?:c؄;2L\GE~yJJKUPT!DŻ N~gc<%KXm߾l\'wRf$4t)<֏˶Z i횊/y[y5I6NK L635ĕ$HJoxgsʗֳjiVrx?K {f;Mfw\_uW:0qnA}Pq8{q'su _WNSK{|IxI:5oʲ¹3e&Lq?߮+D޶98wW9')#Zo޺d|7_A{QU/E徾yOAeqJTB8o`YY\˛6˴AnLtwt_3Շ‡&{<_n=Ҍ?ǐutx_7װsT& f(`uR-HS77HsMdO4(ٓkzGCϑե@u|PQfדBMɂN,UUofhßz026 W(QkqhAd{Y )-$X F3]Z Q}!46ښ]M^[n6rC~A>qpx QfpSwUN܉kREY_ *_8˒{քopgDK9Y8T}З}Mԟ1t {L{oayO6_W~ wgA'UsJ35U^a)g AM]yk)UJ/G`)\8| =5z{YhsYQw{RM+ /@J֭s%X35#q-9 ޔKL+>7R]U%5"jcYtIqŻ"Z ߰]Sl>.2A->ķ]*zO~%2aG;5L,O#Y,|8=_S8ҸŊD޹n_|@U/뷙8\}ŸBpcuh6D/TQ6304Ul3c}u\/y |W:uE2<'V*TF_6'7Eԗf.z5o0rsqIѠ\Vivu}}Hօ͑ciY,g\qB^oÐcLAqͨ0e)B)fM??{\?;/uMENezWnFV|P%7TWFR2>8'()ɤ*-dV$y^/JJͅxS}?畋NV}`\ؐ -yf2<^4]4 nh~W.J z 8~/WU7%pxj/z,2wm;w9klz*V|x{j5ǧU͔3p{.}%#֪zuW5jS Sr4 JFWiqoH^t S=3y`CaAϸ9'xK<(N0N xgd{g0ixuoꒉڲƀWp c@:Sț4~MTk'23sd8?ó@㓪Yew]Ni\=sF>7ƓXxig/koQfySM;5ޑx5y>(WKp>p53#6-ՇI2+o>Kz?͠O%pBf5jkgómto߻)RJghj#r^p6'̐,ujYIf6ahXvlJ|_@@%vufLv#F^/nRL?< ^gx{)ݶ,ElK1}qL;^* =:+o?\%aR,qVOw.s>386ܟ;{݄*wDsVrm[.oKߙyR _ĐcflzS&CD6.=8əR;3@rXºiŭz99"vV>?\?6Hƒ rQQ:xقK>I;|$bu˿%%rQ|xtm&|(fBuԲâLuuC~QY[\wG;]`w#|,q#E,3 G[#=.Ih"% F"t hG. hogzuG[)! $v+?(9dh1oW& tG!P1T$F8 ԡ> Ȇ7ع)-NaV H@*2x8S( .\Zqդ#T n.Sz)c &C O|]Bsit4oX+DX=\WH0F8\vw@O>t";nVWLY ;/! F>(B6(&<ݐ G88<ÆaH?D"?/HA>{ ;hQMRާC[H 2,(h&х.6p=Ěb^4 |&D\l:d%L quI#vtЀx] V [: "ρ==!TeaPdukWg9i"z:D<)P顔CKa Unw--^47z \ljk$# ~ r/P7Q7=>.h"(m8^T)H*8ͳ9 Ikx2F>ѡ h+tMY$+C{09c9:^DP9IQbO4m6V"Z? >oY/\aKe& iA!x&fG󪈠4>яZ\?T(8'~I_D +N**'Zcsb㈸DYfO.[ C;,o#lA(wiz`WXj o`C|]xL(z:C)A?@r' F s4*x:+p}Ef.pw+gHo{ ѭa@WJ5t*tDa{}2|#<0$"]f C`U yxv؁66><Ȉp[M3Tyf͠.‰Qˆ{ο;A*iFӼ t ܨBH<ڹS_j'+o+wG7Իqv!&H@;Ik GHG"j^ =pn$;?,?\X0Ʉ vV򴂐2!=a>ԭ\콀 <Y2fL3jG%0 ʱ'# p`)B:ƍRh* 9`W:{M|b A*~x`h˜}(p\R!n@CS.@)JJ_1(ERi^X_ġHv2bh e6 =X#h@_]񒕁~@VpMHeuv(Zn@)Zf H#+u(E_ͪ"GjA)Ws zcԃHB)d׀B1( 4hx 73tWqJNc @[fE| hG"e @Ո0s Ȯ gsvĩs @ "q\>Lh @άGvC;'y&]hvOs]ߞuiEs .vbB:-;9?ځ'#sVvql&ocp~ϴYXhMҙ H\jEֺ(h= !xS|@0laġ(?Y\(=!> "CVR P%! @)B97pA0ўʪR Bة&ZDNVk(P<~I!2hJ2S@rТj"bJEw 2JAe1 ' a'E S)_E{h-ZRc(B\OEA)8E^A<&//GS ؉Vz3PMW]3q0J M?@wB:;c c`8pABw\WN@\P!:Ϧlu蝳D`:."0dCV~%C4 T4xK3T:#p>fA'KmM;ִG, rtq~6 tD:oyh:>̍Nܗj/5A;jy1@ЙO3CvF0@Щsaऽvz csȩ4Fhȴ("sh'۱~52&CR  Q!=9 zܿP"=[.QoIZTPCvwGSj@;ۼ b҃]h:`j{2BkW!ܒIh)=1iQpHN~e6\h:o P0ڭy,[b =Gh: ԧm"B:~| Z}nA;߈,?Z}=8ڈO9Z?'@;aZ(?pZ&X(mk S@i['"ކvct傯;&0_ށv'f-x#)NDHh9BC?ݏL?AŸKK&j[nj_x}K޳:vD5&oG^ǃ=Al.먼c<譿x#"  ͊ _PK ~A} AQMVyzor-master/vyzor.xmlks6+дJL=l'qzs%׹q\ %BcdHʖ]%ʍL,X, [=rG g}P8?=xvuyoNߝ\krp<ǷBqm:l) dqqуg+?˳shtC*^zOe{y޼ &o? r(C\EL#Pv6-j=歩L_ߞK''3;K"Gnz'|ES0-O͖ ȈL) 2F26@$Z8wcB "A7(nij4d<pdFfჀ}EԾm64 H~_U輪1n!1~LiQKtFH)"2 ̜є{dz!tz:nP/eqBub8 C9ZnLA&3.h*3dPe7>]1I9{ ao_w$S%6MEbށ^dNC?MG`WJgSLzʖ q x\ "Ld]dmDA"uW)]} sq՟exG{Lr z)QBx\t ~W,RLi+thh!ݿt窩+ڎ<׎-k\m+ lw%-ӏO]G8&gز"r]b\xZՂ&.F,X`˘dCk dgB*# WOfnLVWaDA!= '{ݫ<{]ȗNkA0q9nmw]]1m23YbF# wVu "YyzME=~oPp-di[z7g $Ƞ5{1u8t1^D.:|SSAq:vRY5d3LJIX۵!s^@=1Ba,úSY5RxVnkk!fk!a .pՆt`ޣ>k%vq߅n@0,nO I ;֓I7YgdLߠ rˍ0a! Bme Ϊnl^HjiJ"융.Yʻtkta:cLFApӚeKF=ww]h/az#G'){CN\=ESmtɁVl~¦~[v1?B:e. ؔR^WU.v -#iD*3NE&9IJ7zrl P,;d!2ctkn8~d#ͬ㻻s+4Fl*V .5BRHuR#vDdn𥱅LxR;&Xqr rb6ܰ=-gx@Rhjll}|8tH:ˬB!rXS2ƲCQ9Gs$)f='OgG|َ 7wISF!Z%[6AK2Yr?tZRT;[Rc&C82׌#>feGfg/?=<'}L#p,y 7M̺Ĉ*C|KG+m{'bB;R>~>[b'crBVØ"!+sj(M!Sխf4=,Ƌ_ۆUUewN)ΐzij*yFTe=ʸWSnZN)fjf=rűCƬ0Hvy/S@FFFMhk-|o&Ijbq$ߎg==?#}MX 4H*u䉴#6g7|s\bsc:>V*XxPG31 ꛔtiDU(>O5õ*wڎu=)e0lEJAn~A B1#]zuXIr0lLJ W0HL>G@V;*vAVJgu*sU$^4' X5g\d1}} "zUa%!"0#<{\zи06MWif޲PK ~A Vyzor-master/PK ~A67+Vyzor-master/READMEPK ~AVyzor-master/base/PK ~AJdxpEVyzor-master/base/frame.luaPK ~A"% Vyzor-master/base/hud.luaPK ~A<6Vyzor-master/base/init.luaPK ~A{!WVyzor-master/base/options.luaPK ~A$Vyzor-master/component/PK ~AţlҊ %$Vyzor-master/component/background.luaPK ~Aga!)Vyzor-master/component/border.luaPK ~Ag=J&-0Vyzor-master/component/border_side.luaPK ~Ak11² 5Vyzor-master/component/brush.luaPK ~AK5j{ 8Vyzor-master/component/color.luaPK ~AA֓&P =Vyzor-master/component/font.luaPK ~Aq# BVyzor-master/component/gradient.luaPK ~AjC5& -HVyzor-master/component/hover.luaPK ~A1DJ VMVyzor-master/component/image.luaPK ~AmQVyzor-master/component/map.luaPK ~Akl !XVyzor-master/component/margin.luaPK ~Ak ,'R\Vyzor-master/component/mini_console.luaPK ~AQ "gVyzor-master/component/padding.luaPK ~AnǙA#kVyzor-master/component/position.luaPK ~Ad &KtVyzor-master/component/size.luaPK ~A|Vyzor-master/compound/PK ~Ac|Vyzor-master/compound/box.luaPK ~Ao ;ǂVyzor-master/compound/chat.luaPK ~Ah #͐Vyzor-master/compound/gauge.luaPK ~AVyzor-master/doc/PK ~A!Vyzor-master/doc/Data/PK ~Aȉ'UVyzor-master/doc/Data/ClassHierarchy.ndPK ~Al'Vyzor-master/doc/Data/ConfigFileInfo.ndPK ~A@;_!Vyzor-master/doc/Data/FileInfo.ndPK ~Aњ&Vyzor-master/doc/Data/ImageFileInfo.ndPK ~Aњ,?Vyzor-master/doc/Data/ImageReferenceTable.ndPK ~AOe"Vyzor-master/doc/Data/IndexInfo.ndPK ~A9*5Vyzor-master/doc/Data/PreviousMenuState.ndPK ~A*hX):Vyzor-master/doc/Data/PreviousSettings.ndPK ~Ao4X$٥Vyzor-master/doc/Data/SymbolTable.ndPK ~AnFVyzor-master/doc/Languages.txtPK ~AG#:, Vyzor-master/doc/Menu.txtPK ~AC#? Vyzor-master/doc/Topics.txtPK ~AVyzor-master/doc/files/PK ~AVyzor-master/doc/files/base/PK ~A]5/Q*;Vyzor-master/doc/files/base/frame-lua.htmlPK ~A8Jzj v;(Vyzor-master/doc/files/base/hud-lua.htmlPK ~Aݓf -)bVyzor-master/doc/files/base/init-lua.htmlPK ~A^z >F,Vyzor-master/doc/files/base/options-lua.htmlPK ~A!$Vyzor-master/doc/files/component/PK ~AX% Q45%Vyzor-master/doc/files/component/background-lua.htmlPK ~A&͈c02Vyzor-master/doc/files/component/border-lua.htmlPK ~A]E W5AVyzor-master/doc/files/component/border_side-lua.htmlPK ~A6 :/VOVyzor-master/doc/files/component/brush-lua.htmlPK ~A+ 9D/NZVyzor-master/doc/files/component/color-lua.htmlPK ~AߧAn LO.fVyzor-master/doc/files/component/font-lua.htmlPK ~AS;3 G2SsVyzor-master/doc/files/component/gradient-lua.htmlPK ~AVV6 V/.Vyzor-master/doc/files/component/hover-lua.htmlPK ~Aq| F/mVyzor-master/doc/files/component/image-lua.htmlPK ~A7醢 ]-6Vyzor-master/doc/files/component/map-lua.htmlPK ~An# R0$Vyzor-master/doc/files/component/margin-lua.htmlPK ~AL%C6vVyzor-master/doc/files/component/mini_console-lua.htmlPK ~A^ R1 Vyzor-master/doc/files/component/padding-lua.htmlPK ~AxFu Z2`Vyzor-master/doc/files/component/position-lua.htmlPK ~A4 [.Vyzor-master/doc/files/component/size-lua.htmlPK ~A Vyzor-master/doc/files/compound/PK ~A iU E,Vyzor-master/doc/files/compound/box-lua.htmlPK ~Ah C-Vyzor-master/doc/files/compound/chat-lua.htmlPK ~ArU\.`Vyzor-master/doc/files/compound/gauge-lua.htmlPK ~A&Vyzor-master/doc/files/enum/PK ~AM 0*.;&Vyzor-master/doc/files/enum/alignment-lua.htmlPK ~AN(SY -1/Vyzor-master/doc/files/enum/border_style-lua.htmlPK ~AZQj)229Vyzor-master/doc/files/enum/bounding_mode-lua.htmlPK ~A #{R&-jBVyzor-master/doc/files/enum/box_mode-lua.htmlPK ~A/G )/0KVyzor-master/doc/files/enum/color_mode-lua.htmlPK ~A`Wh(4lTVyzor-master/doc/files/enum/font_decoration-lua.htmlPK ~AV'/]Vyzor-master/doc/files/enum/font_style-lua.htmlPK ~A9'0fVyzor-master/doc/files/enum/font_weight-lua.htmlPK ~AEt&/oVyzor-master/doc/files/enum/gauge_fill-lua.htmlPK ~A: (2WxVyzor-master/doc/files/enum/gradient_mode-lua.htmlPK ~AwAX 81)Vyzor-master/doc/files/enum/init-lua.htmlPK ~A80'+Vyzor-master/doc/files/enum/repeat-lua.htmlPK ~Ax'1iVyzor-master/doc/files/enum/tab_location-lua.htmlPK ~A+ w8 f8$_Vyzor-master/doc/files/init-lua.htmlPK ~A٧Vyzor-master/doc/files/lib/PK ~AiKV 8(Vyzor-master/doc/files/lib/init-lua.htmlPK ~A3E`!'Vyzor-master/doc/files/license-txt.htmlPK ~APSZBVyzor-master/doc/index.htmlPK ~AμVyzor-master/doc/index/PK ~AK̘s0'hVyzor-master/doc/search/FunctionsA.htmlPK ~AQ%U'SlVyzor-master/doc/search/FunctionsC.htmlPK ~APQ'oVyzor-master/doc/search/FunctionsD.htmlPK ~AH*M6 'sVyzor-master/doc/search/FunctionsE.htmlPK ~A` 'wVyzor-master/doc/search/FunctionsG.htmlPK ~AY,'zVyzor-master/doc/search/FunctionsH.htmlPK ~AQ'}Vyzor-master/doc/search/FunctionsI.htmlPK ~A)\ 'Vyzor-master/doc/search/FunctionsM.htmlPK ~A-~ 'ڃVyzor-master/doc/search/FunctionsN.htmlPK ~A 'Vyzor-master/doc/search/FunctionsO.htmlPK ~A`'Vyzor-master/doc/search/FunctionsP.htmlPK ~A ($Vyzor-master/doc/search/PropertiesF.htmlPK ~A ('Vyzor-master/doc/search/PropertiesG.htmlPK ~A~f(5+Vyzor-master/doc/search/PropertiesH.htmlPK ~AמPr (.Vyzor-master/doc/search/PropertiesI.htmlPK ~A (w2Vyzor-master/doc/search/PropertiesL.htmlPK ~A (5Vyzor-master/doc/search/PropertiesM.htmlPK ~Aj!(9Vyzor-master/doc/search/PropertiesN.htmlPK ~A+-v(7=Vyzor-master/doc/search/PropertiesO.htmlPK ~A9C6(q@Vyzor-master/doc/search/PropertiesP.htmlPK ~A d (CVyzor-master/doc/search/PropertiesR.htmlPK ~A7 9s(GVyzor-master/doc/search/PropertiesS.htmlPK ~An( (LVyzor-master/doc/search/PropertiesT.htmlPK ~A9(OVyzor-master/doc/search/PropertiesU.htmlPK ~A!DZ|F (RVyzor-master/doc/search/PropertiesW.htmlPK ~As~(VVyzor-master/doc/search/PropertiesX.htmlPK ~AI<(YVyzor-master/doc/search/PropertiesY.htmlPK ~A. '2]Vyzor-master/doc/search/VariablesA.htmlPK ~AeƆo')aVyzor-master/doc/search/VariablesB.htmlPK ~AqL 2/'eVyzor-master/doc/search/VariablesC.htmlPK ~A3\N 'TkVyzor-master/doc/search/VariablesD.htmlPK ~AɈ= 'nVyzor-master/doc/search/VariablesE.htmlPK ~Ag 'rVyzor-master/doc/search/VariablesF.htmlPK ~A6 'vVyzor-master/doc/search/VariablesG.htmlPK ~Adl'-zVyzor-master/doc/search/VariablesH.htmlPK ~A%4  'f}Vyzor-master/doc/search/VariablesI.htmlPK ~Aem,':Vyzor-master/doc/search/VariablesL.htmlPK ~A #include #include #include #define js_check_generator(L, narg) \ (yajl_gen*)luaL_checkudata((L), (narg), "yajl.generator.meta") static void* js_null; static int js_generator(lua_State *L); static int js_generator_value(lua_State *L); static void js_parser_assert(lua_State* L, yajl_status status, yajl_handle* handle, const unsigned char* json_text, unsigned int json_text_len, int expect_complete, const char* file, int line); static int got_map_key(lua_State* L); static int got_map_value(lua_State* L); ////////////////////////////////////////////////////////////////////// static double todouble(lua_State* L, const char* val, unsigned int len) { // Convert into number using a temporary: char* tmp = (char*)lua_newuserdata(L, len+1); memcpy(tmp, val, len); tmp[len] = '\0'; double num = strtod(tmp, NULL); /* if ((num == HUGE_VAL || num == -HUGE_VAL) && errno == ERANGE) { TODO: Add appropriate handling of large numbers by delegating. } TODO: How can we tell if there was information loss? aka the number of significant digits in the string exceeds the significant digits in the double. */ lua_pop(L, 1); return num; } ////////////////////////////////////////////////////////////////////// static int js_to_string(lua_State *L) { lua_pushcfunction(L, js_generator); // convert_me, {extra}, ?, js_gen if ( lua_istable(L, 2) ) { // Be sure printer is not defined: lua_pushliteral(L, "printer"); lua_pushnil(L); lua_rawset(L, 2); lua_pushvalue(L, 2); // convert_me, {extra}, ?, js_gen, {extra} } else { lua_newtable(L); // convert_me, {extra}, ?, js_gen, {} } lua_call(L, 1, 1); // convert_me, {extra}, ?, gen_ud lua_pushcfunction(L, js_generator_value); // convert_me, {extra}, ?, gen_ud, js_gen_val lua_pushvalue(L, -2); // convert_me, {extra}, ?, gen_ud, js_gen_val, gen_ud lua_pushvalue(L, 1); // convert_me, {extra}, ?, gen_ud, js_gen_val, gen_ud, convert_me lua_call(L, 2, 0); // convert_me, {extra}, ?, gen_ud yajl_gen* gen = js_check_generator(L, -1); const unsigned char *buf; unsigned int len; yajl_gen_get_buf(*gen, &buf, &len); // Copy into results: lua_pushlstring(L, (char*)buf, len); yajl_gen_clear(*gen); return 1; } static int to_value_null(void* ctx) { lua_State* L = (lua_State*)ctx; lua_getfield(L, LUA_REGISTRYINDEX, "yajl.null"); (lua_tocfunction(L, -2))(L); return 1; } static int to_value_boolean(void* ctx, int val) { lua_State* L = (lua_State*)ctx; lua_pushboolean(L, val); (lua_tocfunction(L, -2))(L); return 1; } static int to_value_number(void* ctx, const char* val, unsigned int len) { lua_State* L = (lua_State*)ctx; lua_pushnumber(L, todouble(L, val, len)); (lua_tocfunction(L, -2))(L); return 1; } static int to_value_string(void* ctx, const unsigned char *val, unsigned int len) { lua_State* L = (lua_State*)ctx; lua_pushlstring(L, (const char*)val, len); (lua_tocfunction(L, -2))(L); return 1; } static int got_map_value(lua_State* L) { /* ..., Table, Key, Func, Value */ lua_insert(L, -2); lua_pop(L, 1); lua_rawset(L, -3); lua_pushnil(L); // Store future key here. lua_pushcfunction(L, got_map_key); return 0; // Ignored. } static int got_map_key(lua_State* L) { lua_replace(L, -3); lua_pop(L, 1); lua_pushcfunction(L, got_map_value); return 0; // Ignored. } static int got_array_value(lua_State* L) { /* ..., Table, Integer, Func, Value */ lua_rawseti(L, -4, lua_tointeger(L, -3)); lua_pushinteger(L, lua_tointeger(L, -2)+1); lua_replace(L, -3); //HEIKO: return 0; } static int to_value_start_map(void* ctx) { lua_State* L = (lua_State*)ctx; /* The layout of the stack for "objects" is: - Table we are appending to. - Storage for the "last key found". - Function to call in to_value_* functions. - Value pushed on the stack by to_value_* functions. */ if ( ! lua_checkstack(L, 4) ) { // TODO: So far, YAJL seems to be fine with the longjmp, but // perhaps we should do errors a different way? return luaL_error(L, "lua stack overflow"); } lua_newtable(L); lua_pushnil(L); // Store future key here. lua_pushcfunction(L, got_map_key); return 1; } static int to_value_start_array(void* ctx) { lua_State* L = (lua_State*)ctx; /* The layout of the stack for "arrays" is: - Table we are appending to. - The index to use for the next insertion. - Function to call in to_value_* functions. - Value pushed on the stack by to_value_* functions. */ if ( ! lua_checkstack(L, 4) ) { // TODO: So far, YAJL seems to be fine with the longjmp, but // perhaps we should do errors a different way? return luaL_error(L, "lua stack overflow"); } lua_newtable(L); lua_pushinteger(L, 1); lua_pushcfunction(L, got_array_value); return 1; } static int to_value_end(void* ctx) { lua_State* L = (lua_State*)ctx; // Simply pop the stack and call the cfunction: lua_pop(L, 2); (lua_tocfunction(L, -2))(L); return 1; } static int noop(lua_State* L) { return 0; } static yajl_callbacks js_to_value_callbacks = { to_value_null, to_value_boolean, NULL, NULL, to_value_number, to_value_string, to_value_start_map, to_value_string, to_value_end, to_value_start_array, to_value_end, }; ////////////////////////////////////////////////////////////////////// static int js_to_value(lua_State *L) { yajl_parser_config cfg = { 1, 1 }; yajl_handle handle; size_t len; const unsigned char* buff = (const unsigned char*) luaL_checklstring(L, 1, &len); int expect_complete = 1; if ( NULL == buff ) return 0; if ( lua_istable(L, 2) ) { lua_getfield(L, 2, "allow_comments"); if ( ! lua_isnil(L, -1) ) { cfg.allowComments = lua_toboolean(L, -1); } lua_pop(L, 1); lua_getfield(L, 2, "check_utf8"); if ( ! lua_isnil(L, -1) ) { cfg.checkUTF8 = lua_toboolean(L, -1); } lua_pop(L, 1); } handle = yajl_alloc(&js_to_value_callbacks, &cfg, NULL, (void*)L); lua_pushcfunction(L, noop); js_parser_assert(L, yajl_parse(handle, buff, len), &handle, buff, len, expect_complete, __FILE__, __LINE__); yajl_free(handle); return 1; } ////////////////////////////////////////////////////////////////////// static int js_parser_null(void *ctx) { lua_State *L=(lua_State*)ctx; lua_getfield(L, lua_upvalueindex(2), "value"); if ( ! lua_isnil(L, -1) ) { lua_pushvalue(L, lua_upvalueindex(2)); lua_getfield(L, LUA_REGISTRYINDEX, "yajl.null"); lua_pushliteral(L, "null"); lua_call(L, 3, 0); } else { lua_pop(L, 1); } return 1; } ////////////////////////////////////////////////////////////////////// static int js_parser_boolean(void *ctx, int val) { lua_State *L=(lua_State*)ctx; lua_getfield(L, lua_upvalueindex(2), "value"); if ( ! lua_isnil(L, -1) ) { lua_pushvalue(L, lua_upvalueindex(2)); lua_pushboolean(L, val); lua_pushliteral(L, "boolean"); lua_call(L, 3, 0); } else { lua_pop(L, 1); } return 1; } ////////////////////////////////////////////////////////////////////// static int js_parser_number(void *ctx, const char* buffer, unsigned int buffer_len) { lua_State *L=(lua_State*)ctx; lua_getfield(L, lua_upvalueindex(2), "value"); if ( ! lua_isnil(L, -1) ) { lua_pushvalue(L, lua_upvalueindex(2)); lua_pushnumber(L, todouble(L, buffer, buffer_len)); lua_pushliteral(L, "number"); lua_call(L, 3, 0); } else { lua_pop(L, 1); } return 1; } ////////////////////////////////////////////////////////////////////// static int js_parser_string(void *ctx, const unsigned char *val, unsigned int len) { lua_State *L=(lua_State*)ctx; lua_getfield(L, lua_upvalueindex(2), "value"); if ( ! lua_isnil(L, -1) ) { lua_pushvalue(L, lua_upvalueindex(2)); lua_pushlstring(L, (const char*)val, len); lua_pushliteral(L, "string"); lua_call(L, 3, 0); } else { lua_pop(L, 1); } return 1; } ////////////////////////////////////////////////////////////////////// static int js_parser_start_map(void *ctx) { lua_State *L=(lua_State*)ctx; lua_getfield(L, lua_upvalueindex(2), "open_object"); if ( ! lua_isnil(L, -1) ) { lua_pushvalue(L, lua_upvalueindex(2)); lua_call(L, 1, 0); } else { lua_pop(L, 1); } return 1; } ////////////////////////////////////////////////////////////////////// static int js_parser_map_key(void *ctx, const unsigned char *val, unsigned int len) { lua_State *L=(lua_State*)ctx; // TODO: Do we want to fall-back to calling "value"? lua_getfield(L, lua_upvalueindex(2), "object_key"); if ( ! lua_isnil(L, -1) ) { lua_pushvalue(L, lua_upvalueindex(2)); lua_pushlstring(L, (const char*)val, len); lua_call(L, 2, 0); } else { lua_pop(L, 1); } return 1; } ////////////////////////////////////////////////////////////////////// static int js_parser_end_map(void *ctx) { lua_State *L=(lua_State*)ctx; lua_getfield(L, lua_upvalueindex(2), "close"); if ( ! lua_isnil(L, -1) ) { lua_pushvalue(L, lua_upvalueindex(2)); lua_pushliteral(L, "object"); lua_call(L, 2, 0); } else { lua_pop(L, 1); } return 1; } ////////////////////////////////////////////////////////////////////// static int js_parser_start_array(void *ctx) { lua_State *L=(lua_State*)ctx; lua_getfield(L, lua_upvalueindex(2), "open_array"); if ( ! lua_isnil(L, -1) ) { lua_pushvalue(L, lua_upvalueindex(2)); lua_call(L, 1, 0); } else { lua_pop(L, 1); } return 1; } ////////////////////////////////////////////////////////////////////// static int js_parser_end_array(void *ctx) { lua_State *L=(lua_State*)ctx; lua_getfield(L, lua_upvalueindex(2), "close"); if ( ! lua_isnil(L, -1) ) { lua_pushvalue(L, lua_upvalueindex(2)); lua_pushliteral(L, "array"); lua_call(L, 2, 0); } else { lua_pop(L, 1); } return 1; } static yajl_callbacks js_parser_callbacks = { js_parser_null, js_parser_boolean, NULL, NULL, js_parser_number, js_parser_string, js_parser_start_map, js_parser_map_key, js_parser_end_map, js_parser_start_array, js_parser_end_array }; ////////////////////////////////////////////////////////////////////// static void js_parser_assert(lua_State* L, yajl_status status, yajl_handle* handle, const unsigned char* json_text, unsigned int json_text_len, int expect_complete, const char* file, int line) { int verbose = 1; unsigned char* msg; switch ( status ) { case yajl_status_ok: return; case yajl_status_client_canceled: lua_pushfstring(L, "Unreachable: yajl_status_client_canceled should never be returned since all callbacks return true at %s line %d", file, line); break; case yajl_status_insufficient_data: if ( ! expect_complete ) return; lua_pushfstring(L, "IncompleteInput: js_parser_parse called with nil input, but the json input was not complete at %s line %d", file, line); break; case yajl_status_error: msg = yajl_get_error(*handle, verbose, json_text, json_text_len); lua_pushfstring(L, "InvalidJSONInput: %s at %s line %d", msg, file, line); yajl_free_error(*handle, msg); break; } lua_error(L); } ////////////////////////////////////////////////////////////////////// static int js_parser_parse(lua_State *L) { yajl_handle* handle = (yajl_handle*) lua_touserdata(L, lua_upvalueindex(1)); if ( lua_isnil(L, 1) ) { int expect_complete = 1; js_parser_assert(L, yajl_parse_complete(*handle), handle, NULL, 0, expect_complete, __FILE__, __LINE__); } else { int expect_complete = 0; size_t len; const unsigned char* buff = (const unsigned char*) luaL_checklstring(L, 1, &len); if ( NULL == buff ) return 0; js_parser_assert(L, yajl_parse(*handle, buff, len), handle, buff, len, expect_complete, __FILE__, __LINE__); } return 0; } ////////////////////////////////////////////////////////////////////// static int js_parser_delete(lua_State *L) { luaL_checktype(L, 1, LUA_TUSERDATA); yajl_free(*(yajl_handle*)lua_touserdata(L, 1)); return 0; } ////////////////////////////////////////////////////////////////////// static int js_parser(lua_State *L) { yajl_parser_config cfg = { 1, 1 }; luaL_checktype(L, 1, LUA_TTABLE); lua_getfield(L, 1, "allow_comments"); if ( ! lua_isnil(L, -1) ) { cfg.allowComments = lua_toboolean(L, -1); } lua_pop(L, 1); lua_getfield(L, 1, "check_utf8"); if ( ! lua_isnil(L, -1) ) { cfg.checkUTF8 = lua_toboolean(L, -1); } lua_pop(L, 1); yajl_handle* handle = (yajl_handle*)lua_newuserdata(L, sizeof(yajl_handle)); *handle = yajl_alloc(&js_parser_callbacks, &cfg, NULL, (void*)L); luaL_getmetatable(L, "yajl.parser.meta"); lua_setmetatable(L, -2); lua_getfield(L, 1, "events"); // Create callback function that calls yajl_parse[_complete]() // // upvalue(1) = yajl_handle* // upvalue(2) = events table lua_pushcclosure(L, &js_parser_parse, 2); return 1; } ////////////////////////////////////////////////////////////////////// static int js_generator_delete(lua_State *L) { yajl_gen* handle = js_check_generator(L, 1); yajl_gen_free(*handle); return 0; } ////////////////////////////////////////////////////////////////////// static void js_generator_assert(lua_State *L, yajl_gen_status status, const char* file, int line) { switch ( status ) { case yajl_gen_status_ok: case yajl_gen_generation_complete: return; case yajl_gen_keys_must_be_strings: lua_pushfstring(L, "InvalidState: expected either a call to close() or string() since we are in the middle of an object declaration at %s line %d", file, line); break; case yajl_max_depth_exceeded: lua_pushfstring(L, "StackOverflow: YAJL's max generation depth was exceeded at %s line %d", file, line); break; case yajl_gen_in_error_state: lua_pushfstring(L, "AlreadyInError: generator method was called when the generator is already in an error state at %s line %d", file, line); break; default: lua_pushfstring(L, "Unreachable: yajl_gen_status (%d) not recognized at %s line %d", status, file, line); break; } lua_error(L); } ////////////////////////////////////////////////////////////////////// static int js_generator_integer(lua_State *L) { js_generator_assert(L, yajl_gen_integer(*js_check_generator(L, 1), luaL_checkinteger(L, 2)), __FILE__, __LINE__); return 0; } ////////////////////////////////////////////////////////////////////// static int js_generator_double(lua_State *L) { js_generator_assert(L, yajl_gen_double(*js_check_generator(L, 1), luaL_checknumber(L, 2)), __FILE__, __LINE__); return 0; } ////////////////////////////////////////////////////////////////////// static int js_generator_number(lua_State *L) { // It would be better to make it so an arbitrary string can be // used here, however we would then need to validate that the // generated string is a JSON number which is a bit beyond scope // at this point. Perhaps in the future we will loosen this // restriction, it is always easier to loosen restrictions than it // is to make new restrictions that break other people's code. double num = luaL_checknumber(L, 2); size_t len; const char* str; // These are special cases, not sure how better to represent them // :-(. if ( num == HUGE_VAL ) { str = "1e+666"; len = 6; } else if ( num == -HUGE_VAL ) { str = "-1e+666"; len = 7; } else if ( isnan(num) ) { str = "-0"; len = 2; } else { str = luaL_checklstring(L, 2, &len); } js_generator_assert(L, yajl_gen_number(*js_check_generator(L, 1), str, len), __FILE__, __LINE__); return 0; } ////////////////////////////////////////////////////////////////////// static int js_generator_string(lua_State *L) { size_t len; const unsigned char* str = (const unsigned char*)luaL_checklstring(L, 2, &len); js_generator_assert(L, yajl_gen_string(*js_check_generator(L, 1), str, len), __FILE__, __LINE__); return 0; } ////////////////////////////////////////////////////////////////////// static int js_generator_null(lua_State *L) { js_generator_assert(L, yajl_gen_null(*js_check_generator(L, 1)), __FILE__, __LINE__); return 0; } ////////////////////////////////////////////////////////////////////// static int js_generator_boolean(lua_State *L) { luaL_checktype(L, 2, LUA_TBOOLEAN); js_generator_assert(L, yajl_gen_bool(*js_check_generator(L, 1), lua_toboolean(L, 2)), __FILE__, __LINE__); return 0; } #define JS_OPEN_OBJECT 1 #define JS_OPEN_ARRAY 2 ////////////////////////////////////////////////////////////////////// static int js_generator_open_object(lua_State *L) { js_generator_assert(L, yajl_gen_map_open(*js_check_generator(L, 1)), __FILE__, __LINE__); // Why doesn't yajl_gen keep track of this!? lua_getfenv(L, 1); lua_getfield(L, -1, "stack"); lua_pushinteger(L, JS_OPEN_OBJECT); lua_rawseti(L, -2, lua_objlen(L, -2) + 1); return 0; } ////////////////////////////////////////////////////////////////////// static int js_generator_open_array(lua_State *L) { js_generator_assert(L, yajl_gen_array_open(*js_check_generator(L, 1)), __FILE__, __LINE__); // Why doesn't yajl_gen keep track of this!? lua_getfenv(L, 1); lua_getfield(L, -1, "stack"); lua_pushinteger(L, JS_OPEN_ARRAY); lua_rawseti(L, -2, lua_objlen(L, -2) + 1); return 0; } ////////////////////////////////////////////////////////////////////// static int js_generator_close(lua_State *L) { // Why doesn't yajl_gen keep track of this!? lua_getfenv(L, 1); lua_getfield(L, -1, "stack"); lua_rawgeti(L, -1, lua_objlen(L, -1)); if ( lua_isnil(L, -1) ) { lua_pushfstring(L, "StackUnderflow: Attempt to call close() when no array or object has been opened at %s line %d", __FILE__, __LINE__); lua_error(L); } lua_Integer type = lua_tointeger(L, -1); switch ( type ) { case JS_OPEN_OBJECT: js_generator_assert(L, yajl_gen_map_close(*js_check_generator(L, 1)), __FILE__, __LINE__); break; case JS_OPEN_ARRAY: js_generator_assert(L, yajl_gen_array_close(*js_check_generator(L, 1)), __FILE__, __LINE__); break; default: lua_pushfstring(L, "Unreachable: internal 'stack' contained invalid integer (%d) at %s line %d", type, __FILE__, __LINE__); lua_error(L); } // delete the top of the "stack": lua_pop(L, 1); lua_pushnil(L); lua_rawseti(L, -2, lua_objlen(L, -2)); return 0; } ////////////////////////////////////////////////////////////////////// static int js_generator_value(lua_State *L) { int max = 0; int is_array = 1; int type = lua_type(L, 2); switch ( type ) { case LUA_TNIL: return js_generator_null(L); case LUA_TNUMBER: return js_generator_number(L); case LUA_TBOOLEAN: return js_generator_boolean(L); case LUA_TSTRING: return js_generator_string(L); case LUA_TUSERDATA: if ( lua_topointer(L, 2) == js_null ) { return js_generator_null(L); } case LUA_TLIGHTUSERDATA: case LUA_TTABLE: case LUA_TFUNCTION: case LUA_TTHREAD: if ( luaL_getmetafield(L, 2, "__gen_json") ) { if ( lua_isfunction(L, -1) ) { lua_settop(L, 3); // gen, obj, func lua_insert(L, 1); // func, gen, obj lua_insert(L, 2); // func, obj, gen lua_call(L, 2, 0); return 0; } lua_pop(L, 1); } // Simply ignore it, perhaps we should warn? if ( type != LUA_TTABLE ) return 0; // First iterate over the table to see if it is an array: lua_pushnil(L); while ( lua_next(L, 2) != 0 ) { if ( lua_isnumber(L, -2) ) { double num = lua_tonumber(L, -2); if ( num == floor(num) ) { if ( num > max ) max = num; } else { lua_pop(L, 2); is_array = 0; break; } } else { lua_pop(L, 2); is_array = 0; break; } lua_pop(L, 1); } if ( is_array ) { int i; js_generator_open_array(L); for ( i=1; i <= max; i++ ) { lua_pushinteger(L, i); lua_gettable(L, 2); // RECURSIVE CALL: // gen, obj, ?, val, func, gen, val lua_pushcfunction(L, js_generator_value); lua_pushvalue(L, 1); lua_pushvalue(L, -3); lua_call(L, 2, 0); lua_pop(L, 1); } } else { js_generator_open_object(L); lua_pushnil(L); while ( lua_next(L, 2) != 0 ) { //size_t len; //const char* str; // gen, obj, ?, key, val, func, gen, key lua_pushcfunction(L, js_generator_string); lua_pushvalue(L, 1); if ( lua_isstring(L, -4) ) { lua_pushvalue(L, -4); } else { // Must coerce into a string: lua_getglobal(L, "tostring"); lua_pushvalue(L, -5); lua_call(L, 1, 1); } lua_call(L, 2, 0); // RECURSIVE CALL: // gen, obj, ?, key, val, func, gen, val lua_pushcfunction(L, js_generator_value); lua_pushvalue(L, 1); lua_pushvalue(L, -3); lua_call(L, 2, 0); lua_pop(L, 1); } } js_generator_close(L); return 0; case LUA_TNONE: lua_pushfstring(L, "MissingArgument: second parameter to js_generator_value() must be defined at %s line %d", type, __FILE__, __LINE__); default: lua_pushfstring(L, "Unreachable: js_generator_value passed lua type (%d) not recognized at %s line %d", type, __FILE__, __LINE__); } // Shouldn't get here: lua_error(L); return 0; } typedef struct { lua_State* L; int printer_ref; } js_printer_ctx; ////////////////////////////////////////////////////////////////////// static void js_printer(void* void_ctx, const char* str, unsigned int len) { js_printer_ctx* ctx = (js_printer_ctx*)void_ctx; lua_State* L = ctx->L; // refs lua_getfield(L, LUA_REGISTRYINDEX, "yajl.refs"); // refs, printer lua_rawgeti(L, -1, ctx->printer_ref); if ( lua_isfunction(L, -1) ) { lua_pushlstring(L, str, len); // Not sure if yajl can handle longjmp's if this errors... lua_call(L, 1, 0); lua_pop(L, 1); } else { lua_pop(L, 2); } } ////////////////////////////////////////////////////////////////////// static int js_generator(lua_State *L) { yajl_gen_config cfg = { 0, NULL }; yajl_print_t print = NULL; void * ctx = NULL; luaL_checktype(L, 1, LUA_TTABLE); // {args}, ?, tbl lua_newtable(L); // Validate and save in fenv so it isn't gc'ed: lua_getfield(L, 1, "printer"); if ( ! lua_isnil(L, -1) ) { luaL_checktype(L, -1, LUA_TFUNCTION); lua_pushvalue(L, -1); // {args}, ?, tbl, printer, printer lua_setfield(L, -3, "printer"); js_printer_ctx* print_ctx = (js_printer_ctx*) lua_newuserdata(L, sizeof(js_printer_ctx)); // {args}, ?, tbl, printer, printer_ctx lua_setfield(L, -3, "printer_ctx"); // {args}, ?, tbl, printer lua_getfield(L, LUA_REGISTRYINDEX, "yajl.refs"); // {args}, ?, tbl, printer, refs lua_insert(L, -2); // {args}, ?, tbl, refs, printer print_ctx->printer_ref = luaL_ref(L, -2); print_ctx->L = L; print = &js_printer; ctx = print_ctx; } lua_pop(L, 1); // {args}, ?, tbl // Get the indent and save so it isn't gc'ed: lua_getfield(L, 1, "indent"); if ( ! lua_isnil(L, -1) ) { cfg.beautify = 1; cfg.indentString = lua_tostring(L, -1); lua_setfield(L, -2, "indent"); } else { lua_pop(L, 1); } // {args}, ?, tbl // Sucks that yajl's generator doesn't keep track of this for me // (this is a stack of strings "array" and "object" so I can keep // track of what to "close"): lua_newtable(L); lua_setfield(L, -2, "stack"); // {args}, ?, tbl yajl_gen* handle = (yajl_gen*)lua_newuserdata(L, sizeof(yajl_gen)); *handle = yajl_gen_alloc2(print, &cfg, NULL, ctx); // {args}, ?, tbl, ud, meta luaL_getmetatable(L, "yajl.generator.meta"); lua_setmetatable(L, -2); // {args}, ?, tbl, ud lua_insert(L, -2); // {args}, ?, ud, tbl lua_setfenv(L, -2); return 1; } ////////////////////////////////////////////////////////////////////// static void js_create_parser_mt(lua_State *L) { luaL_newmetatable(L, "yajl.parser.meta"); // {} lua_pushcfunction(L, js_parser_delete); lua_setfield(L, -2, "__gc"); lua_pop(L, 1); // } ////////////////////////////////////////////////////////////////////// static void js_create_generator_mt(lua_State *L) { luaL_newmetatable(L, "yajl.generator.meta"); // {} lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, js_generator_delete); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, js_generator_value); lua_setfield(L, -2, "value"); lua_pushcfunction(L, js_generator_integer); lua_setfield(L, -2, "integer"); lua_pushcfunction(L, js_generator_double); lua_setfield(L, -2, "double"); lua_pushcfunction(L, js_generator_number); lua_setfield(L, -2, "number"); lua_pushcfunction(L, js_generator_string); lua_setfield(L, -2, "string"); lua_pushcfunction(L, js_generator_null); lua_setfield(L, -2, "null"); lua_pushcfunction(L, js_generator_boolean); lua_setfield(L, -2, "boolean"); lua_pushcfunction(L, js_generator_open_object); lua_setfield(L, -2, "open_object"); lua_pushcfunction(L, js_generator_open_array); lua_setfield(L, -2, "open_array"); lua_pushcfunction(L, js_generator_close); lua_setfield(L, -2, "close"); lua_pop(L, 1); // } static int js_null_tostring(lua_State* L) { lua_pushstring(L, "null"); return 1; } ////////////////////////////////////////////////////////////////////// static void js_create_null_mt(lua_State *L) { luaL_newmetatable(L, "yajl.null.meta"); // {} lua_pushcfunction(L, js_null_tostring); lua_setfield(L, -2, "__tostring"); lua_pop(L, 1); // } ////////////////////////////////////////////////////////////////////// LUALIB_API int luaopen_yajl(lua_State *L) { js_create_parser_mt(L); js_create_generator_mt(L); js_create_null_mt(L); // Create the yajl.refs weak table: lua_createtable(L, 0, 2); lua_pushliteral(L, "v"); // tbl, "v" lua_setfield(L, -2, "__mode"); lua_pushvalue(L, -1); // tbl, tbl lua_setmetatable(L, -2); // tbl lua_setfield(L, LUA_REGISTRYINDEX, "yajl.refs"); lua_createtable(L, 0, 4); lua_pushcfunction(L, js_to_string); lua_setfield(L, -2, "to_string"); lua_pushcfunction(L, js_to_value); lua_setfield(L, -2, "to_value"); lua_pushcfunction(L, js_parser); lua_setfield(L, -2, "parser"); lua_pushcfunction(L, js_generator); lua_setfield(L, -2, "generator"); js_null = lua_newuserdata(L, 0); luaL_getmetatable(L, "yajl.null.meta"); lua_setmetatable(L, -2); lua_pushvalue(L, -1); lua_setfield(L, LUA_REGISTRYINDEX, "yajl.null"); lua_setfield(L, -2, "null"); return 1; } mudlet-2.1/src/TMap.h0000644000175000017500000001246112070466512013766 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn KoehnHeiko@googlemail.com * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TMAP_H #define TMAP_H class TRoom; class TArea; class Host; class GLWidget; class T2DMap; #include #include "TRoom.h" #include "TArea.h" #include "glwidget.h" #include #include "TAstar.h" //#include "dlgMapper.h" #include #include #include #include class dlgMapper; class TMapLabel { public: TMapLabel(){ hilite=false; showOnTop=false; noScaling=false; } QVector3D pos; QPointF pointer; QSizeF size; QString text; QColor fgColor; QColor bgColor; QPixmap pix; bool hilite; bool showOnTop; bool noScaling; }; class TMap { public: TMap( Host *); int createMapLabelID( int area ); int createMapImageLabel(int area, QString filePath, float x, float y, float z, float width, float height, float zoom, bool showOnTop, bool noScaling ); int createMapLabel(int area, QString text, float x, float y, float z, QColor fg, QColor bg, bool showOnTop=true, bool noScaling=true, qreal zoom=15.0, int fontSize=15 ); void deleteMapLabel( int area, int labelID ); bool addRoom( int id=0 ); void auditRooms(); void setRoomArea( int id, int area ); void deleteRoom( int id ); void deleteArea( int id ); int createNewRoomID(); bool fixExits2(int); void tidyMap( int area ); void getConnectedNodesGreaterThanX( int id, int x ); void getConnectedNodesSmallerThanX( int id, int x ); void getConnectedNodesGreaterThanY( int id, int x ); void getConnectedNodesSmallerThanY( int id, int x ); bool plausabilitaetsCheck( int area ); void astBreitenAnpassung( int id, int ); void astHoehenAnpassung( int id, int ); bool setExit( int from, int to, int dir ); bool setRoomCoordinates( int id, int x, int y, int z ); void init(Host*); void buildAreas(); bool fixExits( int id, int dir ); QList detectRoomCollisions( int id ); void solveRoomCollision( int id, int creationDirection, bool PCheck=true ); void setRoom( int ); bool findPath( int from, int to ); bool gotoRoom( int ); bool gotoRoom( int, int ); void setView( float, float, float, float ); bool serialize( QDataStream & ); bool restore(QString location); void initGraph(); void exportMapToDatabase(); void importMapFromDatabase(); void connectExitStub(int roomId, int dirType); QMap rooms; QMap areas; QMap areaNamesMap; QMap envColors; QVector3D span; Host * mpHost; int mRoomId; bool m2DPanMode; bool mLeftDown; bool mRightDown; float m2DPanXStart; float m2DPanYStart; int mViewArea; //mapVar mVars[20]; //mapVar mvRoomId; //QMap mVars; //QMap mVars; //mVars.insert("RoomId", &mRoomId); int mTargetID; QList mPathList; QList mDirList; QMap customEnvColors; QMap unitVectors; QMap reverseDirections; //contains complementary directions of dirs on TRoom.h GLWidget * mpM; dlgMapper * mpMapper; QList mTestedNodes; QList conList; int mPlausaOptOut; QMap hashTable; QMap pixNameTable; QMap pixTable; typedef adjacency_list > mygraph_t; typedef property_map::type WeightMap; typedef mygraph_t::vertex_descriptor vertex; typedef mygraph_t::edge_descriptor edge_descriptor; typedef mygraph_t::vertex_iterator vertex_iterator; typedef std::pair edge; mygraph_t g; WeightMap weightmap; std::vector locations; bool mMapGraphNeedsUpdate; bool mNewMove; QMap > mapLabels; int version; //map file format version }; #endif // TMAP_H mudlet-2.1/src/AliasUnit.cpp0000644000175000017500000003157712020507606015355 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include // NULL #include #include #include #include #include "Host.h" #include "TLuaInterpreter.h" #include "TConsole.h" #include #include "AliasUnit.h" using namespace std; void AliasUnit::_uninstall( TAlias * pChild, QString packageName ) { typedef list::const_iterator I; list * childrenList = pChild->mpMyChildrenList; for( I it2 = childrenList->begin(); it2 != childrenList->end(); it2++) { TAlias * pT = *it2; _uninstall( pT, packageName ); uninstallList.append( pT ); } } void AliasUnit::uninstall( QString packageName ) { typedef std::list::iterator IT; for( IT it = mAliasRootNodeList.begin(); it != mAliasRootNodeList.end(); it ++ ) { TAlias * pT = *it; if( pT->mPackageName == packageName ) { _uninstall( pT, packageName ); uninstallList.append( pT ); } } for( int i=0; i::const_iterator I; for( I it = mAliasRootNodeList.begin(); it != mAliasRootNodeList.end(); it++) { TAlias * pChild = *it; if( pChild->isActive() ) { pChild->compileAll(); } } } void AliasUnit::initStats() { statsAliasTotal = 0; statsTempAliass = 0; statsActiveAliass = 0; statsActiveAliassMax = 0; statsActiveAliassMin = 0; statsActiveAliassAverage = 0; statsTempAliassCreated = 0; statsTempAliassKilled = 0; statsAverageLineProcessingTime = 0; statsMaxLineProcessingTime = 0; statsMinLineProcessingTime = 0; statsRegexAliass = 0; } void AliasUnit::addAliasRootNode( TAlias * pT, int parentPosition, int childPosition, bool moveAlias ) { if( ! pT ) return; if( ! pT->getID() ) { pT->setID( getNewID() ); } if( ( parentPosition == -1 ) || ( childPosition >= static_cast(mAliasRootNodeList.size()) ) ) { mAliasRootNodeList.push_back( pT ); } else { // insert item at proper position int cnt = 0; typedef std::list::iterator IT; for( IT it = mAliasRootNodeList.begin(); it != mAliasRootNodeList.end(); it ++ ) { if( cnt >= childPosition ) { mAliasRootNodeList.insert( it, pT ); break; } cnt++; } } if( ! moveAlias ) { mAliasMap.insert( pT->getID(), pT ); } } void AliasUnit::reParentAlias( int childID, int oldParentID, int newParentID, int parentPosition, int childPosition ) { TAlias * pOldParent = getAliasPrivate( oldParentID ); TAlias * pNewParent = getAliasPrivate( newParentID ); TAlias * pChild = getAliasPrivate( childID ); if( ! pChild ) { return; } if( pOldParent ) { pOldParent->popChild( pChild ); } else { mAliasRootNodeList.remove( pChild ); } if( pNewParent ) { pNewParent->addChild( pChild, parentPosition, childPosition ); if( pChild ) pChild->setParent( pNewParent ); //cout << "dumping family of newParent:"<Dump(); } else { pChild->Tree::setParent( 0 ); addAliasRootNode( pChild, parentPosition, childPosition, true ); } } void AliasUnit::removeAliasRootNode( TAlias * pT ) { if( ! pT ) return; if( ! pT->mIsTempAlias ) { mLookupTable.remove( pT->mName, pT ); } else { mLookupTable.remove( pT->getName() ); } mAliasMap.remove( pT->getID() ); mAliasRootNodeList.remove( pT ); } TAlias * AliasUnit::getAlias( int id ) { QMutexLocker locker(& mAliasUnitLock); if( mAliasMap.find( id ) != mAliasMap.end() ) { return mAliasMap.value( id ); } else { return 0; } } TAlias * AliasUnit::getAliasPrivate( int id ) { if( mAliasMap.find( id ) != mAliasMap.end() ) { return mAliasMap.value( id ); } else { return 0; } } bool AliasUnit::registerAlias( TAlias * pT ) { if( ! pT ) return false; if( pT->getParent() ) { addAlias( pT ); return true; } else { addAliasRootNode( pT ); return true; } } void AliasUnit::unregisterAlias( TAlias * pT ) { if( ! pT ) return; if( pT->getParent() ) { removeAlias( pT ); return; } else { removeAliasRootNode( pT ); return; } } void AliasUnit::addAlias( TAlias * pT ) { if( ! pT ) return; if( ! pT->getID() ) { pT->setID( getNewID() ); } mAliasMap.insert( pT->getID(), pT ); } void AliasUnit::removeAlias( TAlias * pT ) { if( ! pT ) return; if( ! pT->mIsTempAlias ) { mLookupTable.remove( pT->mName, pT ); } else mLookupTable.remove( pT->getName() ); mAliasMap.remove(pT->getID()); } qint64 AliasUnit::getNewID() { return ++mMaxID; } bool AliasUnit::processDataStream( QString & data ) { TLuaInterpreter * Lua = mpHost->getLuaInterpreter(); QString lua_command_string = "command"; Lua->set_lua_string( lua_command_string, data ); bool state = false; typedef list::const_iterator I; for( I it = mAliasRootNodeList.begin(); it != mAliasRootNodeList.end(); it++) { TAlias * pChild = *it; // = data.replace( "\n", "" ); if( pChild->match( data ) ) { state = true; } } // the idea to get "command" after alias processing is finished and send its value // was too difficult for users because if multiple alias change the value of command it becomes too difficult to handle for many users // it's easier if we simply intercepts the command and hand responsibility for // sending a command to the user scripts. //data = Lua->get_lua_string( lua_command_string ); return state; } void AliasUnit::stopAllTriggers() { typedef list::const_iterator I; for( I it = mAliasRootNodeList.begin(); it != mAliasRootNodeList.end(); it++) { TAlias * pChild = *it; QString name = pChild->getName(); pChild->disableFamily(); } } void AliasUnit::reenableAllTriggers() { typedef list::const_iterator I; for( I it = mAliasRootNodeList.begin(); it != mAliasRootNodeList.end(); it++) { TAlias * pChild = *it; pChild->enableFamily(); } } //bool AliasUnit::serialize( QDataStream & ofs ) //{ // return true; //} //bool AliasUnit::restore( QDataStream & ifs, bool initMode ) //{ // return true; //} TAlias * AliasUnit::findAlias( QString & name ) { //TAlias * pT = 0; QMap::const_iterator it = mLookupTable.find( name ); while( it != mLookupTable.end() && it.key() == name ) { TAlias * pT = it.value(); return pT; } return 0; } bool AliasUnit::enableAlias( QString & name ) { bool found = false; QMap::const_iterator it = mLookupTable.find( name ); while( it != mLookupTable.end() && it.key() == name ) { TAlias * pT = it.value(); pT->setIsActive( true ); ++it; found = true; } return found; } bool AliasUnit::disableAlias( QString & name ) { bool found = false; QMap::const_iterator it = mLookupTable.find( name ); while( it != mLookupTable.end() && it.key() == name ) { TAlias * pT = it.value(); pT->setIsActive( false ); ++it; found = true; } return found; } bool AliasUnit::killAlias( QString & name ) { typedef list::const_iterator I; for( I it = mAliasRootNodeList.begin(); it != mAliasRootNodeList.end(); it++) { TAlias * pChild = *it; if( pChild->getName() == name ) { // only temporary Aliass can be killed if( ! pChild->isTempAlias() ) { return false; } else { pChild->setIsActive( false ); markCleanup( pChild ); return true; } } } return false; } void AliasUnit::dump() { //bool ret = true; typedef list::const_iterator I; cout << "AliasUnit::dump() entries="<DumpFamily(); } } void AliasUnit::_assembleReport( TAlias * pChild ) { typedef list::const_iterator I; list * childrenList = pChild->mpMyChildrenList; for( I it2 = childrenList->begin(); it2 != childrenList->end(); it2++) { TAlias * pT = *it2; _assembleReport( pT ); if( pT->isActive() ) statsActiveAliass++; if( pT->isTempAlias() ) statsTempAliass++; statsAliasTotal++; } } QString AliasUnit::assembleReport() { statsActiveAliass = 0; statsAliasTotal = 0; statsTempAliass = 0; typedef list::const_iterator I; for( I it = mAliasRootNodeList.begin(); it != mAliasRootNodeList.end(); it++) { TAlias * pChild = *it; if( pChild->isActive() ) statsActiveAliass++; if( pChild->isTempAlias() ) statsTempAliass++; statsAliasTotal++; list * childrenList = pChild->mpMyChildrenList; for( I it2 = childrenList->begin(); it2 != childrenList->end(); it2++) { TAlias * pT = *it2; _assembleReport( pT ); if( pT->isActive() ) statsActiveAliass++; if( pT->isTempAlias() ) statsTempAliass++; statsAliasTotal++; } } QStringList msg; msg << "Aliass current total: " << QString::number(statsAliasTotal) << "\n" << "tempAliass current total: " << QString::number(statsTempAliass) << "\n" << "active Aliass: " << QString::number(statsActiveAliass) << "\n"; /*<< "active Aliass max this session: " << QString::number(statsActiveAliassMax) << "\n" << "active Aliass min this session: " << QString::number(statsActiveAliassMin) << "\n" << "active Aliass average this session: " << QString::number(statsActiveAliassAverage) << "\n"*/ //<< "tempAliass created this session: " << QString::number(statsTempAliassCreated) << "\n" //<< "tempAliass killed this session: " << QString::number(statsTempAliassKilled) << "\n" //<< "current total regex Aliass: " << QString::number(statsRegexAliass) << "\n" //<< "average line processing time: " << QString::number(statsAverageLineProcessingTime) << "\n" //<< "max line processing time: " << QString::number(statsMaxLineProcessingTime) << "\n" //<< "min line processing time: " << QString::number(statsMinLineProcessingTime) << "\n"; return msg.join(""); } void AliasUnit::doCleanup() { typedef list::iterator I; for( I it = mCleanupList.begin(); it != mCleanupList.end(); it++) { delete *it; } mCleanupList.clear(); } void AliasUnit::markCleanup( TAlias * pT ) { typedef list::iterator I; for( I it = mCleanupList.begin(); it != mCleanupList.end(); it++) { if( *it == pT ) { return; } } mCleanupList.push_back( pT ); } mudlet-2.1/src/TLuaInterpreter.cpp0000644000175000017500000104666712076170616016574 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include "TLuaInterpreter.h" #include "TForkedProcess.h" #include "TTrigger.h" #include "HostManager.h" #include "mudlet.h" #include "TDebug.h" #include #include #include "TEvent.h" #include "dlgMapper.h" //#ifdef Q_OS_WIN32 // #include "lua_yajl.c" //#else #include "lua_yajl1.c" //#endif extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" } #include /*//for map var access union mVarTypes { int * i; float * f; bool * b; string * s; QString * qs; };*/ extern QStringList gSysErrors; using namespace std; map TLuaInterpreter::luaInterpreterMap; TLuaInterpreter::TLuaInterpreter( Host * pH, int id ) :mpHost( pH ) ,mHostID( id ) ,purgeTimer(this) { pGlobalLua = 0; connect(this,SIGNAL(signalEchoMessage(int, QString)), this,SLOT(slotEchoMessage(int,QString)));//,Qt::DirectConnection); connect(this,SIGNAL(signalNewCommand(int,QString)), this,SLOT(slotNewCommand(int,QString)));//,Qt::QueuedConnection); connect(this,SIGNAL(signalOpenUserWindow(int,QString)), this,SLOT(slotOpenUserWindow(int,QString))); connect(this,SIGNAL(signalEchoUserWindow(int,QString,QString)), this,SLOT(slotEchoUserWindow(int,QString,QString))); connect(this,SIGNAL(signalEnableTimer(int,QString)),this,SLOT(slotEnableTimer(int,QString))); connect(this,SIGNAL(signalDisableTimer(int,QString)),this,SLOT(slotDisableTimer(int,QString))); connect(this,SIGNAL(signalClearUserWindow(int,QString)),this,SLOT(slotClearUserWindow(int,QString))); connect(this, SIGNAL(signalSelect(int, QString, int)), this, SLOT(slotSelect(int,QString,int))); connect(this, SIGNAL(signalSelectSection(int, int,int)), this, SLOT(slotSelectSection(int,int,int))); connect(this, SIGNAL(signalTempTimer(int, double,QString,QString)), this, SLOT(slotTempTimer(int,double,QString,QString))); connect(this, SIGNAL(signalReplace(int, QString)), this, SLOT(slotReplace(int,QString))); connect(this, SIGNAL(signalSetFgColor(int, int,int,int)), this, SLOT(slotSetFgColor(int,int,int,int))); connect(this, SIGNAL(signalSetBgColor(int, int,int,int)), this, SLOT(slotSetBgColor(int,int,int,int))); connect(&purgeTimer, SIGNAL(timeout()), this, SLOT(slotPurge())); mpFileDownloader = new QNetworkAccessManager( this ); connect(mpFileDownloader, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*))); initLuaGlobals(); purgeTimer.start(2000); } lua_State * TLuaInterpreter::getLuaExecutionUnit( int unit ) { switch( unit ) { case 1: return pGlobalLua; case 2: return pGlobalLua; case 3: return pGlobalLua; case 4: return pGlobalLua; case 5: return pGlobalLua; }; return 0; } void TLuaInterpreter::replyFinished(QNetworkReply * reply ) { if( ! downloadMap.contains(reply) ) return; QString name = downloadMap[reply]; QFile file(name); file.open( QFile::WriteOnly ); file.write( reply->readAll() ); file.flush(); file.close(); TEvent * e = new TEvent; if( reply->error() == 0 ) { e->mArgumentList << "sysDownloadDone"; e->mArgumentTypeList << ARGUMENT_TYPE_STRING; e->mArgumentList << name; e->mArgumentTypeList << ARGUMENT_TYPE_STRING; } else { e->mArgumentList << "sysDownloadError"; e->mArgumentTypeList << ARGUMENT_TYPE_STRING; e->mArgumentList << reply->errorString(); e->mArgumentTypeList << ARGUMENT_TYPE_STRING; e->mArgumentList << name; e->mArgumentTypeList << ARGUMENT_TYPE_STRING; } mpHost->raiseEvent( e ); } void TLuaInterpreter::slotDeleteSender() { objectsToDelete.append(sender()); } void TLuaInterpreter::slotPurge() { while (!objectsToDelete.isEmpty()) { delete objectsToDelete.takeFirst(); } } int TLuaInterpreter::Wait( lua_State *L ) { int n = lua_gettop( L ); if(n!=1) { lua_pushstring( L, "Wait: wrong number of arguments" ); lua_error( L ); return 1; } int luaSleepMsec; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "Wait: wrong argument type" ); lua_error( L ); return 1; } else { luaSleepMsec = lua_tointeger( L, 1 ); } msleep( luaSleepMsec );//FIXME thread::sleep() return 0; } int TLuaInterpreter::denyCurrentSend( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mAllowToSendCommand = false; return 0; } int TLuaInterpreter::raiseEvent( lua_State * L ) { TEvent * pE = new TEvent; int n = lua_gettop( L ); for( int i=1; i<=n; i++) { if( lua_isnumber( L, i ) ) { pE->mArgumentList.append( QString::number(lua_tonumber( L, i ) ) ); pE->mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); } else if( lua_isstring( L, i ) ) { pE->mArgumentList.append( QString(lua_tostring( L, i )) ); pE->mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->raiseEvent( pE ); delete pE; return 0; } int TLuaInterpreter::resetProfile( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mResetProfile = true; return 0; } // cursorPositionInLine = select( text ) if not found -1 int TLuaInterpreter::select( lua_State * L ) { int s = 1; int n = lua_gettop( L ); string a1; if( n > 2 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "select: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } } string luaSendText=""; if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "select: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, s ); s++; } int luaNumOfMatch; if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "select: wrong argument type" ); lua_error( L ); return 1; } else { luaNumOfMatch = lua_tointeger( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( n == 2 ) { int pos = pHost->mpConsole->select( QString( luaSendText.c_str() ), luaNumOfMatch ); lua_pushnumber( L, pos ); return 1; } else { QString _name(a1.c_str()); int pos = mudlet::self()->selectString( pHost, _name, QString( luaSendText.c_str() ), luaNumOfMatch ); lua_pushnumber( L, pos ); return 1; } } int TLuaInterpreter::selectCurrentLine( lua_State * L ) { string luaSendText=""; if( lua_gettop( L ) == 0 ) { luaSendText = "main"; } else { if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "selectCurrentLine: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->selectCurrentLine( luaSendText ); return 0; } int TLuaInterpreter::isAnsiFgColor( lua_State * L ) { int ansiFg; std::string console = "main"; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "isAnsiFgColor: wrong argument type" ); lua_error( L ); return 1; } else { ansiFg = lua_tointeger( L, 1 ); } std::list result; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; result = pHost->mpConsole->getFgColor( console ); typedef std::list::iterator IT; IT it=result.begin(); if( result.size() < 3 ) return 0; if( ansiFg < 0 ) return 0; if( ansiFg > 16 ) return 0; QColor c; switch( ansiFg ) { case 0: c = pHost->mFgColor; break; case 1: c = pHost->mLightBlack; break; case 2: c = pHost->mBlack; break; case 3: c = pHost->mLightRed; break; case 4: c = pHost->mRed; break; case 5: c = pHost->mLightGreen; break; case 6: c = pHost->mGreen; break; case 7: c = pHost->mLightYellow; break; case 8: c = pHost->mYellow; break; case 9: c = pHost->mLightBlue; break; case 10: c = pHost->mBlue; break; case 11: c = pHost->mLightMagenta; break; case 12: c = pHost->mMagenta; break; case 13: c = pHost->mLightCyan; break; case 14: c = pHost->mCyan; break; case 15: c = pHost->mLightWhite; break; case 16: c = pHost->mWhite; break; } int val = *it; if( val == c.red() ) { it++; val = *it; if( val == c.green() ) { it++; val = *it; if( val == c.blue() ) { lua_pushboolean( L, 1 ); return 1; } } } lua_pushboolean( L, 0 ); return 1; } int TLuaInterpreter::isAnsiBgColor( lua_State * L ) { int ansiFg; std::string console = "main"; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "isAnsiBgColor: wrong argument type" ); lua_error( L ); return 1; } else { ansiFg = lua_tointeger( L, 1 ); } std::list result; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( ! pHost ) return 0; result = pHost->mpConsole->getBgColor( console ); typedef std::list::iterator IT; IT it=result.begin(); if( result.size() < 3 ) return 0; if( ansiFg < 0 ) return 0; if( ansiFg > 16 ) return 0; QColor c; switch( ansiFg ) { case 0: c = pHost->mBgColor; break; case 1: c = pHost->mLightBlack; break; case 2: c = pHost->mBlack; break; case 3: c = pHost->mLightRed; break; case 4: c = pHost->mRed; break; case 5: c = pHost->mLightGreen; break; case 6: c = pHost->mGreen; break; case 7: c = pHost->mLightYellow; break; case 8: c = pHost->mYellow; break; case 9: c = pHost->mLightBlue; break; case 10: c = pHost->mBlue; break; case 11: c = pHost->mLightMagenta; break; case 12: c = pHost->mMagenta; break; case 13: c = pHost->mLightCyan; break; case 14: c = pHost->mCyan; break; case 15: c = pHost->mLightWhite; break; case 16: c = pHost->mWhite; break; } int val = *it; if( val == c.red() ) { it++; val = *it; if( val == c.green() ) { it++; val = *it; if( val == c.blue() ) { lua_pushboolean( L, 1 ); return 1; } } } lua_pushboolean( L, 0 ); return 1; } int TLuaInterpreter::getFgColor( lua_State * L ) { string luaSendText=""; if( lua_gettop( L ) == 0 ) { luaSendText = "main"; } else { if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "getFgColor: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } } QString _name(luaSendText.c_str()); std::list result; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; result = pHost->mpConsole->getFgColor( luaSendText ); typedef std::list::iterator IT; for( IT it=result.begin(); it!=result.end(); it++ ) { int pos = *it; lua_pushnumber( L, pos ); } return result.size(); } int TLuaInterpreter::getBgColor( lua_State * L ) { string luaSendText=""; if( lua_gettop( L ) == 0 ) { luaSendText = "main"; } else { if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "getBgColor: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } } std::list result; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; result = pHost->mpConsole->getBgColor( luaSendText ); typedef std::list::iterator IT; for( IT it=result.begin(); it!=result.end(); it++ ) { int pos = *it; lua_pushnumber( L, pos ); } return result.size(); } int TLuaInterpreter::wrapLine( lua_State * L ) { int s = 1; int n = lua_gettop( L ); string a1 = "main"; if( n > 1 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "wrapLine: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } } int luaNumOfMatch; if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "wrapLine: wrong argument type" ); lua_error( L ); return 1; } else { luaNumOfMatch = lua_tointeger( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->luaWrapLine( a1, luaNumOfMatch ); return 0; } int TLuaInterpreter::spawn( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; return TForkedProcess::startProcess(pHost->getLuaInterpreter(), L); } // cursorPositionInLine = selectCaptureGroup( groupNumber ) if not found -1 int TLuaInterpreter::selectCaptureGroup( lua_State * L ) { int luaNumOfMatch; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "selectCaptureGroup: wrong argument type" ); lua_error( L ); return 1; } else { luaNumOfMatch = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( luaNumOfMatch < 1 ) { lua_pushnumber( L, -1 ); return 1; } luaNumOfMatch--; //we want capture groups to start with 1 instead of 0 if( luaNumOfMatch < static_cast(pHost->getLuaInterpreter()->mCaptureGroupList.size()) ) { TLuaInterpreter * pL = pHost->getLuaInterpreter(); std::list::iterator its = pL->mCaptureGroupList.begin(); std::list::iterator iti = pL->mCaptureGroupPosList.begin(); for( int i=0; iti!=pL->mCaptureGroupPosList.end(); ++iti,++i ) { if( i >= luaNumOfMatch ) break; } for( int i=0; its!=pL->mCaptureGroupList.end(); ++its,++i) { if( i >= luaNumOfMatch ) break; } int begin = *iti; std::string & s = *its; int length = s.size(); //cout << "selectSection("<>0;} int pos = pHost->mpConsole->selectSection( begin, length ); lua_pushnumber( L, pos ); } else { lua_pushnumber( L, -1 ); } return 1; } // luaTable result[line_number, content] = getLines( from_cursorPos, to_cursorPos ) int TLuaInterpreter::getLines( lua_State * L ) { int luaFrom; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getLines: wrong argument type" ); lua_error( L ); return 1; } else { luaFrom = lua_tointeger( L, 1 ); } int luaTo; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "getLines: wrong argument type" ); lua_error( L ); return 1; } else { luaTo=lua_tointeger( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QStringList strList = pHost->mpConsole->getLines( luaFrom, luaTo ); lua_newtable(L); for( int i=0; igetBufferTable( luaFrom, luaTo ); if( mudlet::debugMode ) qDebug()<<"TLuaInterpreter::getBufferTable() strList="<mpConsole->loadRawFile( luaSendText ); return 0; } int TLuaInterpreter::getCurrentLine( lua_State * L ) { string luaSendText=""; if( lua_gettop( L ) == 0 ) { luaSendText = "main"; } else { if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "getCurrentLine: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString line = pHost->mpConsole->getCurrentLine( luaSendText ); lua_pushstring( L, line.toLatin1().data() ); return 1; } int TLuaInterpreter::setMiniConsoleFontSize( lua_State * L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "setMiniConsoleFontSize: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } int luaNumOfMatch; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setMiniConsoleFontSize: wrong argument type" ); lua_error( L ); return 1; } else { luaNumOfMatch = lua_tointeger( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->setMiniConsoleFontSize( luaSendText, luaNumOfMatch ); return 0; } // returns current y position of the user cursor int TLuaInterpreter::getLineNumber( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; int lineNumber = pHost->mpConsole->getLineNumber(); lua_pushnumber( L, lineNumber ); return 1; } int TLuaInterpreter::updateMap(lua_State * L){ Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap) { if (pHost->mpMap->mpM) pHost->mpMap->mpM->update(); if (pHost->mpMap->mpMapper){ if (pHost->mpMap->mpMapper->mp2dMap){ pHost->mpMap->mpMapper->mp2dMap->mNewMoveAction=true; pHost->mpMap->mpMapper->mp2dMap->update(); } } } return 0; } int TLuaInterpreter::addMapMenu(lua_State * L){ // first arg = unique name, second arg= parent name, third arg = display name (=unique name if not provided) QString uniqueName; QStringList menuList; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "addMapMenu: wrong first argument type" ); lua_error( L ); return 1; } else { uniqueName = lua_tostring( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { menuList << ""; } else { menuList << lua_tostring( L, 2 ); } if( ! lua_isstring( L, 3 ) ) { menuList << uniqueName; } else { menuList << lua_tostring( L, 3 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap) { if (pHost->mpMap->mpMapper){ if (pHost->mpMap->mpMapper->mp2dMap){ pHost->mpMap->mpMapper->mp2dMap->mUserMenus.insert(uniqueName,menuList); } } } return 0; } int TLuaInterpreter::removeMapMenu(lua_State * L){ QString uniqueName; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "removeMapMenu: wrong first argument type" ); lua_error( L ); return 1; } else { uniqueName = lua_tostring( L, 1 ); } if (uniqueName == "") return 0; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap) { if (pHost->mpMap->mpMapper){ if (pHost->mpMap->mpMapper->mp2dMap){ pHost->mpMap->mpMapper->mp2dMap->mUserMenus.remove(uniqueName); //remove all entries with this as parent QStringList removeList; removeList.append(uniqueName); bool newElement = true; while (newElement){ newElement = false; QMapIterator it(pHost->mpMap->mpMapper->mp2dMap->mUserMenus); while (it.hasNext()){ it.next(); QStringList menuInfo = it.value(); QString parent = menuInfo[0]; if (removeList.contains(parent)){ pHost->mpMap->mpMapper->mp2dMap->mUserMenus.remove(it.key()); if (it.key() != "" && !removeList.contains(it.key())){ pHost->mpMap->mpMapper->mp2dMap->mUserMenus.remove(it.key()); removeList.append(it.key()); newElement = true; } } } } qDebug()< it2(pHost->mpMap->mpMapper->mp2dMap->mUserActions); while (it2.hasNext()){ it2.next(); QString actParent = it2.value()[1]; if (removeList.contains(actParent)){ pHost->mpMap->mpMapper->mp2dMap->mUserActions.remove(it2.key()); } } } } } return 0; } int TLuaInterpreter::getMapMenus(lua_State * L){ Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap) { if (pHost->mpMap->mpMapper){ if (pHost->mpMap->mpMapper->mp2dMap){ lua_newtable(L); QMapIterator it (pHost->mpMap->mpMapper->mp2dMap->mUserMenus); while (it.hasNext()){ it.next(); QString parent, display; QStringList menuInfo = it.value(); parent = menuInfo[0]; display = menuInfo[1]; lua_pushstring( L, it.key().toLatin1().data() ); lua_pushstring( L, parent.toLatin1().data() ); lua_pushstring( L, display.toLatin1().data() ); lua_settable(L, -3); } } return 1; } } return 0; } int TLuaInterpreter::addMapEvent(lua_State * L){ QString uniqueName, eventName, parent, displayName; QStringList actionInfo; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "addMapEvent: wrong first argument type" ); lua_error( L ); return 1; } else { uniqueName = lua_tostring( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "addMapEvent: wrong second argument type" ); lua_error( L ); return 1; } else { actionInfo << lua_tostring( L, 2 ); } if( ! lua_isstring( L, 3 ) ) { actionInfo << ""; } else { actionInfo << lua_tostring( L, 3 ); } if( ! lua_isstring( L, 4 ) ) { actionInfo << uniqueName; } else { actionInfo << lua_tostring( L, 4 ); } //variable number of arguments for (int i=5;i<=lua_gettop(L);i++) actionInfo << lua_tostring(L,i); qDebug()<mpMap) { if (pHost->mpMap->mpMapper){ if (pHost->mpMap->mpMapper->mp2dMap){ pHost->mpMap->mpMapper->mp2dMap->mUserActions.insert(uniqueName, actionInfo); } } } return 0; } int TLuaInterpreter::removeMapEvent(lua_State * L){ QString displayName; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "removeMapEvent: wrong first argument type" ); lua_error( L ); return 1; } else { displayName = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap) { if (pHost->mpMap->mpMapper){ if (pHost->mpMap->mpMapper->mp2dMap){ pHost->mpMap->mpMapper->mp2dMap->mUserActions.remove(displayName); } } } return 0; } int TLuaInterpreter::getMapEvents(lua_State * L){ Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap) { if (pHost->mpMap->mpMapper){ if (pHost->mpMap->mpMapper->mp2dMap){ lua_newtable(L); QMapIterator it(pHost->mpMap->mpMapper->mp2dMap->mUserActions); while (it.hasNext()){ it.next(); lua_newtable(L); QStringList eventInfo = it.value(); lua_pushstring( L, eventInfo[0].toLatin1().data() ); lua_pushstring( L, eventInfo[1].toLatin1().data() ); lua_pushstring( L, eventInfo[2].toLatin1().data() ); lua_settable(L, -3); lua_pushstring(L, it.key().toLatin1().data()); lua_insert(L,-2); lua_settable(L, -3); } } return 1; } } return 0; } int TLuaInterpreter::centerview( lua_State * L ) { int roomid; if( lua_isnumber( L, 1 ) || lua_isstring( L, 1 ) ) { roomid = lua_tointeger( L, 1 ); } else { lua_pushstring( L, "centerview: need a valid room ID" ); lua_error( L ); return 1; } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap && pHost->mpMap->rooms.contains( roomid ) ) { pHost->mpMap->mRoomId = roomid; pHost->mpMap->mNewMove = true; if( pHost->mpMap->mpM ) { pHost->mpMap->mpM->update(); } if( pHost->mpMap->mpM ) { pHost->mpMap->mpMapper->mp2dMap->isCenterViewCall = true; pHost->mpMap->mpMapper->mp2dMap->update(); pHost->mpMap->mpMapper->mp2dMap->isCenterViewCall = false; } } return 0; } int TLuaInterpreter::copy( lua_State * L ) { string luaWindowName=""; if( lua_isstring( L, 1 ) ) { luaWindowName = lua_tostring( L, 1 ); } else luaWindowName = "main"; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); if( luaWindowName == "main" ) pHost->mpConsole->copy(); else mudlet::self()->copy( pHost, windowName ); return 0; } int TLuaInterpreter::cut( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->cut(); return 0; } int TLuaInterpreter::paste( lua_State * L ) { string luaWindowName=""; if( lua_isstring( L, 1 ) ) { luaWindowName = lua_tostring( L, 1 ); } else luaWindowName = "main"; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); if( luaWindowName == "main" ) pHost->mpConsole->paste(); else mudlet::self()->pasteWindow( pHost, windowName ); return 0; } int TLuaInterpreter::feedTriggers( lua_State * L ) { string luaWindowName=""; if( lua_isstring( L, 1 ) ) { luaWindowName = lua_tostring( L, 1 ); } else { lua_pushstring( L, "feedTriggers: wrong argument type" ); lua_error( L ); return 1; } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->printOnDisplay( luaWindowName ); return 0; } int TLuaInterpreter::isPrompt( lua_State *L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; int userCursorY = pHost->mpConsole->getLineNumber(); if( userCursorY < pHost->mpConsole->buffer.promptBuffer.size() && userCursorY >= 0 ) { lua_pushboolean( L, pHost->mpConsole->buffer.promptBuffer.at( userCursorY ) ); return 1; } else { if( pHost->mpConsole->mTriggerEngineMode && pHost->mpConsole->mIsPromptLine ) lua_pushboolean( L, true ); else lua_pushboolean( L, false ); return 1; } } int TLuaInterpreter::setWindowWrap( lua_State * L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "setWindowWrap: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } int luaFrom; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setWindowWrap: wrong argument type" ); lua_error( L ); return 1; } else { luaFrom = lua_tointeger( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString name = luaSendText.c_str(); if( name == "main" ) pHost->mpConsole->setWrapAt( luaFrom ); else mudlet::self()->setWindowWrap( pHost, name, luaFrom ); return 0; } int TLuaInterpreter::setWindowWrapIndent( lua_State * L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "setWindowWrapIndent: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } int luaFrom; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setWindowWrapIndent: wrong argument type" ); lua_error( L ); return 1; } else { luaFrom = lua_tointeger( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString name = luaSendText.c_str(); mudlet::self()->setWindowWrapIndent( pHost, name, luaFrom ); return 0; } int TLuaInterpreter::getLineCount( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( lua_isstring( L, 1 ) ) { string window = lua_tostring( L, 1 ); QString _window = window.c_str(); lua_pushnumber( L, mudlet::self()->getLastLineNumber( pHost, _window ) + 1 ); return 1; } else { int lineNumber = pHost->mpConsole->getLineCount(); lua_pushnumber( L, lineNumber ); return 1; } return 0; } int TLuaInterpreter::getColumnNumber( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; int lineNumber = pHost->mpConsole->getColumnNumber(); lua_pushnumber( L, lineNumber ); return 1; } int TLuaInterpreter::getStopWatchTime( lua_State * L ) { int watchID; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getStopWatchTime: wrong argument type" ); lua_error( L ); return 1; } else { watchID = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; double time = pHost->getStopWatchTime( watchID ); lua_pushnumber( L, time ); return 1; } int TLuaInterpreter::createStopWatch( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; double watchID = pHost->createStopWatch(); lua_pushnumber( L, watchID ); return 1; } int TLuaInterpreter::stopStopWatch( lua_State * L ) { int watchID; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "stopStopWatch: wrong argument type" ); lua_error( L ); return 1; } else { watchID = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; double time = pHost->stopStopWatch( watchID ); lua_pushnumber( L, time ); return 1; } int TLuaInterpreter::startStopWatch( lua_State * L ) { int watchID; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "startStopWatch: wrong argument type" ); lua_error( L ); return 1; } else { watchID = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; bool b = pHost->startStopWatch( watchID ); lua_pushboolean( L, b ); return 1; } int TLuaInterpreter::resetStopWatch( lua_State * L ) { int watchID; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "resetStopWatch: wrong argument type" ); lua_error( L ); return 1; } else { watchID = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; bool b = pHost->resetStopWatch( watchID ); lua_pushboolean( L, b ); return 1; } // cusorPositionInLine = selectSection( from_cursorPos, to_cursorPos ) -1 on not found int TLuaInterpreter::selectSection( lua_State * L ) { int s = 1; int n = lua_gettop( L ); string a1; if( n > 2 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "selectSection: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } } int luaFrom; if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "selectSection: wrong argument type" ); lua_error( L ); return 1; } else { luaFrom = lua_tointeger( L, s ); s++; } int luaTo; if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "selectSection: wrong argument type" ); lua_error( L ); return 1; } else { luaTo=lua_tointeger( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; bool ret; if( n > 2 ) { QString _name = a1.c_str(); ret = mudlet::self()->selectSection( pHost, _name, luaFrom, luaTo ); } else { ret = pHost->mpConsole->selectSection( luaFrom, luaTo ); } lua_pushboolean( L, ret ); return 1; } int TLuaInterpreter::moveCursor( lua_State * L ) { int s = 1; int n = lua_gettop( L ); string a1; if( n > 2 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "moveCursor: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } } int luaFrom; if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "moveCursor: wrong argument type" ); lua_error( L ); return 1; } else { luaFrom = lua_tointeger( L, s ); s++; } int luaTo; if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "moveCursor: wrong argument type" ); lua_error( L ); return 1; } else { luaTo=lua_tointeger( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( a1 == "main" || n < 3 ) lua_pushboolean( L, pHost->mpConsole->moveCursor( luaFrom, luaTo ) ); else { QString windowName = a1.c_str(); lua_pushboolean( L, mudlet::self()->moveCursor( pHost, windowName, luaFrom, luaTo ) ); } return 1; } int TLuaInterpreter::setConsoleBufferSize( lua_State * L ) { int s = 1; int n = lua_gettop( L ); string a1; if( n > 2 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setConsoleBufferSize: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } } int luaFrom; if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "setConsoleBufferSize: wrong argument type" ); lua_error( L ); return 1; } else { luaFrom = lua_tointeger( L, s ); s++; } int luaTo; if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "setConsoleBufferSize: wrong argument type" ); lua_error( L ); return 1; } else { luaTo=lua_tointeger( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( a1 == "main" || n < 3 ) { pHost->mpConsole->buffer.setBufferSize( luaFrom, luaTo ); } else { QString windowName = a1.c_str(); mudlet::self()->setConsoleBufferSize( pHost, windowName, luaFrom, luaTo ); } return 0; } int TLuaInterpreter::getBufferLine( lua_State * L ) { int luaLine; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getBufferLine: wrong argument type" ); lua_error( L ); return 1; } else { luaLine = lua_tointeger( L, 1 ); } /*Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString line = pHost->getBufferLine( luaLine ); if( mudlet::debugMode ) qDebug()<<"TLuaInterpreter::getBufferLine() line="< 1 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "replace: wrong argument type" ); lua_error( L ); return 1; } else { a2 = lua_tostring( L, s ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( n == 1 ) pHost->mpConsole->replace( QString(a1.c_str()) ); else mudlet::self()->replace( pHost, _name, QString(a2.c_str()) ); return 0; } int TLuaInterpreter::deleteLine( lua_State * L ) { string name=""; if( lua_gettop( L ) == 1 ) { if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "deleteLine: wrong argument type" ); lua_error( L ); return 1; } else { name = lua_tostring( L, 1 ); } } QString _name( name.c_str() ); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( name == "" ) pHost->mpConsole->skipLine(); else mudlet::self()->deleteLine( pHost, _name ); return 0; } int TLuaInterpreter::saveMap( lua_State * L ) { string location=""; if( lua_gettop( L ) == 1 ) { if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "saveMap: where do you want to save to?" ); lua_error( L ); return 1; } else { location = lua_tostring( L, 1 ); } } QString _location( location.c_str() ); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; bool error = pHost->mpConsole->saveMap(_location); lua_pushboolean( L, error ); return 1; } int TLuaInterpreter::setExitStub( lua_State * L ){ //args:room id, direction (as given by the #define direction table), status int roomId, dirType; bool status; if (!lua_isnumber(L,1)){ lua_pushstring( L, "setExitStub: Need a room number as first argument" ); lua_error( L ); return 1; } else{ roomId = lua_tonumber(L,1); } if (!lua_isnumber(L,2)){ lua_pushstring( L, "setExitStub: Need a dir number as 2nd argument" ); lua_error( L ); return 1; } else{ dirType = lua_tonumber(L,2); } if (!lua_isboolean(L,3)){ lua_pushstring( L, "setExitStub: Need a true/false for third argument" ); lua_error( L ); return 1; } else{ status = lua_toboolean(L,3); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if (!pHost->mpMap->rooms.contains( roomId )){ lua_pushstring( L, "setExitStub: RoomId doesn't exist" ); lua_error( L ); return 1; } if (dirType>10 || dirType < 1){ lua_pushstring( L, "setExitStub: dirType must be between 1 and 10" ); lua_error( L ); return 1; } if (status){ if (pHost->mpMap->rooms[roomId]->exitStubs.contains(dirType)) return 1; pHost->mpMap->rooms[roomId]->setExitStub(dirType, 1); } else{ if (pHost->mpMap->rooms[roomId]->exitStubs.contains(dirType)) pHost->mpMap->rooms[roomId]->setExitStub(dirType, 0); } return 1; } int TLuaInterpreter::connectExitStub( lua_State * L ){ //takes exit stubs from the selected room, finds the room in that direction and if //that room has a stub, a two way exit is formed //args:room id, direction //OR if 3 arguments, takes first argument as from room, 2nd at to room, 3rd as direction //from start room to end room int roomId; int toRoom; int dirType; int roomsGiven = 0; if (!lua_isnumber(L,1)){ lua_pushstring( L, "connectExitStub: Need a room number as first argument" ); lua_error( L ); return 1; } else roomId = lua_tonumber(L,1); if (!lua_isnumber(L,2)){ lua_pushstring( L, "connectExitStub: Need a direction number (or room id) as 2nd argument" ); lua_error( L ); return 1; } else dirType = lua_tonumber(L,2); if (!lua_isnumber(L,3) && !lua_isstring(L,3)){ roomsGiven = 0; } else{ roomsGiven = 1; toRoom = lua_tonumber(L,2); dirType = lua_tonumber(L,3); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if (!pHost->mpMap->rooms.contains( roomId )){ lua_pushstring( L, "connectExitStubs: RoomId doesn't exist" ); lua_error( L ); return 1; } if (!pHost->mpMap->rooms[roomId]->exitStubs.contains(dirType)){ lua_pushstring( L, "connectExitStubs: ExitStub doesn't exist" ); lua_error( L ); return 1; } if (roomsGiven){ if (!pHost->mpMap->rooms.contains( toRoom )){ lua_pushstring( L, "connectExitStubs: toRoom doesn't exist" ); lua_error( L ); return 1; } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; lua_pushboolean(L, pHost->mpMap->setExit( roomId, toRoom, dirType ) ); //pHost->mpMap->rooms[roomId]->setExitStub(dirType, 0); //setExit( toRoom, roomId, pHost->mpMap->reverseDirections[dirType]); //pHost->mpMap->rooms[toRoom]->setExitStub(pHost->mpMap->reverseDirections[dirType], 0); } else{ if (!pHost->mpMap->rooms[roomId]->exitStubs.contains(dirType)){ lua_pushstring( L, "connectExitStubs: ExitStub doesn't exist" ); lua_error( L ); return 1; } pHost->mpMap->connectExitStub(roomId, dirType); } pHost->mpMap->mMapGraphNeedsUpdate = true; return 1; } int TLuaInterpreter::getExitStubs( lua_State * L ){ //args:room id int roomId; if (!lua_isnumber(L,1)){ lua_pushstring( L, "getExitStubs: Need a room number as first argument" ); lua_error( L ); return 1; } else roomId = lua_tonumber(L,1); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if (!pHost->mpMap->rooms.contains( roomId )){ lua_pushstring( L, "getExitStubs: RoomId doesn't exist" ); lua_error( L ); return 1; } else{ QList stubs = pHost->mpMap->rooms[roomId]->exitStubs; if (stubs.size()){ lua_newtable(L); for(int i=0;imModulePriorities.contains(moduleName)){ int priority = mpHost->mModulePriorities[moduleName]; lua_pushnumber( L, priority ); return 1; } else{ lua_pushstring(L, "getModulePriority: Module doesn't exist"); lua_error(L); return 1; } return 0; } int TLuaInterpreter::setModulePriority( lua_State * L ){ QString moduleName; int modulePriority; if (!lua_isstring(L,1)){ lua_pushstring(L, "setModulePriority: Module be be a string"); lua_error(L); return 1; } else moduleName = lua_tostring(L,1); if (!lua_isnumber(L,2)){ lua_pushstring(L, "setModulePriority: Module priority must be an integer"); lua_error(L); return 1; } else modulePriority = lua_tonumber(L,2); Host * mpHost = TLuaInterpreter::luaInterpreterMap[L]; if (mpHost->mModulePriorities.contains(moduleName)) mpHost->mModulePriorities[moduleName] = modulePriority; else{ lua_pushstring(L, "setModulePriority: Module doesn't exist"); lua_error(L); return 1; } return 0; } int TLuaInterpreter::loadMap( lua_State * L ) { string location=""; if( lua_gettop( L ) == 1 ) { if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "loadMap: where do you want to load from?" ); lua_error( L ); return 1; } else { location = lua_tostring( L, 1 ); } } QString _location( location.c_str() ); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; bool error = pHost->mpConsole->loadMap(_location); lua_pushboolean( L, error ); return 1; } // enableTimer( sess, timer_name ) int TLuaInterpreter::enableTimer( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "enableTimer: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); bool error = pHost->getTimerUnit()->enableTimer( text ); lua_pushboolean( L, error ); return 1; } // disableTimer( session, timer_name ) int TLuaInterpreter::disableTimer( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "disableTimer: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); bool error = pHost->getTimerUnit()->disableTimer( text ); lua_pushboolean( L, error ); return 1; } int TLuaInterpreter::enableKey( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "enableKey: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); bool error = pHost->getKeyUnit()->enableKey( text ); lua_pushboolean( L, error ); return 1; } // disableTimer( session, timer_name ) int TLuaInterpreter::disableKey( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "disableKey: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); bool error = pHost->getKeyUnit()->disableKey( text ); lua_pushboolean( L, error ); return 1; } int TLuaInterpreter::enableAlias( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "enableAlias: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); bool error = pHost->getAliasUnit()->enableAlias( text ); lua_pushboolean( L, error ); return 1; } // disableTimer( session, timer_name ) int TLuaInterpreter::disableAlias( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "disableAlias: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); bool error = pHost->getAliasUnit()->disableAlias( text ); lua_pushboolean( L, error ); return 1; } int TLuaInterpreter::killAlias( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "killAlias: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); lua_pushboolean( L, pHost->getAliasUnit()->killAlias( text ) ); return 1; } // enableTimer( sess, timer_name ) int TLuaInterpreter::enableTrigger( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "enableTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); bool error = pHost->getTriggerUnit()->enableTrigger( text ); lua_pushboolean( L, error ); return 1; } // disableTimer( session, timer_name ) int TLuaInterpreter::disableTrigger( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "disableTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); bool error = pHost->getTriggerUnit()->disableTrigger( text ); lua_pushboolean( L, error ); return 1; } int TLuaInterpreter::killTimer( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "killTimer: killTimer requires a string ID" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); //pHost->disableTimer( text ); lua_pushboolean( L, pHost->killTimer( text ) ); return 1; } int TLuaInterpreter::killTrigger( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "killTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); lua_pushboolean( L, pHost->killTrigger( text ) ); return 1; } // openUserWindow( session, string window_name ) int TLuaInterpreter::openUserWindow( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "openUserWindow: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); mudlet::self()->openWindow( pHost, text ); return 0; } int TLuaInterpreter::createMiniConsole( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "createMiniConsole: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } int x,y,width,height; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "createMiniConsole: wrong argument type" ); lua_error( L ); return 1; } else { x = lua_tonumber( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "createMiniConsole: wrong argument type" ); lua_error( L ); return 1; } else { y = lua_tonumber( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "createMiniConsole: wrong argument type" ); lua_error( L ); return 1; } else { width = lua_tonumber( L, 4 ); } if( ! lua_isnumber( L, 5 ) ) { lua_pushstring( L, "createMiniConsole: wrong argument type" ); lua_error( L ); return 1; } else { height = lua_tonumber( L, 5 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString name(luaSendText.c_str()); lua_pushboolean( L, mudlet::self()->createMiniConsole( pHost, name, x, y, width, height ) ); return 1; } int TLuaInterpreter::createLabel( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "createLabel: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } int x,y,width,height; bool fillBackground=false; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "createLabel: wrong argument type" ); lua_error( L ); return 1; } else { x = lua_tonumber( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "createLabel: wrong argument type" ); lua_error( L ); return 1; } else { y = lua_tonumber( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "createLabel: wrong argument type" ); lua_error( L ); return 1; } else { width = lua_tonumber( L, 4 ); } if( ! lua_isnumber( L, 5 ) ) { lua_pushstring( L, "createLabel: wrong argument type" ); lua_error( L ); return 1; } else { height = lua_tonumber( L, 5 ); } if( ! lua_isnumber( L, 6 ) ) { lua_pushstring( L, "createLabel: wrong argument type" ); lua_error( L ); return 1; } else { fillBackground = lua_toboolean( L, 6 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString name(luaSendText.c_str()); lua_pushboolean( L, mudlet::self()->createLabel( pHost, name, x, y, width, height, fillBackground ) ); return 1; } int TLuaInterpreter::createMapper( lua_State *L ) { int x,y,width,height; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "createMapper: wrong argument type" ); lua_error( L ); return 1; } else { x = lua_tonumber( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "createMapper: wrong argument type" ); lua_error( L ); return 1; } else { y = lua_tonumber( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "createMapper: wrong argument type" ); lua_error( L ); return 1; } else { width = lua_tonumber( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "createMapper: wrong argument type" ); lua_error( L ); return 1; } else { height = lua_tonumber( L, 4 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->createMapper( x, y, width, height ); return 0; } int TLuaInterpreter::createButton( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "createButton: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } int x,y,width,height; bool fillBackground=false; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "createButton: wrong argument type" ); lua_error( L ); return 1; } else { x = lua_tonumber( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "createButton: wrong argument type" ); lua_error( L ); return 1; } else { y = lua_tonumber( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "createButton: wrong argument type" ); lua_error( L ); return 1; } else { width = lua_tonumber( L, 4 ); } if( ! lua_isnumber( L, 5 ) ) { lua_pushstring( L, "createButton: wrong argument type" ); lua_error( L ); return 1; } else { height = lua_tonumber( L, 5 ); } if( ! lua_isnumber( L, 6 ) ) { lua_pushstring( L, "createButton: wrong argument type" ); lua_error( L ); return 1; } else { fillBackground = lua_toboolean( L, 6 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString name(luaSendText.c_str()); //TODO FIXME mudlet::self()->createLabel( pHost, name, x, y, width, height, fillBackground ); return 0; } int TLuaInterpreter::createBuffer( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "createBuffer: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); mudlet::self()->createBuffer( pHost, text ); return 0; } #include "TTextEdit.h" int TLuaInterpreter::clearUserWindow( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->buffer.clear(); pHost->mpConsole->console->forceUpdate(); return 0; // lua_pushstring( L, "clearUserWindow: wrong argument type" ); // lua_error( L ); // return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); mudlet::self()->clearWindow( pHost, text ); return 0; } int TLuaInterpreter::closeUserWindow( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "closeUserWindow: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); mudlet::self()->hideWindow( pHost, text ); return 0; } int TLuaInterpreter::hideUserWindow( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "hideUserWindow: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); //mudlet::self()->hideWindow( pHost, text ); pHost->mpConsole->hideWindow( text ); return 0; } int TLuaInterpreter::setBorderTop( lua_State *L ) { int x1; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setBorderTop: wrong argument type" ); lua_error( L ); return 1; } else { x1 = lua_tonumber( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mBorderTopHeight = x1; int x,y; x = pHost->mpConsole->width(); y = pHost->mpConsole->height(); QSize s = QSize(x,y); QResizeEvent event(s, s); QApplication::sendEvent( pHost->mpConsole, &event); return 0; } int TLuaInterpreter::setBorderBottom( lua_State *L ) { int x1; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setBorderBottom: wrong argument type" ); lua_error( L ); return 1; } else { x1 = lua_tonumber( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mBorderBottomHeight = x1; int x,y; x = pHost->mpConsole->width(); y = pHost->mpConsole->height(); QSize s = QSize(x,y); QResizeEvent event(s, s); QApplication::sendEvent( pHost->mpConsole, &event); return 0; } int TLuaInterpreter::setBorderLeft( lua_State *L ) { int x1; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setBorderLeft: wrong argument type" ); lua_error( L ); return 1; } else { x1 = lua_tonumber( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mBorderLeftWidth = x1; int x,y; x = pHost->mpConsole->width(); y = pHost->mpConsole->height(); QSize s = QSize(x,y); QResizeEvent event(s, s); QApplication::sendEvent( pHost->mpConsole, &event); return 0; } int TLuaInterpreter::setBorderRight( lua_State *L ) { int x1; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setBorderRight: wrong argument type" ); lua_error( L ); return 1; } else { x1 = lua_tonumber( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mBorderRightWidth = x1; int x,y; x = pHost->mpConsole->width(); y = pHost->mpConsole->height(); QSize s = QSize(x,y); QResizeEvent event(s, s); QApplication::sendEvent( pHost->mpConsole, &event); return 0; } int TLuaInterpreter::resizeUserWindow( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "resizeUserWindow: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } double x1; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "resizeUserWindow: wrong argument type" ); lua_error( L ); return 1; } else { x1 = lua_tonumber( L, 2 ); } double y1; if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "resizeUserWindow: wrong argument type" ); lua_error( L ); return 1; } else { y1 = lua_tonumber( L, 3 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); mudlet::self()->resizeWindow( pHost, text, static_cast(x1), static_cast(y1) ); return 0; } int TLuaInterpreter::moveWindow( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "moveWindow: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } double x1; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "moveWindow: wrong argument type" ); lua_error( L ); return 1; } else { x1 = lua_tonumber( L, 2 ); } double y1; if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "moveWindow: wrong argument type" ); lua_error( L ); return 1; } else { y1 = lua_tonumber( L, 3 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); mudlet::self()->moveWindow( pHost, text, static_cast(x1), static_cast(y1) ); return 0; } int TLuaInterpreter::setMainWindowSize( lua_State *L ) { int x1; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setBackgroundColor: wrong argument type" ); lua_error( L ); return 1; } else { x1 = lua_tonumber( L, 1 ); } int y1; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setBackgroundColor: wrong argument type" ); lua_error( L ); return 1; } else { y1 = lua_tonumber( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; mudlet::self()->resize( x1, y1 ); return 0; } int TLuaInterpreter::setBackgroundColor( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "setBackgroundColor: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } double x1; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setBackgroundColor: wrong argument type" ); lua_error( L ); return 1; } else { x1 = lua_tonumber( L, 2 ); } double y1; if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "setBackgroundColor: wrong argument type" ); lua_error( L ); return 1; } else { y1 = lua_tonumber( L, 3 ); } double x2; if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "setBackgroundColor: wrong argument type" ); lua_error( L ); return 1; } else { x2 = lua_tonumber( L, 4 ); } double y2; if( ! lua_isnumber( L, 5 ) ) { lua_pushstring( L, "setBackgroundColor: wrong argument type" ); lua_error( L ); return 1; } else { y2 = lua_tonumber( L, 5 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); mudlet::self()->setBackgroundColor( pHost, text, static_cast(x1), static_cast(y1), static_cast(x2), static_cast(y2) ); return 0; } int TLuaInterpreter::calcFontWidth( int size ) { QFont font = QFont("Bitstream Vera Sans Mono", size, QFont::Courier); return QFontMetrics( font ).width( QChar('W') ); } int TLuaInterpreter::calcFontHeight( int size ) { QFont font = QFont("Bitstream Vera Sans Mono", size, QFont::Courier); int fontDescent = QFontMetrics( font ).descent(); int fontAscent = QFontMetrics( font ).ascent(); return fontAscent + fontDescent; } int TLuaInterpreter::calcFontSize( lua_State *L ) { int x = 0; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "calcFontSize: wrong argument type" ); lua_error( L ); return 1; } else { x = lua_tonumber( L, 1 ); } lua_pushnumber( L, calcFontWidth( x ) ); lua_pushnumber( L, calcFontHeight( x ) ); return 2; } int TLuaInterpreter::startLogging( lua_State *L ) { bool logOn = true; if( ! lua_isboolean( L, 1 ) ) { lua_pushstring( L, "startLogging: wrong argument type" ); lua_error( L ); return 1; } else { logOn = lua_toboolean( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->mLogToLogFile = ! logOn; pHost->mpConsole->slot_toggleLogging(); return 0; } int TLuaInterpreter::setBackgroundImage( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "setBackgroundImage: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } string luaName=""; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setBackgroundImage: wrong argument type" ); lua_error( L ); return 1; } else { luaName = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); QString name(luaName.c_str()); mudlet::self()->setBackgroundImage( pHost, text, name ); return 0; } int TLuaInterpreter::setLabelClickCallback( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "setLabelClickCallback: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } string luaName=""; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setLabelClickCallback: wrong argument type" ); lua_error( L ); return 1; } else { luaName = lua_tostring( L, 2 ); } TEvent * pE = new TEvent; int n = lua_gettop( L ); for( int i=3; i<=n; i++) { if( lua_isnumber( L, i ) ) { pE->mArgumentList.append( QString::number(lua_tonumber( L, i ) ) ); pE->mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); } else if( lua_isstring( L, i ) ) { pE->mArgumentList.append( QString(lua_tostring( L, i )) ); pE->mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); QString name(luaName.c_str()); mudlet::self()->setLabelClickCallback( pHost, text, name, pE ); return 0; } int TLuaInterpreter::setLabelOnEnter( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "setLabelOnEnter: wrong first argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } string luaName=""; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setLabelOnEnter: wrong second argument type" ); lua_error( L ); return 1; } else { luaName = lua_tostring( L, 2 ); } TEvent * pE = new TEvent; int n = lua_gettop( L ); for( int i=3; i<=n; i++) { if( lua_isnumber( L, i ) ) { pE->mArgumentList.append( QString::number(lua_tonumber( L, i ) ) ); pE->mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); } else if( lua_isstring( L, i ) ) { pE->mArgumentList.append( QString(lua_tostring( L, i )) ); pE->mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); QString name(luaName.c_str()); mudlet::self()->setLabelOnEnter( pHost, text, name, pE ); return 0; } int TLuaInterpreter::setLabelOnLeave( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "setLabelClickCallback: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } string luaName=""; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setLabelClickCallback: wrong argument type" ); lua_error( L ); return 1; } else { luaName = lua_tostring( L, 2 ); } TEvent * pE = new TEvent; int n = lua_gettop( L ); for( int i=3; i<=n; i++) { if( lua_isnumber( L, i ) ) { pE->mArgumentList.append( QString::number(lua_tonumber( L, i ) ) ); pE->mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); } else if( lua_isstring( L, i ) ) { pE->mArgumentList.append( QString(lua_tostring( L, i )) ); pE->mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); QString name(luaName.c_str()); mudlet::self()->setLabelOnLeave( pHost, text, name, pE ); return 0; } int TLuaInterpreter::setTextFormat( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "setTextFormat: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } double r1; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setTextFormat: wrong argument type" ); lua_error( L ); return 1; } else { r1 = lua_tonumber( L, 2 ); } double g1; if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "setTextFormat: wrong argument type" ); lua_error( L ); return 1; } else { g1 = lua_tonumber( L, 3 ); } double b1; if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "setTextFormat: wrong argument type" ); lua_error( L ); return 1; } else { b1 = lua_tonumber( L, 4 ); } double r2; if( ! lua_isnumber( L, 5 ) ) { lua_pushstring( L, "setTextFormat: wrong argument type" ); lua_error( L ); return 1; } else { r2 = lua_tonumber( L, 5 ); } double g2; if( ! lua_isnumber( L, 6 ) ) { lua_pushstring( L, "setTextFormat: wrong argument type" ); lua_error( L ); return 1; } else { g2 = lua_tonumber( L, 6 ); } double b2; if( ! lua_isnumber( L, 7 ) ) { lua_pushstring( L, "setTextFormat: wrong argument type" ); lua_error( L ); return 1; } else { b2 = lua_tonumber( L, 7 ); } double bold; if( ! lua_isnumber( L, 8 ) ) { lua_pushstring( L, "setTextFormat: wrong argument type" ); lua_error( L ); return 1; } else { bold = lua_tonumber( L, 8 ); } double underline; if( ! lua_isnumber( L, 9 ) ) { lua_pushstring( L, "setTextFormat: wrong argument type" ); lua_error( L ); return 1; } else { underline = lua_tonumber( L, 9 ); } double italics; if( ! lua_isnumber( L, 10 ) ) { lua_pushstring( L, "setTextFormat: wrong argument type" ); lua_error( L ); return 1; } else { italics = lua_tonumber( L, 10 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); if( text == "main" ) { TConsole * pC = pHost->mpConsole; pC->mFormatCurrent.bgR = r1; pC->mFormatCurrent.bgG = g1; pC->mFormatCurrent.bgB = b1; pC->mFormatCurrent.fgR = r2; pC->mFormatCurrent.fgG = g2; pC->mFormatCurrent.fgB = b2; pC->mFormatCurrent.bold = bold; pC->mFormatCurrent.underline = underline; pC->mFormatCurrent.italics = italics; return true; } else { mudlet::self()->setTextFormat( pHost, text, static_cast(r1), static_cast(g1), static_cast(b1), static_cast(r2),static_cast(g2), static_cast(b2), static_cast(bold), static_cast(underline), static_cast(italics) ); } return 0; } int TLuaInterpreter::showUserWindow( lua_State *L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "showUserWindow: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); lua_pushboolean( L, pHost->mpConsole->showWindow( text )); return 1; } // xRot, yRot, zRot, zoom int TLuaInterpreter::setMapperView( lua_State *L ) { float x, y, z, zoom; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setMapperView: wrong argument type" ); lua_error( L ); return 1; } else { x = lua_tonumber( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setMapperView: wrong argument type" ); lua_error( L ); return 1; } else { y = lua_tonumber( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "setMapperView: wrong argument type" ); lua_error( L ); return 1; } else { z = lua_tonumber( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "setMapperView: wrong argument type" ); lua_error( L ); return 1; } else { zoom = lua_tonumber( L, 4 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpMap->setView( x, y, z, zoom ); return 0; } int TLuaInterpreter::setRoomEnv( lua_State *L ) { int id, env; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setRoomEnv: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setRoomEnv: wrong argument type" ); lua_error( L ); return 1; } else { env = lua_tonumber( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { pHost->mpMap->rooms[id]->environment = env; } return 0; } int TLuaInterpreter::setRoomName( lua_State *L ) { int id; string name; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setRoomName: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setRoomName: wrong argument type" ); lua_error( L ); return 1; } else { name = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString _name = name.c_str(); if( pHost->mpMap->rooms.contains( id ) ) { pHost->mpMap->rooms[id]->name = _name; } return 0; } int TLuaInterpreter::getRoomName( lua_State *L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getRoomName: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { lua_pushstring(L, pHost->mpMap->rooms[id]->name.toLatin1().data() ); } return 1; } int TLuaInterpreter::setRoomWeight( lua_State *L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setRoomWeight: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } int w; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setRoomWeight: wrong argument type" ); lua_error( L ); return 1; } else { w = lua_tonumber( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { pHost->mpMap->rooms[id]->weight = w; pHost->mpMap->mMapGraphNeedsUpdate = true; } return 0; } int TLuaInterpreter::connectToServer( lua_State *L ) { int port; string url; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "connectToServer: wrong argument type" ); lua_error( L ); return 1; } else { url = lua_tostring( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "connectToServer: wrong argument type" ); lua_error( L ); return 1; } else { port = lua_tonumber( L, 2 ); } QString _url = url.c_str(); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mTelnet.connectIt( _url, port ); return 0; } int TLuaInterpreter::setRoomIDbyHash( lua_State *L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setRoomIDbyHash: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } string hash; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setRoomIDbyHash: wrong argument type" ); lua_error( L ); return 1; } else { hash = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpMap->hashTable[QString(hash.c_str())] = id; return 0; } int TLuaInterpreter::getRoomIDbyHash( lua_State *L ) { string hash; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "getRoomIDbyHash() wrong argument type" ); lua_error( L ); return 1; } else { hash = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; int retID = -1; QString _hash = hash.c_str(); if( pHost->mpMap->hashTable.contains( _hash ) ) { retID = pHost->mpMap->hashTable[_hash]; lua_pushnumber( L, retID ); } else lua_pushnumber( L, -1 ); return 1; } int TLuaInterpreter::solveRoomCollisions( lua_State *L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "solveRoomCollisions() wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } int creationDirection=0; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "solveRoomCollisons() wrong argument type" ); lua_error( L ); return 1; } else { creationDirection = lua_tonumber( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { pHost->mpMap->solveRoomCollision( id, creationDirection ); } return 0; } int TLuaInterpreter::roomLocked( lua_State *L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "roomLocked: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { bool r = pHost->mpMap->rooms[id]->isLocked; lua_pushboolean( L, r ); } else { lua_pushboolean(L, false); } return 1; } int TLuaInterpreter::lockRoom( lua_State *L ) { bool b = true; int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "lockRoom: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } if( ! lua_isboolean( L, 2 ) ) { lua_pushstring( L, "lockRoom: wrong argument type" ); lua_error( L ); return 1; } else { b = lua_toboolean( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { pHost->mpMap->rooms[id]->isLocked = b; pHost->mpMap->mMapGraphNeedsUpdate = true; lua_pushboolean(L, true); } else { lua_pushboolean(L, false); } return 1; } int TLuaInterpreter::lockExit( lua_State *L ) { bool b = true; int id; int dir; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "lockExit: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "lockExit: wrong argument type" ); lua_error( L ); return 1; } else { dir = lua_tonumber( L, 2 ); } if( ! lua_isboolean( L, 3 ) ) { lua_pushstring( L, "lockRoom: wrong argument type" ); lua_error( L ); return 1; } else { b = lua_toboolean( L, 3 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { pHost->mpMap->rooms[id]->setExitLock( dir, b ); pHost->mpMap->mMapGraphNeedsUpdate = true; } return 0; } int TLuaInterpreter::lockSpecialExit( lua_State *L ) { bool b = true; int id, to; std::string dir; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "lockSpecialExit: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "lockExit: wrong argument type" ); lua_error( L ); return 1; } else { to = lua_tonumber( L, 2 ); } if( ! lua_isstring( L, 3 ) ) { lua_pushstring( L, "lockSpecialExit: wrong argument type" ); lua_error( L ); return 1; } else { dir = lua_tostring( L, 3 ); } if( ! lua_isboolean( L, 4 ) ) { lua_pushstring( L, "lockSpecialExit: wrong argument type" ); lua_error( L ); return 1; } else { b = lua_toboolean( L, 4 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { QString _dir = dir.c_str(); pHost->mpMap->rooms[id]->setSpecialExitLock( to, _dir, b ); pHost->mpMap->mMapGraphNeedsUpdate = true; } return 0; } int TLuaInterpreter::hasSpecialExitLock( lua_State *L ) { bool b = true; int id, to; std::string dir; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "lockExit: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "lockExit: wrong argument type" ); lua_error( L ); return 1; } else { to = lua_tonumber( L, 2 ); } if( ! lua_isstring( L, 3 ) ) { lua_pushstring( L, "hasSpecialExitLock: wrong argument type" ); lua_error( L ); return 1; } else { dir = lua_tostring( L, 3 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { QString _dir = dir.c_str(); lua_pushboolean( L, pHost->mpMap->rooms[id]->hasSpecialExitLock( to, _dir ) ); return 1; } return 0; } int TLuaInterpreter::hasExitLock( lua_State *L ) { int id; int dir; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "lockExit: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "lockExit: wrong argument type" ); lua_error( L ); return 1; } else { dir = lua_tonumber( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { lua_pushboolean( L, pHost->mpMap->rooms[id]->hasExitLock(dir) ); return 1; } return 0; } int TLuaInterpreter::isLockedRoom( lua_State *L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "lockRoom: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { lua_pushboolean( L, pHost->mpMap->rooms[id]->isLocked ); } else { lua_pushboolean(L, false); } return 1; } int TLuaInterpreter::getRoomExits( lua_State *L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getRoomExits: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tonumber( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { lua_newtable(L); if( pHost->mpMap->rooms[id]->north != -1 ) { lua_pushstring( L, "north" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->north ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->northwest != -1 ) { lua_pushstring( L, "northwest" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->northwest ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->northeast != -1 ) { lua_pushstring( L, "northeast" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->northeast ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->south != -1 ) { lua_pushstring( L, "south" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->south ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->southwest != -1 ) { lua_pushstring( L, "southwest" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->southwest ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->southeast != -1 ) { lua_pushstring( L, "southeast" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->southeast ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->west != -1 ) { lua_pushstring( L, "west" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->west ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->east != -1 ) { lua_pushstring( L, "east" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->east ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->up != -1 ) { lua_pushstring( L, "up" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->up ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->down != -1 ) { lua_pushstring( L, "down" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->down ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->in != -1 ) { lua_pushstring( L, "in" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->in ); lua_settable(L, -3); } if( pHost->mpMap->rooms[id]->out != -1 ) { lua_pushstring( L, "out" ); lua_pushnumber( L, pHost->mpMap->rooms[id]->out ); lua_settable(L, -3); } return 1; } else return 0; } int TLuaInterpreter::searchRoom( lua_State *L ) { int room_id = 0; bool gotRoomID = false; string room; if( lua_isnumber( L, 1 ) ) { room_id = lua_tointeger( L, 1 ); gotRoomID = true; } else if( lua_isstring( L, 1 ) ) { room = lua_tostring( L, 1 ); } else { lua_pushstring( L, "searchRoom: wrong argument type" ); lua_error( L ); return 1; } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( gotRoomID ) { if( pHost->mpMap->rooms.contains( room_id ) ) { lua_pushstring( L, pHost->mpMap->rooms[room_id]->name.toLatin1().data() ); return 1; } else { lua_pushstring( L, "searchRoom ERROR: no such room" ); return 1; } } else { QMapIterator it( pHost->mpMap->rooms ); lua_newtable(L); while( it.hasNext() ) { it.next(); int i = it.key(); if( pHost->mpMap->rooms[i]->name.contains( QString(room.c_str()), Qt::CaseInsensitive ) ) { QString name = pHost->mpMap->rooms[i]->name; int roomID = pHost->mpMap->rooms[i]->id; lua_pushnumber( L, roomID ); lua_pushstring( L, name.toLatin1().data() ); lua_settable(L, -3); } } return 1; } } int TLuaInterpreter::searchRoomUserData( lua_State *L ) { //basically stolen from searchRoom //if we have, searchUserData(key, value) //we look through all room ids in a given field for the string and //return a table of roomids matching string key, value; if( lua_isstring( L, 1 ) ) { key = lua_tostring( L, 1 ); } else { lua_pushstring( L, "searchRoomUserData: wrong argument type" ); lua_error( L ); return 1; } if( lua_isstring( L, 2 ) ) { value = lua_tostring( L, 2 ); } else { lua_pushstring( L, "searchRoomUserData: wrong 2nd argument type" ); lua_error( L ); return 1; } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QMapIterator it( pHost->mpMap->rooms ); lua_newtable(L); while( it.hasNext() ) { it.next(); int i = it.key(); QString _key = key.c_str(); QString _value = value.c_str(); if (pHost->mpMap->rooms[i]->userData.contains( _key )) { QString _keyValue = pHost->mpMap->rooms[i]->userData[_key]; if (_keyValue.contains(_value)) { lua_pushnumber( L, i ); lua_pushstring( L, _keyValue.toLatin1().data() ); lua_settable(L, -3); } } } return 1; } int TLuaInterpreter::getAreaTable( lua_State *L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QMapIterator it( pHost->mpMap->areaNamesMap ); lua_newtable(L); while( it.hasNext() ) { it.next(); int roomID = it.key(); QString name = it.value(); lua_pushstring( L, name.toLatin1().data() ); lua_pushnumber( L, roomID ); lua_settable(L, -3); } return 1; } int TLuaInterpreter::getAreaTableSwap( lua_State *L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QMapIterator it( pHost->mpMap->areaNamesMap ); lua_newtable(L); while( it.hasNext() ) { it.next(); int roomID = it.key(); QString name = it.value(); lua_pushnumber( L, roomID ); lua_pushstring( L, name.toLatin1().data() ); lua_settable(L, -3); } return 1; } int TLuaInterpreter::getAreaRooms( lua_State *L ) { int area; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getAreaRooms: wrong argument type" ); lua_error( L ); return 1; } else { area = lua_tonumber( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( ! pHost->mpMap->areas.contains( area ) ) { lua_pushnil(L); return 1; } lua_newtable(L); for( int i=0; impMap->areas[area]->rooms.size(); i++ ) { int roomID = pHost->mpMap->areas[area]->rooms.at( i ); lua_pushnumber( L, i ); lua_pushnumber( L, roomID ); lua_settable(L, -3); } return 1; } int TLuaInterpreter::getRooms( lua_State *L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; lua_newtable(L); QMapIterator it(pHost->mpMap->rooms); while( it.hasNext() ) { it.next(); lua_pushnumber( L, it.key() ); lua_pushstring( L, it.value()->name.toLatin1().data() ); lua_settable(L, -3); } return 1; } int TLuaInterpreter::getRoomWeight( lua_State *L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( pHost->mpMap->mRoomId ) ) { lua_pushnumber( L, pHost->mpMap->rooms[pHost->mpMap->mRoomId]->weight ); } return 1; } int TLuaInterpreter::gotoRoom( lua_State *L ) { int r; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "gotoRoom: wrong argument type" ); lua_error( L ); return 1; } else { r = lua_tonumber( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; bool ret = pHost->mpMap->gotoRoom( r ); pHost->startSpeedWalk(); lua_pushboolean( L, ret ); return 1; } int TLuaInterpreter::getPath( lua_State *L ) { int r1; int r2; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getPath: wrong argument type" ); lua_error( L ); return 1; } else { r1 = lua_tonumber( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "getPath: wrong argument type" ); lua_error( L ); return 1; } else { r2 = lua_tonumber( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; bool ret = pHost->mpMap->gotoRoom( r1, r2 ); pHost->assemblePath(); lua_pushboolean( L, ret ); return 1; } int TLuaInterpreter::deselect( lua_State *L ) { string luaWindowName=""; if( lua_isstring( L, 1 ) ) { luaWindowName = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString name = luaWindowName.c_str(); if( luaWindowName.size() < 1 || luaWindowName == "main" ) { pHost->mpConsole->deselect(); } else { mudlet::self()->deselect( pHost, name ); } return 0; } int TLuaInterpreter::reset( lua_State *L ) { string luaWindowName=""; if( lua_isstring( L, 1 ) ) { luaWindowName = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString name = luaWindowName.c_str(); if( luaWindowName.size() < 1 || luaWindowName == "main" ) { pHost->mpConsole->reset(); } else { mudlet::self()->resetFormat( pHost, name ); } return 0; } int TLuaInterpreter::hasFocus( lua_State *L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; lua_pushboolean( L, pHost->mpConsole->hasFocus() );//FIXME return 1; } int TLuaInterpreter::echoUserWindow( lua_State *L ) { string luaWindowName=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "echoUserWindow: wrong argument type" ); lua_error( L ); return 1; } else { luaWindowName = lua_tostring( L, 1 ); } string luaSendText=""; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "echoUserWindow: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString text(luaSendText.c_str()); QString windowName(luaWindowName.c_str()); mudlet::self()->echoWindow( pHost, windowName, text ); return 0; } //qApp->setStyleSheet("QMainWindow::separator{border: 0px;width: 0px; height: 0px; padding: 0px;} QMainWindow::separator:hover {background: red;}"); int TLuaInterpreter::setAppStyleSheet( lua_State *L ) { string luaWindowName=""; if( lua_isstring( L, 1 ) ) { luaWindowName = lua_tostring( L, 1 ); } else luaWindowName = "main"; qApp->setStyleSheet( luaWindowName.c_str() ); } // this is an internal only function used by the package system int TLuaInterpreter::showUnzipProgress( lua_State * L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "showUnzipProgress: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } QString txt = luaSendText.c_str(); mudlet::self()->showUnzipProgress( txt ); return 0; } #ifdef Q_OS_LINUX #include #else #include #endif int TLuaInterpreter::playSoundFile( lua_State * L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "playSoundFile: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } QString sound = luaSendText.c_str(); //QSound::play( QString( luaSendText.c_str() ) ); if( QDir::homePath().contains('\\') ) { sound.replace('/', "\\"); } else { sound.replace('\\', "/"); } mudlet::self()->playSound( sound ); return 0; } int TLuaInterpreter::moveCursorEnd( lua_State *L ) { string luaWindowName=""; if( lua_isstring( L, 1 ) ) { luaWindowName = lua_tostring( L, 1 ); } else luaWindowName = "main"; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); if( luaWindowName == "main" ) pHost->mpConsole->moveCursorEnd(); else mudlet::self()->moveCursorEnd( pHost, windowName ); return 0; } int TLuaInterpreter::getLastLineNumber( lua_State *L ) { string luaWindowName; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "getLastLineNumber: wrong argument type" ); lua_error( L ); return 1; } else { luaWindowName = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); int number; if( luaWindowName == "main" ) number = pHost->mpConsole->getLastLineNumber(); else number = mudlet::self()->getLastLineNumber( pHost, windowName ); lua_pushnumber( L, number ); return 1; } int TLuaInterpreter::getMudletHomeDir( lua_State * L ) { QString home = QDir::homePath(); home.append( "/.config/mudlet/profiles/" ); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString name = pHost->getName(); home.append( name ); QString erg = QDir::toNativeSeparators( home ); lua_pushstring( L, erg.toLatin1().data() ); return 1; } int TLuaInterpreter::disconnect( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mTelnet.disconnect(); return 0; } int TLuaInterpreter::reconnect( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mTelnet.connectIt( pHost->getUrl(), pHost->getPort() ); return 0; } int TLuaInterpreter::setTriggerStayOpen( lua_State *L ) { string luaWindowName; double b; int s = 1; if( lua_gettop( L ) > 1 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setTriggerStayOpen: wrong argument type" ); lua_error( L ); return 1; } else { luaWindowName = lua_tostring( L, s ); s++; } } if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "setTriggerStayOpen: wrong argument type" ); lua_error( L ); return 1; } else { b = lua_tonumber( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); pHost->getTriggerUnit()->setTriggerStayOpen( QString( luaWindowName.c_str() ), static_cast(b) ); return 0; } int TLuaInterpreter::setLink( lua_State * L ) { string luaWindowName; string linkText; string linkFunction; string linkHint; int s = 1; if( lua_gettop( L ) > 2 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setLink: wrong argument type" ); lua_error( L ); return 1; } else { luaWindowName = lua_tostring( L, s ); s++; } } /*if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setLink: wrong argument type" ); lua_error( L ); return 1; } else { linkText = lua_tostring( L, s ); s++; }*/ if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setLink: wrong argument type" ); lua_error( L ); return 1; } else { linkFunction = lua_tostring( L, s ); s++; } if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setLink: wrong argument type" ); lua_error( L ); return 1; } else { linkHint = lua_tostring( L, s ); s++; } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); QString _linkText = "";//QString(linkText.c_str()); QStringList _linkFunction; _linkFunction << QString(linkFunction.c_str()); QStringList _linkHint; _linkHint << QString(linkHint.c_str()); if( windowName.size() > 0 ) mudlet::self()->setLink( pHost, windowName, _linkText, _linkFunction, _linkHint ); else pHost->mpConsole->setLink( _linkText, _linkFunction, _linkHint ); return 0; } int TLuaInterpreter::setPopup( lua_State *L ) { string a1 = ""; string a2; QStringList _hintList; QStringList _commandList; bool customFormat = false; int s = 1; int n = lua_gettop( L ); // console name is an optional first argument if( n > 4 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setPopup: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } } if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setPopup: wrong argument type" ); lua_error( L ); return 1; } else { a2 = lua_tostring( L, s ); s++; } if( ! lua_istable( L, s ) ) { lua_pushstring( L, "setPopup: wrong argument type" ); lua_error( L ); return 1; } else { lua_pushnil( L ); while( lua_next( L, s ) != 0 ) { // key at index -2 and value at index -1 if( lua_type(L, -1) == LUA_TSTRING ) { QString cmd = lua_tostring( L, -1 ); _commandList << cmd; } // removes value, but keeps key for next iteration lua_pop(L, 1); } s++; } if( ! lua_istable( L, s ) ) { lua_pushstring( L, "setPopup: wrong argument type" ); lua_error( L ); return 1; } else { lua_pushnil( L ); while( lua_next( L, s ) != 0 ) { // key at index -2 and value at index -1 if( lua_type(L, -1) == LUA_TSTRING ) { QString hint = lua_tostring( L, -1 ); _hintList << hint; } // removes value, but keeps key for next iteration lua_pop(L, 1); } s++; } if( n >= s ) { customFormat = lua_toboolean( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString txt = a2.c_str(); QString name = a1.c_str(); if( _commandList.size() != _hintList.size() ) { lua_pushstring( L, "Error: command list size and hint list size do not match cannot create popup" ); lua_error( L ); return 1; } if( a1 == "" ) { pHost->mpConsole->setLink( txt, _commandList, _hintList ); } else { mudlet::self()->setLink( pHost, name, txt, _commandList, _hintList ); } return 0; } int TLuaInterpreter::setBold( lua_State * L ) { string luaWindowName; bool b; int s = 1; if( lua_gettop( L ) > 1 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setBold: wrong argument type" ); lua_error( L ); return 1; } else { luaWindowName = lua_tostring( L, s ); s++; } } if( ! lua_isboolean( L, s ) ) { lua_pushstring( L, "setBold: wrong argument type" ); lua_error( L ); return 1; } else { b = lua_toboolean( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); if( windowName.size() > 0 ) mudlet::self()->setBold( pHost, windowName, b ); else pHost->mpConsole->setBold( b ); return 0; } int TLuaInterpreter::setItalics( lua_State *L ) { string luaWindowName; bool b; int s = 1; if( lua_gettop( L ) > 1 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setItalics: wrong argument type" ); lua_error( L ); return 1; } else { luaWindowName = lua_tostring( L, s ); s++; } } if( ! lua_isboolean( L, s ) ) { lua_pushstring( L, "setItalics: wrong argument type" ); lua_error( L ); return 1; } else { b = lua_toboolean( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); if( windowName.size() > 0 ) mudlet::self()->setItalics( pHost, windowName, b ); else pHost->mpConsole->setItalics( b ); return 0; } int TLuaInterpreter::setUnderline( lua_State *L ) { string luaWindowName; bool b; int s = 1; if( lua_gettop( L ) > 1 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "setUnderline: wrong argument type" ); lua_error( L ); return 1; } else { luaWindowName = lua_tostring( L, s ); s++; } } if( ! lua_isboolean( L, s ) ) { lua_pushstring( L, "setUnderline: wrong argument type" ); lua_error( L ); return 1; } else { b = lua_toboolean( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); if( windowName.size() > 0 ) mudlet::self()->setUnderline( pHost, windowName, b ); else pHost->mpConsole->setUnderline( b ); return 0; } int TLuaInterpreter::debug( lua_State *L ) { int nbargs = lua_gettop(L); QString luaDebugText=""; for (int i=0; i 1 ? " [" + QString::number(i) + "] " : " ") + lua_tostring( L, i+1 ); } return 0; } int TLuaInterpreter::hideToolBar( lua_State *L ) { string luaWindowName; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "hideToolBar: wrong argument type" ); lua_error( L ); return 1; } else { luaWindowName = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); pHost->getActionUnit()->hideToolBar( windowName ); return 0; } int TLuaInterpreter::showToolBar( lua_State *L ) { string luaWindowName; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "showToolBar: wrong argument type" ); lua_error( L ); return 1; } else { luaWindowName = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString windowName(luaWindowName.c_str()); pHost->getActionUnit()->showToolBar( windowName ); return 0; } int TLuaInterpreter::sendATCP( lua_State *L ) { string msg; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "sendATCP: what do you want to send?" ); lua_error( L ); return 1; } else { msg = lua_tostring( L, 1 ); } string what; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "sendATCP: wrong argument type" ); lua_error( L ); return 1; } else { what = lua_tostring( L, 2 ); } string _h; _h += TN_IAC; _h += TN_SB; _h += 200; _h += msg; if (what != "") { _h += " "; _h += what; } _h += TN_IAC; _h += TN_SE; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mTelnet.socketOutRaw( _h ); return 0; } int TLuaInterpreter::sendGMCP( lua_State *L ) { string msg; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "sendGMCP: what do you want to send?" ); lua_error( L ); return 1; } else { msg = lua_tostring( L, 1 ); } string what; if( lua_isstring( L, 2 ) ) { what = lua_tostring( L, 2 ); } string _h; _h += TN_IAC; _h += TN_SB; _h += GMCP; _h += msg; if( what != "" ) { _h += " "; _h += what; } _h += TN_IAC; _h += TN_SE; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mTelnet.socketOutRaw( _h ); return 0; } int TLuaInterpreter::sendTelnetChannel102( lua_State *L ) { string msg; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "sendTelnetChannel102: wrong argument type" ); lua_error( L ); return 1; } else { msg = lua_tostring( L, 1 ); } string _h; _h += TN_IAC; _h += TN_SB; _h += 102; _h += msg; _h += TN_IAC; _h += TN_SE; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mTelnet.socketOutRaw( _h ); return 0; } int TLuaInterpreter::getButtonState( lua_State *L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; int state; state = pHost->mpConsole->getButtonState(); lua_pushnumber( L, state ); return 1; } int TLuaInterpreter::getNetworkLatency( lua_State *L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; double number; number = pHost->mTelnet.networkLatency; lua_pushnumber( L, number ); return 1; } int TLuaInterpreter::getMainConsoleWidth( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; int fw = QFontMetrics(pHost->mDisplayFont).width("W"); fw *= pHost->mWrapAt + 1; lua_pushnumber( L, fw ); return 1; } int TLuaInterpreter::getMainWindowSize( lua_State *L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QSize mainWindowSize = pHost->mpConsole->getMainWindowSize(); lua_pushnumber( L, mainWindowSize.width() ); lua_pushnumber( L, mainWindowSize.height() ); return 2; } // tempTimer(int session, float seconds, string function to call, string name) // one shot timer. int TLuaInterpreter::tempTimer( lua_State *L ) { double luaTimeout; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "tempTimer: wrong argument type" ); lua_error( L ); return 1; } else { luaTimeout = lua_tonumber( L, 1 ); } string luaFunction; if( lua_isfunction( L, 2 ) ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _fun; int timerID = pLuaInterpreter->startTempTimer( luaTimeout, _fun ); TTimer * pT = pHost->getTimerUnit()->getTimer( timerID ); pT->mRegisteredAnonymousLuaFunction = true; lua_pushlightuserdata( L, pT ); lua_pushvalue( L, 2 ); lua_settable( L, LUA_REGISTRYINDEX ); lua_pushnumber( L, timerID ); return 1; } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "tempTimer: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _fun = luaFunction.c_str(); int timerID = pLuaInterpreter->startTempTimer( luaTimeout, _fun ); lua_pushnumber( L, timerID ); return 1; } int TLuaInterpreter::tempExactMatchTrigger( lua_State *L ) { string luaRegex; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "tempTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaRegex = lua_tostring( L, 1 ); } string luaFunction; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "tempTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _reg = luaRegex.c_str(); QString _fun = luaFunction.c_str(); int timerID = pLuaInterpreter->startTempExactMatchTrigger( _reg, _fun ); lua_pushnumber( L, timerID ); return 1; } int TLuaInterpreter::tempBeginOfLineTrigger( lua_State *L ) { string luaRegex; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "tempTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaRegex = lua_tostring( L, 1 ); } string luaFunction; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "tempTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _reg = luaRegex.c_str(); QString _fun = luaFunction.c_str(); int timerID = pLuaInterpreter->startTempBeginOfLineTrigger( _reg, _fun ); lua_pushnumber( L, timerID ); return 1; } // tempTrigger( string regex, string function to call ) // one shot timer. int TLuaInterpreter::tempTrigger( lua_State *L ) { string luaRegex; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "tempTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaRegex = lua_tostring( L, 1 ); } string luaFunction; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "tempTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _reg = luaRegex.c_str(); QString _fun = luaFunction.c_str(); int timerID = pLuaInterpreter->startTempTrigger( _reg, _fun ); lua_pushnumber( L, timerID ); //lua_pushstring( L, _reg.toLatin1().data()); return 1; } // temporary color trigger. args: ansiFGColorCode, ansiBgColorCode, luaCode int TLuaInterpreter::tempColorTrigger( lua_State *L ) { int luaFrom; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "tempColorTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFrom = lua_tointeger( L, 1 ); } int luaTo; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "tempColorTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaTo = lua_tointeger( L, 2 ); } string luaFunction; if( ! lua_isstring( L, 3 ) ) { lua_pushstring( L, "tempColorTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 3 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _fun = luaFunction.c_str(); int timerID = pLuaInterpreter->startTempColorTrigger( luaFrom, luaTo, _fun ); lua_pushnumber( L, timerID ); return 1; } // triggerID = tempLineTrigger( from, howmany, func ) int TLuaInterpreter::tempLineTrigger( lua_State *L ) { int luaFrom; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "tempLineTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFrom = lua_tointeger( L, 1 ); } int luaTo; if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "tempLineTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaTo = lua_tointeger( L, 2 ); } string luaFunction; if( ! lua_isstring( L, 3 ) ) { lua_pushstring( L, "tempLineTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 3 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _fun = luaFunction.c_str(); int timerID = pLuaInterpreter->startTempLineTrigger( luaFrom, luaTo, _fun ); lua_pushnumber( L, timerID ); return 1; } // tempTrigger( string name, string regex, string function to call, multiline, fg, bg, filter, match all(perlSlashG), highlight, // play sound, fire length(mStayOpen), lineDelta). int TLuaInterpreter::tempComplexRegexTrigger( lua_State *L ) { bool multiLine, matchAll, highlight, playSound, filter, colorTrigger; int fireLength, lineDelta; QString fgColor, bgColor; QStringList regexList; QString script, parent, pattern, soundFile; QColor hlFgColor, hlBgColor; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "tempComplexRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { parent = lua_tostring( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "tempComplexRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { pattern = lua_tostring( L, 2 ); } if( ! lua_isstring( L, 3 ) ) { lua_pushstring( L, "tempComplexRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { script = lua_tostring( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "tempComplexRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { multiLine = lua_tonumber( L, 4 ); } if( lua_isnumber( L, 5 ) ) { colorTrigger = false; } else { colorTrigger = true; fgColor = lua_tostring( L, 5 ); } if( lua_isnumber( L, 6 ) ) { colorTrigger = false; } else { bgColor = lua_tostring( L, 6 ); } if( ! lua_isnumber( L, 7 ) ) { lua_pushstring( L, "tempComplexRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { filter = lua_tonumber( L, 7 ); } if( ! lua_isnumber( L, 8 ) ) { lua_pushstring( L, "tempComplexRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { matchAll = lua_tonumber( L, 8 ); } if(lua_isnumber( L, 9 ) ) { highlight = false; } else { highlight = true; hlFgColor.setNamedColor(lua_tostring( L, 9 )); } if(lua_isnumber( L, 9 ) ) { highlight = false; } else { highlight = true; hlBgColor.setNamedColor(lua_tostring( L, 9 )); } //lineDelta). if(lua_isnumber( L, 10 ) ) { playSound = false; } else { playSound = true; soundFile = lua_tostring( L, 10 ); } if( ! lua_isnumber( L, 11 ) ) { lua_pushstring( L, "tempComplexRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { fireLength = lua_tonumber( L, 11 ); } if( ! lua_isnumber( L, 12 ) ) { lua_pushstring( L, "tempComplexRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { lineDelta = lua_tonumber( L, 12 ); } Host * mpHost = TLuaInterpreter::luaInterpreterMap[L]; //TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); //mpHost = pLuaInterpreter->mpHost; TTrigger * pT; QList propertyList; TTrigger * pP = mpHost->getTriggerUnit()->findTrigger( parent ); if( !pP ) { regexList << pattern; if (colorTrigger) propertyList << REGEX_COLOR_PATTERN; else propertyList << REGEX_PERL; } else{ regexList = pP->getRegexCodeList(); propertyList = pP->getRegexCodePropertyList(); } pT = new TTrigger( "a", regexList, propertyList, multiLine, mpHost ); //pT->setRegexCodeList( regexList, propertyList ); pT->setIsFolder( 0 ); pT->setIsActive( true ); pT->setIsTempTrigger( true ); pT->registerTrigger(); pT->setScript( script ); pT->setName( pattern ); //pT->setIsMultiline( multiLine ); pT->mPerlSlashGOption = matchAll;//match all pT->mFilterTrigger = filter; pT->setConditionLineDelta( lineDelta );//line delta pT->mStayOpen = fireLength;//fire length pT->mSoundTrigger = playSound;//sound trigger, need to set sound file if true if (playSound){ pT->setSound(soundFile); } pT->setIsColorizerTrigger(highlight); //highlight if (highlight){ pT->setFgColor( hlFgColor ); pT->setBgColor( hlBgColor ); } //lua_pushnumber( L, pT->getID() ); lua_pushstring( L, pattern.toLatin1().data()); return 1; } int TLuaInterpreter::tempButton( lua_State *L){ //args: parent, name, orientation QString toolbar, name; QString cmdButtonUp = ""; QString cmdButtonDown = ""; QString script = ""; QStringList nameL; nameL << toolbar; int orientation; if(!lua_isstring( L, 1 ) ) { lua_pushstring( L, "tempButtonToolbar: wrong first arg" ); lua_error( L ); return 1; } else { toolbar = lua_tostring( L, 1 ); } if(!lua_isstring( L, 2 ) ) { lua_pushstring( L, "tempButtonToolbar: wrong 2nd arg" ); lua_error( L ); return 1; } else { name = lua_tostring( L, 2 ); } if(!lua_isnumber( L, 3 ) ) { lua_pushstring( L, "tempButtonToolbar: wrong first arg" ); lua_error( L ); return 1; } else { orientation = lua_tonumber( L, 3 ); } Host * mpHost = TLuaInterpreter::luaInterpreterMap[L]; TAction * pP = mpHost->getActionUnit()->findAction( toolbar ); if (!pP) return 0; TAction * pT = mpHost->getActionUnit()->findAction( name ); if (pT) return 0; pT = new TAction( pP, mpHost ); pT->setName( name ); pT->setCommandButtonUp( cmdButtonUp ); pT->setCommandButtonDown( cmdButtonDown ); pT->setIsPushDownButton( false ); pT->mLocation = pP->mLocation; pT->mOrientation = orientation; pT->setScript( script ); pT->setIsFolder( false ); pT->setIsActive( true ); // pT->setIsPushDownButton( isChecked ); // pT->mLocation = location; // pT->mOrientation = orientation; // pT->setIsActive( pT->shouldBeActive() ); // pT->setButtonColor( color ); // pT->setButtonRotation( rotation ); // pT->setButtonColumns( columns ); //// pT->setButtonFlat( flatButton ); // pT->mUseCustomLayout = useCustomLayout; // pT->mPosX = posX; // pT->mPosY = posY; // pT->mSizeX = sizeX; // pT->mSizeY = sizeY; // pT->css = mpActionsMainArea->css->toPlainText(); pT->registerAction(); int childID = pT->getID(); mpHost->getActionUnit()->updateToolbar(); return 1; } int TLuaInterpreter::tempButtonToolbar( lua_State *L ) {//args: name, location(0-4), orientation(0/1) QString name; QString cmdButtonUp = ""; QString cmdButtonDown = ""; QString script = ""; QStringList nameL; nameL << name; int location, orientation; if(!lua_isstring( L, 1 ) ) { lua_pushstring( L, "tempButtonToolbar: wrong first arg" ); lua_error( L ); return 1; } else { name = lua_tostring( L, 1 ); } if(!lua_isnumber( L, 2 ) ) { lua_pushstring( L, "tempButtonToolbar: wrong first arg" ); lua_error( L ); return 1; } else { location = lua_tonumber( L, 2 ); } if(!lua_isnumber( L, 3 ) ) { lua_pushstring( L, "tempButtonToolbar: wrong first arg" ); lua_error( L ); return 1; } else { orientation = lua_tonumber( L, 3 ); } if( location > 0 ) location++; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TAction * pT = pHost->getActionUnit()->findAction( name ); if (pT) return 0; //insert a new root item //ROOT_ACTION: pT = new TAction( name, pHost ); pT->setCommandButtonUp( cmdButtonUp ); QStringList nl; nl << name; pT->setName( name ); pT->setCommandButtonUp( cmdButtonUp ); pT->setCommandButtonDown( cmdButtonDown ); pT->setIsPushDownButton( false ); pT->mLocation = location; pT->mOrientation = orientation; pT->setScript( script ); pT->setIsFolder( true ); pT->setIsActive( true ); pT->registerAction(); int childID = pT->getID(); pHost->getActionUnit()->updateToolbar(); return 1; } // tempTrigger( string regex, string function to call ) // one shot timer. int TLuaInterpreter::tempRegexTrigger( lua_State *L ) { string luaRegex; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "tempRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaRegex = lua_tostring( L, 1 ); } string luaFunction; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "tempRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _luaFunction = luaFunction.c_str(); QString _luaRegex = luaRegex.c_str(); int timerID = pLuaInterpreter->startTempRegexTrigger( _luaRegex, _luaFunction ); lua_pushnumber( L, timerID ); return 1; } int TLuaInterpreter::tempAlias( lua_State *L ) { string luaRegex; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "tempAlias: wrong argument type" ); lua_error( L ); return 1; } else { luaRegex = lua_tostring( L, 1 ); } string luaFunction; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "tempAlias: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _luaFunction = luaFunction.c_str(); QString _luaRegex = luaRegex.c_str(); int timerID = pLuaInterpreter->startTempAlias( _luaRegex, _luaFunction ); lua_pushnumber( L, timerID ); return 1; } int TLuaInterpreter::exists( lua_State * L ) { string _name; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "exists: wrong argument type" ); lua_error( L ); return 1; } else { _name = lua_tostring( L, 1 ); } string _type; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "exists: wrong argument type" ); lua_error( L ); return 1; } else { _type = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; int cnt = 0; QString type = _type.c_str(); type = type.toLower(); QString name = _name.c_str(); if( type == "timer") { QMap::const_iterator it1 = pHost->getTimerUnit()->mLookupTable.find( name ); while( it1 != pHost->getTimerUnit()->mLookupTable.end() && it1.key() == name ) { cnt++; it1++; } } else if( type == "trigger") { QMap::const_iterator it1 = pHost->getTriggerUnit()->mLookupTable.find( name ); while( it1 != pHost->getTriggerUnit()->mLookupTable.end() && it1.key() == name ) { cnt++; it1++; } } else if( type == "alias") { QMap::const_iterator it1 = pHost->getAliasUnit()->mLookupTable.find( name ); while( it1 != pHost->getAliasUnit()->mLookupTable.end() && it1.key() == name ) { cnt++; it1++; } } lua_pushnumber( L, cnt ); return 1; } int TLuaInterpreter::isActive( lua_State * L ) { string _name; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "isActive: wrong argument type" ); lua_error( L ); return 1; } else { _name = lua_tostring( L, 1 ); } string _type; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "isActive: wrong argument type" ); lua_error( L ); return 1; } else { _type = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; int cnt = 0; QString type = _type.c_str(); type = type.toLower(); QString name = _name.c_str(); if( type == "timer") { QMap::const_iterator it1 = pHost->getTimerUnit()->mLookupTable.find( name ); while( it1 != pHost->getTimerUnit()->mLookupTable.end() && it1.key() == name ) { if( it1.value()->isActive() ) { cnt++; } it1++; } } else if( type == "trigger") { QMap::const_iterator it1 = pHost->getTriggerUnit()->mLookupTable.find( name ); while( it1 != pHost->getTriggerUnit()->mLookupTable.end() && it1.key() == name ) { if( it1.value()->isActive() ) { cnt++; } it1++; } } else if( type == "alias") { QMap::const_iterator it1 = pHost->getAliasUnit()->mLookupTable.find( name ); while( it1 != pHost->getAliasUnit()->mLookupTable.end() && it1.key() == name ) { if( it1.value()->isActive() ) { cnt++; } it1++; } } lua_pushnumber( L, cnt ); return 1; } int TLuaInterpreter::permAlias( lua_State *L ) { string luaName; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "permAlias: need a name for this alias" ); lua_error( L ); return 1; } else { luaName = lua_tostring( L, 1 ); } string luaParent; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "permAlias: need a parent alias/group to add this alias to" ); lua_error( L ); return 1; } else { luaParent = lua_tostring( L, 2 ); } string luaRegex; if( ! lua_isstring( L, 3 ) ) { lua_pushstring( L, "permAlias: need the pattern for the alias" ); lua_error( L ); return 1; } else { luaRegex = lua_tostring( L, 3 ); } string luaFunction; if( ! lua_isstring( L, 4 ) ) { lua_pushstring( L, "permAlias: need Lua code for this alias" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 4 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _luaName = luaName.c_str(); QString _luaParent = luaParent.c_str(); QString _luaFunction = luaFunction.c_str(); QString _luaRegex = luaRegex.c_str(); int aliasID = pLuaInterpreter->startPermAlias( _luaName, _luaParent, _luaRegex, _luaFunction ); lua_pushnumber( L, aliasID ); return 1; } int TLuaInterpreter::permTimer( lua_State * L ) { string luaName; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "permTimer: wrong argument type" ); lua_error( L ); return 1; } else { luaName = lua_tostring( L, 1 ); } string luaParent; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "permTimer: wrong argument type" ); lua_error( L ); return 1; } else { luaParent = lua_tostring( L, 2 ); } double luaTimeout; if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "permTimer: wrong argument type" ); lua_error( L ); return 1; } else { luaTimeout = lua_tonumber( L, 3 ); } string luaFunction; if( ! lua_isstring( L, 4 ) ) { lua_pushstring( L, "permTimer: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 4 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _name = luaName.c_str(); QString _parent = luaParent.c_str(); QString _fun = luaFunction.c_str(); int timerID = pLuaInterpreter->startPermTimer( _name, _parent, luaTimeout, _fun ); lua_pushnumber( L, timerID ); return 1; } int TLuaInterpreter::permSubstringTrigger( lua_State * L ) { string name; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "permSubstringTrigger: wrong argument type" ); lua_error( L ); return 1; } else { name = lua_tostring( L, 1 ); } string parent; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "permSubstringTrigger: wrong argument type" ); lua_error( L ); return 1; } else { parent = lua_tostring( L, 2 ); } QStringList _regList; if( ! lua_istable( L, 3 ) ) { lua_pushstring( L, "permSubstringTrigger: wrong argument type" ); lua_error( L ); return 1; } else { lua_pushnil( L ); while( lua_next( L, 3 ) != 0 ) { // key at index -2 and value at index -1 if( lua_type(L, -1) == LUA_TSTRING ) { QString regex = lua_tostring( L, -1 ); _regList << regex; } // removes value, but keeps key for next iteration lua_pop(L, 1); } } string luaFunction; if( ! lua_isstring( L, 4 ) ) { lua_pushstring( L, "permSubstringTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 4 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _name = name.c_str(); QString _parent = parent.c_str(); QString _luaFunction = luaFunction.c_str(); int ret = pLuaInterpreter->startPermSubstringTrigger( _name, _parent, _regList, _luaFunction ); lua_pushnumber( L, ret ); return 1; } int TLuaInterpreter::permBeginOfLineStringTrigger( lua_State * L ) { string name; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "permBeginOfLineStringTrigger: wrong argument type" ); lua_error( L ); return 1; } else { name = lua_tostring( L, 1 ); } string parent; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "permBeginOfLineStringTrigger: wrong argument type" ); lua_error( L ); return 1; } else { parent = lua_tostring( L, 2 ); } QStringList _regList; if( ! lua_istable( L, 3 ) ) { lua_pushstring( L, "permBeginOfLineStringTrigger: wrong argument type" ); lua_error( L ); return 1; } else { lua_pushnil( L ); while( lua_next( L, 3 ) != 0 ) { // key at index -2 and value at index -1 if( lua_type(L, -1) == LUA_TSTRING ) { QString regex = lua_tostring( L, -1 ); _regList << regex; } // removes value, but keeps key for next iteration lua_pop(L, 1); } } string luaFunction; if( ! lua_isstring( L, 4 ) ) { lua_pushstring( L, "permBeginOfLineStringTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 4 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _name = name.c_str(); QString _parent = parent.c_str(); QString _luaFunction = luaFunction.c_str(); int ret = pLuaInterpreter->startPermBeginOfLineStringTrigger( _name, _parent, _regList, _luaFunction ); lua_pushnumber( L, ret ); return 1; } int TLuaInterpreter::permRegexTrigger( lua_State *L ) { string name; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "permRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { name = lua_tostring( L, 1 ); } string parent; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "permRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { parent = lua_tostring( L, 2 ); } QStringList _regList; if( ! lua_istable( L, 3 ) ) { lua_pushstring( L, "permRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { lua_pushnil( L ); while( lua_next( L, 3 ) != 0 ) { // key at index -2 and value at index -1 if( lua_type(L, -1) == LUA_TSTRING ) { QString regex = lua_tostring( L, -1 ); _regList << regex; } // removes value, but keeps key for next iteration lua_pop(L, 1); } } string luaFunction; if( ! lua_isstring( L, 4 ) ) { lua_pushstring( L, "permRegexTrigger: wrong argument type" ); lua_error( L ); return 1; } else { luaFunction = lua_tostring( L, 4 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; TLuaInterpreter * pLuaInterpreter = pHost->getLuaInterpreter(); QString _name = name.c_str(); QString _parent = parent.c_str(); QString _luaFunction = luaFunction.c_str(); int ret = pLuaInterpreter->startPermRegexTrigger( _name, _parent, _regList, _luaFunction ); lua_pushnumber( L, ret ); return 1; } #include int TLuaInterpreter::invokeFileDialog( lua_State * L ) { bool luaDir = false; //default is to chose a directory if( ! lua_isboolean( L, 1 ) ) { lua_pushstring( L, "invokeFileDialog: wrong argument type" ); lua_error( L ); return 1; } else { luaDir = lua_toboolean( L, 1 ); } string luaTitle; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "invokeFileDialog: wrong argument type" ); lua_error( L ); return 1; } else { luaTitle = lua_tostring( L, 2 ); } if( ! luaDir ) { QString fileName = QFileDialog::getExistingDirectory(0, QString( luaTitle.c_str()), QDir::currentPath() ); lua_pushstring( L, fileName.toLatin1().data() ); return 1; } else { QString fileName = QFileDialog::getOpenFileName(0, QString( luaTitle.c_str()), QDir::currentPath() ); lua_pushstring( L, fileName.toLatin1().data() ); return 1; } } int TLuaInterpreter::getTimestamp( lua_State * L ) { int luaLine; int args = lua_gettop( L ); int n = 1; string name = ""; if( args < 1 ) { return 0; } if( args == 2 ) { if( lua_isstring( L, n ) ) { name = lua_tostring( L, n ); n++; } } if( ! lua_isnumber( L, n ) ) { lua_pushstring( L, "getTimestamp: wrong argument type" ); lua_error( L ); return 1; } else { luaLine = lua_tointeger( L, n ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( name == "" ) { if( luaLine > 0 && luaLine < pHost->mpConsole->buffer.timeBuffer.size() ) { lua_pushstring( L, pHost->mpConsole->buffer.timeBuffer.at(luaLine).toLatin1().data() ); } else { lua_pushstring( L, "getTimestamp: invalid line number"); } return 1; } QString _name = name.c_str(); QMap & dockWindowConsoleMap = mudlet::self()->mHostConsoleMap[pHost]; if( dockWindowConsoleMap.contains( _name ) ) { TConsole * pC = dockWindowConsoleMap[_name]; if( luaLine > 0 && luaLine < pC->buffer.timeBuffer.size() ) { lua_pushstring( L, pC->buffer.timeBuffer.at(luaLine).toLatin1().data() ); } else { lua_pushstring( L, "getTimestamp: invalid line number"); } return 1; } return 0; } int TLuaInterpreter::setBorderColor( lua_State *L ) { int luaRed; int luaGreen; int luaBlue; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setBorderColor: wrong argument type" ); lua_error( L ); return 1; } else { luaRed = lua_tointeger( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setBorderColor: wrong argument type" ); lua_error( L ); return 1; } else { luaGreen=lua_tointeger( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "setBorderColor: wrong argument type" ); lua_error( L ); return 1; } else { luaBlue = lua_tointeger( L, 3 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QPalette framePalette; framePalette.setColor( QPalette::Text, QColor(0,0,0) ); framePalette.setColor( QPalette::Highlight, QColor(55,55,255) ); framePalette.setColor( QPalette::Window, QColor( luaRed, luaGreen, luaBlue, 255 ) ); pHost->mpConsole->mpMainFrame->setPalette( framePalette ); return 0; } int TLuaInterpreter::setRoomCoordinates( lua_State *L ) { int id; int x; int y; int z; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setRoomCoordinates: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setRoomCoordinates: wrong argument type" ); lua_error( L ); return 1; } else { x = lua_tointeger( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "setRoomCoordinates: wrong argument type" ); lua_error( L ); return 1; } else { y = lua_tointeger( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "setRoomCoordinates: wrong argument type" ); lua_error( L ); return 1; } else { z = lua_tointeger( L, 4 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; lua_pushboolean(L, pHost->mpMap->setRoomCoordinates( id, x, y, z ) ); return 1; } int TLuaInterpreter::setCustomEnvColor( lua_State *L ) { int id; int r; int g; int b; int alpha; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setCustomEnvColor: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setCustomEnvColor: wrong argument type" ); lua_error( L ); return 1; } else { r = lua_tointeger( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "setCustomEnvColor: wrong argument type" ); lua_error( L ); return 1; } else { g = lua_tointeger( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "setCustomEnvColor: wrong argument type" ); lua_error( L ); return 1; } else { b = lua_tointeger( L, 4 ); } if( ! lua_isnumber( L, 5 ) ) { lua_pushstring( L, "setCustomEnvColor: wrong argument type" ); lua_error( L ); return 1; } else { alpha = lua_tointeger( L, 5 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpMap->customEnvColors[id] = QColor( r,g,b,alpha ); return 0; } int TLuaInterpreter::setAreaName( lua_State *L ) { int id; string name; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setAreaName: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setAreaName: wrong argument type" ); lua_error( L ); return 1; } else { name = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString _name = name.c_str(); pHost->mpMap->areaNamesMap[id] = _name; return 0; } int TLuaInterpreter::getRoomAreaName( lua_State *L ) { int id; string name; bool gotString = false; if( ! lua_isnumber( L, 1 ) ) { if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "getRoomAreaName: wrong argument type" ); lua_error( L ); return 1; } else { name = lua_tostring( L, 1 ); gotString = true; } } else { id = lua_tonumber( L, 1 ); } QString _name = name.c_str(); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( gotString ) { QList idList = pHost->mpMap->areaNamesMap.keys( _name ); if( idList.size() > 0 ) { lua_pushnumber( L, idList[0] ); return 1; } else { lua_pushnumber( L, -1 ); return 1; } } else { if( pHost->mpMap->areaNamesMap.contains( id ) ) { lua_pushstring( L, pHost->mpMap->areaNamesMap[id].toLatin1().data() ); } else lua_pushnumber( L, -1 ); return 1; } } int TLuaInterpreter::addAreaName( lua_State *L ) { int id; string name; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "addAreaName: wrong argument type" ); lua_error( L ); return 1; } else { name = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString _name = name.c_str(); id = pHost->mpMap->areaNamesMap.size()+1; if( ! pHost->mpMap->areaNamesMap.values().contains( _name ) ) { while( pHost->mpMap->areaNamesMap.contains( id ) ) { id++; } pHost->mpMap->areaNamesMap[id] = _name; pHost->mpMap->buildAreas(); if( pHost->mpMap->mpMapper ) { pHost->mpMap->mpMapper->showArea->clear(); QMapIterator it( pHost->mpMap->areaNamesMap ); //sort them alphabetically (case sensitive) QMap areaNames; while( it.hasNext() ) { it.next(); QString name = it.value(); areaNames.insert(name.toLower(), name); } QMapIterator areaIt( areaNames ); while( areaIt.hasNext() ) { areaIt.next(); pHost->mpMap->mpMapper->showArea->addItem( areaIt.value() ); } } lua_pushnumber( L, id ); } else lua_pushnumber( L, -1 ); return 1; } int TLuaInterpreter::deleteArea( lua_State *L ) { int id = -1; string name; if( lua_isnumber( L, 1 ) ) { id = lua_tonumber( L, 1 ); if( id == -1 ) return 0; } else if( lua_isstring( L, 1 ) ) { name = lua_tostring( L, 1 ); } else { lua_pushstring( L, "deleteArea: wrong argument type" ); lua_error( L ); return 1; } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( id == -1 ) { QString _name = name.c_str(); if( pHost->mpMap->areaNamesMap.values().contains( _name ) ) { pHost->mpMap->deleteArea( pHost->mpMap->areaNamesMap.key(_name) ); pHost->mpMap->mMapGraphNeedsUpdate = false; pHost->mpMap->areaNamesMap.remove( pHost->mpMap->areaNamesMap.key(_name) ); } else pHost->mpMap->areaNamesMap.remove( pHost->mpMap->areaNamesMap.key(_name) ); } else { if( pHost->mpMap->areas.contains( id ) ) { pHost->mpMap->deleteArea( id ); pHost->mpMap->mMapGraphNeedsUpdate = false; pHost->mpMap->areaNamesMap.remove( id ); } else pHost->mpMap->areaNamesMap.remove( id ); } return 0; } int TLuaInterpreter::deleteRoom( lua_State *L ) { int id; if( lua_isnumber( L, 1 ) ) { id = lua_tonumber( L, 1 ); if( id <= 0 ) return 0; } else { lua_pushstring( L, "addAreaName: wrong argument type" ); lua_error( L ); return 1; } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { pHost->mpMap->deleteRoom( id ); pHost->mpMap->mMapGraphNeedsUpdate = false; } return 0; } int TLuaInterpreter::setExit( lua_State *L ) { int from, to; int dir; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setExit: wrong argument type" ); lua_error( L ); return 1; } else { from = lua_tointeger( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setExit: wrong argument type" ); lua_error( L ); return 1; } else { to = lua_tointeger( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "setExit: wrong argument type" ); lua_error( L ); return 1; } else { dir = lua_tointeger( L, 3 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; lua_pushboolean(L, pHost->mpMap->setExit( from, to, dir ) ); pHost->mpMap->mMapGraphNeedsUpdate = true; return 1; } int TLuaInterpreter::getRoomCoordinates( lua_State * L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getRoomCoordinates: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( ! pHost->mpMap->rooms.contains( id ) ) { lua_pushnil( L ); lua_pushnil( L ); lua_pushnil( L ); return 3; } lua_pushnumber( L, pHost->mpMap->rooms[id]->x ); lua_pushnumber( L, pHost->mpMap->rooms[id]->y ); lua_pushnumber( L, pHost->mpMap->rooms[id]->z ); return 3; } int TLuaInterpreter::getRoomArea( lua_State * L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getRoomArea: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( ! pHost->mpMap->rooms.contains( id ) ) { lua_pushnil(L); return 1; } lua_pushnumber( L, pHost->mpMap->rooms[id]->area ); return 1; } int TLuaInterpreter::roomExists( lua_State * L ) { int id; if( ! lua_isnumber( L, 1 ) || ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "roomExists: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id ) ) { lua_pushboolean( L, 1 ); return 1; } lua_pushboolean( L, 0 ); return 1; } int TLuaInterpreter::addRoom( lua_State * L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getRoomArea: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; lua_pushboolean( L, pHost->mpMap->addRoom( id ) ); pHost->mpMap->mMapGraphNeedsUpdate = true; return 1; } int TLuaInterpreter::createRoomID( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; lua_pushnumber( L, pHost->mpMap->createNewRoomID() ); return 1; } int TLuaInterpreter::unHighlightRoom( lua_State * L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( ! pHost->mpMap->rooms.contains( id ) ) return 0; pHost->mpMap->rooms[id]->highlight = false; if( pHost->mpMap ) if( pHost->mpMap->mpMapper ) pHost->mpMap->mpMapper->mp2dMap->update(); return 0; } // highlightRoom( roomID, colorRed, colorGreen, colorBlue, col2Red, col2Green, col2Blue, (float)highlightRadius, alphaColor1, alphaColor2 ) int TLuaInterpreter::highlightRoom( lua_State * L ) { int id, fgr, fgg, fgb, bgr, bgg, bgb; float radius; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { fgr = lua_tointeger( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { fgg = lua_tointeger( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { fgb = lua_tointeger( L, 4 ); } if( ! lua_isnumber( L, 5 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { bgr = lua_tointeger( L, 5 ); } if( ! lua_isnumber( L, 6 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { bgg = lua_tointeger( L, 6 ); } if( ! lua_isnumber( L, 7 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { bgb = lua_tointeger( L, 7 ); } if( ! lua_isnumber( L, 8 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { radius = lua_tonumber( L, 8 ); } int alpha1, alpha2; if( ! lua_isnumber( L, 9 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { alpha1 = lua_tointeger( L, 9 ); } if( ! lua_isnumber( L, 10 ) ) { lua_pushstring( L, "highlightRoom: wrong argument type" ); lua_error( L ); return 1; } else { alpha2 = lua_tointeger( L, 10 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( !pHost->mpMap ) return 0; if( ! pHost->mpMap->rooms.contains( id ) ) return 0; QColor fg = QColor(fgr,fgg,fgb,alpha1); QColor bg = QColor(bgr,bgg,bgb,alpha2); pHost->mpMap->rooms[id]->highlight = true; pHost->mpMap->rooms[id]->highlightColor = fg; pHost->mpMap->rooms[id]->highlightColor2 = bg; pHost->mpMap->rooms[id]->highlightRadius = radius; if( pHost->mpMap->mpMapper ) if( pHost->mpMap->mpMapper->mp2dMap ) pHost->mpMap->mpMapper->mp2dMap->update(); return 0; } //SYNTAX: int labelID = createMapLabel( int area, string text, float posx, float posy, int fgRed, int fgGreen, int fgBlue, bgRed, int bgGreen, int bgBlue, bool showOnTop=true, bool noScaling=true ) int TLuaInterpreter::createMapLabel( lua_State * L ) { int area, fgr, fgg, fgb, bgr, bgg, bgb; float posx, posy, posz; int fontSize = 50; float zoom = 30.0; string text; bool showOnTop = true; bool noScaling = true; int args = lua_gettop(L); if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { area = lua_tointeger( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { text = lua_tostring( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { posx = lua_tonumber( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { posy = lua_tonumber( L, 4 ); } if( ! lua_isnumber( L, 5 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { posz = lua_tonumber( L, 5 ); } if( ! lua_isnumber( L, 6 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { fgr = lua_tointeger( L, 6 ); } if( ! lua_isnumber( L, 7 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { fgg = lua_tointeger( L, 7 ); } if( ! lua_isnumber( L, 8 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { fgb = lua_tointeger( L, 8 ); } if( ! lua_isnumber( L, 9 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { bgr = lua_tointeger( L, 9 ); } if( ! lua_isnumber( L, 10 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { bgg = lua_tointeger( L, 10 ); } if( ! lua_isnumber( L, 11 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { bgb = lua_tointeger( L, 11 ); } if( args > 11 ) { if( ! lua_isnumber( L, 12 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { zoom = lua_tonumber( L, 12 ); } if( ! lua_isnumber( L, 13 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { fontSize = lua_tointeger( L, 13 ); } if( args > 13 ) { if( ! lua_isboolean( L, 14 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { showOnTop = lua_toboolean( L, 14 ); } } if( args > 14 ) { if( ! lua_isboolean( L, 15 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { noScaling = lua_toboolean( L, 15 ); } } } QString _text = text.c_str(); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QColor fg = QColor(fgr,fgg,fgb); QColor bg = QColor(bgr, bgg, bgb); lua_pushinteger( L, pHost->mpMap->createMapLabel( area, _text, posx, posy, posz, fg, bg, showOnTop, noScaling, zoom, fontSize ) ); return 1; } int TLuaInterpreter::setMapZoom( lua_State * L ) { int zoom = 3; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { zoom = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap ) if( pHost->mpMap->mpMapper ) if( pHost->mpMap->mpMapper->mp2dMap ) pHost->mpMap->mpMapper->mp2dMap->setMapZoom( zoom ); return 0; } //SYNTAX: int labelID = createMapImageLabel( int area, string filePath, float posx, float posy, float posz, float width, float height, float zoom, bool showOnTop=true ) int TLuaInterpreter::createMapImageLabel( lua_State * L ) { int area; float posx, posy, posz, width, height, zoom; string text; bool showOnTop = true; int args = lua_gettop(L); if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { area = lua_tointeger( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { text = lua_tostring( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { posx = lua_tonumber( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { posy = lua_tonumber( L, 4 ); } if( ! lua_isnumber( L, 5 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { posz = lua_tonumber( L, 5 ); } if( ! lua_isnumber( L, 6 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { width = lua_tonumber( L, 6 ); } if( ! lua_isnumber( L, 7 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { height = lua_tonumber( L, 7 ); } if( ! lua_isnumber( L, 8 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { zoom = lua_tonumber( L, 8 ); } if( ! lua_isboolean( L, 9 ) ) { lua_pushstring( L, "createMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { showOnTop = lua_toboolean( L, 9 ); } QString _text = text.c_str(); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; lua_pushinteger( L, pHost->mpMap->createMapImageLabel( area, _text, posx, posy, posz, width, height, zoom, showOnTop, false ) ); return 1; } //SYNTAX: setDoor( roomID, exitCommand, doorStatus ) status: 0=no door, 1=open, 2=closed, 3=locked // to remove a door set doorStatus = 0 int TLuaInterpreter::setDoor( lua_State * L ) { int roomID; int doorStatus; //0= no door, 1=open, 2=closed, 3=locked string exitCmd; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setDoor: wrong argument type" ); lua_error( L ); return 1; } else { roomID = lua_tointeger( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setDoor: wrong argument type" ); lua_error( L ); return 1; } else { exitCmd = lua_tostring( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "roomID: wrong argument type" ); lua_error( L ); return 1; } else { doorStatus = lua_tonumber( L, 3 ); } QString exit = exitCmd.c_str(); exit = exit.toLower(); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap ) { if( pHost->mpMap->rooms.contains(roomID) ) { TRoom * pR = pHost->mpMap->rooms[roomID]; if( doorStatus == 0 ) pR->doors.remove( exit ); else pR->doors[exit] = doorStatus; if( pHost->mpMap->mpMapper ) if( pHost->mpMap->mpMapper->mp2dMap ) pHost->mpMap->mpMapper->mp2dMap->update(); } } return 0; } //SYNTAX: doors table = getDoors( roomID ) int TLuaInterpreter::getDoors( lua_State * L ) { int roomID; if( ! lua_isnumber( L, 1 ) ) { lua_pushfstring( L, "getDoors: bad argument #1 (room ID as number expected, got %s)", luaL_typename(L, 1) ); lua_error( L ); return 1; } else { roomID = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap ) { if( pHost->mpMap->rooms.contains(roomID) ) { TRoom * pR = pHost->mpMap->rooms[roomID]; lua_newtable(L); QStringList keys = pR->doors.keys(); for( int i=0; idoors[keys[i]] ); lua_settable(L, -3); } return 1; } } return 0; } //SYNTAX: setExitWeight( roomID, exitCommand, exitWeight ) int TLuaInterpreter::setExitWeight( lua_State * L ) { int roomID; int weight; string text; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setExitWeight: wrong argument type" ); lua_error( L ); return 1; } else { roomID = lua_tointeger( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setExitWeight: wrong argument type" ); lua_error( L ); return 1; } else { text = lua_tostring( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "setExitWeight: wrong argument type" ); lua_error( L ); return 1; } else { weight = lua_tonumber( L, 3 ); } QString _text = text.c_str(); _text = _text.toLower(); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap ) { if( pHost->mpMap->rooms.contains(roomID) ) { TRoom * pR = pHost->mpMap->rooms[roomID]; pR->exitWeights[_text] = weight; pHost->mpMap->mMapGraphNeedsUpdate = true; } } return 0; } //SYNTAX: exit weight table = getExitWeights( roomID ) int TLuaInterpreter::getExitWeights( lua_State * L ) { int roomID; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getExitWeights: wrong argument type" ); lua_error( L ); return 1; } else { roomID = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap ) { if( pHost->mpMap->rooms.contains(roomID) ) { TRoom * pR = pHost->mpMap->rooms[roomID]; lua_newtable(L); QStringList keys = pR->exitWeights.keys(); for( int i=0; iexitWeights[keys[i]] ); lua_settable(L, -3); } return 1; } } return 0; } int TLuaInterpreter::deleteMapLabel( lua_State * L ) { int area, labelID; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "deleteMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { area = lua_tointeger( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "deleteMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { labelID = lua_tointeger( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpMap->deleteMapLabel( area, labelID ); return 0; } int TLuaInterpreter::getMapLabels( lua_State * L ) { int area; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "deleteMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { area = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->mapLabels.contains( area ) ) { lua_newtable(L); QMapIterator it(pHost->mpMap->mapLabels[area]); while( it.hasNext() ) { it.next(); lua_pushnumber( L, it.key() ); lua_pushstring( L, it.value().text.toLatin1().data() ); lua_settable(L, -3); } } return 1; } int TLuaInterpreter::getMapLabel( lua_State * L ) { int area, labelId = -1; QString labelText; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getMapLabel: wrong argument type" ); lua_error( L ); return 1; } else { area = lua_tointeger( L, 1 ); } if (!lua_isstring(L,2) && !lua_isnumber(L,2)){ lua_pushstring( L, "getMapLabel: wrong argument type" ); lua_error( L ); return 1; } else{ if (lua_isnumber(L,2)) labelId = lua_tointeger(L,2); else labelText = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->mapLabels.contains( area ) ) { lua_newtable(L); if (labelId != -1){ if (pHost->mpMap->mapLabels[area].contains(labelId)){ TMapLabel label = pHost->mpMap->mapLabels[area][labelId]; qDebug()<<"here"; int x = label.pos.x(); int y = label.pos.y(); int z = label.pos.z(); qDebug()<<"herea"; float height = label.size.height(); float width = label.size.width(); qDebug()<<"hereb"; QString text = label.text; qDebug()<<"herec"; lua_pushstring( L, "X" ); lua_pushnumber( L, x ); lua_settable(L, -3); lua_pushstring( L, "Y" ); lua_pushnumber( L, y ); lua_settable(L, -3); lua_pushstring( L, "Z" ); lua_pushnumber( L, z ); lua_settable(L, -3); lua_pushstring( L, "Height" ); lua_pushnumber( L, height ); lua_settable(L, -3); lua_pushstring( L, "Width" ); lua_pushnumber( L, width ); lua_settable(L, -3); lua_pushstring( L, "Text" ); lua_pushstring( L, text.toLatin1().data() ); lua_settable(L, -3); } else{ lua_pushstring( L, "getMapLabel: labelId doesn't exist" ); lua_error( L ); return 1; } } else{ QMapIterator it(pHost->mpMap->mapLabels[area]); while( it.hasNext() ) { it.next(); if(it.value().text==labelText){ TMapLabel label = it.value(); lua_newtable(L); int id = it.key(); int x = label.pos.x(); int y = label.pos.y(); int z = label.pos.z(); float height = label.size.height(); float width = label.size.width(); QString text = label.text; qDebug()<<"here"; lua_pushstring( L, "X" ); lua_pushnumber( L, x ); lua_settable(L, -3); lua_pushstring( L, "Y" ); lua_pushnumber( L, y ); lua_settable(L, -3); lua_pushstring( L, "Z" ); lua_pushnumber( L, z ); lua_settable(L, -3); lua_pushstring( L, "Height" ); lua_pushnumber( L, height ); lua_settable(L, -3); lua_pushstring( L, "Width" ); lua_pushnumber( L, width ); lua_settable(L, -3); lua_pushstring( L, "Text" ); lua_pushstring( L, text.toLatin1().data() ); lua_settable(L, -3); lua_pushnumber(L, id); lua_insert(L,-2); lua_settable(L, -3); } } } } return 1; } int TLuaInterpreter::addSpecialExit( lua_State * L ) { int id_from, id_to; string dir; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "addSpecialExit: wrong argument type" ); lua_error( L ); return 1; } else { id_from = lua_tointeger( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "addSpecialExit: wrong argument type" ); lua_error( L ); return 1; } else { id_to = lua_tointeger( L, 2 ); } if( ! lua_isstring( L, 3 ) ) { lua_pushstring( L, "addSpecialExit: wrong argument type" ); lua_error( L ); return 1; } else { dir = lua_tostring( L, 3 ); } QString _dir = dir.c_str(); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id_from ) ) { if( pHost->mpMap->rooms.contains( id_to ) ) { pHost->mpMap->rooms[id_from]->addSpecialExit( id_to, _dir ); pHost->mpMap->rooms[id_from]->setSpecialExitLock( id_to, _dir, false ); pHost->mpMap->mMapGraphNeedsUpdate = true; } } return 0; } int TLuaInterpreter::clearRoomUserData( lua_State * L ) { int id_from; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "clearRoomUserData: wrong argument type" ); lua_error( L ); return 1; } else { id_from = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id_from ) ) { pHost->mpMap->rooms[id_from]->userData.clear(); } return 0; } int TLuaInterpreter::clearSpecialExits( lua_State * L ) { int id_from; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "clearSpecialExits: wrong argument type" ); lua_error( L ); return 1; } else { id_from = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id_from ) ) { pHost->mpMap->rooms[id_from]->other.clear(); pHost->mpMap->mMapGraphNeedsUpdate = true; } return 0; } int TLuaInterpreter::getSpecialExits( lua_State * L ) { int id_from; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getSpecialExits: wrong argument type" ); lua_error( L ); return 1; } else { id_from = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id_from ) ) { QMapIterator it(pHost->mpMap->rooms[id_from]->other); lua_newtable(L); while( it.hasNext() ) { it.next(); lua_newtable(L); int id_to = it.key(); QString dir = it.value(); QString exitStatus; if( dir.size() > 0 && ( dir.startsWith('0') || dir.startsWith('1')) ) exitStatus = dir.left(1); else exitStatus = "0"; QString exit; if( dir.size() > 0 && ( dir.startsWith('0') || dir.startsWith('1')) ) exit = dir.remove(0,1); else exit = dir; lua_pushstring( L, exit.toLatin1().data() );//done to remove the prepended special exit status lua_pushstring( L, exitStatus.toLatin1().data() );//done to remove the prepended special exit status lua_settable(L, -3); lua_pushnumber(L, id_to); lua_insert(L,-2); lua_settable(L, -3); } return 1; } return 0; } int TLuaInterpreter::getSpecialExitsSwap( lua_State * L ) { int id_from; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getSpecialExitsSwap: wrong argument type" ); lua_error( L ); return 1; } else { id_from = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( id_from ) ) { QMapIterator it(pHost->mpMap->rooms[id_from]->other); lua_newtable(L); while( it.hasNext() ) { it.next(); int id_to = it.key(); QString dir = it.value(); //lua_pushstring( L, dir.toLatin1().data() ); QString exitStatus; QString exit; if( dir.size() > 0 && ( dir.startsWith('0') || dir.startsWith('1')) ) exitStatus = dir.left(1); else exitStatus = "0"; if( dir.size() > 0 && ( dir.startsWith('0') || dir.startsWith('1')) ) exit = dir.remove(0,1); else exit = dir; lua_pushstring( L, exit.toLatin1().data() ); lua_pushnumber( L, id_to ); lua_settable(L, -3); } return 1; } return 0; } int TLuaInterpreter::getRoomEnv( lua_State * L ) { int roomID; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getRoomEnv: wrong argument type" ); lua_error( L ); return 1; } else { roomID = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( roomID ) ) { lua_pushnumber( L, pHost->mpMap->rooms[roomID]->environment ); return 1; } return 0; } int TLuaInterpreter::getRoomUserData( lua_State * L ) { int roomID; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getRoomUserData: wrong argument type" ); lua_error( L ); return 1; } else { roomID = lua_tointeger( L, 1 ); } string key; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "getRoomUserData: wrong argument type" ); lua_error( L ); return 1; } else { key = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( roomID ) ) { QString _key = key.c_str(); if( pHost->mpMap->rooms[roomID]->userData.contains( _key ) ) { lua_pushstring( L, pHost->mpMap->rooms[roomID]->userData[_key].toLatin1().data() ); return 1; } else { lua_pushstring( L, "" ); return 1; } } else { lua_pushstring( L, "" ); return 1; } } int TLuaInterpreter::setRoomUserData( lua_State * L ) { int roomID; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getRoomUserData: wrong argument type" ); lua_error( L ); return 1; } else { roomID = lua_tointeger( L, 1 ); } string key; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "getRoomUserData: wrong argument type" ); lua_error( L ); return 1; } else { key = lua_tostring( L, 2 ); } string value; if( ! lua_isstring( L, 3 ) ) { lua_pushstring( L, "getRoomUserData: wrong argument type" ); lua_error( L ); return 1; } else { value = lua_tostring( L, 3 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->rooms.contains( roomID ) ) { QString _key = key.c_str(); QString _value = value.c_str(); pHost->mpMap->rooms[roomID]->userData[_key] = _value; lua_pushboolean( L, true ); return 1; } else { lua_pushboolean( L, false ); return 1; } } int TLuaInterpreter::downloadFile( lua_State * L ) { string path, url; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "downloadFile: wrong argument type" ); lua_error( L ); return 1; } else { path = lua_tostring( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "downloadFile: wrong argument type" ); lua_error( L ); return 1; } else { url = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString _url = url.c_str(); QString _path = path.c_str(); QNetworkReply * reply = pHost->mLuaInterpreter.mpFileDownloader->get( QNetworkRequest( QUrl( _url ) ) ); pHost->mLuaInterpreter.downloadMap[reply] = _path; return 0; } int TLuaInterpreter::setRoomArea( lua_State * L ) { int id, area; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setRoomArea: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "setRoomArea: wrong argument type" ); lua_error( L ); return 1; } else { area = lua_tointeger( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpMap->setRoomArea( id, area ); return 0; } int TLuaInterpreter::setRoomChar( lua_State * L ) { int id; string c; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "setRoomArea: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setRoomArea: wrong argument type" ); lua_error( L ); return 1; } else { c = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( ! pHost->mpMap->rooms.contains( id ) ) { lua_pushstring( L, "setRoomArea: room ID does not exist"); lua_error( L ); return 1; } else { if( c.size() >= 1 ) { pHost->mpMap->rooms[id]->c = c[0]; } } return 0; } int TLuaInterpreter::getRoomChar( lua_State * L ) { int id; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getRoomChar: wrong argument type" ); lua_error( L ); return 1; } else { id = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( ! pHost->mpMap->rooms.contains( id ) ) { lua_pushstring( L, "getRoomChar: room ID does not exist"); lua_error( L ); return 1; } else { QString c = (QString)pHost->mpMap->rooms[id]->c; lua_pushstring( L, c.toLatin1().data() ); return 1; } return 0; } int TLuaInterpreter::getRoomsByPosition( lua_State * L ) { int area, x, y, z; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "getRoomsByPosition: wrong argument type" ); lua_error( L ); return 1; } else { area = lua_tointeger( L, 1 ); } if( ! lua_isnumber( L, 2 ) ) { lua_pushstring( L, "getRoomsByPosition: wrong argument type" ); lua_error( L ); return 1; } else { x = lua_tointeger( L, 2 ); } if( ! lua_isnumber( L, 3 ) ) { lua_pushstring( L, "getRoomsByPosition: wrong argument type" ); lua_error( L ); return 1; } else { y = lua_tointeger( L, 3 ); } if( ! lua_isnumber( L, 4 ) ) { lua_pushstring( L, "getRoomsByPosition: wrong argument type" ); lua_error( L ); return 1; } else { z = lua_tointeger( L, 4 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( ! pHost->mpMap->areas.contains( area ) ) { lua_pushnil( L ); return 1; } QList rL = pHost->mpMap->areas[area]->getRoomsByPosition( x, y, z); lua_newtable( L ); for( int i=0; impMap->areas.contains( area ) ) { lua_pushboolean( L, false); return 1; } else { pHost->mpMap->areas[area]->gridMode = gridMode; pHost->mpMap->areas[area]->calcSpan(); if( pHost->mpMap->mpMapper ) { if( pHost->mpMap->mpMapper->mp2dMap ) { pHost->mpMap->mpMapper->mp2dMap->init(); cout << "NEW GRID MAP: init" << endl; } } } lua_pushboolean( L, true ); return 1; } int TLuaInterpreter::setFgColor( lua_State *L ) { int s = 1; int n = lua_gettop( L ); string a1; int luaRed; int luaGreen; int luaBlue; if( n > 3 ) { if( lua_isstring( L, s ) ) { a1 = lua_tostring( L, s ); s++; } } if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "setFgColor: wrong argument type" ); lua_error( L ); return 1; } else { luaRed = lua_tointeger( L, s ); s++; } if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "setFgColor: wrong argument type" ); lua_error( L ); return 1; } else { luaGreen=lua_tointeger( L, s ); s++; } if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "setFgColor: wrong argument type" ); lua_error( L ); return 1; } else { luaBlue = lua_tointeger( L, s ); } QString _name( a1.c_str() ); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( n < 4 ) pHost->mpConsole->setFgColor( luaRed, luaGreen, luaBlue ); else mudlet::self()->setFgColor( pHost, _name, luaRed, luaGreen, luaBlue ); return 0; } int TLuaInterpreter::setBgColor( lua_State *L ) { int s = 1; int n = lua_gettop( L ); string a1; int luaRed; int luaGreen; int luaBlue; if( n > 3 ) { if( lua_isstring( L, s ) ) { a1 = lua_tostring( L, s ); s++; } } if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "setBgColor: wrong argument type" ); lua_error( L ); return 1; } else { luaRed = lua_tointeger( L, s ); s++; } if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "setBgColor: wrong argument type" ); lua_error( L ); return 1; } else { luaGreen=lua_tointeger( L, s ); s++; } if( ! lua_isnumber( L, s ) ) { lua_pushstring( L, "setBgColor: wrong argument type" ); lua_error( L ); return 1; } else { luaBlue = lua_tointeger( L, s ); } QString _name( a1.c_str() ); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( n < 4 ) pHost->mpConsole->setBgColor( luaRed, luaGreen, luaBlue ); else mudlet::self()->setBgColor( pHost, _name, luaRed, luaGreen, luaBlue ); return 0; } // params: [windowName,] "printWhat", "LuaScript", "hint", [boolean=true -> use current format else use standard link format] int TLuaInterpreter::insertLink( lua_State *L ) { QStringList sL; int n = lua_gettop( L ); int s = 1; bool b = false; bool gotBool = false; for( ; s<=n; s++ ) { if( lua_isstring( L, s ) ) { string _str = lua_tostring( L, s ); QString qs = _str.c_str(); sL << qs; } else if( lua_isboolean( L, s ) ) { gotBool = true; b = lua_toboolean( L, s ); } } if( sL.size() < 4 ) sL.prepend("main"); if( sL.size() < 4 ) { lua_pushstring( L, "insertLink: wrong number of params or wrong type of params" ); lua_error( L ); return 1; } QString _name( sL[0] ); QString printScreen = sL[1]; QStringList command; QStringList hint; command << sL[2]; hint << sL[3]; Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( _name == "main" ) { pHost->mpConsole->insertLink( printScreen, command, hint, b ); } else { mudlet::self()->insertLink( pHost, _name, printScreen, command, hint, b ); } return 0; } int TLuaInterpreter::insertPopup( lua_State *L ) { string a1 = ""; string a2; QStringList _hintList; QStringList _commandList; bool customFormat = false; int s = 1; int n = lua_gettop( L ); // console name is an optional first argument if( n > 4 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "insertPopup: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } } if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "insertPopup: wrong argument type" ); lua_error( L ); return 1; } else { a2 = lua_tostring( L, s ); s++; } if( ! lua_istable( L, s ) ) { lua_pushstring( L, "insertPopup: wrong argument type" ); lua_error( L ); return 1; } else { lua_pushnil( L ); while( lua_next( L, s ) != 0 ) { // key at index -2 and value at index -1 if( lua_type(L, -1) == LUA_TSTRING ) { QString cmd = lua_tostring( L, -1 ); _commandList << cmd; } // removes value, but keeps key for next iteration lua_pop(L, 1); } s++; } if( ! lua_istable( L, s ) ) { lua_pushstring( L, "insertPopup: wrong argument type" ); lua_error( L ); return 1; } else { lua_pushnil( L ); while( lua_next( L, s ) != 0 ) { // key at index -2 and value at index -1 if( lua_type(L, -1) == LUA_TSTRING ) { QString hint = lua_tostring( L, -1 ); _hintList << hint; } // removes value, but keeps key for next iteration lua_pop(L, 1); } s++; } if( n >= s ) { customFormat = lua_toboolean( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString txt = a2.c_str(); QString name = a1.c_str(); if( _commandList.size() != _hintList.size() ) { lua_pushstring( L, "Error: command list size and hint list size do not match cannot create popup" ); lua_error( L ); return 1; } if( a1 == "" ) { pHost->mpConsole->insertLink( txt, _commandList, _hintList, customFormat ); } else { mudlet::self()->insertLink( pHost, name, txt, _commandList, _hintList, customFormat ); } return 0; } int TLuaInterpreter::insertText( lua_State *L ) { string a1; string a2; int n = lua_gettop( L ); int s = 1; if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "insertText: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } QString _name( a1.c_str() ); if( n > 1 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "insertText: wrong argument type" ); lua_error( L ); return 1; } else { a2 = lua_tostring( L, s ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( n == 1 ) pHost->mpConsole->insertText( QString(a1.c_str()) ); else mudlet::self()->insertText( pHost, _name, QString( a2.c_str() ) ); return 0; } int TLuaInterpreter::insertHTML( lua_State *L ) { string luaSendText; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "insertHTML: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->insertHTML( QString(luaSendText.c_str()) ); return 0; } int TLuaInterpreter::addSupportedTelnetOption( lua_State *L ) { int option; if( ! lua_isnumber( L, 1 ) ) { lua_pushstring( L, "addSupportedTelnetOption: wrong argument type" ); lua_error( L ); return 1; } else { option = lua_tointeger( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mTelnet.supportedTelnetOptions[option] = true; return 0; } int TLuaInterpreter::Echo( lua_State *L ) { string a1; string a2; int s = 1; int n = lua_gettop( L ); if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "Echo: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } if( n > 1 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "Echo: wrong argument type" ); lua_error( L ); return 1; } else { a2 = lua_tostring( L, s ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString txt; QString name; if( n == 1 ) { txt = a1.c_str(); pHost->mpConsole->echo( txt ); } else { txt = a2.c_str(); name = a1.c_str(); mudlet::self()->echoWindow( pHost, name, txt ); } return 0; } int TLuaInterpreter::echoPopup( lua_State *L ) { string a1 = ""; string a2; QStringList _hintList; QStringList _commandList; bool customFormat = false; int s = 1; int n = lua_gettop( L ); // console name is an optional first argument if( n > 4 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "echoPopup: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } } if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "echoPopup: wrong argument type" ); lua_error( L ); return 1; } else { a2 = lua_tostring( L, s ); s++; } if( ! lua_istable( L, s ) ) { lua_pushstring( L, "echoPopup: wrong argument type" ); lua_error( L ); return 1; } else { lua_pushnil( L ); while( lua_next( L, s ) != 0 ) { // key at index -2 and value at index -1 if( lua_type(L, -1) == LUA_TSTRING ) { QString cmd = lua_tostring( L, -1 ); _commandList << cmd; } // removes value, but keeps key for next iteration lua_pop(L, 1); } s++; } if( ! lua_istable( L, s ) ) { lua_pushstring( L, "echoPopup: wrong argument type" ); lua_error( L ); return 1; } else { lua_pushnil( L ); while( lua_next( L, s ) != 0 ) { // key at index -2 and value at index -1 if( lua_type(L, -1) == LUA_TSTRING ) { QString hint = lua_tostring( L, -1 ); _hintList << hint; } // removes value, but keeps key for next iteration lua_pop(L, 1); } s++; } if( n >= s ) { customFormat = lua_toboolean( L, s ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString txt = a2.c_str(); QString name = a1.c_str(); if( _commandList.size() != _hintList.size() ) { lua_pushstring( L, "Error: command list size and hint list size do not match cannot create popup" ); lua_error( L ); return 1; } if( a1 == "" ) { pHost->mpConsole->echoLink( txt, _commandList, _hintList, customFormat ); } else { mudlet::self()->echoLink( pHost, name, txt, _commandList, _hintList, customFormat ); } return 0; } int TLuaInterpreter::echoLink( lua_State *L ) { string a1; string a2; string a3; string a4; bool a5 = false; bool gotBool = false; int s = 1; int n = lua_gettop( L ); if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "echoLink: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } if( n > 1 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "echoLink: wrong argument type" ); lua_error( L ); return 1; } else { a2 = lua_tostring( L, s ); s++; } } if( n > 2 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "echoLink: wrong argument type" ); lua_error( L ); return 1; } else { a3 = lua_tostring( L, s ); s++; } } if( n > 3 ) { if( lua_isstring( L, s ) ) { a4 = lua_tostring( L, s ); s++; } else if( lua_isboolean( L, s ) ) { gotBool = true; a5 = lua_toboolean( L, s ); s++; } } if( n > 4 ) { if( ! lua_isboolean( L, s ) ) { lua_pushstring( L, "echoLink: wrong argument type" ); lua_error( L ); return 1; } else { a5 = lua_toboolean( L, s ); gotBool = true; s++; } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString txt; QString name; QStringList func; QStringList hint; if( n == 3 || ( n == 4 && gotBool ) ) { txt = a1.c_str(); func << a2.c_str(); hint << a3.c_str(); pHost->mpConsole->echoLink( txt, func, hint, a5 ); } else { txt = a2.c_str(); func << a3.c_str(); hint << a4.c_str(); name = a1.c_str(); mudlet::self()->echoLink( pHost, name, txt, func, hint, a5 ); } return 0; } int TLuaInterpreter::setMergeTables( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QStringList modulesList; int n = lua_gettop(L); for (int i = 1; i <= n; i++) { if (!lua_isstring(L, i)) { lua_pushfstring( L, "setMergeTables: bad argument #%d (string expected, got %s)", i, luaL_typename(L, 1) ); lua_error(L); return 1; } modulesList << QString(lua_tostring(L, i)); } pHost->mGMCP_merge_table_keys = pHost->mGMCP_merge_table_keys + modulesList; pHost->mGMCP_merge_table_keys.removeDuplicates(); return 0; } int TLuaInterpreter::pasteWindow( lua_State *L ) { string luaName; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "pasteWindow: wrong argument type" ); lua_error( L ); return 1; } else { luaName = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString name( luaName.c_str()); mudlet::self()->pasteWindow( pHost, name ); return 0; } int TLuaInterpreter::exportAreaImage( lua_State *L ) { int areaID; if( lua_isnumber( L, 1 ) ) { areaID = lua_tointeger( L, 1 ); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpMap->mpMapper->mp2dMap->exportAreaImage( areaID ); } return 0; } int TLuaInterpreter::openUrl( lua_State *L ) { string luaName; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "openUrl: wrong argument type" ); lua_error( L ); return 1; } else { luaName = lua_tostring( L, 1 ); } QString url( luaName.c_str()); QDesktopServices::openUrl(url); return 0; } int TLuaInterpreter::setLabelStyleSheet( lua_State * L ) { string luaSendText=""; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "setLabelStyleSheet: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } string a2; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "setLabelStyleSheet: wrong argument type" ); lua_error( L ); return 1; } else { a2 = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; //qDebug()<<"CSS: name:"<"; pHost->mpConsole->setLabelStyleSheet( luaSendText, a2 ); return 0; } int TLuaInterpreter::getCustomEnvColorTable( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mpMap->customEnvColors.size() > 0 ) { lua_newtable( L ); QList colorList = pHost->mpMap->customEnvColors.keys(); for( int idx=0; idxmpMap->customEnvColors[colorList[idx]].red() ); lua_settable( L, -3 );//match in matches } // green component { lua_pushnumber( L, 2 ); lua_pushnumber( L, pHost->mpMap->customEnvColors[colorList[idx]].green() ); lua_settable( L, -3 );//match in matches } // blue component { lua_pushnumber( L, 3 ); lua_pushnumber( L, pHost->mpMap->customEnvColors[colorList[idx]].blue() ); lua_settable( L, -3 );//match in matches } lua_settable( L, -3 );//matches in regex } } else { lua_newtable( L ); } return 1; } //syntax: getTime( bool return_string, string time_format ) with return_string == false -> return table int TLuaInterpreter::getTime( lua_State * L ) { int n = lua_gettop( L ); bool return_string = false; QString fmt = "yyyy.MM.dd hh:mm:ss.zzz"; QString tm; if( n > 0 ) { return_string = lua_toboolean( L, 1 ); if( n > 1 ) { if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "getTime: wrong argument type" ); lua_error( L ); return 1; } else { fmt = lua_tostring( L, 2 ); } } } QDateTime time = QDateTime::currentDateTime(); if( return_string ) { tm = time.toString( fmt ); lua_pushstring( L, tm.toLatin1().data() ); } else { QDate dt = time.date(); QTime tm = time.time(); lua_createtable( L, 0, 4 ); lua_pushstring( L, "hour" ); lua_pushinteger( L, tm.hour() ); lua_rawset( L, n+1 ); lua_pushstring( L, "min" ); lua_pushinteger( L, tm.minute() ); lua_rawset( L, n+1 ); lua_pushstring( L, "sec" ); lua_pushinteger( L, tm.second() ); lua_rawset( L, n+1 ); lua_pushstring( L, "msec" ); lua_pushinteger( L, tm.msec() ); lua_rawset( L, n+1 ); lua_pushstring( L, "year" ); lua_pushinteger( L, dt.year() ); lua_rawset( L, n+1 ); lua_pushstring( L, "month" ); lua_pushinteger( L, dt.month() ); lua_rawset( L, n+1 ); lua_pushstring( L, "day" ); lua_pushinteger( L, dt.day() ); lua_rawset( L, n+1 ); } return 1; } int TLuaInterpreter::appendBuffer( lua_State *L ) { string a1; string a2; int s = 1; int n = lua_gettop( L ); if( n > 0 ) { if( ! lua_isstring( L, s ) ) { lua_pushstring( L, "appendBuffer: wrong argument type" ); lua_error( L ); return 1; } else { a1 = lua_tostring( L, s ); s++; } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( s == 1 ) { pHost->mpConsole->appendBuffer(); } else { QString name = a1.c_str(); mudlet::self()->appendBuffer( pHost, name ); } return 0; } int TLuaInterpreter::appendCmdLine( lua_State * L ) { string luaSendText; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "appendCmdLine(): wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString curText = pHost->mpConsole->mpCommandLine->toPlainText(); pHost->mpConsole->mpCommandLine->setPlainText( curText + QString( luaSendText.c_str() ) ); QTextCursor cur = pHost->mpConsole->mpCommandLine->textCursor(); cur.clearSelection(); cur.movePosition(QTextCursor::EndOfLine); pHost->mpConsole->mpCommandLine->setTextCursor(cur); return 0; } int TLuaInterpreter::installPackage( lua_State * L ) { string event; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "installPackage(): wrong argument type" ); lua_error( L ); return 1; } else { event = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString package = event.c_str(); if( pHost ) pHost->installPackage( package, 0 ); } int TLuaInterpreter::uninstallPackage( lua_State * L ) { string event; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "installPackage(): wrong argument type" ); lua_error( L ); return 1; } else { event = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString package = event.c_str(); if( pHost ) pHost->uninstallPackage( package, 0 ); } int TLuaInterpreter::registerAnonymousEventHandler( lua_State * L ) { string event; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "appendCmdLine(): wrong argument type" ); lua_error( L ); return 1; } else { event = lua_tostring( L, 1 ); } string func; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "appendCmdLine(): wrong argument type" ); lua_error( L ); return 1; } else { func = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString e = event.c_str(); QString f = func.c_str(); pHost->registerAnonymousEventHandler( e, f ); return 0; } int TLuaInterpreter::Send( lua_State * L ) { string luaSendText; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "Send: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } bool wantPrint = true; if( lua_gettop( L ) > 1 ) { if( ! lua_isboolean( L, 2 ) ) { lua_pushstring( L, "Send: wrong argument type" ); lua_error( L ); return 1; } else { wantPrint = lua_toboolean( L, 2 ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->send( QString( luaSendText.c_str() ), wantPrint, false ); return 0; } int TLuaInterpreter::printCmdLine( lua_State * L ) { string luaSendText; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "printCmdLine: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->mpCommandLine->setPlainText( QString( luaSendText.c_str() ) ); QTextCursor cur = pHost->mpConsole->mpCommandLine->textCursor(); cur.clearSelection(); cur.movePosition(QTextCursor::EndOfLine); pHost->mpConsole->mpCommandLine->setTextCursor(cur); return 0; } int TLuaInterpreter::clearCmdLine( lua_State * L ) { Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mpConsole->mpCommandLine->clear(); return 0; } int TLuaInterpreter::sendRaw( lua_State * L ) { string luaSendText; if( ! lua_isstring( L, 1 ) ) { lua_pushfstring( L, "sendRaw: bad argument #1 (string expected, got %s)", luaL_typename(L, 1) ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } bool wantPrint = true; if( lua_gettop( L ) > 1 ) { if( ! lua_isboolean( L, 2 ) ) { lua_pushfstring( L, "sendRaw: bad argument #2 (boolean expected, got %s)", luaL_typename(L, 2) ); lua_error( L ); return 1; } else { wantPrint = lua_toboolean( L, 2 ); } } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->send( QString(luaSendText.c_str()), wantPrint, true ); return 0; } int TLuaInterpreter::sendSocket( lua_State * L ) { string luaSendText; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "sendSocket: wrong argument type" ); lua_error( L ); return 1; } else { luaSendText = lua_tostring( L, 1 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->mTelnet.socketOutRaw( luaSendText ); return 0; } #include "dlgIRC.h" int TLuaInterpreter::sendIrc( lua_State * L ) { string who; if( ! lua_isstring( L, 1 ) ) { lua_pushstring( L, "sendSocket: wrong argument type" ); lua_error( L ); return 1; } else { who = lua_tostring( L, 1 ); } string text; if( ! lua_isstring( L, 2 ) ) { lua_pushstring( L, "sendSocket: wrong argument type" ); lua_error( L ); return 1; } else { text = lua_tostring( L, 2 ); } Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; QString chan = who.c_str(); QString txt = text.c_str(); if( ! mudlet::self()->mpIRC ) return 0; mudlet::self()->mpIRC->session->cmdMessage( chan, txt ); return 0; } bool TLuaInterpreter::compileAndExecuteScript( QString & code ) { if( code.size() < 1 ) return false; lua_State * L = pGlobalLua; if( ! L ) { qDebug()<< "LUA CRITICAL ERROR: no suitable Lua execution unit found."; return false; } int error = luaL_dostring( L, code.toLatin1().data() ); QString n; if( error != 0 ) { string e = "no error message available from Lua"; if( lua_isstring( L, 1 ) ) { e = "Lua error:"; e+=lua_tostring( L, 1 ); } if( mudlet::debugMode ) qDebug()<<"LUA ERROR: code did not compile: ERROR:"<>0;} } else { if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::darkGreen))<<"LUA: code compiled without errors. OK\n">>0;} } lua_pop( L, lua_gettop( L ) ); if( error == 0 ) return true; else return false; } bool TLuaInterpreter::compile( QString & code ) { lua_State * L = pGlobalLua; if( ! L ) { qDebug()<< "LUA CRITICAL ERROR: no suitable Lua execution unit found."; return false; } int error = luaL_dostring( L, code.toLatin1().data() ); QString n; if( error != 0 ) { string e = "no error message available from Lua"; if( lua_isstring( L, 1 ) ) { e = "Lua error:"; e+=lua_tostring( L, 1 ); } if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::red))<<"LUA: code did not compile: ERROR:"<>0;} } else { if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::darkGreen))<<"LUA: code compiled without errors. OK\n" >> 0;} } lua_pop( L, lua_gettop( L ) ); if( error == 0 ) return true; else return false; } bool TLuaInterpreter::compile( QString & code, QString & errorMsg ) { lua_State * L = pGlobalLua; if( ! L ) { qDebug()<< "LUA CRITICAL ERROR: no suitable Lua execution unit found."; return false; } int error = luaL_dostring( L, code.toLatin1().data() ); QString n; if( error != 0 ) { string e = "Lua syntax error:"; if( lua_isstring( L, 1 ) ) { e.append( lua_tostring( L, 1 ) ); } errorMsg = ""; errorMsg.append( e.c_str() ); errorMsg.append(""); if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::red))<<"\n "<>0;} } else { if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::red))<<"\nLUA: code compiled without errors. OK\n" >> 0;} } lua_pop( L, lua_gettop( L ) ); if( error == 0 ) return true; else return false; } void TLuaInterpreter::setMultiCaptureGroups( const std::list< std::list > & captureList, const std::list< std::list > & posList ) { mMultiCaptureGroupList = captureList; mMultiCaptureGroupPosList = posList; /*std::list< std::list >::const_iterator mit = mMultiCaptureGroupList.begin(); int k=1; for( ; mit!=mMultiCaptureGroupList.end(); mit++, k++ ) { cout << "regex#"<::const_iterator it = (*mit).begin(); for( int i=1; it!=(*mit).end(); it++, i++ ) { cout << i<<"#"<<"<"<<*it<<">"< & captureList, const std::list & posList ) { mCaptureGroupList = captureList; mCaptureGroupPosList = posList; /*std::list::iterator it2 = mCaptureGroupList.begin(); std::list::iterator it1 = mCaptureGroupPosList.begin(); int i=0; for( ; it1!=mCaptureGroupPosList.end(); it1++, it2++, i++ ) { cout << "group#"<::iterator I; for( I it=mCaptureGroupPosList.begin(); it!=mCaptureGroupPosList.end(); it++ ) { if( *it >= x ) { *it += a; } } } void TLuaInterpreter::setAtcpTable( QString & var, QString & arg ) { lua_State * L = pGlobalLua; lua_getglobal( L, "atcp" ); //defined in LuaGlobal.lua lua_pushstring( L, var.toLatin1().data() ); lua_pushstring( L, arg.toLatin1().data() ); lua_rawset( L, -3 ); lua_pop( L, 1 ); TEvent event; event.mArgumentList.append( var ); event.mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); event.mArgumentList.append( arg ); event.mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->raiseEvent( & event ); } void TLuaInterpreter::setGMCPTable(QString & key, QString & string_data) { lua_State * L = pGlobalLua; lua_getglobal(L, "gmcp"); //defined in Lua init if( !lua_istable(L, -1) ) { qDebug()<<"ERROR: gmcp not defined -> error in LuaGlobal.lua"; return; } // key is in format of Blah.Blah or Blah.Blah.Bleh - we want to push & pre-create the tables as appriate QStringList tokenList = key.split("."); if( ! lua_checkstack( L, tokenList.size()+5 ) ) return; int i = 0; for( ; imGMCP_merge_table_keys.contains( key ) ) { __needMerge = true; } } lua_pop( L, 1 ); if( ! __needMerge ) lua_pushstring(L, tokenList[i].toLatin1().data()); else lua_pushstring(L, "__needMerge"); lua_getglobal(L, "json_to_value"); if( !lua_isfunction(L, -1) ) { lua_settop(L, 0); qDebug()<<"CRITICAL ERROR: json_to_value not defined"; return; } lua_pushlstring(L, string_data.toLatin1().data(), string_data.size()); int error = lua_pcall(L, 1, 1, 0); if( error == 0 ) { // Top of stack should now contain the lua representation of json. lua_rawset(L, -3); if( __needMerge ) { lua_settop(L, 0); lua_getglobal(L, "__gmcp_merge_gmcp_sub_tables"); if( !lua_isfunction(L, -1) ) { lua_settop(L, 0); qDebug()<<"CRITICAL ERROR: __gmcp_merge_gmcp_sub_tables is not defined in lua_LuaGlobal.lua"; return; } lua_getglobal(L, "gmcp"); i = 0; for( ; i display(gmcp) to see the full content\n"); pHost->mpConsole->printSystemMessage(msg); } pHost->raiseEvent( &event ); } // auto-detect IRE composer if( tokenList.size() == 3 && tokenList.at(0) == "IRE" && tokenList.at(1) == "Composer" && tokenList.at(2) == "Edit") { QRegExp rx("\\{ \"title\": \"(.*)\", \"text\": \"(.*)\" \\}"); if( rx.indexIn(string_data) != -1 ) { QString title = rx.cap(1); QString initialText = rx.cap(2); initialText.replace(QString("\\n"), QString("\n")); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; if( pHost->mTelnet.mpComposer ) return; pHost->mTelnet.mpComposer = new dlgComposer( pHost ); pHost->mTelnet.mpComposer->init( title, initialText ); pHost->mTelnet.mpComposer->raise(); pHost->mTelnet.mpComposer->show(); } } lua_pop( L, lua_gettop( L ) ); } void TLuaInterpreter::setChannel102Table( int & var, int & arg ) { lua_State * L = pGlobalLua; lua_getglobal( L, "channel102" ); //defined in LuaGlobal.lua lua_pushnumber( L, var ); lua_pushnumber( L, arg ); lua_rawset( L, -3 ); lua_pop( L, 1 ); TEvent event; QString e = "channel102Message"; event.mArgumentList.append( e ); event.mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); event.mArgumentList.append( QString::number(var) ); event.mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); event.mArgumentList.append( QString::number(arg) ); event.mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); Host * pHost = TLuaInterpreter::luaInterpreterMap[L]; pHost->raiseEvent( & event ); } bool TLuaInterpreter::call_luafunction( void * pT ) { lua_State * L = pGlobalLua; lua_pushlightuserdata( L, pT ); lua_gettable( L, LUA_REGISTRYINDEX ); if( lua_isfunction( L, -1 ) ) { int error = lua_pcall( L, 0, LUA_MULTRET, 0 ); if( error != 0 ) { int nbpossible_errors = lua_gettop(L); for (int i=1; i<=nbpossible_errors; i++) { string e = ""; if(lua_isstring( L, i) ) { e = "Lua error:"; e+=lua_tostring( L, i ); QString _n = "error in anonymous Lua function"; QString _n2 = "no debug data available"; logError( e, _n, _n2 ); if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::red))<<"LUA: ERROR running anonymous Lua function ERROR:"<>0;} } } } else { if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::darkGreen))<<"LUA OK anonymous Lua function ran without errors\n">>0;} } lua_pop( L, lua_gettop( L ) ); //lua_settop(L, 0); if( error == 0 ) return true; else return false; } else { QString _n = "error in anonymous Lua function"; QString _n2 = "func reference not found by Lua, func can not be called"; string e = "Lua error:"; logError( e, _n, _n2 ); } return false; } bool TLuaInterpreter::call( QString & function, QString & mName ) { lua_State * L = pGlobalLua; if( ! L ) { qDebug()<< "LUA CRITICAL ERROR: no suitable Lua execution unit found."; return false; } if( mCaptureGroupList.size() > 0 ) { lua_newtable( L ); // set values int i=1; // Lua indexes start with 1 as a general convention std::list::iterator it = mCaptureGroupList.begin(); for( ; it!=mCaptureGroupList.end(); it++, i++ ) { //if( (*it).length() < 1 ) continue; //have empty capture groups to be undefined keys i.e. machts[emptyCapGroupNumber] = nil otherwise it's = "" i.e. an empty string lua_pushnumber( L, i ); lua_pushstring( L, (*it).c_str() ); lua_settable( L, -3 ); } lua_setglobal( L, "matches" ); } lua_getglobal( L, function.toLatin1().data() ); lua_getfield( L, LUA_GLOBALSINDEX, function.toLatin1().data() ); int error = lua_pcall( L, 0, LUA_MULTRET, 0 ); if( error != 0 ) { int nbpossible_errors = lua_gettop(L); for (int i=1; i<=nbpossible_errors; i++) { string e = ""; if(lua_isstring( L, i) ) { e += lua_tostring( L, i ); logError( e, mName, function ); if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::red))<<"LUA: ERROR running script "<< mName << " (" << function <<") ERROR:"<>0;} } } } else { if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::darkGreen))<<"LUA OK script "<>0;} } lua_pop( L, lua_gettop( L ) ); if( error == 0 ) return true; else return false; } void TLuaInterpreter::logError( std::string & e, QString & name, QString & function ) { //QDateTime time = QDateTime::currentDateTime(); // QString entry = QString("[%1]object:<%2> function:<%3> error:<%4>").arg(time.toString("MMM:dd:yyyy hh-mm-ss")).arg(name).arg(function).arg(e.c_str()); //mpHost->mErrorLogStream << entry << endl; QColor blue = QColor(0,0,255); QColor green = QColor(0,255,0); QColor red = QColor(255,0,0); QColor black = QColor(0,0,0); QString s1 = QString("[ERROR:]"); QString s2 = QString(" object:<%1> function:<%2>\n").arg(name).arg(function); QString s3 = QString(" <%1>\n").arg(e.c_str()); if( mpHost->mpEditorDialog ) { mpHost->mpEditorDialog->mpErrorConsole->printDebug(blue, black, s1 ); mpHost->mpEditorDialog->mpErrorConsole->printDebug(green, black, s2 ); mpHost->mpEditorDialog->mpErrorConsole->printDebug(red, black, s3 ); } } bool TLuaInterpreter::callConditionFunction( std::string & function, QString & mName ) { lua_State * L = pGlobalLua; if( ! L ) { qDebug()<< "LUA CRITICAL ERROR: no suitable Lua execution unit found."; return false; } lua_getfield( L, LUA_GLOBALSINDEX, function.c_str() ); int error = lua_pcall( L, 0, 1, 0 ); if( error != 0 ) { int nbpossible_errors = lua_gettop(L); for (int i=1; i<=nbpossible_errors; i++) { string e = ""; if(lua_isstring( L, i) ) { e+=lua_tostring( L, i ); QString _f = function.c_str(); logError( e, mName, _f ); if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::red))<<"LUA: ERROR running script "<< mName << " (" << function.c_str() <<") ERROR:"<>0;} } } } else { if( mudlet::debugMode ){ TDebug(QColor(Qt::white),QColor(Qt::darkGreen))<<"LUA OK script "<>0;} } int ret = 0; int returnValues = lua_gettop( L ); if( returnValues > 0 ) { // Lua docs: Like all tests in Lua, lua_toboolean returns 1 for any Lua value different from false and nil; otherwise it returns 0 // This means trigger patterns don't have to strictly return true or false, as it is accepted in Lua */ ret = lua_toboolean( L, 1 ); } lua_pop( L, returnValues ); if( (error == 0) && (ret>0) ) { return true; } else { return false; } } bool TLuaInterpreter::callMulti( QString & function, QString & mName ) { lua_State * L = pGlobalLua; if( ! L ) { qDebug()<< "LUA CRITICAL ERROR: no suitable Lua execution unit found."; return false; } if( mMultiCaptureGroupList.size() > 0 ) { int k=1; // Lua indexes start with 1 as a general convention std::list< std::list >::iterator mit = mMultiCaptureGroupList.begin(); lua_newtable( L );//multimatches for( ; mit!=mMultiCaptureGroupList.end(); mit++, k++ ) { // multimatches{ trigger_idx{ table_matches{ ... } } } lua_pushnumber( L, k ); lua_newtable( L );//regex-value => table matches int i=1; // Lua indexes start with 1 as a general convention std::list::iterator it = (*mit).begin(); for( ; it!=(*mit).end(); it++, i++ ) { lua_pushnumber( L, i ); lua_pushstring( L, (*it).c_str() ); lua_settable( L, -3 );//match in matches } lua_settable( L, -3 );//matches in regex } lua_setglobal( L, "multimatches" ); } lua_getglobal( L, function.toLatin1().data() ); lua_getfield( L, LUA_GLOBALSINDEX, function.toLatin1().data() ); int error = lua_pcall( L, 0, LUA_MULTRET, 0 ); if( error != 0 ) { int nbpossible_errors = lua_gettop(L); for (int i=1; i<=nbpossible_errors; i++) { string e = ""; if(lua_isstring( L, i) ) { e += lua_tostring( L, i ); logError( e, mName, function ); if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::red))<<"LUA: ERROR running script "<< mName << " (" << function <<") ERROR:"<>0;} } } } else { if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::darkGreen))<<"LUA OK script "<>0;} } lua_pop( L, lua_gettop( L ) ); if( error == 0 ) return true; else return false; } bool TLuaInterpreter::callEventHandler( QString & function, TEvent * pE ) { lua_State * L = pGlobalLua; int error = luaL_dostring(L, QString("return " + function).toLatin1().data()); QString n; if( error != 0 ) { string e; if( lua_isstring( L, 1 ) ) { e = "Lua error:"; e += lua_tostring( L, 1 ); } QString _n = "event handler function"; logError( e, _n, function ); return false; } for( int i=0; imArgumentList.size(); i++ ) { if( pE->mArgumentTypeList[i] == ARGUMENT_TYPE_NUMBER ) { lua_pushnumber( L, pE->mArgumentList[i].toInt() ); } else { lua_pushstring( L, pE->mArgumentList[i].toLatin1().data() ); } } error = lua_pcall( L, pE->mArgumentList.size(), LUA_MULTRET, 0 ); if( error != 0 ) { string e = ""; if(lua_isstring( L, -1) ) { e+=lua_tostring( L, -1 ); } QString _n = "event handler function"; logError( e, _n, function ); if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::red))<<"LUA: ERROR running script "<< function << " (" << function <<") ERROR:"<>0;} } lua_pop( L, lua_gettop( L ) ); if( error == 0 ) return true; else return false; } void TLuaInterpreter::set_lua_table( QString & tableName, QStringList & variableList ) { lua_State * L = pGlobalLua; if( ! L ) { qDebug()<< "LUA CRITICAL ERROR: no suitable Lua execution unit found."; return; } lua_newtable(L); for( int i=0; isnip--------------------------------------------" <start(); //calls initLuaGlobals() to initialize the interpreter for this session } #ifdef Q_OS_MAC #include "luazip.c" #endif // this function initializes the Lua Session interpreter. // on initialization of a new session *or* in case of an interpreter reset by the user. void TLuaInterpreter::initLuaGlobals() { pGlobalLua = luaL_newstate(); TLuaInterpreter::luaInterpreterMap[pGlobalLua]=mpHost; luaL_openlibs( pGlobalLua ); lua_pushstring( pGlobalLua, "SESSION" ); lua_pushnumber( pGlobalLua, mHostID ); lua_settable( pGlobalLua, LUA_GLOBALSINDEX ); lua_pushstring( pGlobalLua, "SCRIPT_NAME" ); lua_pushstring( pGlobalLua, "Global Lua Session Interpreter" ); lua_settable( pGlobalLua, LUA_GLOBALSINDEX ); lua_pushstring( pGlobalLua, "SCRIPT_ID" ); lua_pushnumber( pGlobalLua, -1 ); // ID 1 is used to indicate that this is the global Lua interpreter lua_settable( pGlobalLua, LUA_GLOBALSINDEX ); lua_register( pGlobalLua, "showUnzipProgress", TLuaInterpreter::showUnzipProgress );//internal function used by the package system NOT FOR USERS lua_register( pGlobalLua, "wait", TLuaInterpreter::Wait ); lua_register( pGlobalLua, "expandAlias", TLuaInterpreter::Send ); lua_register( pGlobalLua, "echo", TLuaInterpreter::Echo ); lua_register( pGlobalLua, "selectString", TLuaInterpreter::select ); lua_register( pGlobalLua, "selectSection", TLuaInterpreter::selectSection ); lua_register( pGlobalLua, "replace", TLuaInterpreter::replace ); lua_register( pGlobalLua, "setBgColor", TLuaInterpreter::setBgColor ); lua_register( pGlobalLua, "setFgColor", TLuaInterpreter::setFgColor ); lua_register( pGlobalLua, "tempTimer", TLuaInterpreter::tempTimer ); lua_register( pGlobalLua, "tempTrigger", TLuaInterpreter::tempTrigger ); lua_register( pGlobalLua, "tempRegexTrigger", TLuaInterpreter::tempRegexTrigger ); lua_register( pGlobalLua, "openUserWindow", TLuaInterpreter::openUserWindow ); lua_register( pGlobalLua, "echoUserWindow", TLuaInterpreter::echoUserWindow ); lua_register( pGlobalLua, "enableTimer", TLuaInterpreter::enableTimer ); lua_register( pGlobalLua, "disableTimer", TLuaInterpreter::disableTimer ); lua_register( pGlobalLua, "enableKey", TLuaInterpreter::enableKey ); lua_register( pGlobalLua, "disableKey", TLuaInterpreter::disableKey ); lua_register( pGlobalLua, "clearUserWindow", TLuaInterpreter::clearUserWindow ); lua_register( pGlobalLua, "clearWindow", TLuaInterpreter::clearUserWindow ); lua_register( pGlobalLua, "killTimer", TLuaInterpreter::killTimer ); lua_register( pGlobalLua, "moveCursor", TLuaInterpreter::moveCursor ); lua_register( pGlobalLua, "getLines", TLuaInterpreter::getLines ); lua_register( pGlobalLua, "getLineNumber", TLuaInterpreter::getLineNumber ); lua_register( pGlobalLua, "insertHTML", TLuaInterpreter::insertHTML ); lua_register( pGlobalLua, "insertText", TLuaInterpreter::insertText ); lua_register( pGlobalLua, "enableTrigger", TLuaInterpreter::enableTrigger ); lua_register( pGlobalLua, "disableTrigger", TLuaInterpreter::disableTrigger ); lua_register( pGlobalLua, "killTrigger", TLuaInterpreter::killTrigger ); lua_register( pGlobalLua, "getLineCount", TLuaInterpreter::getLineCount ); lua_register( pGlobalLua, "getColumnNumber", TLuaInterpreter::getColumnNumber ); //lua_register( pGlobalLua, "getBufferTable", TLuaInterpreter::getBufferTable ); //lua_register( pGlobalLua, "getBufferLine", TLuaInterpreter::getBufferLine ); lua_register( pGlobalLua, "send", TLuaInterpreter::sendRaw ); lua_register( pGlobalLua, "selectCaptureGroup", TLuaInterpreter::selectCaptureGroup ); lua_register( pGlobalLua, "tempLineTrigger", TLuaInterpreter::tempLineTrigger ); lua_register( pGlobalLua, "raiseEvent", TLuaInterpreter::raiseEvent ); lua_register( pGlobalLua, "deleteLine", TLuaInterpreter::deleteLine ); lua_register( pGlobalLua, "copy", TLuaInterpreter::copy ); lua_register( pGlobalLua, "cut", TLuaInterpreter::cut ); lua_register( pGlobalLua, "paste", TLuaInterpreter::paste ); lua_register( pGlobalLua, "pasteWindow", TLuaInterpreter::pasteWindow ); //lua_register( pGlobalLua, "userWindowLineWrap", TLuaInterpreter::userWindowLineWrap ); lua_register( pGlobalLua, "debugc", TLuaInterpreter::debug ); lua_register( pGlobalLua, "setWindowWrap", TLuaInterpreter::setWindowWrap ); lua_register( pGlobalLua, "setWindowWrapIndent", TLuaInterpreter::setWindowWrapIndent ); lua_register( pGlobalLua, "resetFormat", TLuaInterpreter::reset ); lua_register( pGlobalLua, "moveCursorEnd", TLuaInterpreter::moveCursorEnd ); lua_register( pGlobalLua, "getLastLineNumber", TLuaInterpreter::getLastLineNumber ); lua_register( pGlobalLua, "getNetworkLatency", TLuaInterpreter::getNetworkLatency ); lua_register( pGlobalLua, "createMiniConsole", TLuaInterpreter::createMiniConsole ); lua_register( pGlobalLua, "createLabel", TLuaInterpreter::createLabel ); lua_register( pGlobalLua, "hideWindow", TLuaInterpreter::hideUserWindow ); lua_register( pGlobalLua, "showWindow", TLuaInterpreter::showUserWindow ); lua_register( pGlobalLua, "createBuffer", TLuaInterpreter::createBuffer ); lua_register( pGlobalLua, "createStopWatch", TLuaInterpreter::createStopWatch ); lua_register( pGlobalLua, "getStopWatchTime", TLuaInterpreter::getStopWatchTime ); lua_register( pGlobalLua, "stopStopWatch", TLuaInterpreter::stopStopWatch ); lua_register( pGlobalLua, "startStopWatch", TLuaInterpreter::startStopWatch ); lua_register( pGlobalLua, "resetStopWatch", TLuaInterpreter::resetStopWatch ); lua_register( pGlobalLua, "closeUserWindow", TLuaInterpreter::closeUserWindow ); lua_register( pGlobalLua, "resizeWindow", TLuaInterpreter::resizeUserWindow ); lua_register( pGlobalLua, "appendBuffer", TLuaInterpreter::appendBuffer ); lua_register( pGlobalLua, "setBackgroundImage", TLuaInterpreter::setBackgroundImage ); lua_register( pGlobalLua, "setBackgroundColor", TLuaInterpreter::setBackgroundColor ); lua_register( pGlobalLua, "createButton", TLuaInterpreter::createButton ); lua_register( pGlobalLua, "setLabelClickCallback", TLuaInterpreter::setLabelClickCallback ); lua_register( pGlobalLua, "setLabelOnEnter", TLuaInterpreter::setLabelOnEnter ); lua_register( pGlobalLua, "setLabelOnLeave", TLuaInterpreter::setLabelOnLeave ); lua_register( pGlobalLua, "moveWindow", TLuaInterpreter::moveWindow ); lua_register( pGlobalLua, "setTextFormat", TLuaInterpreter::setTextFormat ); lua_register( pGlobalLua, "getMainWindowSize", TLuaInterpreter::getMainWindowSize ); lua_register( pGlobalLua, "getCurrentLine", TLuaInterpreter::getCurrentLine ); lua_register( pGlobalLua, "setMiniConsoleFontSize", TLuaInterpreter::setMiniConsoleFontSize ); lua_register( pGlobalLua, "selectCurrentLine", TLuaInterpreter::selectCurrentLine ); lua_register( pGlobalLua, "spawn", TLuaInterpreter::spawn ); lua_register( pGlobalLua, "getButtonState", TLuaInterpreter::getButtonState ); lua_register( pGlobalLua, "showToolBar", TLuaInterpreter::showToolBar ); lua_register( pGlobalLua, "hideToolBar", TLuaInterpreter::hideToolBar ); lua_register( pGlobalLua, "loadRawFile", TLuaInterpreter::loadRawFile ); lua_register( pGlobalLua, "setBold", TLuaInterpreter::setBold ); lua_register( pGlobalLua, "setItalics", TLuaInterpreter::setItalics ); lua_register( pGlobalLua, "setUnderline", TLuaInterpreter::setUnderline ); lua_register( pGlobalLua, "disconnect", TLuaInterpreter::disconnect ); lua_register( pGlobalLua, "tempButtonToolbar", TLuaInterpreter::tempButtonToolbar ); lua_register( pGlobalLua, "tempButton", TLuaInterpreter::tempButton ); lua_register( pGlobalLua, "reconnect", TLuaInterpreter::reconnect ); lua_register( pGlobalLua, "getMudletHomeDir", TLuaInterpreter::getMudletHomeDir ); lua_register( pGlobalLua, "setTriggerStayOpen", TLuaInterpreter::setTriggerStayOpen ); lua_register( pGlobalLua, "wrapLine", TLuaInterpreter::wrapLine ); lua_register( pGlobalLua, "getFgColor", TLuaInterpreter::getFgColor ); lua_register( pGlobalLua, "getBgColor", TLuaInterpreter::getBgColor ); lua_register( pGlobalLua, "tempColorTrigger", TLuaInterpreter::tempColorTrigger ); lua_register( pGlobalLua, "isAnsiFgColor", TLuaInterpreter::isAnsiFgColor ); lua_register( pGlobalLua, "isAnsiBgColor", TLuaInterpreter::isAnsiBgColor ); lua_register( pGlobalLua, "playSoundFile", TLuaInterpreter::playSoundFile ); lua_register( pGlobalLua, "setBorderTop", TLuaInterpreter::setBorderTop ); lua_register( pGlobalLua, "setBorderBottom", TLuaInterpreter::setBorderBottom ); lua_register( pGlobalLua, "setBorderLeft", TLuaInterpreter::setBorderLeft ); lua_register( pGlobalLua, "setBorderRight", TLuaInterpreter::setBorderRight ); lua_register( pGlobalLua, "setBorderColor", TLuaInterpreter::setBorderColor ); lua_register( pGlobalLua, "setConsoleBufferSize", TLuaInterpreter::setConsoleBufferSize ); lua_register( pGlobalLua, "startLogging", TLuaInterpreter::startLogging ); lua_register( pGlobalLua, "calcFontSize", TLuaInterpreter::calcFontSize ); lua_register( pGlobalLua, "permRegexTrigger", TLuaInterpreter::permRegexTrigger ); lua_register( pGlobalLua, "permSubstringTrigger", TLuaInterpreter::permSubstringTrigger ); lua_register( pGlobalLua, "permBeginOfLineStringTrigger", TLuaInterpreter::permBeginOfLineStringTrigger ); lua_register( pGlobalLua, "tempComplexRegexTrigger", TLuaInterpreter::tempComplexRegexTrigger ); lua_register( pGlobalLua, "permTimer", TLuaInterpreter::permTimer ); lua_register( pGlobalLua, "permAlias", TLuaInterpreter::permAlias ); lua_register( pGlobalLua, "exists", TLuaInterpreter::exists ); lua_register( pGlobalLua, "isActive", TLuaInterpreter::isActive ); lua_register( pGlobalLua, "enableAlias", TLuaInterpreter::enableAlias ); lua_register( pGlobalLua, "tempAlias", TLuaInterpreter::tempAlias ); lua_register( pGlobalLua, "disableAlias", TLuaInterpreter::disableAlias ); lua_register( pGlobalLua, "killAlias", TLuaInterpreter::killAlias ); lua_register( pGlobalLua, "setLabelStyleSheet", TLuaInterpreter::setLabelStyleSheet ); lua_register( pGlobalLua, "getTime", TLuaInterpreter::getTime ); lua_register( pGlobalLua, "invokeFileDialog", TLuaInterpreter::invokeFileDialog ); lua_register( pGlobalLua, "getTimestamp", TLuaInterpreter::getTimestamp ); lua_register( pGlobalLua, "setLink", TLuaInterpreter::setLink ); lua_register( pGlobalLua, "deselect", TLuaInterpreter::deselect ); lua_register( pGlobalLua, "insertLink", TLuaInterpreter::insertLink ); lua_register( pGlobalLua, "echoLink", TLuaInterpreter::echoLink ); lua_register( pGlobalLua, "echoPopup", TLuaInterpreter::echoPopup ); lua_register( pGlobalLua, "insertPopup", TLuaInterpreter::insertPopup ); lua_register( pGlobalLua, "setPopup", TLuaInterpreter::setPopup ); lua_register( pGlobalLua, "sendATCP", TLuaInterpreter::sendATCP ); lua_register( pGlobalLua, "hasFocus", TLuaInterpreter::hasFocus ); lua_register( pGlobalLua, "isPrompt", TLuaInterpreter::isPrompt ); lua_register( pGlobalLua, "feedTriggers", TLuaInterpreter::feedTriggers ); lua_register( pGlobalLua, "sendTelnetChannel102", TLuaInterpreter::sendTelnetChannel102 ); lua_register( pGlobalLua, "setRoomWeight", TLuaInterpreter::setRoomWeight ); lua_register( pGlobalLua, "getRoomWeight", TLuaInterpreter::getRoomWeight ); lua_register( pGlobalLua, "gotoRoom", TLuaInterpreter::gotoRoom ); lua_register( pGlobalLua, "setMapperView", TLuaInterpreter::setMapperView ); lua_register( pGlobalLua, "getRoomExits", TLuaInterpreter::getRoomExits ); lua_register( pGlobalLua, "lockRoom", TLuaInterpreter::lockRoom ); lua_register( pGlobalLua, "createMapper", TLuaInterpreter::createMapper ); lua_register( pGlobalLua, "getMainConsoleWidth", TLuaInterpreter::getMainConsoleWidth ); lua_register( pGlobalLua, "resetProfile", TLuaInterpreter::resetProfile ); lua_register( pGlobalLua, "printCmdLine", TLuaInterpreter::printCmdLine ); lua_register( pGlobalLua, "searchRoom", TLuaInterpreter::searchRoom ); lua_register( pGlobalLua, "clearCmdLine", TLuaInterpreter::clearCmdLine ); lua_register( pGlobalLua, "getAreaTable", TLuaInterpreter::getAreaTable ); lua_register( pGlobalLua, "getAreaTableSwap", TLuaInterpreter::getAreaTableSwap ); lua_register( pGlobalLua, "getAreaRooms", TLuaInterpreter::getAreaRooms ); lua_register( pGlobalLua, "getPath", TLuaInterpreter::getPath ); lua_register( pGlobalLua, "centerview", TLuaInterpreter::centerview ); lua_register( pGlobalLua, "denyCurrentSend", TLuaInterpreter::denyCurrentSend ); lua_register( pGlobalLua, "tempBeginOfLineTrigger", TLuaInterpreter::tempBeginOfLineTrigger ); lua_register( pGlobalLua, "tempExactMatchTrigger", TLuaInterpreter::tempExactMatchTrigger ); lua_register( pGlobalLua, "sendGMCP", TLuaInterpreter::sendGMCP ); lua_register( pGlobalLua, "roomExists", TLuaInterpreter::roomExists ); lua_register( pGlobalLua, "addRoom", TLuaInterpreter::addRoom ); lua_register( pGlobalLua, "setExit", TLuaInterpreter::setExit ); lua_register( pGlobalLua, "setRoomCoordinates", TLuaInterpreter::setRoomCoordinates ); lua_register( pGlobalLua, "getRoomCoordinates", TLuaInterpreter::getRoomCoordinates ); lua_register( pGlobalLua, "createRoomID", TLuaInterpreter::createRoomID ); lua_register( pGlobalLua, "getRoomArea", TLuaInterpreter::getRoomArea ); lua_register( pGlobalLua, "setRoomArea", TLuaInterpreter::setRoomArea ); lua_register( pGlobalLua, "setAreaName", TLuaInterpreter::setAreaName ); lua_register( pGlobalLua, "roomLocked", TLuaInterpreter::roomLocked ); lua_register( pGlobalLua, "setCustomEnvColor", TLuaInterpreter::setCustomEnvColor ); lua_register( pGlobalLua, "getCustomEnvColorTable", TLuaInterpreter::getCustomEnvColorTable ); //lua_register( pGlobalLua, "setLevelColor", TLuaInterpreter::setLevelColor ); //lua_register( pGlobalLua, "getLevelColorTable", TLuaInterpreter::getLevelColorTable ); lua_register( pGlobalLua, "setRoomEnv", TLuaInterpreter::setRoomEnv ); lua_register( pGlobalLua, "setRoomName", TLuaInterpreter::setRoomName ); lua_register( pGlobalLua, "getRoomName", TLuaInterpreter::getRoomName ); lua_register( pGlobalLua, "setGridMode", TLuaInterpreter::setGridMode ); lua_register( pGlobalLua, "solveRoomCollisions", TLuaInterpreter::solveRoomCollisions ); lua_register( pGlobalLua, "addSpecialExit", TLuaInterpreter::addSpecialExit ); lua_register( pGlobalLua, "getSpecialExits", TLuaInterpreter::getSpecialExits ); lua_register( pGlobalLua, "getSpecialExitsSwap", TLuaInterpreter::getSpecialExitsSwap ); lua_register( pGlobalLua, "clearSpecialExits", TLuaInterpreter::clearSpecialExits ); lua_register( pGlobalLua, "getRoomEnv", TLuaInterpreter::getRoomEnv ); lua_register( pGlobalLua, "getRoomUserData", TLuaInterpreter::getRoomUserData ); lua_register( pGlobalLua, "setRoomUserData", TLuaInterpreter::setRoomUserData ); lua_register( pGlobalLua, "searchRoomUserData", TLuaInterpreter::searchRoomUserData ); lua_register( pGlobalLua, "getRoomsByPosition", TLuaInterpreter::getRoomsByPosition ); //lua_register( pGlobalLua, "dumpRoomUserData", TLuaInterpreter::dumpRoomUserData ); lua_register( pGlobalLua, "clearRoomUserData", TLuaInterpreter::clearRoomUserData ); lua_register( pGlobalLua, "downloadFile", TLuaInterpreter::downloadFile ); lua_register( pGlobalLua, "appendCmdLine", TLuaInterpreter::appendCmdLine ); lua_register( pGlobalLua, "openUrl", TLuaInterpreter::openUrl ); lua_register( pGlobalLua, "sendSocket", TLuaInterpreter::sendSocket ); lua_register( pGlobalLua, "setRoomIDbyHash", TLuaInterpreter::setRoomIDbyHash ); lua_register( pGlobalLua, "getRoomIDbyHash", TLuaInterpreter::getRoomIDbyHash ); lua_register( pGlobalLua, "addAreaName", TLuaInterpreter::addAreaName ); lua_register( pGlobalLua, "getRoomAreaName", TLuaInterpreter::getRoomAreaName ); lua_register( pGlobalLua, "deleteArea", TLuaInterpreter::deleteArea ); lua_register( pGlobalLua, "deleteRoom", TLuaInterpreter::deleteRoom ); lua_register( pGlobalLua, "setRoomChar", TLuaInterpreter::setRoomChar ); lua_register( pGlobalLua, "getRoomChar", TLuaInterpreter::getRoomChar ); lua_register( pGlobalLua, "registerAnonymousEventHandler", TLuaInterpreter::registerAnonymousEventHandler ); lua_register( pGlobalLua, "saveMap", TLuaInterpreter::saveMap ); lua_register( pGlobalLua, "loadMap", TLuaInterpreter::loadMap ); lua_register( pGlobalLua, "setMainWindowSize", TLuaInterpreter::setMainWindowSize ); // removed because of various Qt crashes //lua_register( pGlobalLua, "setAppStyleSheet", TLuaInterpreter::setAppStyleSheet ); lua_register( pGlobalLua, "sendIrc", TLuaInterpreter::sendIrc ); lua_register( pGlobalLua, "connectToServer", TLuaInterpreter::connectToServer ); lua_register( pGlobalLua, "getRooms", TLuaInterpreter::getRooms ); lua_register( pGlobalLua, "createMapLabel", TLuaInterpreter::createMapLabel ); lua_register( pGlobalLua, "deleteMapLabel", TLuaInterpreter::deleteMapLabel ); lua_register( pGlobalLua, "highlightRoom", TLuaInterpreter::highlightRoom ); lua_register( pGlobalLua, "unHighlightRoom", TLuaInterpreter::unHighlightRoom ); lua_register( pGlobalLua, "getMapLabels", TLuaInterpreter::getMapLabels ); lua_register( pGlobalLua, "getMapLabel", TLuaInterpreter::getMapLabel ); lua_register( pGlobalLua, "lockExit", TLuaInterpreter::lockExit ); lua_register( pGlobalLua, "hasExitLock", TLuaInterpreter::hasExitLock ); lua_register( pGlobalLua, "lockSpecialExit", TLuaInterpreter::lockSpecialExit ); lua_register( pGlobalLua, "hasSpecialExitLock", TLuaInterpreter::hasSpecialExitLock ); lua_register( pGlobalLua, "setExitStub", TLuaInterpreter::setExitStub ); lua_register( pGlobalLua, "connectExitStub", TLuaInterpreter::connectExitStub ); lua_register( pGlobalLua, "getExitStubs", TLuaInterpreter::getExitStubs ); lua_register( pGlobalLua, "setModulePriority", TLuaInterpreter::setModulePriority ); lua_register( pGlobalLua, "getModulePriority", TLuaInterpreter::getModulePriority ); lua_register( pGlobalLua, "updateMap", TLuaInterpreter::updateMap ); lua_register( pGlobalLua, "addMapEvent", TLuaInterpreter::addMapEvent ); lua_register( pGlobalLua, "removeMapEvent", TLuaInterpreter::removeMapEvent ); lua_register( pGlobalLua, "getMapEvents", TLuaInterpreter::getMapEvents ); lua_register( pGlobalLua, "addMapMenu", TLuaInterpreter::addMapMenu ); lua_register( pGlobalLua, "removeMapMenu", TLuaInterpreter::removeMapMenu ); lua_register( pGlobalLua, "getMapMenus", TLuaInterpreter::getMapMenus ); lua_register( pGlobalLua, "installPackage", TLuaInterpreter::installPackage ); lua_register( pGlobalLua, "exportAreaImage", TLuaInterpreter::exportAreaImage ); lua_register( pGlobalLua, "createMapImageLabel", TLuaInterpreter::createMapImageLabel ); lua_register( pGlobalLua, "setMapZoom", TLuaInterpreter::setMapZoom ); lua_register( pGlobalLua, "uninstallPackage", TLuaInterpreter::uninstallPackage ); lua_register( pGlobalLua, "setExitWeight", TLuaInterpreter::setExitWeight ); lua_register( pGlobalLua, "setDoor", TLuaInterpreter::setDoor ); lua_register( pGlobalLua, "getDoors", TLuaInterpreter::getDoors ); lua_register( pGlobalLua, "getExitWeights", TLuaInterpreter::getExitWeights ); lua_register( pGlobalLua, "addSupportedTelnetOption", TLuaInterpreter::addSupportedTelnetOption ); lua_register( pGlobalLua, "setMergeTables", TLuaInterpreter::setMergeTables ); luaopen_yajl(pGlobalLua); lua_setglobal( pGlobalLua, "yajl" ); #ifdef Q_OS_MAC luaopen_zip( pGlobalLua ); lua_setglobal( pGlobalLua, "zip" ); #endif QString n; int error; // if using LuaJIT, adjust the cpath to look in /usr/lib as well - it doesn't by default luaL_dostring (pGlobalLua, "if jit then package.cpath = package.cpath .. ';/usr/lib/lua/5.1/?.so;/usr/lib/x86_64-linux-gnu/lua/5.1/?.so' end"); error = luaL_dostring( pGlobalLua, "require \"rex_pcre\"" ); if( error != 0 ) { string e = "no error message available from Lua"; if( lua_isstring( pGlobalLua, 1 ) ) { e = "Lua error:"; e+=lua_tostring( pGlobalLua, 1 ); } QString msg = "[ ERROR ] cannot find Lua module rex_pcre. Some functions may not be available."; msg.append( e.c_str() ); gSysErrors << msg; } else { QString msg = "[ OK ] - Lua module rex_pcre loaded"; gSysErrors << msg; } error = luaL_dostring( pGlobalLua, "require \"zip\"" ); if( error != 0 ) { string e = "no error message available from Lua"; if( lua_isstring( pGlobalLua, 1 ) ) { e = "Lua error:"; e+=lua_tostring( pGlobalLua, 1 ); } QString msg = "[ ERROR ] cannot find Lua module zip"; msg.append( e.c_str() ); gSysErrors << msg; } else { QString msg = "[ OK ] - Lua module zip loaded"; gSysErrors << msg; } error = luaL_dostring( pGlobalLua, "require \"lfs\"" ); if( error != 0 ) { string e = "no error message available from Lua"; if( lua_isstring( pGlobalLua, 1 ) ) { e = "Lua error:"; e+=lua_tostring( pGlobalLua, 1 ); } QString msg = "[ ERROR ] cannot find Lua module lfs (Lua File System)."; msg.append( e.c_str() ); gSysErrors << msg; } else { QString msg = "[ OK ] - Lua module lfs loaded"; gSysErrors << msg; } error = luaL_dostring( pGlobalLua, "luasql = require \"luasql.sqlite3\"" ); if( error != 0 ) { string e = "no error message available from Lua"; if( lua_isstring( pGlobalLua, 1 ) ) { e = "Lua error:"; e+=lua_tostring( pGlobalLua, 1 ); } QString msg = "[ ERROR ] cannot find Lua module luasql.sqlite3. Database support will not be available."; msg.append( e.c_str() ); gSysErrors << msg; } else { QString msg = "[ OK ] - Lua module sqlite3 loaded"; gSysErrors << msg; } // QString path = QDir::homePath()+"/.config/mudlet/mudlet-lua/lua/LuaGlobal.lua"; // error = luaL_dofile( pGlobalLua, path.toLatin1().data() ); // if( error != 0 ) // { // string e = "no error message available from Lua"; // if( lua_isstring( pGlobalLua, 1 ) ) // { // e = "[CRITICAL ERROR] LuaGlobal.lua compile error - please report"; // e += lua_tostring( pGlobalLua, 1 ); // } // gSysErrors << e.c_str(); // } // else // { // gSysErrors << "[INFO] LuaGlobal.lua loaded successfully."; // } /*path = QDir::homePath()+"/.config/mudlet/db.lua"; error = luaL_dofile( pGlobalLua, path.toLatin1().data() ); if( error != 0 ) { string e = "no error message available from Lua"; if( lua_isstring( pGlobalLua, 1 ) ) { e = "[CRITICAL ERROR] db.lua compile error - please report"; e += lua_tostring( pGlobalLua, 1 ); } gSysErrors << e.c_str(); } else { gSysErrors << "[INFO] db.lua loaded successfully."; }*/ QString tn = "atcp"; QStringList args; set_lua_table( tn, args ); tn = "channel102"; set_lua_table( tn, args ); lua_pop( pGlobalLua, lua_gettop( pGlobalLua ) ); //FIXME make function call in destructor lua_close(L); } void TLuaInterpreter::loadGlobal() { //QString path = QDir::homePath()+"/.config/mudlet/mudlet-lua/lua/LuaGlobal.lua"; QString path = "mudlet-lua/lua/LuaGlobal.lua"; int error = luaL_dofile( pGlobalLua, path.toLatin1().data() ); if( error != 0 ) { string e = "no error message available from Lua"; if( lua_isstring( pGlobalLua, 1 ) ) { e = "[ ERROR ] - LuaGlobal.lua compile error - please report!"; e += lua_tostring( pGlobalLua, 1 ); } gSysErrors << e.c_str(); } else { gSysErrors << "[ OK ] - mudlet-lua API & Geyser Layout manager loaded."; } } void TLuaInterpreter::slotEchoMessage(int hostID, QString msg) { Host * pHost = HostManager::self()->getHostFromHostID( hostID ); mudlet::self()->print( pHost, msg ); } void TLuaInterpreter::slotNewCommand(int hostID, QString cmd) { Host * pHost = HostManager::self()->getHostFromHostID( hostID ); pHost->send( cmd ); } void TLuaInterpreter::slotOpenUserWindow(int hostID, QString windowName ) { } void TLuaInterpreter::slotClearUserWindow(int hostID, QString windowName ) { } void TLuaInterpreter::slotEnableTimer(int hostID, QString windowName ) { Host * pHost = HostManager::self()->getHostFromHostID( hostID ); pHost->enableTimer( windowName ); } void TLuaInterpreter::slotDisableTimer(int hostID, QString windowName ) { Host * pHost = HostManager::self()->getHostFromHostID( hostID ); pHost->disableTimer( windowName ); } void TLuaInterpreter::slotReplace(int hostID, QString text) { } void TLuaInterpreter::slotEchoUserWindow(int hostID, QString windowName, QString text ) { } void TLuaInterpreter::slotTempTimer( int hostID, double timeout, QString function, QString timerName ) { Host * pHost = HostManager::self()->getHostFromHostID( hostID ); QTime time(0,0,0,0); int msec = static_cast(timeout * 1000); QTime time2 = time.addMSecs( msec ); TTimer * pT; pT = new TTimer( timerName, time2, pHost ); pT->setName( timerName ); pT->setTime( time2 ); //qDebug()<<"setting time of tempTimer to "<getTimerUnit()->findTimer( parent ); if( !pP ) { return -1;//parent not found } pT = new TTimer( pP, mpHost ); } pT->setTime( time2 ); pT->setIsFolder( false ); pT->setIsTempTimer( false ); pT->registerTimer(); pT->setScript( function ); int id = pT->getID(); pT->setName( name );//darf erst nach isTempTimer gesetzt werde, damit setName() schneller ist pT->setIsActive( false ); mpHost->mpEditorDialog->mNeedUpdateData = true; return id; } int TLuaInterpreter::startTempTimer( double timeout, QString & function ) { QTime time( 0, 0, 0, 0 ); int msec = static_cast(timeout * 1000); QTime time2 = time.addMSecs( msec ); TTimer * pT; pT = new TTimer( "a", time2, mpHost ); pT->setTime( time2 ); pT->setIsFolder( false ); pT->setIsTempTimer( true ); pT->registerTimer(); pT->setScript( function ); int id = pT->getID(); pT->setName( QString::number( id ) );//darf erst nach isTempTimer gesetzt werde, damit setName() schneller ist pT->setIsActive( true ); pT->enableTimer( id ); return id; } int TLuaInterpreter::startPermAlias( QString & name, QString & parent, QString & regex, QString & function ) { TAlias * pT; if( parent.isEmpty() ) { pT = new TAlias("a", mpHost ); } else { TAlias * pP = mpHost->getAliasUnit()->findAlias( parent ); if( !pP ) { return -1;//parent not found } pT = new TAlias( pP, mpHost ); } pT->setRegexCode( regex ); pT->setIsFolder( false ); pT->setIsActive( true ); pT->setIsTempAlias( false ); pT->registerAlias(); pT->setScript( function ); int id = pT->getID(); pT->setName( name ); mpHost->mpEditorDialog->mNeedUpdateData = true; return id; } int TLuaInterpreter::startTempAlias( QString & regex, QString & function ) { TAlias * pT; pT = new TAlias("a", mpHost ); pT->setRegexCode( regex ); pT->setIsFolder( false ); pT->setIsActive( true ); pT->setIsTempAlias( true ); pT->registerAlias(); pT->setScript( function ); int id = pT->getID(); pT->setName( QString::number( id ) ); return id; } int TLuaInterpreter::startTempExactMatchTrigger( QString & regex, QString & function ) { TTrigger * pT; QStringList sList; sList< propertyList; propertyList << REGEX_EXACT_MATCH; pT = new TTrigger("a", sList, propertyList, false, mpHost ); pT->setIsFolder( false ); pT->setIsActive( true ); pT->setIsTempTrigger( true ); pT->registerTrigger(); pT->setScript( function ); int id = pT->getID(); pT->setName( QString::number( id ) ); return id; } int TLuaInterpreter::startTempBeginOfLineTrigger( QString & regex, QString & function ) { TTrigger * pT; QStringList sList; sList< propertyList; propertyList << REGEX_BEGIN_OF_LINE_SUBSTRING; pT = new TTrigger("a", sList, propertyList, false, mpHost ); pT->setIsFolder( false ); pT->setIsActive( true ); pT->setIsTempTrigger( true ); pT->registerTrigger(); pT->setScript( function ); int id = pT->getID(); pT->setName( QString::number( id ) ); return id; } int TLuaInterpreter::startTempTrigger( QString & regex, QString & function ) { TTrigger * pT; QStringList sList; sList< propertyList; propertyList << REGEX_SUBSTRING;// substring trigger is default pT = new TTrigger("a", sList, propertyList, false, mpHost ); pT->setIsFolder( false ); pT->setIsActive( true ); pT->setIsTempTrigger( true ); pT->registerTrigger(); pT->setScript( function ); int id = pT->getID(); pT->setName( QString::number( id ) ); return id; } int TLuaInterpreter::startTempLineTrigger( int from, int howmany, QString & function ) { TTrigger * pT; // QStringList sList; // QList propertyList; // propertyList << REGEX_SUBSTRING;// substring trigger is default // pT = new TTrigger("a", sList, propertyList, false, mpHost ); pT = new TTrigger( 0, mpHost ); pT->setIsFolder( false ); pT->setIsActive( true ); pT->setIsTempTrigger( true ); pT->setIsLineTrigger( true ); pT->setStartOfLineDelta( from ); pT->setLineDelta( howmany ); pT->registerTrigger(); pT->setScript( function ); int id = pT->getID(); pT->setName( QString::number( id ) ); return id; } int TLuaInterpreter::startTempColorTrigger( int fg, int bg, QString & function ) { TTrigger * pT; // QStringList sList; // QList propertyList; // propertyList << REGEX_SUBSTRING;// substring trigger is default // pT = new TTrigger("a", sList, propertyList, false, mpHost ); pT = new TTrigger( 0, mpHost ); pT->setIsFolder( false ); pT->setIsActive( true ); pT->setIsTempTrigger( true ); pT->setupTmpColorTrigger( fg, bg ); pT->registerTrigger(); pT->setScript( function ); int id = pT->getID(); pT->setName( QString::number( id ) ); return id; } int TLuaInterpreter::startTempRegexTrigger( QString & regex, QString & function ) { TTrigger * pT; QStringList sList; sList< propertyList; propertyList << REGEX_PERL;// substring trigger is default pT = new TTrigger("a", sList, propertyList, false, mpHost ); pT->setIsFolder( false ); pT->setIsActive( true ); pT->setIsTempTrigger( true ); pT->registerTrigger(); pT->setScript( function ); int id = pT->getID(); pT->setName( QString::number( id ) ); return id; } int TLuaInterpreter::startPermRegexTrigger( QString & name, QString & parent, QStringList & regexList, QString & function ) { TTrigger * pT; QList propertyList; for( int i=0; i1), mpHost ); } else { TTrigger * pP = mpHost->getTriggerUnit()->findTrigger( parent ); if( !pP ) { return -1;//parent not found } pT = new TTrigger( pP, mpHost ); pT->setRegexCodeList( regexList, propertyList ); } pT->setIsFolder( (regexList.size()==0) ); pT->setIsActive( true ); pT->setIsTempTrigger( false ); pT->registerTrigger(); pT->setScript( function ); //pT->setName( name ); int id = pT->getID(); pT->setName( QString::number( id ) ); mpHost->mpEditorDialog->mNeedUpdateData = true; //return 1; return id; } int TLuaInterpreter::startPermBeginOfLineStringTrigger( QString & name, QString & parent, QStringList & regexList, QString & function ) { TTrigger * pT; QList propertyList; for( int i=0; i1), mpHost ); } else { TTrigger * pP = mpHost->getTriggerUnit()->findTrigger( parent ); if( !pP ) { return -1;//parent not found } pT = new TTrigger( pP, mpHost ); pT->setRegexCodeList( regexList, propertyList ); } pT->setIsFolder( (regexList.size()==0) ); pT->setIsActive( true ); pT->setIsTempTrigger( false ); pT->registerTrigger(); pT->setScript( function ); int id = pT->getID(); pT->setName( QString::number( id ) ); mpHost->mpEditorDialog->mNeedUpdateData = true; //return 1; return id; } int TLuaInterpreter::startPermSubstringTrigger( QString & name, QString & parent, QStringList & regexList, QString & function ) { TTrigger * pT; QList propertyList; for( int i=0; i1), mpHost ); } else { TTrigger * pP = mpHost->getTriggerUnit()->findTrigger( parent ); if( !pP ) { return -1;//parent not found } pT = new TTrigger( pP, mpHost ); pT->setRegexCodeList( regexList, propertyList ); } pT->setIsFolder( (regexList.size()==0) ); pT->setIsActive( true ); pT->setIsTempTrigger( false ); pT->registerTrigger(); pT->setScript( function ); int id = pT->getID(); pT->setName( QString::number( id ) ); mpHost->mpEditorDialog->mNeedUpdateData = true; //return 1; return id; } mudlet-2.1/src/doc/0000755000175000017500000000000012070466512013515 5ustar csmallcsmallmudlet-2.1/src/doc/Mudlet_API_Reference.odt0000644000175000017500000031046612070466512020140 0ustar csmallcsmallPK A^2 ''mimetypeapplication/vnd.oasis.opendocument.textPK AConfigurations2/statusbar/PK A'Configurations2/accelerator/current.xmlPK AConfigurations2/floater/PK AConfigurations2/popupmenu/PK AConfigurations2/progressbar/PK AConfigurations2/toolpanel/PK AConfigurations2/menubar/PK AConfigurations2/toolbar/PK AConfigurations2/images/Bitmaps/PK A layout-cacheM?(aw])eń rO.?N.]YB7`ty-y}5R>6%[ A;ip !FB)F$^-hpgSS$4;:85[1VM YAMp)uF @܁O`n)҈Pt&y`y #&4$ .+px D"H=p ^'ɛJ1{3jyi!06x?1`$>o nIK)Z:%@u? y @@s%#&:878l--->n xPK[{Go~PK A content.xmlrHyOOmݖ9#QUmr&MA #`6fs{wk{2O$A P)8xn[7"0xg{{߿?8/?á7n8E kɧ\bo{yE| Éҧγwo+qr~\ݜ}:wIчޅg~/Os[aWVjaX?'Jq{$޶n0ڽ^P:+`vd.wp(|A};S|toHtQqgUQq3ZS5+'*7͋u7o>;v5mrvx!T8 ѸޅDޤaΊJiߙo7~y26>pq^Cyǁn:T:ͱ;󛽇o>8qyDk%=>$Y +LZYٮ~ӯ魣usoʡ/'n7ޡiq=᧣dvGMD$O`J#g}Mv䴾c'+P+yJnS#ၢ5uz}[/i!ԍ1~׽A0$mt_6y|]sݙ&!)zL.m/|_tg_4Ez8}Nu0UD';|D"@X{#E}1LTA3}WŐORiBlV'W,,Q}loUWȟ"/8t`hO/퇑Ԑ.5vK`l=;=?ymKO$!y޳qݲ'b*#ݑp*YoThxL{;ft,<1^צ1t>X}F̭G{:Kn<ܷn1jRX{f=z ݧ#MEYЯlIk:5jڴN>uNj:'iӚiZ6sV9Qզuz5i^ZWֱ5i]ԥ˱@v}(\ԩ:iGmox/'`$KtFb畹jf* I\n-#^ݮ%|'G׮b++=9*¤]7Iu:zيiH&Ei:[AƶTYdԥ+^tD`z V0׵ho*e~pԼ^?*UP,0cCo'+ҏ2i%_Vti^!V2_?T֢w(3[iW[TIm׿lm^oUq ^uty?>MڭH+۔̏ggۘ랞ݠ/YxXOV"><am, X%=`mP%mE練bwSK[A|Znji+j/~?}i+D/XK稜kwÔG}#F>P#znj7G#{n򈑽$gcRQ~F~wnjT\ocFҭ[1'[rF"}Hw-9#e>O-9# >̻0ZrFfXN7ŝp:N1ή7ǝ0r]o;֯7ɝ0C z e0wi7͝pZ44ש7Ҝr4FSFiNiSo97ҜrSiNi!O]Xo)#uMsg4׭7͝1\4wƹZo;3pǙL-<'<͚Rlޤ5'<ִ5O`&yz5D,ج%jbfM/Q$ 6kYYSL<т͚dSsL3a<τ͙h®y 3Մ]\6g <vM؜ 'g9SN59as&kuL;a<͙x®y 3]6g 'lvO؜ (g9SP5Aas&kLCa<͙®y& 3]\6g2 (ltvQ؜ )g9SR5Ias&kLKah+sEyɇ;GdMc/Mo>pb G2?ҟ/?=dU%OJ VuOo)0ZQ8J޳^[gudYCY%x/s1t5 '+acsY1pI '+?D—5ȟ8+0rE؋0苁Eb<[ ygs{O^Y3?k4'Kp3"!}}~ǎlv~x1Bca~Rg%9(NuRceVo=ڭvx0\mQg_W)BEYYw0o;+>uZݲqٟy @6rLGR222L2t GaoōO}_$?`XNFqZ5t|OCONR-~ʑzd0:=:~~Sr[M^&Jٽv;T:GJ>ڽG^B^iROv/Iw֭T }T+eNzږt)Ž\l9S>ɤuq8`0qMĸZE }Ryẚ_Bej\%㸪~4ȕ:䪖$WZp8ǁqfr9q8p85ǁq8p8|8p8ǁq.9q8p85ǁq8p8|8p8ǁq8sǁq8p8k&!8ǁq8p\39q8p8ǁqǁq8p8LC>p8ǁqfr9q8p85ǁq8p8w|8p8ǁq8sǁq8p8k&!8ǁq8p\39q8p8ǁqǁq8p8LC>p8ǁqfr9q8p85ǁq8p8|8p8ǁq8sǁq8p8k$#8ǁq8p\39q8p8ǁqǁq8p8LC>p8ǁqfr9q8p85ǁq8p8|8p8ǁq8sǁq8p8k&!8ǁq8p\39q8p8ǁq'ǁq8p8LC>p8ǁqfr9q8p85ǁq8p8|8p8ǁq8sǁq8p8k&!8ǁq8p\39q8p8ǁqǁq8p8LC>p8ǁqFr)9q8p85ǁq8p8|8p8ǁq8sǁq8p8k&!8ǁq8p\39q8p8ǁqǁq8p8LC>p8ǁqfr9q8p85ǁq8p8w|8p8ǁq8sǁq8p8k&!8ǁq8p\39q8p8ǁqǁq8p8LC>p8ǁqfr9q8p85ǁq8p8|8p8ǁq8sǁq8p8k$ǁq8p8|8p8ǁq8sǁq8p8k&!8ǁq8p\39q8p8ǁqǁq8p8LC>p8ǁqfr9q8p85ǁq8p8|8p8ǁq89@ r 9dtr9@ k(!@ r9\CA9r9@  rHr9@ PCV@ r:r9@ 5 r9@ 9@ r 9dvr9@ k&r9@ PCf@ r2;r9@ 5 r9@ 9@ r 9dvr9@ k(!@ r9\CAr9@  rr9@ PCf@ rf\r9@  rr9@ PCf@ r2;r9@ 5 r9@ 9@ r 9dvr9@ k(!@ r9\CAr9@  rr9@ L"@ r9\CAr9@  rr9@ PCf@ r2;r9@ 5 r9@ 9@ r 9dvr9@ k(!@ r9\CAr9@  rGr9@ PCf@ r2;r9@ 5 r9@ 9@ r 9dvr9@ k(!@ r9\CAr9@  rr9@ PCf@ rf12;r9@ 5 r9@ 9@ r 9dvr9@ k(!@ r9\CAr9@  rr9@ PCf@ r2;r9@ 5 r9@ w9@ r 9dvr9@ k(!@ r9\CAr9@  rr9@ PCf@ r2;r9@ 5 r9@ 9@ r 9dvr9@ k&ȝ"@ r9\CAr9@  rr9@ PCf@ r2;r9@ 5 r9@ 9@ r 9dvr9@ k(!@ r9\CAr9@  rgr9@ PCf@ r2;r9@ 5 r9@ 9@ r 9dvr9@ k(!@ r9\CAr9@  rr9@ PCf@ rf\r9@  rr9@ PCf@ r2;r9@ 5 r9@ 9@ r 9dvr9@ k(!@ r9\CAr9@  rr9@ H봑 r9@ 9@ r 9dvr9@ k(!@ r9\CAr9@  rr9@ PCf@ r2;r9@ 5 r9@ 9@ r9r9@  r,@;$;7?/l~z\b8&g$ :~DS7[~[`*:~,̏/~;uO_"aD' {aƭxĉZtwK^^g";H60R޳|/>P6q0w$+gb}:ي10NE [?p׋'sNnq`g=u|iDJN^b?-~ȹѼ :^RאM.S&PiSOo؉o"? Ǖ廼<>:uώz\쉓So'{//.iSz? t_}`wLoX*ā$ԶTD~pr'~*Y6H1B?%Eg!ѯ{/ӋFؼ7+3da/J(DÜHEɩQo/tae}o3ai y$|Y"2U+J˹;,Rr;wz[g뽋zgݍX:D%V Wn5mu}]2^ _GHvƫBįWwnC r;WsHū5FoNWyxnU^|xn$$YN:^-{;fgm^|vx;mnxXD#q9 _;Wذ2/%yIl^MB񪓟F*^%)_,^1k:è<7~)Fpj)j"e<8QR_Nаc1;I,\惵d.m]>NwY#ߛ0ל5&\~y (݈ƫQh0ϵLw8]htr|.nYWeq: Bӗ6PN~"k6MftӯWƨVl;u˕Ԙ>i͵ٶCw#6eW\/6!DfCtÖ{%_>F=qx#6氋`5w#]-FS \/6%w#2 IvH7YP7{z~n$d ǖT$"1܋Gm\d_B^i7]6NZ#ۛ+'_{εq .V76Mќ[@+-cm6|e6 ӵ6:~]2F2 ~zȌy\Hs;'׎nCCEh$O Ǩ] WH6Fݲ]a ⭗ MN[5.މt>y*ԠD~~i9f:3g2q:ښ?] f@n'- 7cq=ܥp$⬉/gl'/%V "/C-xʟO*X4{B7j;Fşp<ɵ3ۦd7h$)_4F]D[?0|KDD]cNs*J+E"FnSdmN/['ndT-$Zyl{q*p^1bֿٶ'e|7qzF"F uO& áz=~)y=̄ ?OT #k\DTvsmq&bID0p?er:rI=ʍ[` _4NX?|~xYp`?^#X0!H0sMڛ+G7nwrdD*dT&_RL4$=j]\*Shk{W n1M:]N'\#;OZp]%K?.;͵r:؜NF@8~B}vuG2a|m9qx#| N,6#kG"tjf4^w3nsz0~{?ͷKkt5E"lNݙl7"Zx @:~:}{HǽY]xsmN[wBNg[WBv5A*3Zt}{F-Ef%%63e{%>ƙ,w^u8]k)hm dcT"#v(%݁8Z84] 8"$kgp~x0sR6j74x I/glJa_rRN :Mr3+Q\9p01'Xͧy^p:׎2A)~DR)Uu+~ٰ6Xz2MCn[8]l֙Q\y9hO|1jn8h~:Q±&-#ZWv9k9Fw8j70mvk 3 bo uon9jM4 n? .?ʌf_rzՒ|k7cQl&y~߻qn/r9j'NP[\HZf_qN'] ƙLL|g)+5hlMpif_rzFʶi<8d<56 u*c SYc_Fݸ/\5ܭ.W6sU5ƭ*M~Sh$87ȷ.k[dP7@PBޯ T\|{_RxE3/T2Wm:wkXJ/~⩈.m"nZ Ǩb̺vc2j{/Gbƾgp=:4p76pB~;받ۓ $aci)J5$n*G1\PcV6J/jWrznݣ.O/}#oK+9y%pot9wJw}"V $Yw9vi1nԽZΊBC>F k-}}%|9|󑩉p7gM]SgOĞ}/8ANO^'Wr'gѦTo٥-W XFೣ<ٿ>jgwc;vX޽}kC_VfPl۩ǻTsw+.܏}j݊K5aRNE?٥[w.v+.ϻ}jnEߥSOwV]o}jnEߥe腍c+ĪqlI ?wۥl×J< sqWp>9٘pw g؃Yƍ-΅UIù#f5Eaܸ|.W ]`{ɤ8.;tLxqVh)[ѥAiK.[ P@ХOV.U[al1'p[>pRU .eGN88Q\հ8 ׭J$hBkfy8ZէT)gtN)I_$BIÙuoeV*a8cmJaį ;ݤ2IxPēG;VFoNvH[|$iUfSNHVT8q$^pY$*wHI0 ,fg)]W8(*qZ 5 h$.:x5 jW7gf#Qe}i4x kVw-L 5{/ «bQT&RJ2Y6x36А7yu98+tb+id+*t(ݍu蛕q4/D|ϩwj 9jPYFlh6/AP:8F+Neum6C}s7)˰q]Y_el;ʷB<3<"A$N^W& s[F ET4,jpvZp*j02b40;/IY Қ$/Dx_Xp=5C8@9s61??<#9ltUu3΁mFs]uq$ e9QIiפ!tER$>9vgw8DZ84+<ęd˧ŬyuƛiwժC|Ku7ᴲhXv3ېjI갚3[sMr#K+syF U7癚8-58֐<; #/l./±xUW DrF#TRg硤P!!)  *K;<ݕS]VOF7aɯATt2RURe*%M8<rB6T¹ys(ªNz87Tqc~U ;cgEzTJ$gHUsNRQxU'θz!ũʳ[mNZٴr K> V8;\jx7KqF|Wi3LQN`OkDi/I)WΠsY n~u~g8K4՞]<ʪ)rh8Y:hX~yFtqIOqpQ6Ds4œ=A=e˔e5ڄΣFFqxy o.λdR"!NUCA)oo,;v~.;ݕksVx8*xyJ@Ke;P]s')%pDD㊗݌ʊ1 39O64_HU53 uڏ6U.vU1sh_iP:7ixAEd]Rb*Ns/MB=DS{',z8ƪ~RބN-5qBE./Iy~2rT8M6_يi7<.6621NE>Nufg׏Eu#^_$-[+ ɹR#i5Z%ti7kIz^~V 8‰WT<q&40=GW:h<؜lCѥ*uDUY+%<m%9W$H+6fś êC4N߄/r@vS:0cSao9\"&Կ˹Yةo3M\y.g'p.G,+aT.R*V Vfx2HZ/򱻜ęH|@8#]E ~=ETapsC-HL(ƪ`aye8{3J'g%܋Эn%RN!q|oPbY (oDo;ՅaryO%Jw}BhOOt9JY.3> J$޻{Ue,qƣ3⼹,TS3f[=`q1{q*MDg#:]Ro}x՜9+5qvѸXWD~]UR KT].g*:Uۂu˅"VuI$O1yV+ˊR#v9#; ZXaXfD)8X]FJGQ4amV(_AY!mV'.^jjU;8"Qڜ'g܈BTe=[E'~u6#To֓-F '!V'"٬g&@Wg: 8] mه-TO/Z10O  *\rnJ/nnw" H8"'He8N$vU-(!4hĊ/xRبE$0Չ]uP\8Sv 8PSA뇉7p1Ǚ&Q V&g-rNÙLjSQ/)r*Zm>$4I mūGWFW)Ի;g\Ж${:_Tx'Y#$] Umi;IÞht)=;FwqN>߃ѕO'?.[K) )[զDrm(Zј=ܵBo{%3vջ)v*BϽ e$jJNF/×S>W'h˯4{J0a⊡[1y95þSǺIg%WNb9@ı'/Z([Np{%"Ѳ2LϜZߦ(V/{Bۦ-<~08p yH.C޸v*C0DLA<Ξ@8T\ 6tqz)u={/_O=?9 傧 B٠r9\{EdrY E+VOV"DD)ū[cGTh߮xowIk3XXD,? вywג![*n5HM73 K$ i տW%-ԬۊA,O-9șdN&ȻPD‹o_?wLSӤ'r/mũi@r:i)h[E[M}G6$"(it9Yk۾28:ZE!';Aru`/ٲ> zD߬QeGV|ZIh c'NBI{Pe;K>y_fdR[On)UFk$O `^_~x|\=lZ&2?{bWv)ٔ,< e?O2#A13Hu川JkFZywW )PYI ?-[C /ll }M5K߹>6l254ʠ5XrF`ޡj.u@JaDЫ!fWTNDŽr2R <[y8]߳oiG`Kr3<Ƀh1EQOwMPrҟZ>Il~5*WL@jŽHؚ>GŒhYC[9LC%Y},:f+UNE nzU:XTR ]SҷTt˶չP %֕c=/bN=1%zUli`^I6z3YE$?zMj~-~6=2 ZD8ŒU M<<}DXmB{ڸ#[nZߔLV_n!{\qb*H8#ѤCE~JJes{>hT3{0*K]9C:UcN 12I'>{V|3:^utz2kW*<]<>EaXy9-GQ*I&燇޵+lP_O(r&WI0P_q_%"{0:jRyUBܞy}Ry)0T-?f㪉,WFٳW6ڭʹ{e2ϓTNցR Ϟ]o$Z֕_gz' k/g[4D][ # >oI}l(J}RYjo,Hs ^3"j=V"UHsTQ9/7o3gAWe_WlE;lyzvMQ*Bj-xYM7y(+DLwOiEsPhtavMl ^B6 m$0;Fo֋!Iby}N{w琲|C<`JKy,.}G\J>UK7VF=<٦v ʜ]2tAۭn\TnӷC̢1-|9vD@kgZXp!zWܫjO_MT4-~3 ͚Y/G]OY"=l>K$2<'g\lr)-޶5D!`3SGPu:#c-}=[I/n능7izSRK?MzikTxn&hߋLqr|kI1 t/{6uʮX?},ڗ˾`(QާR> ]N ԏkK]ղ^Z{j.v/ڜp5."0N-INF#|T}4Nd!\d-^mB8^=LSW&OU5QcoĖj^ ~ ϧЙ.F*N:w-G⿫:[_%X]0{W Gx`fX2.T1H:xw<*H^d/2}B5o!ۏ/ ;ƗJt-$z:IRucJ0γ|YꌣQ$FRZN합%}M 洴=`=Sff? gu*“L@/"nS|YZjӻq:+BSFֵZt2 $˪׬|ңwcs_c '9>f3Ɂ"uo~dl%a"AM࡚xFnSj8Q6goZ7y)ZWR:5{!3*h<+լmU >]a.^\y+"SUiKo>.@#F1TQP OJG~8Q9q[/,F"LLƨ7-"T)ZZ[J 1/g3ʢԌ] [m=tXZpqb:Y'A9㬭vgYQ6$Tz×h]jђ#R,V^_j{!36:m{W_UՊ_ S?^ŕ%,_n JUMHU"/NrzR@_$B_f8w9զc\M-=]QtrG0MܒLER.S*sBuYt6lw GGR'9Nz){r*v8]);uFRLOJWe*Uۇ,*C9\wO*0z( 'jߟsBnz]sRܮw^մzn_2v0esL=.ea{ʉg8szN}oV&miʺ>(FrmlO~C^Lz͟F- TE+T56;FHiy4X.vT.SN|bs%k GvޡϲS'φS3sIb-v4]fF5֖u~$։"2q՚[]v=խeBʵq3hsOi}b3]^3;ɥ1kK#Y6VAŊd7ήM-ǫV7߿|y~{u, ++ܥR o+NgTU'ZY?Pn(6wmّb9뺡w0 .3ͬ#<`(Vi:bAЛj?~;ʴJKo;dq~# +q)?޲^YjST;P(w:73,=0kexkG h4G)_VřwZA Og_}MP~ԋzSpskBݏ.L'e>UpɍEgnR `]g8 /rEWܟe]l0=!"o7˙/q,|e~v?r˙h7cGfxاEBF\^ӣ+F:RYqGHx)_&!(i[/(gLkˬV 9llŗL͗5Z~  E%*n$(oy;R;5YTJcR>b1[{+g5jnNїp{-RUZ{?nQMSԀ3skB{Q`~'[_Ln^{̷gf,FәEӯ &horB{ >= ?jЛʜGz-3+c_v]hrV\LHݰ+E:Tǩ[h a04mHc]DY-1GwKuy7/4gA"S$a/̙UMƧMiưHH %MHWüŒd:& 0H( įTs$j5r3}Hn+dlVYŧg~ Պ|  Ǥ'tmq9a.Ȑ~D**xSbsTôDDfb r7&?Zvjc击JD>?c#i ՒZ4ʶ RuטD^9MYb霁r iAճIlkK$ odԁaj(/i "eiZ ʱFwl!U4#]97dVa@Ѣn[tC2QLYN`\=[!?[]CƢ. TI+ȹb?r0T=>Rg*XUsTU(do(lٗ`:ZRieq%a9裇ýY")co֥_<a8_}zq\ %9:>}ʦB*{L"eP)SYYD!( dMVfʪԘraq5R{ܶ} S"够5VҜ}\kTyHQ˒'"?Yrk CƔA9})yqŕ)n{8`V2R8 Tg2rj=ʵڶ; ;?.\) 0[֮ʟim[qJ:5rtzZW^ok[jce}m &M6*.Oq>b}ZK $r<V49׫38PAkuש\қ=)9P\.Vrɪ޹[>e1|F#?Sn5[ponN2 )i״fߢ }2N5T}ެa)Xa"h?I1rأkr7MP{5h0ao'(L Pmre,XiWx0 ^3+)Ey~>̥J@gĻ1YB![2S38AOdõpAY'"nb|?k~Q8 zwZSY2 iá `MkZ[rbC7_~ґYq^Y( /(1*k`̆nT.Kb݂1Lrەh,nVv,0 K5 =fTeׄ-꽠7.OiMٮĪk #uAMZ&Zpo*@% KM^p#OٙR |AMz'NU.HF3=D`9ENdj3D$((/>ZeO‘/=w+9H΄Lb>h JLSRYt0>1ʋ#y?,אm ݁iUxjx( mK)I LadMfm#Ny>jDN)0zuwGAKB&5tPȾo*{KMCzLD(ӣfSWn0T'QD6Yȷ#:oXL/ve_d P bcp6?#<:"SiObLzSH3v0 }Ku}sRN}rH5&Ga=KIfVewb 5OWhv&{<IJ\OV\/&#g1\/l4}<$N+yjS cc\`iz)rt<3u\&㬨?ZPJحb|P-2 Oȭ[YII6$l*u( q3|Wtρ$6O CZ&*½ZiW|7Bc3s;EI5.24@RJ ފ,+Ea&ތL C5+ |׳?rm72etWRJ\Y{eA\vAkO?PFr9WLxgOr̞Y; ˇ]~噽ⓔ\wО~퍳(ؾ%`Kart͔&X)4D (R|9>TzdBwTߙdfHrXcWV4+?:ޟOe%>9&,Ozz].3XggpՅp(<1dN\R4 ~KmФF+Y8u4*f(uS-,YfU-Oۊ*IwVA_}1[',U-5RT ]y@|Trr@;Y't`Y#-NΖ,[F85Σ?g$#䙏3ܸd^߷.Heb.59Tzךxo?I-s$䫲ȕ_/}۔;.A~m!Ϣ;l6Q?=F&ב2! FLsԆjO5{N8]Yx3*I6}TܘP8Qbf^S|iMxk?<']?RmFEjzlBOX!IWv?jgj*ʢdrkwRq0[h6q Q3qBSxOeU_Y/RDi1b܋ %^c;I2.DɺNyѰ[)|b_H-,N ;Ρe)5CUzf?kc`9ƙz62,K:C $Mf8Cp6"e^9~V. o("Jo"iWLm] 1Y.qtTh}mGDxs,M/<|׍v{ܜǎuZl8w[n᤿ƹŢ~J6LT b~ƛ2<%X)dM(g\A4X>Hhwj]Y)=h]҂nOĠ7s2]k?:h:짾FV-:TzkjjQ^Qllk*#Qk>V.U=r!G,OE]@dݝWsE}`?DtV6E @J#Ri,Noz'Gs51VQަެҧ.dlc9iy+9$޺|8-oz'~P^V)Sz##|1HS wh`?4JhH":8Qh2g >,i/Ycb5'ppT{L+'yGg+R9kV041sj Zfy[S2uɗ)h7\',uC>={YUPU@C EM`#2gg7m[ ı4]rV$*=z;|V tJm˟:0N^iZ 鱗 ?J:6zs?~"riW?~d_g?NRgoP]^Eg:7(1Vm؝Ⱦ )^W|ͼ"%_qyŽp"|pI8&WyRgMHwn;ItRMbvÒd?E~(l LKMr f(̗iH,ڊ.RO֤e}s3AI͒SU)kuΐuF '}e uZ}z6io< qDvο[z$Gǹ}s:E5W59ZV:Y}eNg}\RtTL:i.EPڨBY 'n&#)auqr]|<>o4 XN=d !wՖ3nwk V23Ŭc{/E|ۆr˒J(1}Ҟ:])iwHW/,׋'s_HCRr].j2%h??=*v)@*x (8҇r]I'^/^$9r|K%65C^~bgW?.Wi|Z(m1ѶBwoYGU^V gs^,3Q'NB,3^.d\PuevQIuP*km87ݵ\?c:Exz Wޠpk-ש$;)G\[%=/wܒڦץ@g5/$粤_ K/.]֋ E 5\iJ}-s{.JgަHgzdKvMY_̩tYTAUlQ-&^&5bL BoُiJ:n^0z_iɽQP複:yY~jTv1] !W*l7w7mۭN=.Su"~tsF54s,rOt1)DZiOQ$Z|OOA6[,[ҥ^8-_ќ*#R7 _,C M7eU-sDuiS`tg0R)g5>gSjoQ| g -!Kܙgbֳ><8%a@Gqps=/4;F0iD3{0U3Ӟ9ϙP'> g7[M^[G'v%`tC{;PrRO+wZDm6ÓÓE5 F{.(= 1;cO'0|8χzL=ʆ#9nW-nvZv} { w=z?JɨkwNy^L g JQM8 gl 8pR3ў' -}̻(/Y+tKOzx =K@Lw7v !m)&[iAR*r҇k?'NOTzî-~ܜoӴ8JX7ԙt\R-ԷqS~vLJ7bUpB= 9x*gj2:RÓJç,-H+ѬJfz^s7peœjŒB(i3#_9U+{-BO8ܙ^B bsWZ +ӠxC>4pwgr:b+ߡǞC1ңӡrS̠2 8I{>Idj@[qxiG/VM&q+wcd}h_(e'~җ0͖lGɇ; 3 &{׶Ѻ2,=qߍs}GtOqwoM2O{}Cc!S/l?ͼRO)EZd(9~*"Ԕ/nGX`ys>6`]!PuDƖXK ? [+ 5&E=;3S{~]AО^d 7ā>=`* * B:oeIZ׊[֥zqfST27' 5 CxMzhS<2s& ؎Tν1gR^oՋV{coqhҋ!P!Cp^Qt\U~3MT5zP7^|ohv$z{dҙ [Lo%h߸2ynMtpyIob(JO$TeEF"K,zA(D(,E`DeGsٳg=;m.hp/%I.鶖-V \DNۓ {'sHVpA0= /9DvUv;+uc V\64 c>(aYI[DG'+$Op;#e5v&Tp\vrk9+K *ӕ07 ~*JP媭$a1HaS~0 {U/$O豺ttW83KƁT*c7rd9)D;O@ATEQsm_,|։./Ǟ vjoK{Rl5Ĵ%i{MW2WzPM.][nF9Zm:ԭQ|*"Tu\vڠC' V)f'W h \8a#oÑwBHЁ;_/~ʏFms!يqS` I~MUn3f%"5܏޷0 [2!3iY7aڛ7#3iqD^HLc!V?*6dc#ZT3ˏ+U:X ZA.@'@"7˶/6P_|Z"S}JT+<~:9IُkB.a]^[am}>gcs6Ej*o?_b_TGſҦî,^{"E;\3wDYN>p bR%ǧUZqcN>Z\C4`į={cPF[T%5X>qQ^VlJ:ErN 䡿 bmi *@A(BL%:m1.me cbμ,e) P$y23ibNeEbKX-$6*r3-8.V=x8>Ղ% :P7Kp>ʟ䪳R!u_yp W7o4TAdHu}/Bu[o@yqyx@ %.A Q$N./>M\=ʏ_ < !C?_߁''W -mÆqE\aebE w7,*KEq|岮D``m+9+|ӵmwWͳ<[ yW0ocA+͊\iGUP ^Tw@:!3x6T=KiC5[[mo~i@xY]XYԿo{j­9sG;Mnu4pc U[pDž堫K0VB2@lF/ R[.FQғ3Yjl7D@F|5)9"0Lu&@i.3 2WZ^FɘyG|8ݾ3xvSơ*f PĴ ؝ a !bED:J?atiS`UE~k"Dn~0Ny0lS\X!S;% 1]/5iwC3ƄX4`P4f=CdrѐxgO/=Mŕg3` iZH`ЗwF,,t [:v,Hț gbJ2zV98-o??5&_kOZ5 ~t#s6?`?}ټ#a׋)EneRFv ݒo{ڪ;xN's勫x/;{uuy|RE1^0n ˀPQjcL҉a lLgEn{qR0qw(驘Uݑ r-~̂}')7r:ҵ.]hnl #7P9V`|d[MDqU*uigkH%cu"u26r#:u .ӱ*`CW۪lPh}MʻFDNom.(Zd5J,q.puy\;7ƚ+ zY]I@[nȉ1W=8Mo2?c+Ē?D!?Czn= P_rw$CۨO(3ĝRtOT@>26js BA1D,,2)4+@4 v3 Lj)1ΰ#$V7iC^)pNDތg.ʟ uL[aKuop܀5s6PeAGV*Ѻsc2{k\!wm]HzGR@0悇f8gALEh JL-+`)a"6[Z"$#=oxWLt~abXӕv4/?7$oԏ!1C%[b#s$(c2 IIl(7cYdvn=WQ(Y"REZF׮l%9A}.dDNҮ}4ML072 S2 Qt| -?D ".]6v¢5E_қtDŽ:'C B!F.,nЖ2N~^ڮ^1a"PJձ$ʞhΤB$RH[%k?<#C9(wv@iulE_M:oBbX^H.lec*Hc1CYjΛEe1f,#q#7J`ؓf1`1AW7/J W\(JaelP9[8Lµy͍; 3֌{4xwwwkc]$UY(X. (M $dF4ǧiJƙ='8=qdZ>o N2wvw;6%cDЦ$7dSW2˱N?*@XG:.Ѕ7˦<+_>HF6CA `lЅxm8^so{[aj+ sJѥ@tIU|LM6)LimqqCQaNc7Nv0ҷo+n)iEDkv0G`] ТGq0 Bs^% U*kLC0>P`R-MdE*79<Y|GmA IvZlhujmCU`+13 d4{l Pbp.?KDĿMHD$t*cjtl);Ԍ˩8j`ҰGI#tc! FTT ͢Ř,tPKOuLj,@᭗2/3M%#ECjNA#iEݧa3Cj@u7Ue$]əe_tŐpNH) r\ye(F(P GAMOfXi++3|9)O`j,֦g^60R=-# aVOYޡfj c@v > ]f69 EGtVR!'_ѓpemƫ6!aC~-6C"Injۥn2#\ˡll8K=.nܫ C r.v?,Ƶ,Of/*뮟V ijubFȓa 57CCQ‹݄i][ʤ.9⢒+I$=9P8_nqi{;5xoWSȭ:[EZ1\UC[?YKmf9X H9X1RI','/&9J֑R]~Mm`y g7Rƀ '%;w@+Ffč S~Ի'3KxɹIڽ =RYl[ڴ;W_ ﰷ-E{~M_横~{w$o٭Y@Y ;;v&ѽ(s{Ċ/<ۧޠwtrrlKy9v;ZЖx`5&$6--2-`zzd5E:f*R@ptCTxy,${kFJdTru'`ʕ>'l c}(QKΡ.Zu`ߵU1v31Pሥi?ost9]ٳG)rN;ٷ˃岝ZvkFaGqI ct<<>ז2@eRM9RHd h14J~t2'?zOKf/jg\ֺLG+RaDC(g[ 2Lmʛ* -"^u0z/\("~Fb(kw~@^_ qOZكd5F :qI]?<ת7W¦*kq>$Tq5)J5; N#~j oUרּ 1FW$غQ? >{VyPgT%^4{=x̽3F%!xQeox{Rh84wvеM6 ,j6":jk#lRZ.zkd-bl*U鱈=dÅwOڕrV6 %SñSԥn#xy1J|͈]ỉv똲?W_ 1V!5X"*G3{Ǽ`Zv!cC ŹUU-n\3*cB vFWEEnt6}^7Nm(:F 1e}\joJĩ.ZT e FVRŝv6l=0h+%Nzc.@~kN.RHӵ$Zr;_uRbtWvePwנi2~cܱT[EduFV#'ՏbKa,"hќ-ڭ(|_R$ƏqDg~={ }?+fq0-5vM$C VH'-5.~{=(E6u1LU˓y8e<^<랞Zv gT\x ã<8;LgN'Ñ|n0w;J0}sQ涱hӜZv\=Uiq% )'7Ŝ bu bT/,o\3Yjư7[adß%a"qQ$Ώ**ʚO[Zv&+H&sN5Pneh0aT2Fa(RIeL>U Pm$ dDDFcntXwҧN$1KRg֙5J `6Ljbj PMUj@-Q5Py3]~q %R*%)@!cG p LWSTSJbU[-B/9]D@kE'69[Fq!/e$_j}-I~m R{?c F*wOI#nL8"1Q0cI4UZ1(V~T~ vMX^<ĕ’VWa,iUeII'򓇸gU xXj\aCliY,,.WlPCZab +a"gE>E~@|yO"*U<5^TCX,ڏ^dYƟoF'k#2 >z+<"rv@бD`ѯѐ +Q>uX,Q굽~`£hoDz8Խ& .\PKv_t%1GҔ j ~Wwa[]^uL&Xӓ9MHӅ35fw+1 K?w;?ZrI+Uli RH*[dRp1KR  %C41N Jf$^guixsq1N3= z,\aoM~T11q;&u@ΊTE#dhw-8U0YSXOk. TXQqw-L&_fMdZwto5]}~cv|Dp$6\㚡<~G1Jf3BS0=oq*1#Ya\uސD~ֱ9[8<|{@TuN.tpâYL+w{:ௗw9n-;1* @E0DvUvj! g0űnBwG`YDU}>iٍœê(sHrzp9K?zO7ah9܃oTmBNj@[Ʈ@A4¥D 8k^@F IC\xU5τz}!B]33< $NTSօV(J~@&dj*tz_!FU)6wҪ*^NޔxL *-")wJB.6!ĈD6O{Nn*{r;G n; |l- lLR1}Z %g0u7oMLC~Ĭovv*7=I fg~˓Cx ~'aoz8OSQI"u33y #t̿QƵX2;Lp`yI+'NL56LXDQQB2Iˬ,uҽ( 0rc}^Hu:O0eϓaW_0nh W 7`)j Z gFP[ 5l<0 -fpDh_QedR6ᱢPdյ ^sIqR/5: "!VAkxE<&-TJI 1 yT{?d~| 'O1 c@`?m]r}lqX! # Nmk+' 0@ n PȒϖ7 XCu+.b75byvIIǨT9HPs=KQ^ R$z]"KoqonA#uՉz\vrEm,(xk9ܐkUԟ ގI23D6 ^xXaDeu8B`+FnZor=ɠ%όM5υw0<;{:ƿ$#NO{! )\V&o4U8<  c11 ;Z>nR(Jܺ0~9hĉqj,(B05Bn$`KUf8m0d`* ewkÍNxdžZv7h-'r-!p,B+\p!‚2Iy8dECQ\NkUU=d4]AH!KZp;[%)m}}u `)*|MK&,dSoDc8>1vJ3.& *1H):PC5?u2 .ôu*=clSl]J-,cåҍL/E4)?5ڿm*F^&[~Wwf٧sOG׮~٨W4j!0o"c5 p#Xa1 Ն|u0zǻ* },tHR"ġnKcI-m/ ߃lX$lk֙)^{gynpw^-\pCm=@ U0CV)fyq@LqR5?x#YuݣIWky@Wh 8uX'ޱ=ϸko,ywh2@EsDNͳ~wjHq|q8/FI`5|6P&vBPtYcIoდs^t+nPY 4:A?w`%ّXӄ5@O=_*.^7gꦗr:&ȵ.[*tQEUA TgB]T?W4x $*h-'\r4(ÚIƅ_`@DFEꚃxB BndIV;!K'a u3![Κl9}lA̷y mvopz;MJES$O!IMxDDx )KIDn^d|u /1rT̀sD"8@ZvbeZSDf9:"cli7&ȯKq4]+ Y~r2p݂g@8a]GXyC6rfз@~r :Wo%:hkdsa0'ZKeHdȈ<ⱟP1҄m!m[fb˶y\t ڈIW6)xPi0G̞p)RWjUk{Ho? #@;/?8Z?x]vm>*A(hޒmA[w`m>+Y{)Z Uָ訣}[DJ|d PZxlmxm[4F`ܿÈ1u6yU:IP`bJ0$*FtueL8 K N:P!(*Ɍ:yq*y_J3F-b<-"3 6h^vz+InZP%Ƿ@ԏW9\5Z⺺w{-xWLڞi\7CtF_1tYo]bdnm$VaF4 }ja|.bCFwU_%cPAZ)7qV|~rk`nySh2X1͠evqh8G*6񢄟)Y"cbѱF+¯ Va.ۿ,FXx^ә ׀\W` 0:\=S #ZDi}+'[WrzQו.[3HaBmo.O[g[rI1tܮ+x1,%k%I1 |?D]5xD"RNkLBbC6(ڄ-Dfw51 $eF5r$/9ByǺMFi МNZПj Si\8X>?۫yL>u C(NR;aG)C0I(YyTCa%yo#A}'Ѿ6yDc'#Gm?R(TrE0ߵ ANȍӑ:: yګEȂy.A E85;]W'5@]<k`LjǮ+gڠ=ꚽ}>lDtύ=476{Km=lhOKA❭Ѣ)?gPLugE=.؅|ݦVgbzB3KQD>]8lwQm$Q{kѣ$GAHJh*d(Y2޵e|Y7F-ѩn 2|w!ohq Z> r#^O<0IA!p4j,bH mL4Să( AaZk'[ 2[rCfYEYbʃe($"}x4-yVy2o}7ưlōv, ?̶f#htxHMˮK9_{ oq%N3T Z%'$'M;@~̂ϝN6쨖A;CMxעXD:|yI׼*in_6#GI Eh$]PY@}fm%U:%7I8k9 TS| X-FiCIá%"rJ59dcCYPF gkM(PJjRPh__e{$H4cjƻAHEm+MKGYGjYdAn%4N"v  x<(UUjjp㨵+zMweL/t ]gT]BG>ߣ?>2]Z?u4Z(sP7:(LKT(Er@C0Z ^TD2AWdIDefO(ej$gy^TKڛ Ac/YVI`UTv RZUM)PN0=6Hz+4!\9mn5,(w> :l𾆲̘DR܄YdNM2(:\Ud):_zb~QgRDnFGR+׸+A"D%H1ӎ, ~t]qDbnه 6O))It֕9W'=DN< G!8r-DIIBȟvta9QFaF❉:k8TЙvvgށ `P4 uc@W03 5C+ #8 ƣW`)/6ֆ :4Lj^3B (aW llNWNYomAߗJAŌ| #E4g*lF 1tԉ^tJ?mW cJˬ8'/f k/ [z^ %=7Zݫ4x>#x>.]Dg\|0#X[`B"ٽhfJuǜjԷPyd (Yd5f 9$)` t~K5ٟ:E~,ļH"1Xi}yOA6-i²np6hqowf ]_#$)ݵI9ҒeN`aCkc|^όZ"&d~Hň9vK@"l,.mf}nwzR;#d!*:\uP=\ "I|>MC -sACOKVߕ^?ŷJ,+mr1sg(f*h8w*̰[? w'ʑ=ݢvaMq ui9li]]~ŷ @s_y8چےx KP1sh̎.ќMPLv JyM]sʫ!b&$x!?_~2av,Hѯ9w~lT6iT( ^Ͻ/LqRZ\2Iq/qwFg!OA| Zf}f#uҟ{o{38A>, ƕ' S#f +ÁϏOgk q=wa+稇91rpъuqCjl@JECQ0?ؑT"=HFEڃ2sQQi\*NfeT6*,*]3%cLtշ4lbȊJYI$f!#ˁSBH@DQRTs :RF6XEH2 g?i(Kէx`M6I1T"s Do2t$L\|*O g/#W[Ύ3&F%Y.Kdg, <ȥZx&q4bE_~bcFGt@9T{1}d "1~WYa]㧟`p:8>7?<{cv.aZSZ)=V<}r>(6o.}lLro߾ z!tͻwMȿ Ň~ ɓ {''4}N.0_qd;Z&4ssR; 8W38/ ɿNYGvkN\[xOR4O3؁ # `^0#Ԧ4EH)Mo w[Y e_Ĺ9KzZR[Fwn!k]9dNu{gGѦ< G.3& gCO(#hohB^N\qZM+tVEX3!M ~o?&ir=C"Fcd(i !.!4’ &9 J)9H)f`L26}edF3 ;S#֡ Z3D[m1j%`aÂRZVlf;T;7Z>@9܇x &T;3M#02 'iL(sKdR6=yNyWmmED=w6ё0wÿiFwVvtx- ;y t0'YbYjmL-T 0{W9YՑQӅ fKv1TˮK&T+$"#7B ip4qJ@O\͂YZLK;k-AВueh6v&ݭJYRVd4L!S)yaqs'#,8a;;,EctBdbyلRiɉZkYc*=ZMl7#,Z` 9h~f" fD~1,:?ş>h?BD jjpe&  {"ii~#e2 (ip*6oe7Mw{6ڍ]# A I4Sq"bOq?+X'|AD.௝a3rZ$lj8G8;4F8+Q2Nhu`2e!&@x3*&6[ey0"$%^8!m`:Ӑ0[p i~:Qb `XRf̡n<ԧNz :l5{A'+mrl7 X49f(Q&R/_vP^t])ׄ ¡"T|@UkNՈ̝0]Ba\n5cC)tkfܘ[- ٝ={S'a2e&eߚZS?TJzoa3 ћ ǻ&/QP(m)tSysMyE/a43u:pg&}ıO?fAm/?d6*da`Z c~de$cg/˜mzՏW5M9i֐6hiSC–7e9NV0yzga:G⫲!;8oΝ٧odwqb|p:>I^gcsb/ +s uIS puVݣ[hƅ cɅX˘VM٬y-Ӎ {ǛXGlYON=4.G872bnlLN.vaܫN+ns9Zq[&;gul:"SK -&"[3΅΁/@l/|Ќurv̥.\FʩuLgL.dG9;hVSUxlsr5@BU]4s/Ö*1WlZklj8 &@JzQFMzT`y9' u@6FG>W=)?2ӢV}KcPz +%Jf6u1=[Fm--r.7f񆂗gjSC;|W =aLq1C`.߫CН0 Lu9?r"w6qOW*]u;XGЀЍ[5C:ޏuQ?J@/{,}{39qȄB) ]+>4B28lč9̡EeFj9~t6 c)t)RPk8 @eqR (YDqm%e纇`9K6I(J -`yvleqVE+Wr?[ԿoΞm"+9IP}ˉ &Zr=\1G=sKd[\R>mrH#KWKnq ."-Wj|Ur`vεt0*{t#wlFf9C^ɣn]Dk3 *95`MJ1J&0f5.nr扵$=?,:X~tȄ2ޡ6)GMim6oL9eZ3@\ BP~,4A;l4dn\0$Oѓ1V]rlA&0'DQ}Y䬿fUN-44MW-Ļ,id rj£8nsVp]$ĶXr0`RvXe% *.9̈́S HشJ1FX:*3*,ttHؗh,.^;ƭ#;Э:N^][[-]8:i?acrE+r,|`(0gt<tgnEDU_Bow*GM8>]G9AcKcdցj qB#fFJhJqI|AD؆Zַz=9llO3~\YZb yQx %'qO-"6(dl+e۷񤑻qx7U|+<ѱwdSgV!2n@큧g㍡=PeͲYf1TUݾa21mVKp][鞬mM/>lTǸlYX> &&{V1tv3S$W6Qa*8ǝzrj-; u\RZK,(IRz6 Nf*c S}Z?xp??B2zeNUM lVi; /fa bsTB`lɧA2-ÚCìWg9R!Kv5&X:׉ft'˘TP-›pbƗY4؂oxE@rgFcAWz15b~.2⠣K{ԏ_-AZ[)4 d:uNj75pjުQea],vrIOzڒK $8_iHmSSrk}3c5]^Yu,Hx/hzS5-"#O@vqx V*2fưbf ȓķ>` RdL ]Ph ե%1ELV{ޠ,!{ŗ65~D _ZG\x*|I^ۘwJ{>T)Ο%8/( 9h>x zZ ?΂$\3.GcYdFD@>10$.uDb[)[j8o>SN)g9X=_4%'JD >AIb% =A/50]xnpQ)% i"^V\Y2p%ER O\kJC&Db/²[Y|0k{]ocNɽ9stUAҚSzLIAØ&y`~bV X^d$1K`$~bF݋짖åJ Ks 4(u!$F"`*-*M @aFlIik!*8/=c ƽE %;;.nrlm͹\ W=$aTqJv!ED1) ^FY<| MJJHZ\+ZR31) a&/SWa8+ "N(j_pT#4%sU"asVaH%XGr#mm9  Hllg9.C}x \롟h6kh5ϸ%I썒q+ ==ܛ(M*?/5 ߽0wD؋W8Zz~uZQ7;nǃ1? J&xmgȸP^fTQ"Xg aPqE tx?* ZէmN` */m'o?l~_UP4V!B\a֩me_~fέa%YE7&!/+dlx?1@^т8fpeŠ{||,y&ai>Eઙ_BodhEP}iIՏue #;DF\+n WܔY&2VhڀxtJ䃄[BshGcSO5cYyhc3Vn-ݜ{G*R'HLLe2d~9XEJ̰Iv=ޓxOjEWo:wKnaPz:U\ݨZ;[mg`Fq >A;B +U%|Ws [@8`j6!3lCJҽM#U!-NfĝTbŠEfe,D}'_f~8upgze-iYFl(rUWi4 ^#sVt_ZI}c_wN\L~zuH!%ׇaW'wm~ߵ}?T{0 SN:}U }NuXT]3DrtRDܪ,`&. }c^1"Y- yqØ i2GA8#! 3n#hDC{lC.PkE:>R')!,T#~R(BeR3hLQ~(kg*;n,ıJ7" SY!"D }1B\JQj1Sm򷣧Ќz}'}ȘQ7Xk0}4},0SƊ AgzTXdPj)xvJ\R}nvjkɄWʳWI$Ԯ*XZ*Z4.\ ";gx 5<= 4FA_LmݬS Ķ0T1T YB"慔7̊RB"'qu. fYY .d KSunnmTd;I{?5k9Zt4쀙/;hZأԀxscx$uG,aV | $]:x.dABkHQ2nU;YrxX>.Ts`),ҒG9՞=Ti e"R^ 5O0YAHcI$),>%bfPCX',;xƠvy|c$P?aPy̺EBʉ Ћj }pnZnʅ.TզХ#?(AEkL4:HX%Ǡh˲_w[4"7u/jQꪝVĽ}LrH8cI{a I6q-1\f843UpI }:"|@ %Q0 0LBUjF *PAٶ#w­G&GM^. ޻w'R\C.:qifR$Z^<'a&J#T &`L @ .!2>0ǨUyD1@h6m/=2/2<ݞUS+*S+u jg*m,\Fֶb[p h%EEy?יR7e#3:v1~xq8]JWĐ Ev-f .yٸBϡ?+A-}qH{u`ϫ3)l*5mի߻6x-%k؄{ضɧ w[@}5$&edFq2/=SAҠv\D#'y(׳эkqJ#t VVPߒ~q%ݖ{=3V~a`Y'$*E,2zJ(wt؀:] #f *\h_"W'΋k?ЬeLӶɛ׿=0D~ֽqv~]۵Gv .dՖGw{>1O6p$/nߙ+vfKp^w_ԨB ZtTJGn"`M&%Z<5A{JڰEb)XCHXAaP&),Y0'K, A<Ӄ/ lD@_uKF$~Z)uU $ ȣ0!>iF$ǂu /4|zr|1%|Հp&.؆Bo8Rt,],[:S1EᏙ?V$=J|߂1qKΜB[hdSmJ.ˑ4,GU''~GmK[-W7O8'+[d~\'% -s_ G1DU[nQ8A7{s Onj{Wc-gæ~[lZj }"qh%PA[xZO$)D*r6;XqE9+ڙ'g:vǑG.4hm(Ew-*B_9KJթ!r#ˇ b^` ]4_zGN6|¿_ޕzt,q3ac ºKAuRAzp$; 8c!S?bPGie@0e'Y|7.^!e,<3><0A`T}4jK_\] ~ȲK~|'CްQԧqH__0;1r|Dk!P-GȜ<NN?1U͠,'I0 t y]Z|  MЎDHxgc]ގnr vGQO?R45N_G*brSyfIs,:M9^ Eah|)I,FI I:~LBN.;IQ>KJ~徨?a d ;,^R\TЊf3Iw 8޻nmd邯NbV!_TG^˒-6V^F H-``Xn_ͳ̣ԓ̾DfF *emg2@\v˷])w@i8%Y7޻}3 @fd[\>rT 6FRiD nέnW`hY^ZE%2۱&z #Z;P3)vdbL&/sJE(# FrnfsA{bElv={ plPa~3@VBAZW68r~f>16Fz =Ο<(O))[ќ?,4n<&R|)4:gc[>pFmĭ:eicmvf,ozᨬ;d'ұH'AĜ!!-jEK]+u%ce6Rю"NR|`ڛV^]k|Z9'bbpիV`n'_kK uٱ-}/C6۩ a3V؎,X$BUX \"pu>mY %PFjCߜ5kn ;p<|=tO"Rh͹Qwد p fvz3AMh{8fG\$"O'pF s_Q r/h̉+c {w+:eÈLirI.*+Fb *c2، u vgi,|f~Be\}[J?֚z/ΖcQ*#0lqQ|hU]wn2Qo*.bw;yC"" A1OR9Yi* bsBoQ(},J[9~ip-uLČ#-?U^ai5Fռ`;x2m^W_͟W}_iJ*5p#vܞ7ѥw[?Xڻg ,韱 Xb{0-P,}\tG-jA׶[J6cqawf׾حTUYCH|:wBJPe1EAo> f=c|}$nj FM>r&Dtfswa#q2 [Am{aYzaD](6~t[@ucycQ?=m|C.<8۽Mr3D [?&}d "ƒH@K|7(VNO dF$|WT`R[A (~`xZaIJ:޻If>*ov[J{ Z\cЛ27{@z_)^ԍG ~xRؖ%q fQ OmAGf.yR) UZӢ%zZ(yXbŗ֙-V4C ;[)rU4($>uYӼx'׳.p0$R+jc72uVUCui~S_Ĝ^8`(iH:J5H&&3:T fg)E\(Q.=P6i#; e؁E!:VSR~8@;` YT#4K=inu+#t]?K[bu~ԁVFH [K Ж YhnNFutQ2[ɸmɸK?qhq~>@M-Wlp 5^xL۲{A-7WOV[EۭgLCtp]=J;ֺ>7Ul?Wy´jg-\)lqNosXex vo>k״^k vG_yT˙ע_4BT@;j?&/l !0jO+V3 0Aڰ TyNGiKH<$SCI%.u{W@fx$(|(mL M9nv]A(+o=b:rg^PՌI;A%[*ٽ *9CIqPD^H7 ,i$>. cX;g84}v;}OsHpa6rq v$bM:3/ BF/5H*!hV_ne+y`77_2 4hD/nUPrl+ FȋirJo"E&uz \!LcᛛXv|NoѼ`? [R{r !RGvϩaᶥkz5Ls FdiՊl{tZˌjVx7n` ^bbico=FVwq\gֱL[=7պfN Vd[<4X2>e cs.!9N%el݅ꯉyX9=JIJs(!_R8SY Fc$}֫_@XM53ďB+[1(pɋsRZOJ_q~Jw+(5Go(B'O)N\Bsw!q) 8]=||¡C#W\![ֈ_lPVޚK2 zXv^tx']կL-uD.}6t̰/ ~^N,"kj 1uhK9a]&Qh~0n]=~ V P%]&ˆ0eί R+fA y,>~<O+iν'pݗ4i&)Qӫ5${w$4.ݱ4<ٌq&gKch}LWӰ!A(ʻB%-<,[{&4FX Ab$վWxQU }ʿmOj/e2/9G#'^> ɣN{07?Nz!5sr=yDEX[M6hovxyA_L.Fz nZ|GX7Ow^ ߌ¯#q(?/ ,[|qY"R[S˙@(Z8L4ztҩïO>BiE/Mp+_ѕ?X7ѕWT-Y*b,{*le=kozH( |!4=w'uv%zwNiTLޑZ?-[e}c+۵>뭅N4ci,Civ,9;`HjU$zH9IOLǟOho jv`GяOʣ{Lj^tpzoD cB_RCX՜;O8Ii :Gw;o bo>u3 N"2p my'?.ABz~C2 iMdO_d[)C߭vZ&#xqkD4W載LNaVgXLC+$]:38 qe/f}$Z мfs݋=9aUNXlګֺt0*ؑKe",H|`$qMg427dᭀ3@C&#:YDT?')fQjضi!7HK/zmمQ*zrb-ᛚI*;MoOiojcFU[=n;o[KQX)mKnU^^2q'2E J؍4rH ).Yp*GbMAFo'Kqc) tzb2t'v@<XPxf~Ty`ܬ0t];0UPod/]%>3Čx8X6 '7 w D90:c,:;؍z Mȿﶮ3$uꗾxѸxc/Hs@\I>S{) 4G.M0miUF~ _H $ *ϐǑM/3D.67Z{ ڸ#QQU,E[{@=K${ʃҕ)fܯء(D )' shc &q%hb p"I*Oj1IE@^  029VY"vU@lRƾqKʋаD:ˮ(^`$Ϸkƒ.fٖMcBN鎰[X{lW<.V vWēqY-rTQEwHǒA0 G͑ R^"S̞{xԒ8n59A-Uk*el$^1:k;x h3_UDX'PėQ6$DIɹutI8oAIPƕ)A4KXڀU!0l`{sZO2q=b3,hPQ:b}Ja>PR7{2^>q G9̬):;s1,p aat6I=,?~U{r؟zOwWWU/&yQc}2JZ"h`;b ӹ9S !\3 ?`ѧU! {pv}@S#V+&]v qiBTUx"O.#D| Hbr7Uϛ&!3PJ=z돫 ;rAq"qB:/;Tt{ jյ, (RF_dD2$uSd,OeȲb-5WHש2DFf$96b8ōƆxSj |q|y$ԨFi_`B T 7^2 tEݦHkwԀEY Iw;ƷϬǼD9,K^Ɛ©_@ofH毫-ҧ/y۠ש۱b4m9SAdn,c2?jarؑZv Mȑ'C~Iؤڧ[ şNxjӿ8a#x:瑬f: _KfpEDCI~_B>.IN W\gK2?9h7[ ǰLr F3T`lE!Q&H:dz3")S"qw;;Z\.e C@|Άl/}?mZ&ֶeS\H-; A?`NVΗIXmQ&'z {D0b,q'' dfWRnq?A܂~q )C#?Tֺv] wuWOǖ8f^:$* w3$|`lɠ߭,M=#dEV8Lsl22Q~op e +ĥ1q嫼?4RI^^#<ДV\ YDWm@qyPUh*+U "(yOEZuv=jcro_iy[ WH9Iuk! ZTemy80wq jΤ"Yϋ 'Us E|i̜.6m|>FjѠ'E1u=3z_];U9APm_ٜ$Vz<: Le/a卥,u!ДU̶|lg/lcιFLK%€l;~[EҍU JdgD%KB 3RVpvap }_M)Z={e(N -dT<I{J(紑4cgOƃQ5Ǝf`js;[*j}UW[oaB[Ł@޾5;l-Y8ޏtH+ 4oS7sdRv,fp5UdYQ!i!<0֦Q)@fRi jhPd(@61g|&.b`pףOٗ`l0 Z6|~S*sKvl8'ܚ;Nݠ\Ʀm8uUAP`>][o|/D)R.70Uzɜ:Adu~nb2>dNi1XeJ$ =yי\1:Av%>"TvY&HP %9I/A&Hwl^Ei3QeYtn8D$N<2^)(ʖ`؝2?$U˿kHdÎ꜓/'B\+YiaM5pVc$Fzʼnyt}fBI'^/]ݜkyT(tfFG%2zglqk~ ;n1YZw̲C :cQsC똿;Zj+T:A8í&-?a؏oS&@.`.9E z|VxC5K|u0E2q NN2:29?wHȧS]:ͺ5;V|zT Nt\,*anIF@aj?G+U$~q6$o~aLB-wALW,Hپć\=:]"7bm8dHNi GW)]pj7%U@5Űp_ppmYIo~b;~}~Hxxٵp '>3 m|9c] ;n92|~cjݞtd=?T B`4Vgn#'qJ깲 ׍ u'sMc=w3Rf`e>r>DBez"Y[pog_#dvi&Cw8tY&ivA? j iݞjlPYI$Ce)TgK5]$Sy{Xg "eTۮP/z';|U!Ǟj<7`fz1S:`-LBO)!Z!"D\fL^ RW;*[鼅16X^͝&ls=D1IF|3`ta.1ᒣVso6MWJ ꄞ3+!!_9T|\qɫN0 XRTr: O(~(^Ju@lrWZkiw:>K?+,*CY$҃U j:j“.Bԉ(B:B:.Zh+ud3&|h-ҕ"'n[urxbگcz:>֜ ST)n|Czrl e)՘ Mqxv"<ϯ"۰HZd_WE y(tyׁc3 !߈\"Mq@Lx js_jF)Jo]vkT)wof+4X{M P:eh='6d҇ǾhqI!pVGQN+[ t7TL }v;Ɋp"v K-qt * BexY EG7X7+r6U2j̐rCD=;r蓅inӐ!d6C=Z,E TO\{$)CYn٬qS9ՠ*Q5lWޭE@GY8*UcD,/U $]` GncjU&))MXAkǡ nH#Hb6X|Uz5mMf7T659GU6 a[R^||L7 ɴԷCM Pl?7(I)*ޅs("cCJA^ †Ap L)ܘ)Q>tLwpt @W]%|NʧKkvi Cfa1`2G@p~Oq6!Yݾn"қeU.h#@S~! t]J`"LvQE`Ea -&M7]惲sҞZr0Ww XJQ2ਗ਼D8F_L+HIwVA4DZkvŖ]=a%(kEadT]DZo-51Ȗp5xߏ)J]8[|&/FRX/՟=2 6@[,TyPYSpu%v{mZ}VkO}Ы_ {DCT\Q06=^C+LMɁ̼$i)@neBb8C<=_ntj3(q3<7ؤ1IMu Q8 Zq!SRt SH<@my\@AOY:ZR)fuʯsPK@`m:hxx/}~La $-mǬHǭֿ,zV3dRsHȤR[бs2*SҊ「"C5e={5 QN4(d4A݈~Ώqн^qkR7ܫ!sgRs!Me@bO,GYzטnXgpïVTLy/=`_aS"fO` M5,qlp$CLzbaJ2T20 \3N&2b/9Y bO|Òo"_/d7E3%?+&W;5}bS4Y5A$<;; mXZqٗwywZt7Ts--`fV'Eb:VXR 5 Gg*8u%QxG7Й岜#] HVsD@(e\* 1@2 |f@'։/;j5 wwD]!8z`> ߭V)oR~ kڂn"uu{߸J\\Y&qx̂oU9BZԋF7T|uWol'emBWe< M-Q7x3n_}nLRhim`/j"8K7;ÉzH{'>?8dK3 iطDDz-po,:h—n8B=J1*7Rmj:@V,/%n w %xFZ8YY} AJ'XNv`0wA'Wm7\OTrSU^G?SŰu'Nw,{` I8C\5RQQcQwL;b;,-{mX'}Oqblh׾%g-XѕM]Z]z 4+|*lc 1JW˻Zb͑-_BGCow OA ]BM8 Oes_pY0u<@XqbmoTjLj&钤3L/8Άaa)^D>ՖY~%S/-ׅAHK ]7^C1"| C#d- ! {8Awl[Imm 9#A996s^<&jjG/I]/5G? eD(KuiBb8 e%j [ +thS|xBϥos*k˖/o#L/N쓎-~|^t3,38C]CQ{wMW^|~3Bh=e~-\myXI8~ӳG kEkS0^*hq{[ꛜ )v'b*Xƒ$SP ċNm(*_r9NTi>4Ĕ)R/H֬ w=XMY'rBVT d owvWYXɑ:涅G!:pɁ;I35+р[W$/`T)`vr><\JJЬIQBR N 4&p_<>鋧Ofyb~[Dy6) )Tuj]ߢQ!bSl󟱆TXT$qR3:?pZOs :T@\s;(Z?| Zk~ֺkǦz3/~*Gbb_Gn}/|hD 9ϕl΃cű.\6{ ^ lJUp9Kx4󅎾pZ] e`WajP:uRdi>[pi#U}@^tu凘+(i7mrvZq7Sk]nEg;&#JnK ⑦\X~4I4"ddL]7u5~iP h9.l׶G`֊Պ/f=ܢ_ʪzrThԳ)rUX}4OF:]YAY:7.^kkTum+M5ԀC(>z7vӚoG45&XWp+5GhZwN# Wz0`;,)[)?\RdnLƝj;DzӇ/q-8P4LXqש.1O @j.u:&?<}q8Okp bj= [jr?B֚ke +,lЩҴW2 cdyVjr!1! 1J8pt*+/`LVfD=}y!誸,Nfu%>Ԏݟr @E9R HF2onQITW)\MqQyXcc9۳Zm @2.svsv.H GU\ @oLHPSK. 1MFYBVJIov5Ű gܘo_ WMT.4:%M7ք}:9è;5q`GqCD2cZ٣<0אY YJE[(9\TgU^؟U ,DY*U냫u4*t܇Va^ [xTJuBfxj;etӍI}>%}̤S=C,A*CSٿ#CR?멑桱j^&/L/n'[@󇲽 SA],˶|~Wmqj2%pu0}^̗#u?y}Srא3tE hRh&U(85+:ǜS-v U4UTT6~#K #axK0^OWDT(979"n_"Џ7#{W۾"+>gWIɣN{07I?q־L-2YM6h3_;bt1\<ݭg`WlWm|t.O`,G.y( .(8 ҵʣyاkGtNӳ &+?g1UfnQ&AeXٷ-% zgꑈoC$Wa [*W$kSGR,)ӴOXW SJ /tgFA2ћϣ )\y 3y^`'CfIr a;V呍:4G V=Q\d=p3-qilHkZAP{8{8k8h}/=w$(<3>CQ(VCyop2uY:骸sDHe!fx~2\^ ]#3prŞv ΚOwr W|d$akP䈧`v|TL3$FɖK=l!GR; kw9;k~v!Y(qPyo8.pŌKey`FGv5/w 6ԍ_e~nSulf)Uu]ø+( i#'Q 8+Oqn;?1fݡ `KKZc57 m唬?!Mw$j<a3[ "ԕAÝ9q^JaD&ZG{D}GLw[npkPRnκzc4pb>U;l2.m@\\ d$Dd] 8I%ICoxpWSl ¿",JU* m5Lsw[Ѱv\w1ݣ0§jp*1!SG^EEt3rQLP$pޛ6ϡ30v=~{[W3f|AY"0r[y#e2 SI* 138"XS3l!,-?=kߋ5=lc?}X]^;=R˻v-f:=_Ok9n/!;D2r3d]!MN|jLGkm÷pDtĿq[hθ1Y45Cۆ5|\3Z=LKtQ7|VlEҠ eaIq`auHLGx^+cYc?Of /9='ӯ)j0 \,\mG^E)d<9ؘy[_JrߖnٯsN}t.:JFO]KrQĺ7[WƦ__8-JFPhPT3o<Y \p srA-H.z=vݟ~;_-h؝Tg;zjCH`ܝ/ҷWÒF,eU-^,YkfTgӄWC8 CJ1hyuS 2.,k/ 2ғ4ڞ#qK9k556mKo0>v]G&͟V^9y5vFv\];i6x ZrZvS]Wp EW>GCJyC>^d/[B tL֩.Xzq%5(5.:EƵk$kV(Rn(ĵy.@kŹbiXA ?kgoQ8@t +(PPpj71@7}NEW\'.^L.&!(r!ߵ ?𘌦G'4y[ykPa`=nJ2@迀b?4?:ߚ:/p7WHI4: iMԙpt@m=Ln<#AV莦D[?̂vN!ߒS"ߣUQ4v %G6)I @rH% YK@"& UY0|m\bGRf|^$\u(M$DW{D` $h cylJ B`m'HY iD(7Pa3[ _: ܼ8E9ko7QԚN,| }L `Nb zܱyѸ.okQNE2'g2Ϩ)~sv7{qR<F\WhIF/3Tʃ+R/'hti-&Z I>ZQ++{l7ɁhmQ |.ĶLBWtsFPTϥ2.W5"ah{ݟ$w~ĿHCG.fQU k!r(Be? !pq)W].o$8J7U{uk{Z Zڤ!<,UkK[5!1[`woh$b0L?ۯ`kѸt~OY.yREyCq^@klãWqZ*+A f0ur$Q0LV\`zy2 KVĄ&]buL JLՖ6 u_|/؝|B4ay|k?DWz \5&w;URU'Dߡ:uY^`ꍹ-UڋLԁϺTVFpi /-ݬd 2h}foCr6nd>6m[Lz}vJnd֕wKdl0~dgii3A:|1% a+6/i#n̕ʞx { [A]Gcr-5*tؙ"x`\g6c1(b xliV5S@8+FH+frE;HNrV:!Wtʔm8MtNZfEg]6jS(Uc.Ҋcg{Wen :F秘G.wT7LvsPZݚx@}{rSs1)X,c.i@ED$[7D|Cu.2ذՔr#CQ{ΪH,[, %@0# PsBS閧FtɁ^yaBlқjTr缯s52Js?THߛ 9jS&j}=ݘ'3P:x8:P7kl3`i0; $ %Q,w4:$A č`/5, b2Cl=0J{e \F戱{Bπ=aȌWs6tn- f&75eD5Е¦pG<. F%QXةiqiNʞ1A9ݲ#T8T5vh.TϾX^jwpH=a7|Gk+~[Ҽ +؆ڍzbq}?}R4 xt0 #1I5o,fXA|noJ;HlrMkF3XwiqSD"UmGa{gOBFʍQA wB wBOeA~F~XrQ]-=z̫ܚ)"aR{fb#x],"9+ ߉+9Ï\_^%n\(<ّvs"% EŘ*\D㢠D<*B0 ޣ\y)dX-¢I ԉkDxw:fN#ڱϲ©Ipt R.P% so̓t ax[xD39Sm>X}7b/HVDz<*zr"Zn#f1|Wlx =vXʜ0 Ul0/?V`E Xe-*Z\b@[{mH }%~= FeO 1d({P&TYCv{[[uPq g=?6\)Y:()- k=sK} ÜxEL] ~s>k? pLp3(>Ĕ$+r,k߹;D9<\ V &mjzx6^|O jYb˃KS.gQ8ïZrȔ>.z9XVdM,$CvXN`͎Vc .Ϩ|@Ѥ,9~U;7;thpJ>~08N)ݒ krYsz|fl'Hb D"Lj9J )cnnVэaegCu 6T15gJ;mݳ;Y||6<9=\D J03\K;'M*^1D kx OxP4! &ZWo?/ dZQxhg%طбX /umZsEp^_'tRq)y{#!YWF5 t{ J}2B\ϣGQvѸ @y] ׾GFOlI@|Z{2x9 F<ѕL>fXFb~it8o&6:`T iN*jRֲ2Q6%~^#BF؇YǨjRpoWhU$TH:u4W, K< M%Y'`<03FƾcEs,q )6 : f6%5]dyB,HWjrVˁ:697m[CS өɏYW2&CϰYdx㲟J8U<\R` =d΁8WC:&fX`$3XZ-NѺ2&U^ I,{0:H0ɳt$\1"[w 9m!.UDīh:^YF.\.}PξDBzՇVIp dd78Jyϸ)T:1ʉcC7'cаVC)>,4{yMJmƖmcbTf_IdlQaܪS Yޫ򽶈V`?0^LAt^zV7{"`LFn& {º0ɘ^9 |*uz .h,w0VWB !ԁn'i@DzaD4 ĜjIꉂay3k-a +OII,20!-ԓ":WNiF3 +͸_&@ȷfks!{5cҠTXCqj))rWInv/PQ+Iye:% %( Y]O&Jkx]kMV*Q(kR#MH7rGbM.r<07b@fog%ʘ%KTOiK\7ނ逭Q^=yA:U;`OI lՠ_c'SJ|Ԡ>t44(;2k$ïvIQIh*g4~F K!3M1  ⥩7Gz}5.2F@f`ɟF)whDbAn#c3b (,L5i $X|%y*aWkaj{;4s: iˊxCbEvM|X@׻FCNfPQHŋ(NWfiu3^*: xsSBfqzz6UdhOe5l؄R7<]D=\GNTYM|/l Oxwc w[,4Iu]ɃD-1=_$9b_!JQ& 2xD#ѵϩcZ,Wz;h$&׀\T&WY.qſoq>]yn):ww1-)p7 &BP_W{Lz Bw+I9;rn͇ S|.vsUDx4~̤x͈Gn'w6KXDt##!͛h{ի5l%vSE^? 6y,;`Յ,bX+~3Sݮ%I"{S;=Zt ;F4E;Doy:3~DGkV]hޓw143'^'44 hdކyl DxlO ;6C1& A>aDc0zxmP.ϳO4_6~¡|Zj2 p?7}(#IױSI]Yf]-Tuۑ2sW!zU#11!S}NǼ$u} Ӷ}J:X,IrN$۾;UYoGiIp.""e,i@@:  J*LPuH[2[e<,IugρFEᔏX'}xNֳ?&Hݺp%{i_^ &{3˓o[w!U?߼:ZFBxQ^$҃[>LEGf#}dzUf~ʍ;nzO&v1 TBRRr] %%y2 ~^a#<\wL P#Gw_>kOKK"2OҶc6l@2`3bぱDE(I|ѴkLں_COA6Tz;.6ZO Y Dpq/\Q3UQ%AUM' O'^} 3IwtdhZ3 qyD}(Vىy$=i;l_sZ:d_ҬU "ǯ_fO 74 )d91:JJ- Ȣx[ >U EV(GXuZ$fe +<a'er%d<\c6 o~/qG}猪S.'.F*XVVI&g`ᔻ־(N%6Jq0yc[=̎y)1A9A2wOK6 V8bq}8,"bzv r:ь2;]NtgURRycxvN˓"*yxۭ*u6ysqT}ء4(F#]3gQ;|_|q0+?L0H.^yMڲ3S -6V 4;BL3΅0r{UxٝeoWe@x a3b᤺xZT[&Y-v/) iRYWuXċU)_>ڋ*оK84 N8ay, ݼW +tFSoW)EUPA:r>cU29<1uq  GfrduUqL+|I-_l I-g pn8a`<ŧ -W`tAOq2j4+I$hk88BKftxXo/fRz2=tTb0a@Ew'upw m;w4X]g޻j 6a#[^t`P`g.-s=JeK8ONX#[&#ݖJΰSM%Z -۠PwDA =nH+Jsh-.ɸ:׵K$Td']~)  UTsRŭ(i(ngm̤aesICΊ">J?H 2P}<:&jSQ#iG*J~ aT<9[H<)H>'0V8JS]oWTj4$PSG -LGM 0ؠf{#S(9-PVT4`]z_=K{YX'Mڇ[.Dg_?z$,-ҾU-`jPK A styles.xml\_ϧ|fUUs&UyeӒ,[61֍jj˼~NzϘ儦^z=F4&?,fS||ކ3rRG3T39z"u.x6ͻ,1Cۮ/`j_Юwy/u8ihKH[qvߎ-t:HjpTeH8Aw9ꪟ5UJ79fAX5^vhXgߐu5+M&@|x_[wK֠:/Sq)bڠRp8 m+G(JpSĢ3xȢ{tr{:qo/AլKVVPg4?$+AG93-` R! ֕z}!WJTR`*|@EE0(~$FmqO-@|>t>,k5T_ibayG7`{[?6xW)x%N1#kcX2# 1>MjQ\mO[F6% Bށ^ψGT Lη$ϙpHN9^5;~i_W;jRKW .۱ zvOX9Â6^ԃSmCy?c;)%߮J*v xoSX[# Dn en)\ i7 XT\l>?I0QpWm}X=:6U V刟ذ؛%hoXgϱn}i%hqD7M352/hP7W\KvhUPy%E~^7#gbTPu)K¬ie@ң1AI/l_]оDku9//Ҍj=%H5XL.pGEUP/MH[;W᝹,W4yH]6ӍvݳK| '螮D$,d^5g ^̓ԉ+omgkNOJꠘ%xPR5?4LJRsw<Ԉ`a{ _9ɥ#xc1zx;8P]?. hLDGr# ȗO ^SfOg.*Ѣ׈es44 a ^3>s DCerL WkW@u:ƣ{F,sl/ka: 2E`ѻoݢeM?RS>(7N5u:0Ds[ pR,;DgW&@\BʝglyM^nMo_v%7)l@0u{TE&$vlI,>6U>9E t}(dм7|~q\7˸&Gv_7Il>p4([SwIs:Q\hˎn}9hQl]t˅t"T<6iy`gHERR][3twb@ !]!CH-ouۃX{|]r\6L!RpG"tD֠(V`Np}-s8|84; 0>(V/E~Yr5~ӯ5e߽`W5yz`$5AJ<&RȖ4I|nY‘3&/}h|(ٺhtxSHapoEڤ4 puG7t:|,_y9p( Ho 采@ZM!#{:4)55H?ĞMJiE:ғCzl0u\Q@+Ց7?CRZ΁N2܏h _J_tEϠX\D\W L; (`H=`osL H}=Xu'ږs!h]ؕ6oO]/'PB*Ȅ4FL\+Ҫ6sD j:>l=8N![8‰poJªxNSܧJ_M~D, kJAof(ghWEtn)rtX p<&?u[/xJɃWl,((c+Pmfgh~d7^x>0Wj<<T9ޡ5KlC!o)6u6 2012-12-12T13:31:32.442012-12-12T17:41:00.54PT2H55M30S14OpenOffice.org/3.3$Win32 OpenOffice.org_project/330m20$Build-9567PK AThumbnails/thumbnail.pngvg4P5QC"}e0zIN(AD}>FDFtBbF/#JD](Ì}Z{ݳ?:wv:  LDDLDy R,L&"z`h}-CBA".EOu~,mv6onECv:Lg*©S8G~-[b8PnArqHlR)y}BoyokE P>t6D@CG)*]" 8\{,B Dí [٨)"Wgwy(a~x?42<ŀNl]R굱]Z+pQ~w^]8'{Ĭ?Ztx3vNQWOKmxd~vC0֯]e>ʱ8r zI&ᓟ@ūFRe,b|AKA1ϑhQRCrL΂z†kBoYp^`6G S!5[c畦\Jh Y'g% c{7S\|mmH:[=- ~> >h>PJ3 r߲*Asۢ*>H . 'y8@H4Qa剪c m2Br qm-y*|w3ඃq3|.d\Grcfi>u,Or\wAkPfO14kK}z-+ >'ԻzۘWiWsq[xk&{TT})~wcޥ&[5n[=N&ͱqX 7G`,)?A Ń(&ubQυ !Pi UǭpAh =9}?J/*?9te?'Z}Fg Ժ|/k}WSYdSrz֑>B9 ܽSs Ƨ-0;dY-=bS8_a<7E=//3Ds;NNzؖI&4D gbOcf:|%Zk&-:5BxDYn^eXzn1%. N^=e^j&1aMmlF.=r3u4:utˋ'Y@+K:bIGOGdD%m5C^mUrۻ%$O|';~ @nguF 51NiI栳?m:,nG^6^>^K0/U 0(JftнOb9iv{؅3%8_M7 g8a`QkpתQy(/\|!hqZ'TT}I!m*:2Hױ~M-*pfMI*O =qQFU & .{N9'{Kq M)fqg}_%?{3I*$omEލ=W>} 6a:n4^DzLwl2teV_PpXTNw?Bq+&s }ImaV %>TNT` \9:A:+r(`*Yi@9'*<8tg<'zbD[F0Q $WݱNLy3ijvѩ*Ҩhc)GFbܩ*N FjB[ 'שظrTO=,q%H /NJ+5klbS].&ppqNplǓh |[F6RtLn7yW@Bt'UQXDGVX: JJhyIouRzt:-?Zk~הg/œ[JaGR !] se;O{ޘEqV8H֒V"-ԏ5'~0<~X#33yW~RֺI&{֪Vs3%~B dX}`6 d{]bnaLQ /X!*Q;vWW,źA -)O5ꭨn.)E 64q7, A\Bg.0x SvfFaŊdѩ)sQ!|f5cX1B۠G'JT`t_W鸑wG蕏7|v&L*c#"V491 jw XŤw%IUl&NP~?`KU2J+Ӌ(TQdޣnl#?4Ȣ4+ej؟тl޴\zMi}nR: `ɶq""VKqg,N+QF}ɭ.B֩ȒZdJzrsߕ 4啽Il<A,hRK=Tj*[X S@s R#4MPP_BF3(FC~UO~^^8RN%ٹRlW+Mo9dMLM4($>:tRcK\_z١-{IJHO }D?'῾Teu^pf:oe f٤ͣlxA2ǸS6y9Uec63p'MQy$xTHxXm$?ɻ Ix[Iɟoܲ+Akw:H0ÔQ|m]]ՊhT͝?!oBXDpk_a?t #8|HwjO9/;] ^|)_WP0S YŶn0APV}MܰLbVKts4UuTDPK,PK A settings.xmlZr:}_;40 CJKK7a/HrʆLJmĖv՞g~ZE(y;`{w*ާ?8!IT4CCM%4 " 40x;:˞;onLܨV9Y~ssSMn(|vl[WN:.foBs5qnyqTl.#רyy~ coƬczå.o&7ۃɳ[+gfrs]xUh!`О39`(IiT|teKRp }J ! ܏U~vsj}\ĻRQ^&EGY]L޲Fpƒ/.S7d $,ןN&wO$<8*TU!%p(6mT.u3 W-.Z{#B(Ef&*#L]a, Q}m"&!1̳bq_  ıX?iPvNJqz'"tLWP.I3i1&Rs!'/d]meL.4c N/%a SI;ߌ cHp~@ \5\({i+aRFR0 , İ u&mtm?00RΚ{HeYB6(*tm/%WVi_c7y=6qwL~Gc=R-*T\}cT;$n;X)L$)r9Wds+~bey^@kՊv)1u+!D)uO |8aκm,f ń!KP?TRB' 5#-Ҧ&7aqۮRׯ˗' UN>\Y#^֥7Z{ۅ؏}]s({ree-:3:+{\;c6ꃂ-iNr!mQXjW~}h/PK  PK AMETA-INF/manifest.xmlMn 9Ŷi8Z'H0c?ŷ/mӪI7XZ;AZӰhm~+j9[h0@qP}&  &Q["j4TGrV;L~(0l%48l8J>δՁUMy$dJh0U.Z>0灀b؀#B4y*nvV@,fwEnF$m1;iV90ȏ=c/4q.ge%y|# 2F`#D-pJnkGS~DתuWj$[{^o*p:+g{߷H~.PKEkPK A^2 ''mimetypePK AMConfigurations2/statusbar/PK A'Configurations2/accelerator/current.xmlPK AConfigurations2/floater/PK AConfigurations2/popupmenu/PK A:Configurations2/progressbar/PK AtConfigurations2/toolpanel/PK AConfigurations2/menubar/PK AConfigurations2/toolbar/PK AConfigurations2/images/Bitmaps/PK A[{Go~ Ulayout-cachePK AX7 content.xmlPK AO \manifest.rdfPK A$(` bQ ]styles.xmlPK A0Ximeta.xmlPK A,mThumbnails/thumbnail.pngPK A  nsettings.xmlPK AEkȊMETA-INF/manifest.xmlPKvmudlet-2.1/src/doc/Mudlet_API_Reference.pdf0000644000175000017500000234506612070466512020131 0ustar csmallcsmall%PDF-1.4 %äüöß 2 0 obj <> stream xKo6:!E qbm==r-g!r rlIpp8|DmS nt{﫟ӟʺpjpz3vu}[* tjP>wk .Wpa;N4^LE taykz/߯j~3jܩZS5z?8V*U٪MH$9 >2Cp8@43 H`Ջ@~\PWbJuk؁6&~ >Y50ڭb9^fG*Fl`%=°v >|Pөav[ #jMY,le,gsntpn*>uWv@θtxBkBx牢ǖRJRhMI)b,S4ӧ&lԚw^c|w.MMY:?HJ*Gk37Kƅ+ࢵ^=!Đ k-[kjH\odee֘jY3Dm}dQ[+P86?!Ek'X1FG bzidϚBBO-NWf[Nk^??8@ NXrF>-bs- Z*&j:m*vQEz6Ld0ǛzkR&h`Eظja9OCY䨈2rrt@Iic׳`Q`1e~ aôڮ1|'_qޔw!LVog!?cFO,ӓ:u&EmnTvt Py,ܧ=ƤinE&sY BWp~y.2W1qۧ}j9SFg.;T^yfG;`<:v<UN˹'$jn!'0T,IYuf6c_ca_=vA9ʰ1 l& )[4MY$ [aˆ]ϢVTl"$oLfj jTN-VϢ#)*/y*2 %Yk㼑|1d6 mo1'"PuSY!K'=TtDgB<2ALeB3:XQ/ۧڶg9/9HIܮ =S;Xcv粩L? Iq*fEY\5 `O)2H+CL{;'TbO%dkmW5" 35X@@ endstream endobj 3 0 obj 2343 endobj 5 0 obj <> stream xK"7| Α ~-!%rdle~r U.f"!v]v]~Z4K_CvuX~mW˿gء[~c{^6~_Z|ivcӿvr>ٛ-ϋl _>,̺_~ofѺˮ_P |sͶ.~Lg[ylWf&_Nк.{aio:X`;s0;9_W9jupmmQx$E/(mW)@.= [[nc\|l|.ynL(#T\ۧK%,ֆ`z9w z~" 7a;vdJf1e*x- zhx!l7lX$^HQ{}1֚:Q0rD,W2W `CZV i'IW TEhSD6  wGBbtu7ꊌK'MxbY'e%Iw)+2 P|}eii;votPN 2Η r!6]a(xŎ fjf̔Or5FSxy?R|*CHP=$e:Abg6eXB!*0P4Me [`B~fֹ#buWY s tvQYAÁ/u8ڡvW%ێH>`k x{uTAC6|'ٽyIr$wK .PeCʡuE5Zn!V\CluZdm&e$4Fs{XY O1XB)\]}of{S VR6zêk6AeC<95a֩k&@v%$EwQLJ9(WQ_x.VY 0ܫAfJiMJ&) Kjnߘ1A6ST3Z3}w%WE<l&zH$ﲍSMwsyw6H[(MiJ/CJrj'؛uIαS}F4i.:'5NQ}W#1")S#'7 VҨ4\ݓ \)L <|oݶ%R?Df|`DZ=iU@%Ţ3|?ǵqy61X52^wNƽB jM)CM'a|6C]?($e#PH0t+UTyGØX=&v6iq4E݋ Ojݍs OL3tr +rU !* c/I4 >'`>6!5)N]6c3`'7X|HsclëT\]) 3 NO=>+$o8JTv.>͓4$mb҇<&7A`A( qK7 &f# D;s1!#;`$vzGK x>kTWj\h9>/=9;|( '[nPE}-$[աy0xP K12Pd#7F wOMk<ԗ` g.gr8EraW~ HyhaOH Kp ޱLU49.'!RO򊔲Z;5ɜ#I Hm:'c;!>锣n&sSsͺnΛ /}<R0WCxG,$`S`ܺVw 0y9PKs-WIs˪7$hf0t֔amIEwc/vryAwi=TKT6-d*SH@ 3|ԧ2]qs5@:`OLddTh X&bwo,cE W֒5$(XH&D_W-_ endstream endobj 6 0 obj 2329 endobj 8 0 obj <> stream xK6 )|.0dANRm/^W i-DDGmtF5*nc՛O4§҃k>ypmx}hm?~~woV;FQ>۽*STw2<}wx:Эn&]Nm| SͽfjRw#4fuhf۵$TSwƑ>c_C0ʙ2HnhH3 6cー iݦ{ƐX.[;o4 ŷ<\]{| !JA&|r0_h/.Ru?0MǤcxvo~3ٱ>~4@ԍWw0AgEzb!K[]= Nuϑa]£jʂ" B>= rw&N`tƟ';ew&5YĦm6H몇zE``JW~^8&Y,J3 iNz}sH>|^}k*Y?B.:ċS)L{ 6q}wbxJO%`h8tvA# I3h9ߣX=vcʾyӰ.GEFuH~&L8iZivNS՘ eZ0GWӁ(#L 46a_p0KPdȩyucb%SQoc(>IE4鶜neSwPU#32b]f ]1a %rQfܒ/7Sꠜ⦿#Šaz5p8Rzu>͔ϒ+8NPE^^ vui<@>a29;-Y^:vƴqݔK$)IS)mHHhL|15Pӏ:I[q`,a COmNgڦX_G O&IՍiѧi̧94lHXu"2y48sgôAXM|ގpv9I8ב&֦fu K1^<8u)1d@PNt\d2el/-Q)7Z#m dE?R;XFl>ep>͟Kݕ" Dvp v>@&E=Tȳ.ʇ vmǤ÷@h>>#@o@eQӽnc` hLPFhv< _J) Mvg|΍QAP;oģգ8R$ OF^Z/â E=|7 tS&xFǝꁬ`%ـxyq쪨 ;kTg蘁>OB#(f<ƍ ʼQ\C<ȃ A!c;$guIT&{$Kuؗ2vÆ?)!J|V`AV;7v%i.Y,/8{x<>P?ХlVhhHjXq+RetS勲},ʦ,ɪzp( 8I>q\n?*7焦>g@ʠ t+xcwpM-i!KY3/7`鴊+QLMgP XAYWAcT4+3aqA[CX; 5!O 1C>mM6a#(&x$MŒ-A>I K@ox>e6@T;RYngpGQ!|LE<(o{ 8bӳAƧ4#}R|RQ=U9A~rb9 ń='$dO\=j%ܡhDsXN aq<]3\'2TGLq*^g9fk5 6VyBQDHZB -U)|3W84lQ -զ,  Y V 0s"vj7kq EDh^HL endstream endobj 9 0 obj 2566 endobj 11 0 obj <> stream xݝK6 >Hl 0$zvne~%yd"'Xlv'vh(Z+}YۉNTϿ/~' G>ؼ.zNބߺo{G~\F)BKV2-\%' gxv 2ڌڮF GA ~ؽ.>$h&3m~+}[pg:)ʦ~1ptcJޙ'Z6V`Ll_L'VoOA`^RH"[;kh +q0.Vg@PUb2>FƜڭt7+ lQ)6 (b`j 0>iI +{@JmH>W : @:A'fk?_4;ȶ\v夹J-Rp^bW֩AwQ7d̖d \>{Q)x|hiSj=|.f̂2W!nIM w R&<=MIX$Q_"qpV 쀁-iQJC !bD/RNAH ȯRlD\!3p6CLU8,YKh}l2AV37L-h(Dz܄xR$$TI2+Uj%<(YqQ$dU0F9MV^gPq~r%zKj'emwLq!!GŐӫkQC ɗ:jv08)E l(wŒ8FejÃF-((1H0(~(3ΒU̒4óDl%y^GuZN ;aSO/Z}8p'UO~cM4,y SȪJZ_u fC{f8].Zqj7hBV3ƒJ(Z8P%DXl(`F5kCDcDR1Iy\^ O"HNzX@5HYʌ lPVQ}ZjY4濌% 3PԨ$y鮈dUkzn${O\zSRl:.wfa4"g,szXwϪڜYKe ~{G$;J6Yɫ3w<G̍1ɳpAyhWb 4Zs"5,.YF3te"{jP:-|uHMm̎zXG 84FYD[YiHږ.Ogk$3!0ҽg'LUK͘*ڜGRmxN #rjYv͹9N]D |GVN9^4"Ȣ\D㗞Syz,q|͝v핆 V dsi'9Ȭ9z^in]ȞZOOWl4FW!)܃ a +q&wD`Y]Ms;rfױ9D ' 5$5H~IzdžIG $]lY;{ƈ`kr1_>?:sV@M YE{!wE1bgSWO|Z5wSEc YZe$`BUlCᒧ-N`Oe@f}htۜ]z9yPi#AKp CěC5̸CB~)G-T=ݴT6Yg[LW2oa8tk[dӵp6,Bw>tXEq@i 3N;]? /CkW7P֋$jhe+0%75sqz?(:WbPpJ"*7y*pkf0M[ I!5&$u \[jNoZS/ s) 3WWbi{04g 0eglEOpvjآ-ќxh͹HIy]xa #"\_B5Y-[;|vpр @8 @kEbC7\^k6>Ѻ F9&p} {hT-BgtkÓ@GDɗ1ҩX*XM2,)[k'?;F}: endstream endobj 12 0 obj 2326 endobj 14 0 obj <> stream xK6 >Hm L[{ٿ_=(fg20ĶDRE9b#OvM|c7Ϳ?j]yYrA7R5NmɭpB/8'qݺ݊>|?>:=~}؋l&-a%6m[f-g7.)e6\ ) LujCuUy=}u B}1}84D[ik;ןP΋P- Umj3e.fm쭘ENx :~XxbeЌvev:10kva42qdG#;<Qyj ,,a6ႀ!mR ږ!4ҧp8~RzTږ]S4/@\^fWSxN~-B:\XnU_E`ahzvҝ_0K]cp:!¤ I4L;~N(0{N`Ŧi!Ra5` .jJ쥛j2M]3DT,A25@hsI!iq쀑si<8t1kq&Dg1} Dw+-J8*O۪WERsK/5wpy9$%P\J:y%&^#O/"зH_7I2:Sсmņq1X:QqJ]0OTچ#Tj@!r|gĐ%^_Eu-RbԶykV\t摰TrI|`'-mvQq_Is&m)Tڼ,I(ﰒ2Q ޔ0i{aOAbW6kCI*&sm *=.*R¬7J7le#\ xL"dmU`C6w8}H)2SRi2-AŨ1Hu¤!.nB[2Erԓ"c8Y۾ `fL+:Ì1R=:2;WƭO_yw:96 { MZJf;]H|5"2rT7cFClgL#T/佂`MGDA%*eu .ݵ0MLRcx`M{)*[u#>:Pa0c0ЭP64*_l)!c26]H-rpFHb앏gUZhLچ% 00q0}O7V2<&!--F̸vm&ȉr m64Auc4*nGGkhꅴVMFٽGE1J+*R[MI%j4;:/bKo9!B&eQdҴFZ8KX+OI?&Gm-!GJJ]Ҝ?=f3J5-6'I>mL6 gQkFnxMl0BOOD!b6Yei_>Dk!' ;U5IW 0,dR󕶥߮> stream xKo#7 s.`Woic8m==JԌc[JZlqfl&P$Exqo:^D߹]xonUQv\tg ݰ&`tE+<9>o9LA}a;}6r/NY/!<FWNq)mL>.akUg9ש"NQ2!.ޅbNbxX̞q f&'\F&S#?,CCg@F[T[$4Pfk`ֻR8`<6n}JRP%^8󰄩kё=IH`"v ,DW@ wc×N a267pSD1Ʃ)ti7ky_EEJr5GGcؤ34E0{>qb8d4c*NVFkD*|9R֦$ĎzQ .d)`0A0gj5cb5р$< ְP"8@ȸc 6*Gr> QgULyWk W%LTaKx"JV%?b!2VG0IZH٧ 5!:}J!{|\ta,s^t9,H͹7 Mo̥!5py0n~0xfbP6 VȞ-8(q"?ݫ4cΗ6yjob6gNY$B5]MciDe_1P؈Nƌi1Vm#{br74[IoᢱtZitʄ}n1, L]ޫt6*us6*LPipEPS̒O2d>7*ps Oő=*1p%4<;Ug $*Xs * LUdX DCD'_c}>>LUރf)\j-"L5Dޑ3t%z-a-Bkn;&vGN2D,:(\-z%E`_{IX듋p Y8' [jnO&`m븊 #qTJQO6-MR7Ggha/4v PqҘ7LcUpWFDq{q twnnF2n-ZʖCQx6t"SJsYfȯW> *ls7dDϳ+8p>RT5 Fbj}^%XY@G]QrG/QKJTlCLoUY8_"b w!&`szE*L3U% B|>$tM“8 -nqC K}(9:Ki G!=) " *8B]%jQ%+*)l,]QlxCen xSMLo[4MK4[XXErtS$2 Up<ǂKo$T뀐_9m#X D]*E*-Ekn;5T%X@1Ix%[s<>"6\`yDejm7kPKlsڻ?Ete endstream endobj 18 0 obj 2158 endobj 20 0 obj <> stream xK#7}Q` d S^e~JU;lԠ蛍vC0 ?6?36u[÷W W9la{p"[zWC#K!a=!"!>f6!KنǠH:+u|Y }IK-`rBCiEM }4=MVZtGMOpAeSLj mꬁاo, |A̻Yh:˵n-}ڵo:&jH/{r˽Jj<ĭZ=T}~PU݆7qtosamIQKS>@F-OѾ `ΈHn>LM|[RpF\dd =gӵU{O%wOƫTcȿiW4 mս1.~P)C4> stream xϯ6 +tO~X y}Nݺءi[ i7Nb,aSb;0kl C$]2_=, |xxR{̯ggF piae@Vlvvck)]R#sMm_ǡEgu0>vcrM^Wh}0j@8Ȅ!{QTHv=c-9ɮӆzg7!r\ur0Qd_PJa2PNo5aR#LKq(9^-":1 )zH fc/!zu^/QYR ]lxɵC\>Pq SJ+P!ɄI+ȞH3 %\rel]8ՍM$iFZ#5G #'ȅs*ouzNr^ NנqȷVIv\r'\r&x6-j'**Rcn_;FC´zSw2x.z`{u'_϶\iOK׭A j{'dHZgߦLK>=m5#bˊ'p o*/ BP+T؅xL ys[ش]J ž6ԧy7}dP kAcV!Yڑ̥~OJ)C`T5Y`d- ۳ۗ#GpfI&zdJ03Ӻd˅rtc عj B1#vA}mD>g r:8oQrn:(ÒHKZ@U=s݃I퓍n1aE6W017*2;s+6b[Hm$1vYYa_\ۆJEVw TYD}3z*CV^HkʥHl@0Cw `͈lh|'6I`]>m IFɌpބvOV~ "j5>;ۙr-7Ѻ꧘֍M KȹP>BTl-<6J+[RtVWm+P|Aͻ4^G( G^d=փamw i͋\O[w =W endstream endobj 24 0 obj 1188 endobj 26 0 obj <> stream xYM6 W\ oIcm=,zjw R1q$1eqQz|(uNu ?ޝt-b;)}v_@w00YAaTA]c8C>:\n?r_oAuG@_^<@{u2uW%(b%M["֟\ kL)/3.Lp1v\)V7^d4Z*~Ȇ2<ք笔O} B`_%Ed !*WM=gӍ),{&ۃ-$kB .B= #seyɶmg(¢@f>I،ey`@bjn1ɬd)~Mђv"|KzU“6(7u1 p gI/̔ǘiC*!8L A^1>Lϑ`h*mYmo5KrL$qqT/;m颪K S!l Wׇz([&^n\%mgc.3v"7ϙt"Hr_ѨNPj =v GvedRR^CgeV6~}2l$[ڑH';±grhƻRKM kz.L`SZ,hRS4CrX^wS kS)hKƂm&0r.'of2ZO$5D_ yEQ \A峉'/40M kz1 !dr4 +ʁL7&!#9xM+)V"q9t۶΃o1s5jOŶ}k/<R*pW`?/Ic2XhU=S0#A鏝1BXD@_RN.ez|=M0Vlg'hׁrqF;gt帏+]iϗ.WZܦ-{4JH} g\4."#KFqyTQtOSu_g)k3o{~GImQbRC?nU(eda|2Vl[/j0re %Jёv&KglOus+Z[O)oЮnF%h[>fd̺eԵ)6u3/0 2FN4z+e2 2*>iO{T(RK۲ʰ<7Rˉu> stream xYMD Wd2|IU[ {P+!!o>{M&El~x=9AOg:|'ۥNo3ȡz?$_u`g/ rgO8Ռ/`]l~lC9ө?~0w'ǯ~"+͊}: :W\NǶr >;dr9|y(.7"[JOεQbc(kcym$2u01ae$S`~y0Qkw>8J es~)3j3r xJmڸȎ(Vk,Z!m#c28 s_Y@ApqcS-;bJljVD8|>W[I4 \I[N>؞t|Cz>3a9I+7yMkV+FΌv(v oTn k\Nqjl@D6Sl׼W6`lZ)cS~^ &qB;nl@zWr bO'ɱO]r ‚V'Wti Z ɰ 0UkcD(KqlH[ oMqrcv+HVGt[ն _;EVH& qmdb0k΀p"G> x(ѩżtUQex%dݽ2jsvJr@eU j؋ՂԷi4aՙ3F_tcCfV*lWA;ɮ&ߚ> stream xZMF W\pֱTzzj\%r,ϐ["h%- G>R6'`,dᔇ/~a``×O> `gўMlt?{)lptL]l3a@ð[sJ`t097n!NG( *C_܆NKУçT}<NaiUD!hzhcXC=tNPMhdLХsrgȜ-Ap`qdwbJ]. "秘Ԙf%?Hsƶ 3bBUIt0])m')&bZ@NCjKlID B_̕d3zx1]v MIg0X`9S(kVK?Fu%krjMRu=ۑSы*P] $a))_{ 1 kEY{ĺWΆE`Ƥ!&z׾ iW..+u #ZK2 I{@ɰT nThKb\%YdСAd\..EW|1 HcnԾ5N Tm-ptLAZLhZ,E˶#məW>{r]yښ嚥F5ڬ ݂Dt^[Q=6Wj'pL~{+K ^-* :!IejKH.R4nr U W}U|D6vNPj曾>_m5E(UϰNaɔBV\S9 {i T H q(TD2oYeJ:.8X-Њ|֖D\=pmĦ]GAx7AYRցtVLPxЮlPD8{v/FK.vW}FHe&Ȝkut3RLÍ@7rrPO-Z'ge#vbreQ[d.Q&K|Xut;?b+֏o!{]9(i.:鰺 nc5%ԉR2Gem'VPwkgvG W23IMenR9k]n _ٶw-7a27_&֏h`KrFlK ^Ff+c޽[q*-]rTh& oc42%{Fh,kkmK2 rtOMX'ئ̶*6r> stream xˮ6~ X*;d@EW(&_rSPmhqn2#9\(RoskuYjo?5gS?sqp6~~n~MC~}n} 9xnoU9?obHy:B7 endstream endobj 36 0 obj 1219 endobj 38 0 obj <> stream xZK@Oh4КmrrJƎ⿟z,RwtXǪ̋838׍?Cl4vsOc!,{3^ s՚poONj.4Ԇ8b?LwG7ڗ_=z[Ptyy ={Ac gIdٌezM3l~1Ӧ;Wh;Nj _Ӧ;.E5zvIT!I[<4v%a|BBi%C #f3we!b)`Y#bcM9&Ť\`g y' '\Ә=:y`~=[ Lt%W˓ x큠g3Ñ ,D(ki$Bl;ߛ=O ͞6sdG,}b3-&埲\L^E!Z$pDBȫ/xl;/!ɏW;S`a#8)xK/{88=C='x(OiI?A8'Ùn^j!YZ-kh Y.MZ&e:hZ I4YRY4[a?]y&<*tR[YkYK׉0ԤeGnZt4klZKm?*gxKHvܖwLDyBTSJwPƨ<_aTFD@KJ.ӅX B<.՘T51v^L>DAZ&.^,/2ѨiE!8;)  (/#P0F u5C=*XPkC0`vyVhY[:H h;PG)4GU(_#&K!}]G L4 G*zjXI%9pT=HAs X"Cգ:ب%9*l7"ҜTJ: )$oQvRݨ;3Mf&dTb#٭ )%LIn۳#8|XcEnp{{Yqfުތ;W6bB+旅[ёמYK1C~%Ērk:] lbUNũ0 = ]T}Βj#p0;k\ f=m\6]1TBذaZF:L^1n-GbὪ䘥2'Jc[#rL;pn鎲5LpUa޵!m2 U<l`]@Xk'Go;gbfl.k*>пǢ&AҦfmgaG: ͱehjؾouh k7{d?m(v[Axr##9*?%p_:Y)A} *Ц-FYK WE4b+=8ͶFՇ4@Z'zIiPLn7cXLSUg+xl{p: ;8L5YKe)?Nm_,MžJV׊V:V dDN'߻tm)zkZMbQ%͗g77씒$vS M-glNt)7Z/>j͒b2$)x2n=k>sAԓFӤݙpU8 15\1*qlΡfZN" B>նʞ#K̰ٓB<%yڞzh `ߊG> ;\>'Z@8Ez/GzyUn3oQ|Ҳ0PV>l_iאU/-GK`ྏI_2mM_̏ CSggq7}K(;jl|E::!ܦUBICa_/R#xNKRw"oxQA'UvƂ!˄oGCm mmiUOZbw#u±zkT}(H.,lvo*|Y;r~j> stream xZIׯPor<Mƾ]0'o`63%WeJ1Ew[EIN4IIMS~c0j_no/ ,yݢ'xV^Y [Ы) kbVݣx<-* O=H?tm1DC. .vNI>kB}πB&XjM .#,R¯Q' ~H]O >UL9Գ'@:]I|!t#UD{~C%u)JM^eLNmQ:sMJj J0*a#`7uލĚr%m=gqitʱp4܈}Y)T +ብCбHn| 4%7(^8؏Xj.M&5VvC)G bTS&iҦ[R/(:]7Jf(˩$SO]Ptp D\͖RN*l6L;/B5}_IkO4xRm[ћJ xAeT'ƸV]57"xdBG(mJԚ6+G,[-@DVEkESet;)4xzcc} ؐ>xH'm'd}EeId|! =b(b]R-u;M x 9Vm*[фyyXe0A:VmM`wG^=Wđ芾AL˩iXvǴWmw46'lmj.lIoJ8G8|4Fzj}?O`[Lꓙ=Lv]@wb;~)MgK^ n( vP펎Ksm |tc@}m3tGg}W҄R'gd貣AAWe([a,3SAH%ٷOݰq\2m5 d# ٨m(>dpJ {0; }bgȁ؞aor l50B8_rZpnih$b *+ZSTy r(]_7<Ȟ#+lq Ę]MvOx4xKiE Nͤ#F@T? 3 endstream endobj 42 0 obj 2530 endobj 43 0 obj <> stream x}mLGBBZ;R+4m*0un>M&SRMMۈCNMլO4 :r}r!͖]h֯,*֊s-v9bw eŻZ݋ Ƭ;G%-W`r7G2eB /\8E}X &~B^|ad(L&(cq5[sW]7'+6"7;Il@A6# ~#? u۷/|oz5"q;7_kɻ|sʯh^w.͆w-./1G endstream endobj 44 0 obj 860 endobj 45 0 obj <> stream x=ٽx|[!v^ oa/*D@#*DK1' 0, )f@@aH"j"|D4E~&#‚I yh>qzIߤ? =A, \ >fH H'؜$]@"J"?&C\5 DzꂌIא_pH} endstream endobj 46 0 obj 209 endobj 48 0 obj <> stream xZI#5WH$mI'6 sO-.۽&`an\Wc|:՘Їm:Ǯ/?}0BWm_?&ZӚf8Ǔ⋛_޿>V);'t]:'q;h> '*{/eeOFsO`[<;n`nN);緖ބVOKBYDYW {|ق+Z j Y89T9T6# $kD[%-$MbnCw~mУM.ֶ|+ǫnjD=E] :]D „*);Jguݨ˦!E嚜d\ jɂxT&(gOh=@|~L^%D50h?q0Ƕ4WӼ?|X@BaǷb!ݙEcnb 9(5 O<+[$;A(j`"P"9d{Õ*|߮3bG`GY*?ɂXdMr_sϙL'3[kP(Nj R#Yh1$.ހQ8G~#2efC5I1blNFrM[LduC(\*{ :<2cb^0 1pk)Yh!ٶ6Ež wғu2'(N20rct SC Ȍ+";i2hzjA[UѺc?!3*Cr f:]u PBl>cOĻlrj.q:N3TWJPA=n0?*J%Xqӣ~ᠪDOYD:JFlN7`Q˞w5{Mw-Y6;H- (9tiѓcѣy5rV4\ٯQuE!VCo1&TGXg@=(_LP';L'P6JI6N 8oLUX~:Eu˘TʸUCݾk>ಡOilw%aQ,trM} 3}a_s2e][ךIm u@M]Hի g^E%$iDzиOʁɸ3*"*/U=5:=vH[V*iH@-h`˕F tM<[lVݖ&DS 7NK}Ն[–Z>p.+]~'2R%29zwzȥu|s5zx9>y<:_paSOSzvJЌv݊i=TUHG预 ۳t6x2-*A*Ҥry]"6YtK0QꨘZau밼p-]8E@g~0w u<܍ԿipJz[~|q :KFx3_YPxeuPGۗk: R;vIޭ\~l<-/f 61Z'#V)]N&üf6^T/*k\ŷP?EُC)Цk_O+?{cAۇo( endstream endobj 49 0 obj 2250 endobj 51 0 obj <> stream x[K ϯȺzX ^tw(nKID줝)2ŏorU^E\\\eu?k?c0#ܲV]ˋ._MxVmO}9_ؾ>~inipC}o(˛ZY}ۆQ=MwJE.;> R,增]bүYM=xjt-OU:XMNO)`/a܍x` 5_n'"I*x.lKe>[ _ު`1|D_u8R`cܑ2m`WE5\@yaoiozXRiS[12=jH.Q2{wUwǃ)Iuk-T%K$ 7g퉱8γuP7hr f IQ@Qg839[2'L@˂ iKX) {md˙AZA"3szPAR=T0V}\fՉ ӭpHͤL&fp@?"GQ?N6dotVvs%W !$(6,mL0(}G05@g*qKG:L02G@Hfb"_ `՞ۃ @v4z ?p&re ,@^.dܓ=3[Ex o tQQ@ZPX#Qc 3(_ԋ珄`x1Ͻ NKu%TA?3*H!&(ASZ&C꾫+Ņ-*-I+Y!:(-pU BNU\CӖ xb @ bͽ_o?V(@x 4+VthhI e5˩ͥ5Ng1 4pRL2E 2|+NYՎ4t0kߙ%ڸ%d IJh1k#,-N @nD3oBLǴ L <)QԪ_37:?UėlEfGaY;cAXbrdf4 '$ )qLl, 'A1EaaF4ࠛ~1!9,) 9)OGVy#p$֧5L<dyw&RM UT1L:FM:U^L)%xWcE ϿY@t'"R``fWa+"?-x:/ΤHkzUX9tPF1<.=vW 0+g!NR CPc? @SP:==Lr|I~6t. lKˀJ;aW?RjUOjA+4+@$B"V9- ߩBnj>8~0S@^cm 9WzH@z7=wPЗѱ (~L%\_I1(Hc<5k]~hc_ |Ip ۅlJDƨ]N <"ݚwE7;Gj(<8(}Pzy Hݮ){K:&x`L92}y|$TL1*du!^p޶^y7XI)j.j*VI tLT&قZiKMz.hQqi]O$-y ЧC Q>GLU ̉K%\xbW7i!*%&UO. fNUQ5D*1D؂u \V?K1INxXir6! [Ω9iV_=aæX &Ku*w |RC7: WLX<ᜡpH.lًL&L*W5Ӑ&-dST+Uy,kwBg H˱o43emy4YSҟWpSߌ{UB^1RJy6Av&B 5S8(>Aw!eP}[5.g@]VƒuqߊGuƊŞdP6#(Wؐj- 5Y'?+P"Xl+ /^8û!FcE۶}37H/ޘJz]k6]u SO8)SE+0Nw#3WO%<)U !VEʑ+wMI7~h6;N d7O0PRև X _.'T endstream endobj 52 0 obj 2795 endobj 54 0 obj <> stream xZI#7W9cp݁&y#l2e~J*-%0$J| >ќe7h8ݗ?N|KߗNip ^߻Ձ^|EWy3,\_EL__<ͯOc^DCw EDׂRh'iuOp.qw|{ 0m,l@ 0 %"p/W"|n'~Xh"M,C^@/ _>.o̮llXyEkCERY؋.kZ^O0 2_č##AW/i ;0*Ry6y;_MBW?(hOm }eyHKR兟xJsh/~A .\iV|im</`F¢9kͽC^ܺG0)yVdC6(>r:8nѭ SAعЦzd PѨn@o2bzVPچ Ř Lw7ox~IzygzIaϓ)GD`J()bB PB-3clNs簶M1D}Ȉ'ԝ$ن"jڲwY~ϒBMmɉ#@ 32sb :8V:R\Pv%Ƶ"xy@^\lTh#5%%,3`A1ƣF[C\n#C+NjA: ,q^bxJXݿ}>s}-釓^YIMOt?7Rl`Ԅs3 O@P   )1W(X[<a:.nE(p3* '#b|IZ̒Dz͚G0ZhO[Gi&sy%<990a6K`خ{ O!Kp6qxՇ^ j?T{Ж h }n0ismǘ>ʄaF1Kw26e/\wgpOVZ, ~:Sʒ:JㅯcH UpU326nZ|M2}3m;%G%{F\ RV1U[^yK`RBocah-oq.jl^".duՅJw\d\])|CSĪS]rw;HsL)defL iE6p2L4W`kHz2i?9.MO]b \c-UUGRx9:8ʶc\5D#z]ݹ<<{R2/碵%6Q=oQy]$7ʯpрr˘V'tѱOHAk풁)e;I_ 8kE-T͟쩓WC}Ys8n:ubicEcs?7SIVMOОI! ,F")C+!\F{@tfqHօ@9$ C.N6E\W whX'hEyJ֦O endstream endobj 55 0 obj 2151 endobj 57 0 obj <> stream xZK ϯs;_UC- r&C`?-ϪafY$}[ouQ-/|׏ ~c] zyOuWV{|w߭^s?'OOO ZOtx?/zmN8DŽUΗj:=聈hp6Jr"++DT_yd<1Q4>^4p 'yu3xpxt5XY p'uzZn [ʤB~M :LVl9=1 gm\mP!a^e S*#o=Su937pQlV?0;>G+rjRKO0G?yJrIzUqV*!ʑ]B/bSeX#ѧ#a+lUNjMV*:08jc@]?5knS!lh8g1A֨fɝ֡ VxD 2f 9n@ujmݼ|<~(I7gpGk>Уd醺xY\U"y`g 0BEhˉӘ2CHblNw/+ɽJ9%-RP mrfa\j"ҽFQ&񃰙VmK RZD2pq @FؒHBfMxF%)!K":tBrA3|ۊ#HY-O:~ŭ @`>WDFNSRd0:&Am*.-G`]F*ҊZ Nzli&~%3_RBWxkNSu < u Hn1'5d|p\S*T}U5x Ȭ_UBP= $ .@QUeGG/uVY$9L{\`9! Oa*ߟ*RAItpNgΠ|Rn`b2[HS LaB:tTT|4+m˽1JnjMcf‹ \VJ`~`C"J*SB)ZjUA6Ob}a:%ϩQ扉P .VZi݋*lI8)TdkW d)a?$gwe`3Cz%AڞlRmM-~S'Aϰu'1BE+?I#{ 77#IE nִt)]DPFv93 ,e-'b(Rm<ӫ;O5w+cE޼0`gy_~C8Mc=]0(0lT+LhK׳'D&]u^RY1{]!t:"SS^EcB;fi'V= B%XZ*Nd֎~(`bxA3axٕp6/)e^AZJ 3ፔYɥhUm}Tg.I_ At`(x1q?:|UirN3ITSW8 nO 69A ?MҠoDCHnӗ!(G/%C{3):s^\s{5]> stream xY˪F+$0?Ev,BvlS]UrKn0ײԭS^} o/r;np?c88C}OcqYuëS> ܕ7e F J+z^ݧǟq,*Yɟtg\̇rӯ=9c:$@'}E xQge:D0cVW3}ܩY]…ޗƣFPO[,RqIQyR0LGP(V\Ax0qa2鬕yT~ʕ,GG䄹LQ>>ZG (-D%i ^a8HC,jD{oX#od>?$櫨@*f Yo+Q^K7/ѷ@{ȊZ8_OOA _s3@ZJI¥lU`Eb-biXf1wmʊ`/~>CZd$ *y6 ݂0pxA n 8:KRo;D;{IN*h00~18Pܔ9[EZOoԑhLı*cFF9̨&𣗓y /q*imjnZ\ b^&f)]3RHׇ6 [Om,'FO`u2td&*۱*8A,vɄa۷_?(@keIuI_SRhUJnusLGg)<@]/Q09Nj*ivC\H3\$XX d0fi+\bW a{M\(:Lw͓:y ;(VŃ얻 ;_ED )HW%#-6ReܐstsL,td0%>TFL# v@O'4{~jlks8B j) 04jf_Cpt)V M%J0vŦfgu9,J uDv endstream endobj 61 0 obj 1541 endobj 63 0 obj <> stream xZI6 ϯȹ$6c CK~)ڽhȏ߷.S7vW},\~7_|?:?a]~|_nL^w}Svzr~mxV'+ hZ @9M8Saznf?W齿fz7VuޝL5LLW󞌃WHok-Ѽ@k+Pdstq}8:%Ϳ:1*!4/lXWexm&ಎBtf6輫ijFd6ǒqQc7ʍj90XuZ j]]vp Q0O?<;lUECk!FG/,ja!?;&!;ou B N =$?74dDO4qYدk> ll/ꧡO };0ޔ[׮d(]ao?V15oZ6GxXՁ.eTUq8yB"ϻGoB-y Hh5qTFO᧒i?/^qW`⃻w -b脁lENo,g:4$ˠ<(fKOz#oTG P)18P[xO Pz;P!0H&d`<-~kN{ گvb!jyNN L 6"b~}/ʖ \@>8jPQCuij v T jz!r&(xFVa5<sLAEw؄AeJC}(Ej!!r+iSЄYvD[QNS='$h"' ICz(/3ȇY ZkuM8>uVM 3O49(QL|nU)IȨ @;SVLHztP;N%}А}ݼ}[;6lHQ*7gpDž0`˸$Efd3*yIux17D*=A1 P@T. rrU{E8ZJ=݁8zEx+bT;`w*Ћ[p';k}8,800a BX5' B8lLWy⴫!<+fzUУ@cd @zYC}2@`A'Bؑ !PӞX|ׅHC!AbcJh8Ԍ1K.V[C.w"r>_ p;HB5|*GE(z>a50͔Tmdh g&96^( ָch<֣ZL뱔.mT4xQ# 8k;^TIx@sث̠\(,H&eB02ѢGVcPU%.Qs[x%S 7˺Ml'6efPq~ikBéJDX4½ٷ_磓Q@:20^cz Փ f՞Tz7Փ %)fSrkndS:P@jK-E~R1tvH)U>_\W{(_,MS9mMh_.8- endstream endobj 64 0 obj 2199 endobj 66 0 obj <> stream xZK690mCcOm2C)/@?RI*YcȐKYwTWY\ew':OvW F^ӯ O_ůt_/{Ǜ6 #,pNO&I|/or?q驿>Ŭ/) _ nV@?~G&f0AIYϳr\H'DPj" jFX- 2bWFpp V ?Hxh_2IQ,f#tfQ3lGyZu@[ KK *t].V.[B ,% {^)|lt S7ɪQIC-7!Qa0eʟT_#[g T/DZl/sqw\D}쾯7u5+ۦ@D0ƾGV+.Y80`BqFD=G)t dUg)!MH\O/[vk*cJ &J6衿ڪo ^^WT{_B߱dM+[4~9ܬj6;lQSOC/C !(`M/Y?1fYad/by]47uUc+8LK>['Xi3! U9G(ecW#f?gg6ؒDM]iAid땪_#&f8$N(Bha-m"@ςsMsB3 Ӹ2 Pe~s _pPbW)<'g33-P4'g?QrǭAjtF~VeW?NdЕWY_Ċfz3ջcJkşOu-dq9s܅3/1JN&;J+F-!j*@4Tr> stream xZI69@;,$aCn!- HJڲĥ6V}U%u{QW<\ep.3mhq7s}=jx}{?ԃďj'Fxx;.p >> zpAk<\ߣO?FZa 4 6MyOZHng(^fn~m|y'A Wې:.|5C${oh0k"]Nѷafqzr[[: A4 aQ: ~މb*IqI êb:&y\@&?nS4G6@XXdm7OV39%KĥDoVmi&'X An .^ɚ62 Y2JgFfulY&)2 Rβ'Y(-!Kpt(NE΢?p[4Y7ctA Hx2p?A쇍/%H*[@D M>\Nj0 b  7!X8p 5.jS3aϊ*&<W̤#| jh錧sȋgͪbX{[VuU}VȖz0SMʦ:0N.l?e=3̋4)'DK \d_f[Q@i r[ -XU)Y!%HxIi@ K Unq2 \#^l*,x+sZH/* |TWvxyKJHށKL'޺*(2^fx'vӆ}>bV\ $S݋3xV;|Khg Z8K)8Ր$C)L fBa,Hτ/`Gu8>8̷ȷ1T­-J]=E(*衛|%%Lf̬v31 X.}chDJL_~-ħj'FX)lqDk};;T_2'gkC4Tr86e9fJFKqbR ?⋴+bLխX֖Ș#orVډldckԪ8ӝJ|]=щI,eJۙHaXA"GAgh wN5հKS*^PL.%۝hB7 B0jl9tp%3 ^ֆG{f DjӌU8~MhjV0eg7Kޡ<ߋwίS _%0'PȨv7@0>NSmp+ 5zeh^pRYG"f2kGe:Datr%yIQzE>Jk[bRbp_zdUC!.Ԝ˿(vsP5繌_ x uW)>ЅٔkwI#t c4ZEU˄"A[ rFErk1r =F_U"H7p+,NXRNUMFfŻ\. qLo)ۗGp$CkI[ !46(h|AzL ěDPFZ8mx*5vn jn#f49l`_\^Υ$_Zͅ%n.Se޹z0HZ*eqJ='x-5>$|5|RCI>;fo'p)>dS٠WlYB@Xs)["RxzQG/8DNX754أثʺ|,˴k1#"9` Uy26Z>x۵dfU{&$/7֍oԕu endstream endobj 70 0 obj 2440 endobj 72 0 obj <> stream xYɎ6+|( r&i l@ H-ݓ 0ږ(j+:+rsp O~<ϧOS ]gq/篟 ۏW5)7+MyT ]80諲x MtaQsx*oN(1E蓤hE-鎂{7.L"n׎n niYb-%=7v՟^=MxtF8J^X{C\.򢘌zS1}"X U9CwWm@x:ШF8pGJTZap.T.DkI=*GVN"GQҌ'pCE bS9 j;G]7z]|Fʒ 5xQK0鉃ةC1]rbFxi,BR fO qIxTqHfU9+]}Hj؎V&dȧ̜D#2TυrfjQ [ashRm+ʝGD_Eh*e*6S~a[!Kċ6.͵)k_AU5ΦI&aa"rO!AGxryXy/-W8:!22o rXPgٜmŭ.yZba 9" qeQ;XY_ce,>1]Jx6ꜵ'uwn؄fjS g(81/N"|'za@UDJnlG%]4ZIJD^?OrickaP(hK*ֲ]fnK#lq?m7 rHj8edMsNp3x,yP!'P|^h:#<; 3[eL 6p+BOWk `)Ąl&QhccEgyHO8޽%*[^T@ܒH{^Kֱ(@k|)zW` D  XJ#@j K=vU*jU`ݖ jcY+#BJo@3`@7q=JdT="֡,?Mnu>LPvVV-`wfFlh[WHVQ>5`Z`8Nn7ۑl/%{pw!0j{j(H4 P ?o]cR(h)óbZ_ ?{W`~r`;R =Wlϯw ҆#=1nTnY5n4彾j&w.4J{5`[wMOWX=K=I2n[qe>b׉=m+rs]uyw‰D6u{P2320ixSNլi·12Oc=0#}Y{; G$)t}ʘ9|HL=m߃^_>׭ HB{v1dlmހf/EMm5߃v5+6谀;n`0}bJ7H쿌c;C5oZM18n}J[mܷw~lMD0\w~88o endstream endobj 73 0 obj 2023 endobj 75 0 obj <> stream xYK6ϯ90*$v@KNI6؄K~J/{5䪯V{VJѝmEWKS}ן]z_vz4 T媀.w|R>'uS =C##N ؠ 4 aTw@Gfj5v_v:{qK$oԷ*d`o` p΀M dk+|=`IHC @C0="j 5 2:EwJYdi5D6ǩe:ﬥh ŮySS|"ZLQ }.M1e> )|lsl6)nt_L$2 ?R[8[ -]~ On /a&Ϣi(iw`2.]SRpd6Yp n' S[UbvzWr2M~M3@Q wO֨Kv7Qҏ wl=Yd]; iՅGBZz0 UO,jr kI*NÊф3)yؿUI\W.4=kdUkfTXvֿ <¡Dl`K`,= Iic`E X.V@gtt?zJo;B߽6gwʮF4γ?)}hWPEUۭ^]ioBS}g㴤D+PMYrP[7"'}[C0y yBߌRsMbŔaDwuN^o)S -ЊO`N^m DnHLZ6cd-O qPv4~ !rRHPF\s M1;؆;J\mY+AFM !^3v-eCj;@Ϭ 6חO?5XV^ң?GԊ 5._+{!˼I8zӮϬr c 'T;sŔ`s_{_Ykj먞R@9 oҙK' _|3>:x[rn.xUVjjueWfF+==DLJ eM*)$j>Sz9W}!D-٘k2&6c&-&ʛl{2Y@z|ԹP| &7F.\+kKq[F}׶M@ 0&7xA/&YU7|e`UO3 Mo>]4nRwuFg-AYjvqK wnCiC߽ {a}'I5z(CCiwfKw#MVp endstream endobj 76 0 obj 1889 endobj 78 0 obj <> stream xWˮ6 +.W]it1/lK,?ؖ!yH/(m |7߲F- v `Cʨ wP5⠞jRCz\UeYg;|3 E`"nQd~.`-O:GݓUdzI@d(% }"]ęlBlN̢WʢO~}^-OןG'$`Nzq-S`@%O(_zGxtJRbncAJhR CئT rR2ɷ $Q ddkA9>Ƒxd".*-Ake,Z{ xhC eIɘ\v6"]˨Y2&Jf\i\*H%y>1ؠw9(jp].cIMMzkj~y>3x*fzIW-rJkny_Y/# *cn r9uym[P|0mµS5O/al˻"҉lk̙_)d%:coJ]L9eHQ98j{K &fNCkt.顶Y`&CU؁Tg~te%nytWI'c:lmm61Iͮμk6 fc?V\ U?ݹ'  Y(hωmeew>4+ɷ+xϙ4|do-Zџ!Rs`\g%W-t>3{e]i7tΡUN%AxSS5kGUcKF6X,N|, 7٭E)&Y冈w>4nP endstream endobj 79 0 obj 1211 endobj 81 0 obj <> stream xW˪9 W:dwaì&dȒrnKnےt$Gݠ֩N7׻[~}~qtN{կݷu㍈9KQu.G_PѪɀŰ~Fv\Q\NA+~n=W¶]>p^NY4=.0{|4>~\^׭Gg$ǢN# `UNQj~z|>w ] -сa0.{Nj lx^JcxM{qЏ6aG9?m9i&LI(1'\_RC1њu,o!sƄIbGuR|_œDrؿ\+ijR 9̓RZb0-ټb(_OpxL@=^HkIg2sQ3}vCm9`VѸ8UYL5QXF Or;UЏ|Q䈕 -'e*;Z|pr˝3MkQnU̦"5\VgA&m3 u8˂ ʸB3ffi*mTZE[(~s'd-!!5&fX9ɧ&F$5^}遶靸-7:?qfCa6 AT&BUP'~`uy5@<:t 9q6zp09՘MtMKm Z3jS{cO3Mg3Zz[^8KӮ:9Zt["N4π"G_UjQ՚ѧX;r,$VK0wygviT_[`)2L' pI|LIMVml*iJ5*5TSG֓#^etŝ*mx"\[-cqKBRW0P#46!ЕBEuVXF,)K6*},jY=0*BC󀙸S)>iң6o/'u_9F͈̯MN[vtTS endstream endobj 82 0 obj 1100 endobj 83 0 obj <> stream xwuwNC;5uR 4WL`Ő@DMNv@ ';Lqb4`E(wqSss}gc-<:k?g}k}Ҳ \Sð3]qu/vm#OV\10kͫݘl.f䛽g6ɾo s4~O-N3MZuH>I!Tǒ{ˌ%lQ?lg㏅[dл2>#HBjzcKO>8L^[0q! O [z `6AB1ȝ7C2}xl &q!wܻ lrV~NXX byQ]ߖZW/eduK;o ǚԹB_O`ao*ә J|ɼxG )kZ_.w"r74XH*v֖岺#ߦ?X3EC$!V̀⫑H:z)/S,X/յ5Gnhd',X &xwo8:Jp0u<OoV. 1lbUdo\}I7J>rEvR?t"t[i]Wy؞۸X`]CVC3dU…Bc?dl)\ M,I.k0aXsYh+hk^-KLqZhcaOr$qfxJR_/*>gS,t [ Wl=][RjNu(_a(e3Pӝ7WC3Eψ}T#@7Ivٗ'f";A2 !޺Ɛ*2ҺCj8-ura SD/ꣀǵ4`u9^b[규 ^BVw")؝";Axr.%j$wPcA2J|ɼ.PAt` l j *I'\ P `NUwyޒaܕ u?,.pwZ/sY7l ʹ[Nu99C5&ErJ[^xw ,9үkp?ċ?T^JDŽfP ـI=2To/}`ic`";·@z 2%BcbrZ7'-~<{`H/c`',de`Jd'@a(p̙ߪ &B 4V$pZ8k?7çM,#%VN 5?ɝB|3xsYhN@;CM⏅lrc Q!q-ȝBll掳lKG}zK*{ٳpޓJ];PfK#-g a|X0.(=kM4'DFPC|3$!a8*M{F 3T۸N؁CcA:10l, 9'z4Cft^vuU\칇ˋ_ʞO2 V!ꖪaʖVu)tA=$USBֵ,Axwaq.A"Xz,g*$AEO)euAhcDO@|e(d!_^.90|}Dvf`0&5]ɽr̀9NկV9CU` g1Fb0ZKEv`qv@;Wm`/10[WFW#-g o!af8M9KNl8ԄjT:?cP=m)0g` Oi!ɯmZpS=U?S[N~K!3掳lM+owfoVL BCw"\d',4[ll0ɻiN䃋_S}7ǂ;B7;B7;B7'-o.uxS oOcDOk[G|3H) Gd'$lQ#)t%FT~Ig?i!dJ!&,.3Z%gS$XؙyjotagFfH@ᒮ1N[ŵ\f7}DvǨ@-dE-A|3$h{㠆~2trK``-3~7_ /p(aFFL<`c՜)k y|ᔑ2*dT7f9-A|3HWB\/A&b-.瓟kfA'EBYRj@Yݪȋ`I+t}Z,`akd<oF2U:sBSȪ~| 1 *VOhNp/ b|]%VK'اuyBU Mj"uc8'(tm`Cu\Ar|10Ef&@/65C4Po5 \.V--tݎአе7×{`v _@v X|375;8ghNrbӹX0'j\V!tAt~噿yXu 9%eu~`hҵ7C_/k (dE}%a}~ fLc䝡Q";a ͝ ˝y[llXSwfowfowfeIzǂ;B7;Άk%_lь@ SSN6vWw, ][|3|"/iJX}n%>gv ]@,#4CsSH[ pTj b%_}>/?03*@XF᥾,.J `%os2Ͱ3c`_,#|$ˣ\P, {N*,gtS,=9:-VE'2oy|7D$^xH%\{>{˯]XF|%<pY%ǃU%Gҭ rͺ*׏Ofy74G|3XKF}N <30Un4-t cjjp@^vr2O%̀_Kdczq.γ*b`xc-]@.ro}``Ɂa0u`P_ )4*,$1T+h (Kl,Mː]JŠ俒Z_eVuq&ӧW#3oKdxFvddՏgj0Y";aK.Ԗ1檓Y8y*~E<_Ę{L jýX.H2BWz,[Ad#;g⏅{;fz~D|3x,lloO ܕ04䓬Z+}s0Do?dd'8b˝7,exfpYhf 3 鵎e4XQ/G=l{PfaW7?yO/?k$۞*d-)wq㏅}4ViMiooM7]o|C4%.`P™^6faӍol}2";J},.Uy" !;H: #V3@ZuU $STHgQb|3XVXShaE*FR 8"FEL=Wy+k`<֜P+(c|mXj..)M%'ZfPym[8 BXd'H`XrL_)BVZH`@_xu /TDK p"RƇfp81' V i}\Tw ]cAR*p[ agwBk|3fpo =Nzl` lZ=V`:ˈ>U\ ] >Y{ *U+L!2R Vg )Sm|3\~ltaTS(4p`ǂ;uiJ!4laSowfoM7XpǙӆo)<7;BEv6cgfaӍowf/~{󃅳|=ºkoHY֘&-Z7[}zaIhcA xّȲ$agV \E|3$Fwh˰ёvxˋon pxZEş 83 Ͱ10\|3tc(ӈd`M)F9W# .c<10V ~ճ<;*M |ma2,m^R7:W E5X% =T$# KYz1FQy+2Ok`'!B|3`ح:gh@஌aE%߬f@j@qN Vk?l"aP1 Ciy-P왐i90`6`"kP(T MԮ"o`G<Y4oT'߬fȱ\.VŇ+ ኡef2/;#T0]]#UZg( 1B|龜x檑`PԪ&.Ϊw O6pB̀ `yZڱ:E2&r,)B-dV7 ˼$x'~}2`sk@@ҵSb%2-uZDC'?p>jkkCK0U ZygЍSrwtρo Ɉrgeh= |d~m?S||3L#Ċd7Bş :eyS/-[W|3^[N&~nQK'Ғ'h(5Ԋ!毣jHC_b٧T|3_1Mb6{oXA mS9E:CS[h$UKdd;ڲSoL*M{N$Z)ETNT |Ͱr՟;q-wօce?4rcXWu|h+REu-,g\T7«JU_w$ZEK|3>9R Uk]iBjNfyR1m=L$^%ښмhLgS.iU7WߕCBDuo10[F k\cK]El+7,)$SY r5tK*-x=;^^Zǀ-[10$L\zr,9VhO6 ـ>/j%qe-TdW‘TfL\ erz5OGNEl+pyf!ӧXӪ.o$=^P5e˫իy:r,b[ ʓ0TBM2@rYO7 d>R=`[7 TSsH}}[<:q-:NPxsYhf؂!wlցwě;B7C7}9"Ŷi u61 u7wfowf4WY֘&- X}p%&QU{OUV,";nٴ?ca,b`8Z ^";̍aca,b`8Z ^";d>|ma2,m"`(ɷy!L,O{ᴖ,*}S-/yNuyY( I@,Vӆ_fKM~ 00wBy ku6L7 w \0z`j@h^^})wf&j7A/ ]oo` 9?~,~m[@'"_Wp)=kR 򄶋Ɓ!Rcҵ,Jv ; []ȩÊ? "w10\|3!ۊdW#*Penzcm2! mȶ"*5OՉBv}sSUk-d[҉DTNO10ot_lfi-{sGZ !'w4(ǘj$;CSEvB7P!Yx]|3l; C^&w> J6⏅IB^jD/}9"h61Tݰ%mOhV,-Nқbܩ 8 ֖Sa'76z{>g߭;o T%v~^5 f[Rmo=x{p6@oI;v'7W"zJϳh]8aDE;ܧ;h{0+WVpv9cfaf(rESy5 (9\H ٌ}ؿ>ouYRMiCě|@兕Jk nyqP`n @qKW3XrKjuk` %K>8L^eXGuryҩFV`U{ UgCkNItf -oh}hפRw=ֻ OI|u$/Eb3dQe`ȀdX ]}^z5R:c`(,| _]b9,pHGf@C6i`PAoRW5UNկb;>wu`a107 ->aafLtί%UgG vQ`vH(/EɬWcg> )%7 Stx@F`7wZ꒪cD Gͥe3NPN^Bi{O+ k934S%dKp~r5ҚaC1`H UVZr:9~JG8 @N hz*I'Bo8  wV3q(q掳l掳l5 b`Cj8q'}锑MPxsYhfpYhwf7e %IC[: 9 ,> ][|3|'FvB>j@4l (:$gSō`uE;B77¦ ;.]\ɩ  |[ri8  4 nd'H>^Z_Ԝ*Э*5zޑ C*#05HRs2;fx0%9Ji ąNo(M!Gjd'c|8 pO/ϝ',X!0#g漘fH W<] Ʃfpz7ln](-$>jNw<0  w) :rs_[S:0B YA2zBU -h2d70T⁁=cb) 9 T_@|3Hv"n\|3|+RȊa +~1068C_%sƗȎ8; Dp#;!=zA,g+S0[NjdጁF2) =0Xխ_F|3|A[*|d A2O$#yFv;B 8  ;++`hUa[wf?q-q|-Ma[wf?q-6hP!H̸F[}Z??D: ӽгX{l/eo';, m ~/KY֘s'{. V%& :Ͱ-9H=oQe.pV% {םp hݒ3*[`ȿgG[/ S“sJܣ^u o=l2-jw`9sg1X d?PF o@F.ο? e@6(.V{0qo,^A:/?-r@z7fpP\ea8$;.Q#s˫$o j8 rJ|r o4SrrOnj-7CN؜Ue*550Ȝ`6`"| 70pi-/g[;cAviOBX{uda × gu66-1p9@I?v%10k<0Ĵ0fh搁A af\b`_IX$UZ:L=ғ;_ѿ*5) 0}Hy6ȿo+eTZhҹ}`KBWޘ;B~L owp!`hz=5 yR4{ 8kҵL A4w^R *y-bm#d a\@s9}-wDd'x_}w~Qo.ϐvxO -~b OeDb`8x[Pߢtsp d2[10D q VK;~aX{5}{y2QtR#Co&rTwUO{́!;^0y] jNkLgXV-&#մu(cкUg;Su-l717@=Tܱvl)F3n En@c񐤿q-b`8xH[%rKuoPK;A] rgjQ׾2PȄaceC

    V:`;rPSK;V{́kF?aJˈb`xtρ/g 5C kF̨MCL eCx ;CoO -½XJRAn]_]-퀐Y΢kp tKzB[d2Qr2$ZVpcx'z#Z-lM,2"tu d jiwf5oӍeDm?rI&M8 k4 nd'ԯ}zn⏅wKvHuyٷ?fѿ-RKa;Ėѣ^!X10@e%ߡm7a d yLԗ10,\ rg 7a d 48r~`P(?MƐ* dPUF]uϔFϖ|"f(R P5 /]SUFPP(EzgŅ\hE2PUI'ڪLOrpz N# 4/A@u9,g5cK' 1JQ( z,d@oE9q%,Vܓ[i z\Z[o< p\TY-dE9Ӊ ;UT( V#.ӴP.,6 VP]Orw c9^%רBj;N`@é M 20[10Lom|10 c9^%רBj;N)?߼Sx}C}[-P$բ|ocg]KȩBVuV⛡g"1S /CUGX6(ovo8  Fw;Io" );CRl掳lͰ3󺡝?sl8 ,YS/-q-!;4,֯wlFPck7^>q>;C*ֿzO V_Bj>P[_^^~ˣ)A;_0U10CmUԢe4ƁAz&/alOMf؂`wa P1 !.'10 $ *'/ܞI@ڭ{=o{,<[b͂T~=?,ZG$T r+Չ7Jd0}c_ItD< cQ9V ]cZ1M}.10C(.1,$8&Is'fّܝ.C)XcuKdu yN+ IE90|8CpZHJMD.Okwf?1t^l3U}U=q-X ebggb`(XYhcgge0w^Oƾ,D⏅O#.\>V>SWx;ԻUM; Evƒ)1\XPM9~y{ 9 LoAv#$F ,L⏅cu?jޔIx[ ^p `ԯ*!˫9հwG1 yD\oTX[ϓꃏ·)Šk5pddC|3Hz~ X5 ;)r|/?Lm+Rw Jk`XUsJ%΀sܸoI82r+ !vɁLj𲣺EvF-90Uri9A V <oeс#ha m 獁9؄rQK $f!tuѭl547B7vB0.qfYhfA'\Evo? ]~tUxYHu| >g˽=C$#;g#!. p=1Bggd'HNIe$=Sg˘.#aПn|aJteoS+-,.Դ='.dUO~w; `}<^)ZalqmXS.1,|2ZP~cB⛡H5 N&.LթT|32y*%[``nL &:˵ɣY݆iR)*-]I졠=FHr0%0s߾ dTſBjY,'s:j?=djڰFvV^u2YBn@MP' 8xpT` ĭ` #uW00Xc`jd'R/; E~G\LAmw-Oh`ĭ3dP x)^7 1-3$StV#e*З~[.TϕDv",edE|3$,s e¦|Zk` |`H(>[r2$ZVp#; }N ?q-q6P M,FvB/Swfowm f}t#;[$cga*|FΛooM7~}nSUǒ$4^n⏅ׯWk|W|3ס+o?/wwz";*wc_+F$Xx7;B7' Ӂ"uDvvpp.q-svܾ♿Hy,$jZk16zjphg͐u~kyh/Xa8UvICݒ";8A3(^,~~Ug% (O$!NJ7tEd'XD@6,!NJͺm`P7=ZVSD NHxUNf~fPr⏅(hTH6f@)XcahO%H90B}VNjˋwf?ɝB|3L;+C.Mwf?"!)Bʝ5P&fj;?q-q-q-~O/cxEiнc\/LᩪcIa3f.jh|36vN^Ϙ|~~ T۱Tķ*(ӄd1g1Istk|'}:ca;c`8fCX74e4l=X,Fv/^nhVc( 10XB,$d'< 羕5S K~`XIW  lI&oEIr HeDiUOqZFAbbBa'`_<0鸺Z_Nh";ax`@I]\^[mTPsZN5PŭECvcL ޼5 [ş -Ɓ紜w.;b`]5ʸ"p4^Y}iy*UɄ̖|; I-^O:8^'XׄWTZ٪l8L }\˗3[*b_NHc`HfQUb"dk\"4S^C²b`I,[8dz8R VQh= vr-Д sZ֪iHu4 UJH_*P!1510ks)gEEuWjzTl&:,go-#=MFv;B 8S䃈on@Szg7i6NpYhca*][faӍoGlVFvBWjߣA`3}N-XxgF^>:˙H=6yO|3|K_PxX}XwPU|3Wz{+4Vd'̀vwEЍ!00-C}AGqgѢC|3lQc`Md' }C.XP g ۉ7vppen9@ OU7SRV+?Yො^jNTݪ$CC![\M+X[μw#oL~|\XaԜ";!kwH_2^BI% %p6 Nn.)ʻVG0/&P+9^?~8ϟW kv guS~>/&Xx?oՑh0CH>9TyỳI #d̆IW2[UpN\| 6H%ग़*4Cd'Xb*\5c,HWA8pNJafT,ڑ310Qd'X?cŴPsa`3C7ȾMO7-|~(̀s}6I r{\y1ۃ}#P)`0=gHb1ـY-q@͐4<^1`}6<4[d',4[l3q*C 8 ,,4[|3lO"Z!q-|Y s ,o\V?fpYhNB^~q ?WBa]е "ҋ2IƦNb/N̿1;(X$~`b50bg~-H҆EvBmN^CpIE$f)XF̯vWC3lG3?0\7A";.Xaz}6xV}Q]fbtpBt>>_Ȣ1z50bYK[ҙH٩VB YtqQxdXZ'@ZOI|eȟj~|3V?~d ՗`USdh@vgU\0N u,ԖP.įSn";ۼXQ.] ;jzg,_!80"C㿭uE+pdq Ʃ0RWn` _Z{k@n";bj}Qݪ+3Ts2o⏅ЁAS#7/.f60R )_CN:3H09yFB.F,10\\ ̀:v`P0Yd'֯w l8R 3W'~$ʋb/$MC㿛uVgqWF.AjhR Μs_U[ZȺNpYhcgj`D7'QC3t >NpYhcgj`D+Q R,q-XpYh፳l547BEvO+Md塪cO?k@/#Հ}tmM|3^?/?c^Q5g:޸Cy⏅I=10ᵘ !ZW yo?}نW 7kc`r2x=s(-gO!,V.5djY  ]@ox7ŸC%Xii& /7)O摑r!,%?-⁁OT~pDtZ}`Pc!G->09c`o׍Cb?ҟ a'[G~pD_ލ!*XQ;v`Pq`a10Aw}`aK 7ehPu`Pщ#xdD~=,⏅10\R|3H.#+@FU ~pprZ.WAOwWr6M%Ar< 97 YYσ-TT 칳8Cp$90TsJ T{?NhP>cggg"; =ɝ&ǂ;B7;B7;BEvnZ&_q7;B7;BEv{?Qߺ|?A ج۞$4M}}n%ҮDnj`7B Xt Z1mhx)wVC፳l547wuI>'*esʝ iؗUE\ dPR#P$h,#tgWC3|Cz> i-=o)ɓ*z,$IB™{kfyo`i^P%oTo9U:R轮s}G3Ua`ɜV̉jhwc 8 .0r SJCLW*cm[,ap c` kPeʩSMV0_%aȠ Zu10hZ)cUu!Yfvк\JpX V60 $xyI `A>gHo ٗjC㪚E.#XX /!^ DgL"xP]^Cx+:-jjPϊiEpP(,ƢOq%ԧfH@ϱ O_FTFP0#[FaH\H |,4[l+ofYb6ś;BE;Bofq֦x.q-|Y sofq-q-cۤ:Hu7ؖsQ;R5O/#LyqsZhӠ> 5 @Nɴ|r?O'ڶcZ%#b.,X蠏;CM⛡("y/e =m;v[rn?"-Qr[ ⏅(*e $5tB[pG17|O> P^H%7SfaP铯-<2. ;Nx0n>*pmut-/?+ֈӚ"a0u$h}E![Zc%@9fpaEvƒ)*LY yez rZN'$?7d m91S+?Q$[ME 83NNx0E_ b`8cbΓkKΪɭ7Eg@vjy6 _";.,X:y[ڒwr+\~`CkM]PmI Evƒ)]]wQb P,H?UY!ZK'\}E[2_ WW YCևi;BEv"0I1wD|3lv"状-3w^[d',4[3󺡝?mFC颭>qkwf?!;4,q-Nқn5tq5[/z#^UB g 8 VU@|64yQB;CfpYpFѭl5[3n !10xQHrb 8k(S''q`@`z:X@ cX@)(S'Ra/ɯe6pCPELS^*TO[YB;EEjpQ  *lBBb-^g咍 V&.EP3f]%xGE MDBm$(k+UQ <[/>@o}`. ^Zט\_nRC k\ Hq2Uą Z D  o^Ia悗5&W#Պ`fuS⾉K ^â^NSJ85!/c`ku]%z`cgFgT7-./S rW!_ 4WGk9PX+,dMRSU#--10*h,OU@>) haڮ`Ś;B7u nHw؅(^,4[|34)HwLGt+x,4[ 掳lܡygp4z";Ὗ>" ^N-X_J ޲4PsZ6 Ɋ @!i]$:Ɋ37VtK݃7p.ϾX'U ']Lj;CN^3vok}@B]Δ @vـ MCI|3 c|N+&B}c xe`( Jd'XnE$x>Oj$>_MLti»o|/*c40Uh^xcߒ1!GJ}P8»10\]|3,4[=[bOV:p6»10\]|3,4[=ÅŞ +; _FkyQo]C4aI4.Xjdn HˋS$ܭ*"_[xd _ŋ6!<*nU80c!q6b7xY,/ UX T||N8'+o▊y@^A>lxmi߇kyuB 0clUm`Xà$5^$ kRsZNr zϏ<"/8\MY UΞh`fĚ԰j!grm⛡ 10Q}Pi-T10\HaPlMg &'ko&doBSPHLQA'9%M  mx48gÑj!)5a~ 2O}_D¹@/֪˛j՘lJ!:@k ;4 3XfYh֍zg"`/f,x,Xk[g"͛faӍ?|Y f%Ś;B7NPH୷^z1k,|D*}7:`'\|3|˧ ^:*5N">sz ?Z7-10N|3lኁ!!;D"$XȮ>Ǽ0R Y?zG,<Ζ' _9CS75dd#q\  ߲! .V.D%㥺W!~AZ5?S-d-QsVWcC*/ZKmc M k`gH7C-":0[S{ad82 1s @$̀ƞ Lq\`-{`ȭ-_HY⏅ ϟۊ?r䳁N'8.bI_hnn'lB'>ÖC fXe 0,~s'~䭜;)XF_~(|y)CS75d %9[8P oVЪ;cg⛡d8fpF }t,"XpYhfhm8N'qQ10T5XNlͰ[dn"q-> ][x? j3IhoyXS3`J>Qiو jjw7'XI&7p[xU(4SY,.<2"imrʴKY\oG~yvpdWb PsZj)>xty" Mo[P8&P5/tR5t3ӭkJnL '2I5^$ k^i9U=f@d`Cfbq+Ug:O|Yw:.Ԛ'ִ0_|Iu^ ɉ 7 wi6^ Lתmx5au9YZ 20wvLDn"Jp9X_k99;a"cf8%('IM:s?=3S?,gdXq-ӪLE:U!AUE"Adk3jiUU Εa1wfo=xۂ!w",#sYhfxp MwH5tCX掳ll掳l5",loՀڿy7/n˖۾%GܨIB7ßR hB ,نW BN>p[10L :xdژ6So";Aw#U cu%af3;.)̰E|3%u   W~կ⻈$XBBcAz> BZEH[w4S|3H?^//eNPuZ(!~!s(ǵC@d'HLI`5@|dz.yBcAz- $J15g)2[PBI|3XY9A&IԻ:濤f(ft:\9-NP/c@n Y*1 9H O臃/P)`5ZuVNwj`mTN$dܒKGT YU<1PR[r10x ^UdW b@Vg ҹ<10L 92⏅V[pa108oZfW10⛡10Nd'.KK3˭/,7rPȳjc؏[臃JտBdrҙ!7Y“Z!VuPwf?q-q-$+q-XpYhfpYhfx0%~mNpYhcggg";a5V?לּ ]U|3۹^NSUǒ|ú3l 6e}?YAlƃl⛡J˰v.X)ӄmL hͲbgk ?^ҶӳcIw-p5 /y\RYv6^q[o~Bl::cA0EƢOw2Rp`B!A3 %G NXGU#zW:յ>4֯_/xZ\ AƏe"ɜ|=#D8$0)6ca<'| Xg:X|7G] 0^B.oneVNy:cacaia|bMy`(hecPf|l«cv39[^-ڑS@%XxÔl ֘+T 0$>Z[JlHVozw{,aJ oqj¶,,_I,:XLqO&TӪyԊ&͐h,glB)淪rvRu\hb, A¡Ś;B7;B aW7XΣ7ݱĚ;B7;B aW7XfYh掳l0PړL||>|zO(lG?j~Mz%օL|fnTvKI:>Oz1n){lPUd'x!rTE+ϖ?j&xc` 62ΧbNB䨊V-4fԤMq  0#vu  2+ ҒFYDvP|,(~1AE&BUY-1-U\0AfA.jB+g *jS˭7pݚdN!X-Yr;U:V*Ց,,agu{K QwuS:0CryZ GyBNr3[߾-rWgrTd',p ZiC|3y`ox`HvWU[ /ʀiHz⏅*;<;m`Bf@C ʹV"ښ?c` ";E>+X`(3Cf09c``n ^vg-)J"";rJKg+ [}6,{`Ph`~%!תA!o#o"rʄ ȄVuZM{< fGZNrgڀ/W#CXd',4[l0 Rw8sYhNpYhcgg3Ӂm8  8릞"XpYhf8W- G,4[d';@2fH!n(X?SV1]9 \n8d>Q=A N#jBVfy- T|3XV<,WB_e%,6n)7Ã)_G*VjphVuPK$S";w ,hrVwR z}8&5YjL떒5UN*,^1zW{[Ũ`pxry7Kd'`/,ru[ YU:3w/?OkB' «?|A"-q0)յj$@?f`Q$ Y-i*F;0@10S~f|A ;ワ10";a+ϖ4CuMUb` @jP!H(o;֐! THJ<Қ TT!Ud',?&[UsZ F{7C H-KG !؆;(ji,l;+C[K6 mV6m\^nFHN0XF /or/=56?0,Od*?ZAz BA>hN1*ed#=j$nײPHQ'@eVc%ZmU쨎7U?NxQA^6 TBXsB5 ^N:ՀPEYΝjp~*&$$?aZTZ pi >lNnzjCkH!Q&'IrUW|3[O x|jeyBh.$?AYBgEuk_kkk$U";aiTUCAW>1 V3Ѧw MBgEuB vZGj:{?NX'%o ĭUMkyg bn.P(NxƊE_en3_ ˛G m)9˵U;1o.X%*_Im) t`ˉq&o Y 0# 7?BE;BvB/}9" 8  8 m8  ~;߻e8  8 m8  ~hRv \ u1!G=𓟬t؍Q|3Uu] OUK ݺN؍j9O:C'Xb5C;oy\ޒi^[|3l#l";Ax93UԀy{c!1e 7< oдvV-5@"pHYʩn ӊM )e}GDQwB )9sOi!I).BLoDdDh&sBVU(OE{D`9ڕt%8 5 U1]\|3^GT#aYĨILo⛡W5@rJ.Ӛ}10йX Kܢ%y/5ϭDv2h`U9Ynk3pVs\p:0`ʃ%10pWV~Zb`T=,Yt@L1}`C0`'퀸yZ*Ĵ}1CSo*>I,:NjE4vaf*r)"^d'HT .pЗ9_ V*[NXi+_Zasb-C_J`)E֊DUB֮n(r@W١w?D'`o";g⏅-9w^C|3]I|3,4[d',4[Mko)t  8  8 ,8b˝7 r'M7 Bܡyg/}i^ɰmj,>y+~1OnᩪcI5Ʀfx/^Fp@";!GyͭUjZDfb⏅!ݞ+$[y410 8  ;.)匁a//X_a;c`8fpYhNn=v~uG&Vg `U X(r#V2[ ,T爵w絻fx0% OA\N+mhN˳sL '"a *-'`Y1|r\1do*aՀₜu`嬽 Pܒ#;Sv̡y";Ae=T,B{gr[r8rM6F&w2@kvD0C J(540j9`|5iN.CawNzj^c-.w%uFs%B+Fjcx3xQ >H',0\]lf!tf^D"lǂ/x=śg0P/;4, xop - J1Ohgg@I ce;,,4[:C&CQFo O䴃[H'LQS>bwf7C}d j1N C. n"2Ţ O>2hd2ϨkNHi_)5š#7zQ |QG6WL4}rYVWײvUݪgwj;t5*ΪލȃtBz0p 7Cdw5H!&4O-f@L2Gnaw GD2j~weeԩpU GՖ!tfP.A#j:Hk PdROX}d4 } C6Ȝ3vr ě!xj1C?QbD:>3=v\/cu4 WoxbZIwHNpnK/6Vy&m"M 8kߤk7CN>Zi%Z./ il2 1w ]yPEU&[[" ҇-1%H'S7ěgCp l5WwwmOͰ2ERfSd24UViBP5-Q '5\ͧgvÃ{xwΙ0&3lv o2)2* +Vϔa"ar*Tq .pLցhEFO] 滛V]H*ƚ6_}#{49hCۤ(.EF"IDsg%oEUH'8ϓ/MϏ5x3ro{-=y+VDޭwD~hMj2Xq[3T`AlÛ8_⼺PuЈH'z-qbmcбP鄴Qw՛CK_ |5 %66t]lÛe>U m( o5 ?Ջ~,TIuy:誻?y5Sf.1h0/Xk1Cv oq8. ft[Hgy-_kguK`o2czlx;g&5Sf s9'چ75 xPhH'mi"oq $0sku ޝ0դzTbǕq׷%pVNo0*n;O^@nM6)*e:6ѿ*eqh\i1=CaI#cC{fFx3,4[i1=1b.u.3\`G{/q- 4~ffx3,4[ jYm^ ?+(2UC۾x3ѿGRM뮚W6sfHC: , 9*3C⏅qaf8a! (C&@ܭ qPp(G0CTCZP98UHx};ȼs k!>;?Vae@% tq],n ͰbղZ[З2I f1_7$aPԱ[e#Db `_߆Z *-Ы^_%Z`hx3`[|^p΃+թFx3`kCu'*tmN,|0+X~tśA2e(ϻ2*P& 4w>⏅5 387+Av5ygMowftB4>UNc(~ G {Ҹ^'aS m. /@)?(#3 +̚w}D: uB/ wykEv~K@*!) G23$3Txx3_,$^0I 4UӄX).~d` |n  XWtYěAK~! ^Aʧ' x?qfn 0OhH' :\:y,`>abfLF7ʗW5w^[>7 0N,wA1n u?0|0/ ERU 1ěh. STX!QU'C"5 WEP/V'VyBx3H[/UěsaD^0t;B 8 o0$ 8 wf?q- q'`Iq- ȝBlfpYhx3,4[ ][~\˲:8\F|,oŞ 8 Vù0Ӧ!w䵻pYhxe6ܡyg7Bp. =wfoNki'-bĞ )kfͫˊwDr5 8ŅֵZln f!0L5"),ZehaѼQy5:7j\(Tn^WZcBb`.fzqAUuBIeu)žLR-/:%|M5'&ϜE<4X)#A23t(F6~ hAzrVQݺVу`О=/x_ͫ8IP*2$Y<_M% lZ9> ;0yuGt0I 6 56 Ϭ ⢚\[8΅mZșGt0I ht-ת^<Ş ڿx\`oPT.0[ ;D} %ธSMVj'({~Kg)9h0}@:Oh7ѡE ̨du*2q- *Ϣ+p|7!жgbOof\pYahS\t,4[l5 sh>wfwf>6*x/xK}Ĭ뵷7?ӧo G '÷I!E[A0jxx/GہśC!E 'Ch.' @ڝ~y^87C7a8N/0\N F5 oëI={ae9TZWYo߉abP42S2ym-?auNo\4 CVT@q h+h >gSX厤*P)_DH7CN*Ֆ, Ydj?\;?<ˬJX`l-$TG :'* \,3|\]]Hݹn>`q_aӉ7k"\|]"?0Z?d_( +n`?y4 o-]MZx/:KTjS ^.aH@3w`wߖJ9Pj8@} ۗh+N{5 L1X6|^t.tJY,aY oO&cW1 h+Xquok")StkfjjKx3_H_&$uB~KMӪѥowKrBk\Z-E[l&0f7_Nq}Nomh+ 꺡yy H=E>NomxE[g0R2ygf87D9Oa*;21uw Do}͵aPx3T1$8,OgB7a8Kfȩ-TB0Lo.0\P\翏SC0%x3H^ooaP_F0U DpAq!"Ackk! 8<%kx8~ՅM*}d5\,. 8g5x3`Gx XT.`JZPY\:<Ϭy4S\W_Ë@o|;nPO.U:"݈G7C+}ԧo/8{pٯcѠ{[RfhBOhFf^Ah8z=񧂊EΌ0x3,4[fJ,мrrYO嗯n [GMo?|T꘺;}ziy6cC= V~g9-%Y5w^R1T:I|,D:.Sgw잣0ݒQ:bhsЍh" +ח4yRVL̄xBE2W+ka/N!/!Q\B$l}G`{cUÐ{+`,WX J:~D:@^I)׆Al:H䒕6&A]N Q)鬶e1uur!f{vPm=v`p60O3) ɂS֐ v⏅A[Mm0S4 vXdLҴ!OS/dm^}M`q 6|RE:8*2M/X`.׎6Jk ^ CuuIxGo?0~% eD:x뮊$ } ^դ:CUPEeE*+0íulPbl@ƢJ A%0 ᘰ~Cy(%:V쪿S$q~ ꡎaYa][q}owftTH2e4 Lq}owft;B 8릞" 8 oݰp'MD:᳟Z@ր6B#⏅- P 97W3Dάnc& #wt3ƈ˼\Da[A~]:x3̃`M$.GOeH'.Ef}9, ⏅nl3w^Xq- 8ۖ{8H',4[lfpYhx3,4[S3Hh۟U Bos-2Uu >{PU~͵~VZC0Ftl$w,,fo8o99.o[-bЋhN#:B;Cx397rF0ckp|*}d5\,. 83kޟC 5vyn!$xN20 iN+X[^$M2kG,brZ%,B!, T Ei8T n*:VZOe>eC40 OV jAqA)ϐxz{#xZ X+d9 ]SWu7I0D0@YToU'a˷&k`d 7nl7BFoMWp%.bЂW.Z0UBt,- C \Nh2;ńE&biV'n qdw4 =X+0CaLt,] Ch*0:&0LXkk@"P 麅h( 墨Zi%Iգax0Ȳ"" XDSgѝod%pU$9-u5gu75rRjZօB@qi S92UD}?cpSPb3? m&:Bʝ%C0-t7;BZ< vc{2K7.w:=ş gtyśa[|whW||͈"Ӻ:||*tyś0L ;}!D3B=9"#BzLk=繹݂/+0!xelÛaū|>e ē(0?Kˋb*eq- YAYȟlC5O# > ?%$a Iܭ*AT?X..T uїd^V_G\c0q dypzF\ Lnx7*/nVeOuf~Kw o@ҧ`dn10OZ |GW6X>%NXmmAn4;0,yk3jMğ juX!m-6I1IL[/C7 pWi{!ϫ/+.6e::ϫgd@Mğ ̶7(R6ϫچ7CIjԅySSI4 h1;~ߜ-u4 x"S=M-@iBVYVyb6pf\0Le -ʓ LoR7p̜$ղ% y)q1r>Ok?eC>46y4g5]i#¯~^C=כrlO' aVI' 0ćs߲PYY ^(&fUTU'$x;!.d$Z+r!PNUɪCc$J+ٽP4 M`a: C& C3 ;pL0u`n4 rܪдPt `Q[f0ܙ9 `#"AvXpWO0uŠG0.A!U՛漥A,qle< jK wGěAbs LR^[Ifx!QMk24 lxu w5)fpYhx3w;unpe4 A:0E07S7cE0[>:p&A:S=dȃ(_CkwJ5rj%domu~]?TY3,FÐX0u2u-kZuW! ol}̚W ʼf7H'Sa{ϼ=2Z.\X 3lm'/0wpoKx$+SM-PSx3-n% ?ȯcA\ Y afx0X30s G @h,R4 Wo =[erukfB@003TPtu[ge.9x3@I>k&++-~B8E:!pf)wV06ڑ={⏅7f_Bʝef=p<={Np?B [%pYěgMA:^b\@ր!TU#1 ք śO#~йf"C/O`7Z!_$mʈ/zhIhgA$3vψ"⏅+ $4&3XXEI:UZ _@P:64%9i]2ibb2D2ƣHb0ܚ*$duT&3Xf g8qWÜ V{PTs.Ꮞ49!M\6M<>AzךP&Gջ l% CXM%:|<ϋ?7 KTZ_1~}s6M(Nl|z2uB:|T7d[cfPeJ<#d:Co~,0 ^ T`ߜǷM#CSzAk+ci|pψ>M #M#e>ᑆ: mĈ>M `APwpψELGbǬr+7C 4k&kIHJk!lwG1E:Oy9xzw=aHwKZ^%[x3X Cդ,rrPSPpfpLV5RVV"QTqFVo'T|ndHTcdW${0|eě(˩Soka-d U+/& )$ГH'$ 9F C/# (AR9^MZ30ƙ7rf On܉|pNM0_`A3]a_U\anb;a8H'X(/VqުBYyS݀U "#Qk@\-紒|VuKx5Tq@)*hZiW&!꜡C( 1"΀Sllf NPH'tǝ!R3w{8x3,4[HS/- r'M 8 owf7;BE:_MT[뵥?""""""^4> stream x1 Om S endstream endobj 86 0 obj 525 endobj 88 0 obj <> stream xYI6 W\ )6pmaS7\k3Ƕ푢HN\}:SQEx?q|j~;vCu0Vlߟ w̆|w gn;3X`t~~p;[ULy;͍b |o+ xj |':;Cܕ+xw BF۟hIX T  XUV 5d ;'+ ;*p _V:`B=;PF4TɌ$XOb:" %z E7jJ00b^ŝ֬6i*AXꓻ7EX<(/o/pSokZL1\Vn5']h0=D*z>(Lf ||Y}|WyLGvj%mw̐*9sZ$cbXөkܳ7\D#}VʚmEA1.z' ^WM;]Jn47pNuZPuSdCp/#-W`G?wFF;YFa 1o7ժ G oYYc1p F WYȸ㼖r"K#b`/#r{Y2>ba(t*(MLpTȡ X- Y9;Y dREtsiu9_vS Gy)L+N_c-Rd\2 &>_KVOK䦎䞲c)SockrRQ 8"wM3ˏ46xPb!qbqZeQ?*CgPg%YEcc(@:2PW  62VM2(ifFZVr9kJ ʹY zF:v/;5Z_tLjJܪZI5Ui(!PDT(EkZ4CxQu9njʲzVk=')MޭjGPJ#mEaDMg0ړlbi[ ,bӲ:\gfAKn}Naq̹+:5^)8L|̉ͷa-/䦯 85Oz[kJD>7>]CH 7m;wޠSi㺠Ք-z6=.Cr`iDƆ:J m[k+qv gʹڲZj]S;6\kƢ4C-[Otc !U(r&}r خ8HqآS"^^O'=B:/u:IiYB^<3@ޮ(h0A c4=>JN7BPn`="Y웕=Sˮkàee-XΊ{=d ZhkB ,R9&OQ?8vQP Yy^y+^Z(gvaEI:;X^[ZK, +uoUpZ-P,P9b195Ck8m˿)rMﴘY`vZa endstream endobj 89 0 obj 1773 endobj 91 0 obj <> stream xI޿@WY6r!A2y$Zo&–ﲺ&5)r)X駿}7ӿׇhe:vWբ@??_?tyw6/mA iRwԬ_xF=C@Jj+Hڢ}(  Cuq?sPZ\  ^Ԭ^9rI4nR.I&/)wW7pWMt=CjC>Xef͐+8 7tp<㭾3;= eU㦇ZFM CVW ɫE \@me%۞fȏ Ws2S 5] (I,"BLi߳7RѡZM #3TC>հ_D$IG1VGnHy(>Ƽܲ/x-/2R0FLXo># %*y>$ܳ:H]0w)K=Bf7By3#ӨLnN1"vȨEL e3sYj;@ea /I.7Cy! 9OL"o ^1ыh# 5L ߭@Đqi>R&L3ZsBCM跍ZKWk,>)t2޷D Q/?~<P'~fy5`Mѧ9^D&v=U & e%Z*"$y`*vn~nk &8߈fEn%tq3"d0* >jQǙC)[0دeMkW[<26ň$9L+"nm|!-[q(rF+f.H, u9y[t]RKUvX Vu Z=JZcMbm2${w\;1X₁=ce`aFU~$Z,C~jHDZP&,s`|YF/,9Ԡo㵝NJ S.&\]{Dvͱ.5|hc w+ 'L+Fd-'НZ1`qw1IƆR ]Ty֝C#XqOrd d'oIs[Ĵ0 ߈[s^( ^U BK(,.swg l~IaCF (`ǬhGc+YZpwne"\0pܚ'Bo & o,\V j5$Oo!vM4, &-69`UJ kʷ O[|3zr{  A#"3\>f } ,Tvsffy8R1EGWx Ѧ|:>JD`(ߥbq]3Y15uc&%eRO#9WifEZVQq؅ʽKٚFcn̅n.kÓVm$`V'emڷx|J,Xz7SEعD9NO(@22riGckL7D[樸>wuYyf\u?Hk*t;jc ,z:iw2O iYQNe_»pbW1S$:t1-a, "_zE=®R*WhFyx`V\49Z9vRO3+Ԧ$PtO-FjbiJx$5cBNy0ݘ;masSiMX";eȫnlnzhHn'q9ѡY3uh'fq)`gT[/3CyAww~3Xo.qZ9.r1Pb;X8+%sG%{Z9w'=x 0Sۄ[4;6[;I}6i3 fA[ [F;[5djNmuGA8lž:k b[pnWB3>1rk!"wp_&Yɬ+ c ٮ ٻ`/3XOv":2|>@ʉN'DNkR-.$ue)]6Dg0'UL`!StqKrx[a A+yJyfV.m/w4?F𸍙 PK\X~b_0>; endstream endobj 92 0 obj 2389 endobj 94 0 obj <> stream xZɎWl4$|h 06f.~0$) 1NjVj~}Q7׻n:Ko]߰_6~9槉?^U_QzrtjT׏?=?޾qiH*FW]h_Oꡞ3.M%~*O,q'dH$$ x^uW 4;/ԤXk鈏ac` O M>g>q*)>Ras5/6OHGP?Ac J ?FeߑSt>MM J ̘7]T]Kv}ǿ"uY;[ߊP`LXwQȦp4]Wf9`هX Ee9xf Ȕ(5@peL :ۋUa<⇘D\EMIo낋?M5o VK)ؾu8$(A4TP`NbXdrQ`I;N%Q}5y֩8+IӲ?cVI)1%Aņ,QmY +j:e4e*fap(ԗ;,lJRh ZqUa3K>i>Gk]ASdФ~iN,B8oBW` ϭkJ-]@O@+]<\mJB*,a쮴g4<3LC.B,TmH f[U|!O<@ "FbxqZ*R>w)U' S_ z 狜y2-pŎZx)| `w) huj35XPfdYOm2 ʦ~q\~Oթ|~qdci|yfV|'8`(%!/qQ:7)WMPTR:A5{T孡N,˞cdLU f %2?rR vݙ8)6kpB}b(,lVxTָSVyl6Kσ6]NWjm'{gHP@umo3W)/Ob j M[UyjA+qWuÝ0˙9Kv4zZ-{y?i7"<3bcZIW\\l-s/ 3m%hC[:wStM[j*6gjr3 1Z]u3kku'P<' [Hl&7sE?!YF3TOnQCQ'I݌?Ւ7O!j>^RNw> stream xYˮ6+.p]! 0 XU/h 4~ IzY.u$q9a̙ϧ+S<֟j履kS~Ku {v\s7t&\b<9M}#<_ _޿?=O64[nWla+g,ί/_V~ ԙ J̅ [Ys7"mn7YSYE8.tP<[kx"A`giDA! qXET<(?'mv,3YzUx̕ 9HUh.7~]BdOv >ە!p}9/&k%C; ~(FQCҚHK!QsIK'$x}bK> xjp>v `^"^F % ש5jԓ'(몤E\eKd'Jq4a\c%G 㹹,R[{t6%}*?ںekyvjcx~Ab fmK-guDw1:9gB9vE˪,lIvMZX7ԆĂ,(HH33@NZpɜ ߝL&D+Տ+-1R0m>8$)&~޶( as'?HpevW\ `JytOKרWH5~*EwrDPiRAw!:m5Asxkмεɑ}2ؐ:-JN"VI@0!DH9+h9oݞ &%<0Yg~ QW~y8ۆsmsObnZ#jΨA@߼ж)_CsD= Mx [Yҏ$ VcA_қvx[]4:1B(crQ0 \b6 b>ehù]"-@lHQQiT*6bʪ5uS0 ~E>Y%N;XtpWge0<7t qL}<}ZRcqЁ7W1M~jBEq ~M-*4h' V̧+ cA Z$ |tWL[rU5Z^ɇD6_.VP7Z|>/MU|=R=|Q٠cfqdn"Oh.ʪe/Ţϣ42Bh=yi8+r/\޵[+`&f#ޠР=O/m8 I*XA7iC:9,CH'x{,=¢oJʛ&~UϧKMLdrQF(p;h2sӈ> stream xXIF 90NIc@n/i! B^ ~$ivʪBlcK,je]|7?~>_ ϛuTUHdߊo'(?~nL*7Հ,x>2.=UяUwo{=?gqUW@VjJh[A&)DwlhCMG J_xʾKjQ`DzrƪI=ogN Dj6<W l%$UQCf<[v\ B_LTQ9/kXID/$I49ZBx'ks TY>A[և> stream xYK690Uzl m` % T$?ڒ==YzܖT*}W|z6xo_~;۟b-yM[i2B (h@!RXәNwpoo,3m>0 1|SXp틺 MB~cM\m+T'̨n-9؇7}7lZּ8Yľ}of!.B_fӺ턡a$ҹu"HB)[(~&Q-e؄B+{Lb{ {{:1.[;$Ns!3.H?F֋!.f"ƅi3Z!.6 /x[$)լM풩͈.j`(DppW)gmTB3uX3u[I8EKT#@Z}(}tCb&גΊȊ6/FWeUG&kY`2) @j,yG~hG+sZ@B}4M"PcLB537jBA2"e 9A;,IG+/3;1s*OCI$bV,b,e#j, :?ų':Wϸ\Ch&9=8@P)-:^j=huXZ9t̗Π;Z,R)-]5:[kʪFPB>[ 9EH`z5C2fMzBۡU9 z4&ъ|ӔɱEoϞ=d h*i1cM.r3=N&4{5@Ґ؝-ml1T{~N= ч* > dkȌbIrlD1nV329-gtاjg$IdVhp1*}$cBϕmPVD =FѸ>$́o899.kIYM˧@J2Iw=˫u`RSLVry>e xx;$0mG–װe*nvbm8)OIA[@FE"oo3 –va`a{)Em^Ad|/oB/ʲ/f8m8,2/C\wLObcS3]ČE'/aD׆b4aRX 8 ۚeȋgxM]"!wćť^MJ ܩ/çIc^DApp/g k7r+H}+rD16/Zv(S%N]K> stream xY˪F߯:p$Zd7p!!dY2~NUeվ+::sӿo7̧Nxy o>`(pnN~܉ڏo_6"!43&"d9| 1֘b>0/"ۋP0lɲ*,H!a3]w]a2e1X+|edx66DeA*fhqeьxd_+&—N=ds AuݮꧥA?{q渦k-i׺ Nh>UV/+l D س{)wPjWvP3X)h(<ҍlDʱ2 xfPUA/V^/:qX+G>}q:a$^:b} Ho- V* PDVЬ.!c}=:_Z^Ygw0jzT\NVJpIn}B4q}!6߾^ } m /޾pj ÷_zaI; Ix ۶h`w!|mOĊDkpy&`z'4 t7q<=^i\(ĤEumHx#M<&- hzLɜ`l޴~W/.s*/e1HfPs8\KB6)ыM1jx.,ff`̽k j rRj6\U"؈nW',YaQǦiji n!Ȍ*h6AO8EXпV2fͼ}]8WDsIe]i+Vhe\ӬOJxT)EmUʹ+xq,mb K|rLnjȶ#KI kv1v0(W̴8<,aoseEt]U:Yҏ8SFQ X퓋9He:sb5唺X0h£d́FJlsh̊})Iu K׆͂nz.8o|]`pnW< C5BS.h#GmSVX־}΁ )7Z[~p?/ôWLƍQ[(Ǔa&HVA^oyρ B1z9|N1zwՒ,V`yC9<1}G8nїrɕ%se86|\r%SJqwMLKtXD9KC6-2D-[rMĦۋFSfw;X&z亅]K>&zZq1.-wkt^'7[K5k`=k^bfZP%5Io o=E|@Q/ȷ:iq/ަ>/O endstream endobj 107 0 obj 1619 endobj 109 0 obj <> stream xXˮ4WdԍHQKݝX V !s'Nҷf>uB͗?hLk..ot;OKۼ|;DV۟a%bZtV{zk?j6kl5^Fӕ ZV>dCX$R$RA<R(n0CZXED, 8aðPXڥ'YEqM ^Vh$Ayu;h[3"X#zhEKZxkF1ɇ0,;AUvxgꤻ1V ɸ0W..^٤[˯%ԐzW+-@&~"Jk;˫M9q37veǾCPD nq@Rb مUQ2Y MajQ0LBT G/J(oV|4"O&$VhcVQ"VndBW؊vaA 6;%>\O1J_Ѥh Ju-֎ǪTPrycbaF-^& xPJ~x;:phcک)5$.0N9j~RLE*)҇h"D )E uRŬ딒][O %-}CcHĹz8.@jEk#eCD<̎͋SG?,b6>ZT$ˡYКFb$[>k&QO!iU"iUn3 =ZaWI{mk4Rh Τ;rWTd&"#"Ϙ\-s/؍Pz4aiaOYxQeYmo^X[yʯXQ\<ϧKL~y 6JYmt+&t!n92Eu֞ƒSsHHrѯaDSH_r!ʡ "o!\Idx+Re$JMZExh<*Ic-%%IFğH dI\߇gv[v^t9&[@/!G߬S41L /_ĭ%Fܦ ǂ])EjOγAPulD`7FR(HNde `R:B6>OKP9Ekmɓ!$y>u//ya:=={[Acz -ǰS!UxE?%ɰ!\DbFFKjӕqAIšzPOe5`|ZMIc9;9;O|U&@+fBV;!kD70uR8|G1#6CxGƣfu t%XAT)}n2O~MD2%\ibvkpGޡX:7.WrƂҫ;ZNU wn endstream endobj 110 0 obj 1594 endobj 112 0 obj <> stream xXI6 W\eHj $.۴z (Z\$vf/7? X|>},s;S,C/oש (K˃zS ??5TC\5< Aa.gIP6/TZ/˚A5\ K'/y8B(nrp T'|T:VN51_0jN81VKdD򠇇Y:}8rn_W E޳t4g_HUSy΂UHBdeCde;7~<|3 ~BW+hEq3xo7*NIɀ+1pAζ֣5{}Kp_Yˢw=Eg8.[q;,bc+;TSH׳%NVZvbX "x "ǝKhQژ6kQ,d1+-:hPF< HP@SCNx?ˆ9qpSȠA-Lqڕ\-c}#]YMGO3v($tszEJ34u eftf3Alp;v Q! l KF}(*&so aݏTs?tmgk i ȏvOqݦq̝dj^V*l˩FTXLz3s~ r^gXyN*+f<;jIU$*3q:ΖP]>f,f(h{޼zL6f=8NU?# a\Gf8Dsf|I%s|^)QҳܴT! l k\DWcU2o]f,j%LT-P4"#R0] V#OTLPa$rLԒi\xD2X;  @j\U4`dg*hEPW#Su( S#1wBo5G䘊|a-o~)~ldԵpOOGUr+/gp%Bk-sv*jz"4F;f6ta8;FD<ğ"PD<kgCb- bXKvome\|CWWM] Zfr,#2iCV?ImUHq endstream endobj 113 0 obj 1471 endobj 115 0 obj <> stream xXˮ6 +.T6@Nf~܋ibǒHC _N0xp]bO1}>NQ&ǯŷ-MYĚN(g2WӦw.髳Txsy%1Ll3ž|dHXdEik*͕%^Id["1BMm+ѓ:LQU@Z;O% rqrmϭ)<\*cS,:r!A4w>WgF0FގZAY>S ]swk;xVRAic5 !&p2 ]4q`)g1kPIQ?ث=½̇a!$#*$7d̞ QXtSlT's$gp) q48Y}>'1_tŭrн5Cs78tbQb?/~{Z.aoCnRP%mX0Cp@TkT{>L&\N Z7~b~΅E1j:*߁5cGQ3JZ00J<.#XB6 fDvYەF #~beLHی>nRF?,i sɍ>Q.,뀼ɨفMIhKdUhFF faHTӫԹ[=KhlUe4ztf=~Xe+5S@[2RT%dU_ d3aST-Z*Hges 8o+vi<u.M׿^'UȢ#NY{E',Ull'Ӿ`"vuR DqlӁ?2ȐvClqks3IjEd5t9%<Æog mt=WMߤ ů;Ũ¾FZSvmc7>X8  pC%rwL`K2%+N$O 5$gca5Cŕyo^kV*t*u^kc u}Mx7,ʭ~S+iCkr|1yqOVWn:K5:5fί8C'AMl꾀~]@mܛ ֗$uq 6(t۪۸m$:SK;K㛹;ViinVnqVl>C/9 endstream endobj 116 0 obj 1642 endobj 118 0 obj <> stream xYˮ6 ߯Ⱥ@Rz@` {]l%)Kd3q$"yIY'W*ǯ?s<??wx@{3otFj -џj?h??T^UsqQ UCgCi!::[o\Ŀ@vk bh;o1@m܍gbttY/mj}Q'Wj<MB25H٤\,>`}W v EzSX%*M|홣 I6;7]N{@`J]X!a-x<+io.iO^6'?3o᝷C];Wb8ٝ)jx᠑XBs4Fy# lznYWSݘi1w&Pvp6) Do%Rէ KꑶV&'EVEg-Ciy *^-3/ŐJ1m8=d)F ifR3U 8 L ej몇, {. JɊףpP>*+V! ;My*D#N`V&̹SV2,Cĵ=:#U,bPBX>b}w^wS4҇F{Dm*Pr)LmϬnRG<bF"CۢeLYphnj9RSNYNԘ1P\#O#`ɗk,*16R4zVXAY(vRl`)|f*qI-LXAiRȽijW!i"m\c;:M km̰K!q/KG;c=&E1`:Yǯ:>3tV3ɡU5ޝꙚ:ijV,qX<["(X VNK!b&s/FW "l#6d]Lj}DkQuPDW4zt2؜x{d@Ck nVF/:Iq*O#UHbcM9ӂ/hԃZǚ46^jcP]b&uE P^Py" ]!eì7pj'+^A^d.nox?;vu3i-B0 lm[@) 3lϤP JK(y,1o\}ޭo,$JY}yI_rd61ޯtocDaQId#t F_fsWzl\Z޷rXϴr}7X\QqL_%\pWΒz*]Jso]v3t>RWVBa2Zp UӠ'=ymk J|#QsXUr-d) Ps^/a9#f7$.98%niƀܽݷ~zDZ] 2J!,ϔ_9R%V=Z=C|UߍZVH S,oLVy$.8 fT`KIcu/` endstream endobj 119 0 obj 1753 endobj 121 0 obj <> stream x˪F~ v#l+$,BVA2y}d]a`%uWuUuWբ WOVTLm.Ry_}7? OX49g/uSJ6_a&i]EHg 9NȲs˸#7J-c(6ĸ?"՗${X F&߬إo"oѻ㈺$k|YGsW W5J&ܲ[U'_oG SK1Ao${rIaroutU.㨡wCґU[^EROgWvǐ!*bQ~Zku[. WݡcTޡq X 4.hzy6"lW6 A ^uDz)Œ!Ii^{J9CG0`{-f{k1_Jġz .ط}(=_c߽e 9d_?~1NT>VxwW?.gWk`zZ#`Pپ=D]BSʼn*2*Z8 ɈKbVl5{bQ`M2dbopԭʳwAafDqcmjW Ԟ]CuhSٸhWvsXj=/3ሲxlotD\TG@4&{PP5!Cl GqT}\Z7K-I$ uFF+ b} "B}l.< ve &޳7d޴n*(kto=±R0^5mwS c1 i ٲ&؍pv?(m90k"bXA׾ŧdq(dK4ȃ}CYok))m);׼ZMiq 'L-! z[(Aoq zg k  ([c#i~W@/I:1Wu߆*) eOL!be{$$7yJyIKJ%SΔA0}J=%c93?s Y`4oT^Avݫz͇@zeCAT&8uR=̢s.6P,,:K_Ңw9fH8> stream xYIFWU ˁܒ r!/wy?_jI#tW{uՉ/(\֞ Nǯ;}p{?XW3|LOg~Sş: ώ.?{UM7đ=C 8=4A܌^GΤX D+ii!V^"Q+OQOn/[o|cyK]ZDϚUn;N1߫0-V'^ 6<|XuiQ )Zvt"]@ѫXCI/zړXl..<ҥ;zr`b'DDMu~pqVO+)aid;O8}Dw/>k"{$dI6"̭yg$]\r*r)͒5+Bndo %VGo#+ nY>m8H/X 'TȩFEߣ%kDIM8gӅFAo%oc&pv(DR.e\^|sTsKX?wE^f1sh8ϜK 9ibKv/ŋSS:7򊈏Z;Zf =ztxLTR]\$酶VO)jRAQwie&)Aip h8%KB+Fr.F[>gw쮬(vy+d"78+տh!s';+DnϴjkDSnb+ewΉWU Z!r]`j(-U+DصC]=o/nJڍ`_lhtDXBD}]ڨFl\!5~K:yW¯x~-MDILf v-F"Q'[1w9Iނh*pNB\ 3 9 4) 3u+8Pɡa{ Uθ؈]ZSVȬs !ϔMIF8Nc~>H6XljJqbUZD-[!*|*vIt#!-?XKs./iwqRleZkp1Wi`cJ}m<Ў'N =wIvLXmaZ_z"t"oR XhË}::wfvLqImMڿCě6Rʾ=^ƌ endstream endobj 125 0 obj 1658 endobj 127 0 obj <> stream xɎ_sj# HI4$ ; O[jeqX${Bۯ޹]u7Xo??y|:v?v-ս, Qzh(uOZCԄf x?z(W%S=?߾lh0 ">µ_ ~7=}$`N4#QVwƛ_paP<=^Xfa"t?녞Uy$:AsloDx2=V?U33v(G-K@ͺOP{4Ǜ^,xً~f5"XіnODmI˅^#A3X DF09!ČPH-Kx $P7m+=7BȪ :E`{&hn(T^GFK ,HF VRlYAWP-0}: k[`/X'{@T%]Ѩl#J!'IU/124\͆jpcY[_V^i=0àk|$0ʐrDJvhD0lsr>ƒ& bdriYjp) R5gfpW?P6 ,gfaZXUlEA$h)^Dza"Ŝ5#VKq%0r肃EJ|ۢ͸|49\v<{&m&ПzS Fv ZA` x0Afs>=0|h IA(` !|"ehy J Fs(I:%!:GꐾuN}rme^ѧ>2G Qoc)q\)*Zx{ɒ @Ԣ>f T64DzZϯo IMuk͌_DSԒ]ksB0@߂Kn\՚N }&wQzJ_k7+DIрJp1WϼU, m4$=>+܎Z/`S1mtaA `+:Lނd~h=DuR m/;.h,VGk={7A0;hk:ϰT(qN":haSITGX:X1ٞF`*3εI$zcyyŗ頨9=dyJ3 leU1?i B"/lp2rв:}O hqT9 XZ(LJ]{ryASJ&8f0A߯s^&Лk9FOocSRө?e+`N0 76%.8>?ƞ_mƞZ'8{y{>͉> stream xX˪6WxN^1݁&i"dd!lsSo24bK.UQα՗?U+苨⋭>~0?N \[SUL㕌?OaaT6 s_ƈƚ~GfDw<*d3Fc._E1bGew< z!cxcƻQk#_4q3F|GkpzOZ81c=75]ɚj[fSGFw1U*Sѥ^,7ͦ Y1ǟ[qeA=+7-ӕd{$0AuW_^WնE=~ѓ;2u}%!|H4R|$C Bz+nk1H1 `eŭ#ZDQl3Gk0u@l3 ~ ^|č.AΕ[2iJ7үB:b~:2NTCN0~\M^ERҩyz;hY"Wa7kSag/1D \>]6`;7oA7Np6ԡ f%q'n^W;qez{Vs4ROrJ &IPܝ87DRbƀe\Ƶ  ġ4V |ae8L8ZB#1+< x~[<>[*rR2qxЧ#Qx;-+wE|Æo ~h@ N!6w"S̼$^EbҁF.)iΑ}JeGm~7 0(~xZS+A*Cd'LYBi[$B(pAB|\(VTaw1'%ysvR*'Aᤁp86Xo°,20zDX2l`B@ /?ׄgD4.,bƢ8um< pLd[vCsAD"&| GGqOƶbЪ7} ,a:0یvLeKZ~7.DǎY@HJj +kJ"Nm#!bɓ 7b慴IdKdq3VTX0 +>YZɬĚQfw|`yt8TN* ZWU9w5cok!] Ƥ6$d[Bqr$4KMMLYe93^CߕY;Ŝ&m9#e>m DdW|B@ M?RI[9wwwԾ#kR}Sp *e) gnK$C&G2wP#P~eՊ'n}e"m#fYt$@mzz!f>jGe|HAEbz^<߇_V endstream endobj 131 0 obj 1514 endobj 133 0 obj <> stream xYɎ6W`:,."4z r0rqϫ")Q %;xn-dzUluF5 WsgK|7>q^Oxo1ۧiH7|^I]Ӵ](/z|Yyz>?KO=>˷<%\/AiA9 b> !#4^H+@׿xKPd"ꋣSݱLwq IyyO(`|ϯߟw ;m`[3Zu6 ?i/d菤rSԵI6zT6ڸ\djJѿ|8o>I5/}>4a\REQ^ʶ0WcTE8@ډ gƮsdB  Y#XZp&9c{[)_t@DLz컍=ælα~OYZ>p-MaA:ҔWccV\oRj lj R7p'4BS[XOOqWD{H rn >d$+;KWoýܞ!ڠs͐Ehcr og2>vg{9zqIEtsnR9)GND y!u(ߨ$Ҧcdzh\ R+k5UENE v)LҺ8(^b1uȊS"ō 2T -$P /!0,s34D=c@ؕ]̅U BFNd`3ft˂nPS) D,1+pYYoH{~-뛭5aaGLwH.앃&[)v6 .@ ).@l`;ݨa7F~~sHr@je h3 D}L݅ 8,Djg4-#5NT'4O8;}gߨܼ[.KɽB9 a3ƬzUWV{^gN ܒ1UqS\:iT!Ov/Ɩ 9Af`>v':4LJ\mk'AHGlr1U6"ә~!0iɚP+-Q-mZ#{5=GQ1}ჰ5|E&dci'`>kvE9gaT*h~@ZsSS5K!~Vպ,:vPZb pꋪ Br*92e]`(%P :YRLP @4GښRˏ.Cdp}~ Mݝd, f8 m %AD:ڹ_D[)ݦZW'8~<mn*k#1g˖> stream xXKF ϯs`{K MnCr[a)/l%?*Wg4>JL_.tlOs{?o}ex} co;=bj/dM~d.]?4c4WO/חOWOdxj Yg:sXِFL ~ip"ķƌf|לj;Ƴ[MB&RHq dQ0JeLQ嬉N6nSEbxkC1DSog;1X͈Y5lS,UF ;6 ~j; g{>D]C;qiZP׺Q$jUB3YIJ҆Llicwv;q_eS [`mG yhqW< Ň4 a;d}HGlѵ>L t>MAw#4{9YzX!co J}7B)~4!;8bd:ۛ:`D:7|-)t@"@&mj8wtdP6l C%'sp+s ]bk Bi¦ "׈gXV| n[@ejj5p VDSL>ʄ6rhJ H뗗?~4sҕڌj 8Hyi@3 Lw?C[~fX9H,5LtAfa0uck'v]GZxgɳV)!Q#NfOϘ=j'eS{=Ib| [2xK\Zd=J2WK(odLMKϸ6x\\+H!W lu"KڋΜmPj"T=LYA`uS*g ) =9Ҷݦa,LJܴLؘ=B4#rkYf4=ɔw8\w9x1W4p#=>AL+<=gcNM+Nq 7 c =}hq^`n*Q=^M'/]Ct!:nܲg7S D.ڻU*as;1 irmVhWrQˆsN~GR$(t7%>SIG9U yr!&{嬕#7G7jK6L)K-ՁM9qK-T]!篩. ˉbx|>'pyVΖJRIer;yu&tf endstream endobj 137 0 obj 1911 endobj 139 0 obj <> stream xYK6ޟ_uᤚ6Ztw!Eл7#vlɎo(cYּGߌt̑u0c{ǏʂqX~:L'ӝ?ɴg>3t10w|7>Ϗ/3ZH@ `Cyr2y<t:Y/yKx0eGbZws#H7|lN[8*"E=iӀZ]swY 2ɴJ((oV-quaaLU w-ԣ̆(RbYMqYɅJ0[b$LrO3KDd'&ړ^l$Vx O-A҂DWY2 Z 1"|]:d_ [Jy1̆Za :=?mĆU+H)ieȖ' }aƖdea$VCR|/Ag->VFr2!)U{WPNU-jaCbPЪ\5ttûg)2*چ !DdavYI<:v )cT!onnjTigFaOX2%p(HPjleSþQ2IYӢ!!|DU|ixKܦE(.5Q¡c5qI|XɅD:*X/""k!lg!\TE\9fF*̹"r 0G_ 1"ݦh޵ͺŠu˝)CfLB h=]Nyi#xJů(APB&wYaӪwJޫ5-T y7޶yU]ˍjBs֖m7Cq"mhIt.-,/֔ʾ[5{)?s Bqg6sM`Ɋ.k\+Rjƞ@aq(xOmŹIӡZ;oĈkh*"LF 6h5덽㼵23Divszts(ʟl6Moim۔68H8h-*Fy7jam[SF\bvTu[yU[Wu-v_^@myd{?aN-I *oxdU{vyJk3åsJay^ k OwՓ ڞ2je>rNS>{׌bpUX=%rf-66缚ރA$ɒ>nU=n*pKF'R]Z s~CŲD2ZF8ߔp $.Qה`-nIG%ٰ!qdUZ5[2%I@Mj$I[no -PMkr 3n $/9%{]\6)k~r=r%$kL/)ci_( Z endstream endobj 140 0 obj 1678 endobj 142 0 obj <> stream xXˊ6WxJO=mKҐE*/JlHC**U_.TRr骶tϿ]~yqBzZ}=ڊTU^ex^[mvʛmNodkO ?ǡ bHZd8U̇'XigwGI(ꛎTy͈ Ͷ h8F2ŖB@N*s,uȩ<Œ}%0Bqrhp-N/9j`{-zHqæ%#1uESe$HsXAkɧeS$z`K4tda-6,] f/ O3NhHJG9nd#J Fߔ7kS@SeFb'FI ==X4k9Rg lTpfFaJ? En?FRMRJqHk Z3 M4$h#Jh6K:%r~ȶ6烥*(& Ƭe>1Mqui $E~]1w*޲$'|r)SJ$|Q&$R^^ F'2vJ ӱn)M()8I%|cbɆeMR^e#v|f.)٦fv\d<qڸ,N5Sl" (ZQ9B.C//CE)T7F<s.hż)ce(ie}Bq6Ci6]/U endstream endobj 143 0 obj 1572 endobj 145 0 obj <> stream xXK6 W\ Yzxcm==m@m{/%q&mݢ3L,-vt3O?~0>.pN/݇IuHh#{:t!=扣G y#L0Gw83g4wL6s4,):#c"%#Ί.q->:IYT5`WÂM QѱAd@Yeg<o?k,DdInbP8銦nv 'jU4T̴iWL,gN޺/9v?1> stream xXTZh=3@4m"SB\Wo#9IڤEJ_ə73QT6UmRW_8MOח?O:]TOru+W?&a[t8sVX5SM +M>)Ի̭%aNư1$o8Ož<:uk{_v,%1M44U,10rP/AHf"j\%fUE} 0p +Vz$K sbVFRؒ&! '/dI@_Zn֝%Uk{9N]T Ca H ~2 A;㨗ٷ,BfHPC߹ Nx?Ө^5Th4dUOU'\Y*)Frd*FBp6 0S'nE68֭;QA[u,~OA8< W5{!(B⏜dh"m43'9fSP3QMDz68կ.(.K\iY1K(d7-:B'^MGUO?ݗ8CU]CX.>i oBtg4v,f#Ӊ5>8AO{Pc΍u $|.p ej:e0$&eJ)DtƩT&fIpNln%JTYx cr )S5 d$c<]pYiMEJmt\]u<7-0Ɨ)ȧB:}]w'U~FqJ?W?mBm|D>FL:]{[®krnIahFZ&6M;^uAɀ4z+ڐ+s^1bF̖n<߁2 ٔB+!8qҠ1IN79nwNvdji梡d6w™mpju5qa*Q+̤4SdB% 5u.WjMC noј꒸g2yÈ`7ES.͠KbƜ|Ԩw29:qCfIb!{6 Su m&3Tf'X8woI mpm-#P> Ȝ4N`xzrT΍*0;Y% Шǩm9SM!)¡a1Qv0;ҏ#Rj1TRԖNUc.7)eIt4~pk\͔_ɿӜ۫}p]_c&{.$4Ҙp*N8R 7XKF?bt97u cj$_ZgG1!^R꟮u%Yw峂8Ei)~IRᏇ0QU^>>$ S"ܣ'+ ${LvrȎV LBEDbNg_,Cpu6B=!ePem endstream endobj 149 0 obj 1616 endobj 151 0 obj <> stream xZˎW:Y|4 6`?Hԫg|13j"NNU_soU^:OOo ?6~cǿ/B?nFք{sNf͌~mx~wWB{̄ai(2;"&3_rr L:밤z,kJJdN9&7#cۃ[}jdpxةê W|ȟ(D<6W9}ul 4Բ "@{;X}b b>GpqWP53PʿԲ'dԓf&ϵW.T+vspyHgG/a =1L8eƽRX{&rOv#uG{h_[18FVsL\ؘܵlN)OODf31>EA 3=>NN؁>*]X_*c]+%81XY+J11kJB)Jѳϓ<U7aI1R>6Z:P{gE8=8bןJDU@n{Xo=&9kH8ytƌfZ0U7Œ#'AVmwLFwa~kN,bMz1,A UA3azgeWv\9d,95bN.bleUEGh5D( 8i>vTk6飈gޤ#kOee@phP Z+axі&n'a+!UC(;437~PjrvzW!IG.]/F{> =!@Oҝ8ުO4;ֶlg5N(6-Rp^rfo"ס1X$,d`EZX_, )w%3mkZCКnd ֙m1HZpy;^|Ě-X2yu 31 $2B) }OK&Sҹl4-G/(uNMFX1g"sK,$q{mN^Qvqف&gcOUeV"j-OڛiˎJ:(-ZC5lA^X;wS5{TKi}kx uwEOL\hj+I¶(dIA{ρnʚh 7./; [jHƾ_D|c9yEp |,v k6$>RSˤ<u40eޟc69숍vO/;vX|a@م ʉ`?(KԦ )wztlgqsUFgVr[Ӽ%z.*uqʸVbAvI=b=+ҩg9).JrDYpҶchvBgd1[%L:*w^ʺJP\)>Iݳ [hLi5Jh}yM3w:zdeSjL*Hy .36-zC C'M O"h5O3G*vƱv  !O _x[FEr}hؔ?XPmK믆wmYS endstream endobj 152 0 obj 2380 endobj 154 0 obj <> stream xZI6_"j  *ۃ[< ـ%?$Xe hR^tb}07i.¦qcsetCKNkJ'4Zԑ{l>2-FS[ӀϙAm:VEf Yl@ xSSP[irĄZyO<̶ m92^aM&H5&%9c:-uZȹ䈍wjjX ezKOZԛoLkV;UTŨDdW`68+)އCэ=Tx(LDVH[f!ֶ:e/KDp7SO)_cg.^V4k-F jklZH4>ANФ,lW$0_6!Vt*`)L4, s(IІ4qT2co >ܩnD4ZL@&QAKϠ{L=ɀ#:<<0c '-ɲ{y / ~FGzjSGdk1!f2EA.;R<5v W$T{ AMp M [Y /[/#0Ό1rc3ٺsr8iR>W!k:e'fa,֜PEg S (-Y"O>bJkfK$TF|EO1j;@!'I2Sr2rF̘>CBbEPy`5z钹,rG+ecTɓ-AYؔQRqt]W[_* .7ZbEQb9Ll5ٶRo F֐Ǭd[A '`kcEA[{c.jOc_}2cd+)Dl;V*ǘZ+ iXSLQ9cVN`tV Zb`ZLŗ M[b(t@*T;W|]P`;wO<`*fpҨ;ˎRZHDx 'q8+&| A;_ +UGq@)H=Ԧ|ӷ=8 5jyk8dFV Pr(+[wdȊԒ Ou?\w7 JCTW-ی?'؋,A3+O`nwuj X@Iw#)IK\2.dj%$ ͝ɒ~saA mUcƩ^{J "oNl]ƎKlyht%:9ֺu1g[8@X.m.;IR`dyv% <9cGs(y'Ce!z8ָMr! ?88H7\88vZ t5׷Uai#z<٘䵜xTeHf ??\)ΗPoms$k<?g+j,5\D˱I3E1CyZ}r+R} ָq]$lr4t tWa&ž*W,٬T%FuO}1%I^J;$ʁu$ VL0V~eLm5^Sg)7FsPa϶?}ƕ0Ac]aV\ }+2TMahK]ř)Əm@\]N|v.,يRF[ia]ɼv/nJȽP|T_)М) ec~y+LWDEA }}9:w^ԴmaަiS^0 KF NHc iY$"nb5r;SA:" nsڞΏNN%%wg<(e[Mб]뇹}}C#'oO6+gVm˦pK'q3)Y܃1l+9J#Q=b.R#OɴBM 5V돀psߙHߘ7Q2!o2?]Уv!W8͇>{cV*}~b endstream endobj 155 0 obj 2610 endobj 157 0 obj <> stream xYYF~s:sfB`Vi^CS7(MKFK)`˳}FT|TLT6JcB-5kzt>^j@@!)U_"}Q0'^WmJ@ DXE7ꪜԪ]i] 4_Hc]ѽw+<CqѦ-MC>Ql֝ʗ`I"25Nl0QŬo*]U0fl팊cJ lB.,0Yի+Ƞ:Pqa %9 iu,1hcw(Ͷb@~4Z8*qGDQߢ $ubYMW#;VjLvL6Z5smY'}XfCp .W[l+*!BQ~n*ȶ>ϦS-;u#eU!Α!AHQx.v#͐ ._[ӨNNN=WG97Z)U" \yAh4Z 1c1rG\y= Vk;~ %`-#)] M:Syynh{1]`^.@)ɭ I3 U iJJsw[|CeJlWq+pM6pXֳSTHȯRxElKB=?#?|{RaѻBLĨJ= VV> %PCJL9 ez凮@,hzz4sϖCM#. m`5ЪxF1:s`#YO8#@ax&A8ɃмV3Q:L4iYNЎfv޴ M0Z5fpQ\nq{9Ȁ VvAe?OMA Qk9J. ]1* ,g_sy< =W߽]JE+O@n!t؅ʼ%h,e Be#' W)9f9;)[is|ނIްS!_[=Ӳt> stream xXM6 ϯȹ"e8-0@Eo@ҿGRM"@냤H=H^=ÿ#@˯?9|2Ąqy۟>8k>9Ƅo\^z D1>'Dc\tf1s*s19Db*/sE hc}>bOffwqbz4qg0c.J9RMQ @\RqWNw893OS/ ;홚`ҁeL+2v $W:a8\M $v)%YwQUO2{%qK#/{ǐBv#:B)FU J m,zJh+_7{7|0d桓3˪kF\ۤX"8P>`T{.+*jDb]SY226^.DaEde<(I4j MllZ:.:̓:| 5k,9hg]GeYG]`Suq,>KM5je+_Mżǡ &,U83 ]I@ eA.`T"y];h3˿ɲ.Ȩ~#~`]p5P03j/X630;iwC+6nh0N do&u('KIW@ 0wչQdhgwrB8cm00@f.b< EsX% 9sCO򉓲pc//S9j75QgUTRK .@ۋ('],3 ϸåD*~WN3)/Zhe0NBB*pD9[V}/JF B.64R(IsLn^UM/eA$~4 %Zi.nkC?¤cbVْkhJzZYTˈ8F߸iU8;FČ554Qcd/3$nltU\ R~-6ƛF*VB=5iSiabk^mKE> stream xX˪F ߯u;%^{,Bvy@&#Uv'C.Wב݅Nur'_ >eO|Ǐߝ,Ϗ*xiN+9.RGىF72<Ie8n?>?6K\])x3Dt'=~pahwļs`l+y$|5B\wl`KX|x\čfp31FR}>w;ᎄh {k4N&Rkӡ{11dĸ)O'P+VPiӕþI/DlB(8{ZRgΫSl='qO8žF^7;mh+625zlylϴ3ަoUMa{5b!w殀p+XJ;P!븫myOzyI'XZiT(n}":E4TVaܓQGUS}q!j"aIKTי`8 z#AE3~ CSu+eWQ_"@9ock@,]WGF!%1j0eZ(N; $Αq׮5l|*Vj~[{YZ@2Z ƴL:NL4ڙSj8SP%!rOKRUwE'Vi3NyyfR^=YA "Ġ ڹU\kK,`+ni)0txea)mP;R:J0n p˫)ĐYEztwIk') eS(~}~!I.28]ee)`)k`4TrAZ㐞A9{*eJ (U>5! 4`ب(`uGq7d B a+7@ZEgL3+z?6x\2t?)Т~S{ZbG!흛QCxPڤ& 疬{+ATԑtnD:%#1Wڗ',}u0EfEm zd0*XbYRUMǂKAT|I{BQW-}jYIrJ4nj~i. ҰQ'7N =xB:8w$^o4)iw}8 uaq6aMlf243q' 3Vǂo5vv.RWs`q RY{xhd8 n@rq+ M9m/kѪ0%)[3z˱nV4l8. g f:8Q&gf"(ᬛ ,KL9̵F.+ $M(YYY2YJieQLM%=H60FfMeFERM%0ܢ^]ywjV l]ۡ|ȩ}Q֦8n&7*ԿfJ= endstream endobj 164 0 obj 1573 endobj 166 0 obj <> stream xY˪6Wx=*=mhoې.\bj$l*-azlIJuNU3 bd&sè<_;_8O# pN_@(}ńx}qwy1.b~/QI5M.C"N!ŋh.bh`܂j[)]#CNӕl•-4Ecي0ՃgE VKL}-~z[Act{(8~9^>T0^ 4kT_;=g9|.{  )34<1A "?̍'[I8h٬ `} .6|=eG`'gl3l OO~{3=\O?y[9otI(1J2=NJkrT,#o<p:GMC8ʄ>VZFœY_K;.>/y!WU$Ka 4;MN2@5 >a /] TNP;c N5|yI&˪:*Fg'X7$TRQ(`Q`ŷa]. i78R/8o<:Ζ2"0E` MAoq+G譵 :YGe  `j@hGrE@%擨,DL*<8M`[UO*h'9GPkb6FBU$Gs"t)EKem`[AݷU൲R1P`eS֩=nױ9액$+Z畍*cG䂐)L/?, ҡoRi%^!}4΂Zr1-"@Jqhe_q0y7b˄{eݍ{oFsE>f!B4_aR^%%̴_ՄJԣ7})3ԙHCOx Qr׊'ykJ~.*JˢmzJG &FEz5{ 6WµW@l-WR}؜@P)pMUgϠzxm՝$TCU"NByQ'C7&U%M-3WZ[)KIqr8_2(mAߡhC/kmFq'YJrj^0~yڅ< -.e[U7FmZa[cg<$aۿYK߈H>P)L+2|(\~%d2j̱t3^QwWalA{ŏme L|ө+HғܭO/_,\XE=ϾAn· ٤Ɔf;xWG 7 #kt7G[@y^Jj ;8 9"}d'Ώu,Xm6acġ|h6l]ϹV )bϙߚ<EZ*D)4{%f_O\&sd#q@cZpxpĢ ?&/TFܪZja].dZUͮ-c;"R8E}w!3WC=5m[T5*Qzfjc&oU[ʇM>-پ}|ARg$UҐ*gN{56/Kˠ+oG~A p$IwTUAmUU*]ZD9*oIV򳛯.=Sv@oÿԍg endstream endobj 167 0 obj 1904 endobj 169 0 obj <> stream xYI6 W\ H-@z6@E@2$%7ǒnP|SBѓ oϿ]~;?.R,V_o[kK|Xle\8VNu6WU@|- :lwxz֡|iQesut\$Pn;}$kU05=Ъs %t?{z}{sl4גyaB?ʘ#煜sty@Y:pl"kTȂLV*a=9DuK]7Q 5u'K;ZSSZ:Ы?[/`=xŻT;dN[8`z@E zFDw&ey3LڻXǪ0ŇD.YY4YT! ^c`+MĭYi4DN:")B^&Pt4BM )T*AzËFRٳ1q!SѡljJ-5~~I}OMc=ݕ n`JI%#zթ; TKdaJ~25֏]ȅM:é29 A;ؠt̆,=Wd4--S2WH< $1|(q7[drErkuNM0/KN^0Zf42 ֜>i2D:a}xcهP[w'6`zg|CGWLM:k1jÞ~S%2㦕_nKޱelg~FNYmSBHX0$ɘ"'˧(2.9Saf_ŏ;RېtG;D-"1\bEiaqQKCٚc B RS$k}ivkҌk)nUՎּug5UϏɔ\lvmb19v8s[EJ'wp+&֚%^R\`M4',(RsjՙA"yg$Q[^WԲf|1zP0QU <~Z ;O7dܘvsԂjQȊWӈkᖺ8mp֔1olpwrwjsc# % f8hjBfKjjW"Aj$ak ZHV` {.EZ"BJ 6V͉Cfف&Ȕ }SnC~U6OVA0bxiT\̣SRI{Rl-Yܡ_u[Uح2 9 )U˨WjLgJz?B7;DVMAwٮcv ,sߟ m(c `i:UǧPU&m;B_Nj19bVqBB+u֛(ֵcn.$73^.,].m$AJTat3jW8 =A$254/Lp]spd)cg1;y-> stream xXɊFWlrDAoc0 e"4LŞE4rpg{RUmTW8]o\`7+VϏ#d;nS-yl}qCQ[F޲ec6=MԿD}uWwb8ˊ4HqBčK>*8ɋNFLt"ݱ)c5, ӁN2T˟P'~B{ɂ&ΖHı#(=l'!sۤ;H^<[~Of1-˥.،1zwRlLYh WqEIRT>(TL ^19f j/ޡ$; 9cƬ!*6ITjUXςuS4\)!uDUַmFd F" `k#[1"rW#j=eG)/.5* ]q9dߍ/1,;_j\,\Q7G9שb[51 Ŵ$xJ"f8^ta"cPT#3;r|*bv@Ƣr!H>"Ƅ.ixGy߱0My}fb$hݔy\ikR }CdxK!;Zf'R/%X;gr3[ApmZ*=F2;Ӳn׌A:~uޱ^+h|)_ h6FLg1)+*r-ji#r _@7G/Sm$lꎛtl&[/ J'4KP- en ,P" BߎEԗfOliIJŻ Vm*-ߊEk(|C$CFz~[z-;5)am?)ưEgamx9 iyvUcچCژ#aHÒ%CI~-i8f4PU4Ʃa1@#@呈P9X3AV&z8}l5LElFvXrb%Msb("^QEbzEm@T2I!.*WF^Jj:0s1 H46?@:} EU:3IvmlS]4nb( ǦJAЊ<]Mn5oѹX?Hت@vldVgaC?s[ٲ endstream endobj 173 0 obj 1396 endobj 175 0 obj <> stream xX˪F+\cd+$Y!ls[j= _8]uJLߍj\κα釯>~O`4~hz(w׷pQG)^ة:ʒ`]TuƧ42$fy1 45-IekCje 7! Sy;)\Y$Q:*)ȈQÇ $RH8j(wB| IK/l-n5ǭ,Et|N9L)u; N|7?@O1ʱLq'Xi3dT gw=rDS<v3V8;E6j42  \PcŗTǐDM-'u}sRa#٥?W0bJhl5=ʘܰaۈGT1Z3۶0yhvy|RܡdB,K =f0 V/@mJ]tĔLS&\,5JބRwlOlCJZOj䑸To(ҝJA*[ZemcFwb1KyC,:o/M9mwl{;xYFuSpqg\yLgz;<BԁEpn| =i ˰!8B,H` 8^ڈߙ:s{2C(|a:ъF=`+/ adLZy'0c 0pE;WMkcߺJ2x ,.`>ќ!w$O b-<)pӒX~9sUae0;ϙ/t՛8[(AF$p,8gtpGU0j唃.1PC6I@([͏G u,MBKb\Xzl/ R*-jTګp ^;tF*o|{d6եRx֣K^Z*6y5lcmXC䄑W^XE]Z;IZT()$;{ GRˎ"sjy/7&of[-0qN/s^v2dg@gutXOGwzsMjے z͠DxBZŽ*_S%Gqz;SW$x/>M^^Bx/.#92W 3y,Yl hQ6ޒ|7 #kSdGmι{F>`W7lQURehtئAukҳ? Zm4vgc endstream endobj 176 0 obj 1638 endobj 178 0 obj <> stream xX˪6WxJ/4݁&ŐU^2d)${I2n۲SGRj9ըFu`9UNy go?7_!ۼ);+o_9]e~ǷoOӪ&tC/h9;yT/5QwӪp(@]be&@!őƢz{ۘ4R_kᑝխ @u[iDHi; 0Y]lOsa׀IaѝM(rЏ݂t&W`AE"RզuzH+P\}# Y4xmzN]nh2@H;L16s*q,Nxv ۀ:la}B}5VNjk` Y`ĄqmrCӆU]ڕ4uJelcb3L3)iz 6m&vF.4˪6h8Oi R+R}B3 HF$K2bH! $ CD*2shZ ZtY-[Iʶ"rW[ x\ˇK5 ǒ|a=IKd3lIxWr V]`ז\NIaC`?TRiPm֋fUFܶ2jT\ Xï״S : O5<(兜xfElˮF \_ΫOɸMX]G@D?N (6YpGb1w05P$g;lr1S`׆9t<[/Pr)|cSfe{ue`qsPSKIf7'՜ v\Nh_rayGOYj|'! KFՍHA#|_VH2$?246f2RSNvD圛Lڗ*N|a)MtOYюU[:I=0LZ|yk .EMAHh!q QF3I H%I,r#I3|roJh۫.3,S㰚ټ@;9ѵv=kkB>5@V endstream endobj 179 0 obj 1766 endobj 181 0 obj <> stream xɮ4"gqDjENqbS;k30OJ'^jG]Q7+6k|凯d>2XG[#{y7AyǛz Toj/mx\۷/M6B @z&zP7g@̓u \= #cbCX`,b&=5A-?#}32e5ғ__?D!5dlZXw$4akP$x[̴DJ ŋ $IWD Bz7mx{OJ&Wf ol)_A, Y.E$t0ը5 ]>+*ۻ uoghQ!=H]Yz"jG ڠh2K"x)Wq0 DIM8TspXLnӊ%Gx¼*gYHDlGgHŊ G0*K2!S?j4j/Vt>0(ЅSPe-ӧxE} pb5ƃ> }ŕX(2 -U'"0?1H,𮰪mbHsb.!Fa].a[49WȻ("oa%`=ģT欹4A*vI\p?GP_$@"pi/Jt1fwj0@J&@do Q:] ߢ'oĝ`C(jB{_ ;ܵ/U$l pʒ$sB()S_etekֹ#hw)sx% XsP 'ZPVRX+h>c">{E6,06uVA[G|Z-tɩK"br .~;b> WGgxX^B56d#6,7 Ba!c XMXTeBEu3e5~p X1t :Dͪڢ29֜nм]က^犀~QHH+IbM"UlD$MO <5qm222`q~AV̉EW^5/FY:aQ7zHIM&$V%XJ c66R}$/MHwQ=8&2'_BN\jD_]}ׁ5b7ʓ@SGyBkVsR&}w#xE "*d&Tq(9Pd 2ŞdJjXGSN7~%ε@j6akϣX16O$?Y^f*f xiXF8ye8dGirKZr)-pqIgF9*t3z.2#[<;ܢOIhqmAlMI6IHi89\::>.'_ʡe5>2h[!ډCoB֩/ҝ#6U4M aL"n(KQzlKBzddaF: "lp*]ФgC,DDT/D*`[ ~^ endstream endobj 182 0 obj 1974 endobj 184 0 obj <> stream xXGFW@@ >Arsy ~le%rw7} /O~s骵pkϿ^~K/i4{z7Cz达]Mߘ;Xy_r`_Lԝm*L[O]alo0|fkytmL{[39aPrtbMtF&@igZJ`q|[S})EUWoko|qtp2z J-ӲCry}[@d΋`G|2PMwrdv5u?sGAr1JHh&yE#@+VN O-FH;uU"55ap$(GZ{]昚X8^E&dcPxFAQ=!\Tf$VA?Nx ,F+y|AyCȎs ,t!4 b%j JkmWFyex^Xr~+mnxݕw Is;&o4eDIPR;-Su ⻈{>[XQ=*z$44ޑq-zxj}U8C٧S݁kpmARY/CbGr[|ɥ*'2VL$t]4I(7^ X7#\ >L" YY%V+y~s5C,%,GԊ,環x)V6:xV%[-.,^ˢ$0u9nY8R15d<r2U$%>=Ǽn|e}bN[`̓` l7>ļ1tses *BDHqМyiU\5)T _0)>H_1uy3t%ecYVYdN-szlY )s#יzꖚ0k${ֶ!R I0ZѨ/Ek]H1֙i9b:dM(ź,y]+ɡXZiDdp"_ep<Ĉ@^:e"0EwznXLܢ}Dy,&|]EOU)P _&b*1SY6=kuӮfFtlc3a$(F|¿kQZPK lAKF 4*k3ܫaDpڬbXDsdV"kb3t`v[BVg1 >A ^vgk@΃;Z<sCU*nTh5>ZF&QTX0䁞jzKVpgPx:=MpB>UȺ4 CiϜj~|͚j*gɍB$@c#ch$3o`݇Hy~ϏT79.O(* @)?"W`IFshsϓ:,/)ϗO;֥J> stream xYɎFW`Hi(9 rqϫꕫ=0%TzHQ7׻n:K_5w횶ջyysq ׽燷z&WrGW; 'Kieώ:^Uc:CSOӳ>ڥ݊'Azū8W$Y$u ԑ7<]8=a5um< ψ<_)|&Urܨeq "v9-=G2 gԦ00Zn)rGHõk$=Jr%GQ.fG /4u@EVVqNw jIC_2UBx-?%1ԯɎnPL;Ptӵܐ\ۑmP^@/G~j 14߯c76}= {մ$b .{?h_2)>R9Q 6l e?ish}U,VcgޕOكhHr% 蜓k,F/~vt]AY+w UY[7jw?ZFO纺%75(J诸5JVQ)VU^fZ}tee/}zYKWп-ԙ3쉾m'vT endstream endobj 188 0 obj 2094 endobj 190 0 obj <> stream xYK4ϯiߑZ-u&i7`$/ z؎Gwf$$4l:rW_ OuSxzw]pC_ק^>tY^j ߟS.gwVj<^h2t_~xjK<8sj2Yp>Cdr$PW⦯x5.KaPSOm=nvyhGpV^}5?Z 8-/ޒn(&e࠮$%C$_rK/ϸh`d➽.yxhJhpwlL-iŴl*l) 4X:3XЮfWnL-n#};On"ݼRU`-,K#Rm}9j Oi` #zouūgJ?>f8Rjq,>ߋQO)iC˃ zltP\+3 X5P)婶ʺ{OQ߫m587Ttb&b5Bx^ y%Hv fOӛ=Bp;܇% iAq`Pј`C1Wߑ4I2#h~mA=dCq?_wufR&%Te 𹛇/YӍv"0QQTʗ6 %' f[=/d~`)`$(2a 5sHeT..\qH` HWdgRh[3bȓ&1&9&DLUmim؋qJp*w5ð[7ϐ~U&c=6Q'Ɨ28 ŢqiLd`JA00TP곃KO@v l+n,*ƮC'$ ik|r AC[lx6roem ajQe>4~œ_ñ|{~4XZ^x`Ŗ.aǒ 0'<ƒ9ْ `=㽅LIr6s CRH)Uv|R(rѣD/cx|fV{ղPK`j+E X IҥPq4ai2,c/e _s[vRNRYM%T [ߋ =( 6Md۲ژ6oNmmX]Mn|M~viٚW p/qMP]0}IWnjVMhIb S~ILWB΄=y!&gJ-1'p(O6Bp+|eӛHjJ7.DZIf(rWJ47IPɵ5CٺH-;6)f5 Qg]KkxuSuÓHtmyڊN3 kظݝ6:Lj'hhxrΦ=VcFZf IkyhY.ڇ̖'? :{~E!Ql"ff*?K4` V!s:^̕)L#%[k%Ө=^SIi ؎OcF}@}r82YLzKtV&ltrgS%@@4Njj5v_ms5vDMJ}Op 8w65>4kƳOn KP BePAzC\[WN 6A endstream endobj 191 0 obj 2018 endobj 193 0 obj <> stream xZɎ+ WxQZdK,m(J"5T/.nw` <lp/bq8.?~. x|>g}.. YsfFxnf΄ax}r 0Ì̊}ڛ^m^|3 qN~uq@ —py`+mY=:]0bod4ߡO%ۗD]oNl3햎{4.࡞aA`'LVȻݥg/"0{ӐoesaiLի 4;xZk}I)Lhލls9򀄒@¤X@APlFi[؜K` ai8E^xHaKDw7S86Jfձ22쬓p%~$ja>[F4mִ`/uD4غ2AOr6s;T\D?.fe[ShQi {h8"E2`7%vALŝ(CW9>gs#zP82w) #=z95@JDS@p"C ]_L"^F֙ol` `w6`,f3xW''#jMLe$"*osfT4DqHr 1dd)?D&*! #@ rg?[K0G wpסv PUr"_ӆpJjj{qhµyc9aja+OOK{HFR3`NQ# U͈tOEP,?:O;Dhrߙ//*pQwC.õ$$QSf ֜d MPsC*W]NBb$tAەE35HkDwyn5:'pȒ<*ieRe<[k0ꢡNU !pF9"Yhą7NZ=qDI$ OKI.r?p5uu|]"!+ju RN/BJnr0 [^+?Vöu2eB0i铌/8s9AgvK0JU\om 1mhAosHxUnD^>ooSS^n:⤴D]b}PUn5a8{)"ȀGey;RtF*.`0N-aşh?3 掶EjԶBA f`_ =,{'8j FJB8TW<C}e\wd!w3FꡢC0Qr1g"Am1?Q<1{]RUt%G+i$~Zl ,9~-,Wۘm:7o/<ʢ^'.F8 endstream endobj 194 0 obj 2439 endobj 196 0 obj <> stream xYIϯ9] I@ Tߞ3@FNv ȋa_]K4/@0D5{z~Lgɏ2toMo>ЫGs:p?!^+7K&x W}4 x7_Gnmx{PL+ p+X{Icw~r.lI f:h`ve7rfdAH00W3fQe[ndI0E$PtSŻl d  %,H8ʀLtH~wײ֤j2jkmzmyLkwH'F)1q:k9x6ba>ݬxch"PCaHRRV6lpoatȠ:Id3ƀ0"8 i@u94YT3o%1|ONjI ֧Ԇ-d FvW!!J2vfsǟ$ށ,̥%HhۅT—F:qՔ083O,(|n%Ő wbE}DҹOۼjn9]8<+z?2^y&3 3$F 0\>-J.d,ې&gǍTJQ/i7:ŵ2gx>}U-K~ig\"6 !enۚ[R. 9}oh\7@F"7լ}ṂAX;+&&'E]=Wnw !>vՂv}1sa:ʪXmH;x@_JH-:C1 RZMOq}Lo`wO]-L>VwnY^̫''y&ܝ~MCɞ2eiecoʍS΂"?sbss0r>ƬBA܂!8+ g (0aGQ9k%‹]@NvBiĦ2L~p9(,̝\(sMwMsF3ȓ9;@sX,v `uDlV϶\ddgʿ3!\W+m(:DP텰$6=-<^lgb;3jE! Xe YbR%ȄE/Y,q:G6FrV*i.6ROzhTr5V87Z#u!bN+D_ט6.6Kkٰ5tvՃ>rq 4G7i+CWrQ-^oJtz .SL| $S<3׽ue:XV|is+V#ڑmTY*Ti8rGS'=vwD/þ;oNf67qg~&oO{&& a5r˱wZ319:tf]P)T3R J6%RSuCď:mכ**vSU-(Qڢ 6nKP؅{puyfK"e?N$o6ԾtKԛ$ȽaI靽XÚc+u$K`0$QTy > stream xZI69:*4vw;$rr!\離XeKyЋ,g辜D',^ù>v >q_O#wvNѽ~ $poJ:qRYJ4SJ܀W(+v ZXuɎ5g`x⅓ JO$b‚֤BW@>KH >^EE^'n}2.FR0:Yp uKpiT0+[ --kκ'V1clEKY#datS /$ViZ^)3zi CލX"!P爔mbŲۿ^4 /rwg菼emcޤ&1bEqe:!:l=Fu ;)w$i(ڮ*dΫ<[Io2DiJcRQmeSjGfYo$F0mCyD7~hOmrP$\CQz\T*p[k;;~l̒aʹͪz fT'?R), :,:n \::Mo da.ejxE־)rům{њȗ;DP_wee8ŪKU=w@qp7cSmܤ~įIJ% 8YǠ% >Ix ]\Ux`^ܠ몢̕RˣŲK.78082',DJo,U(26@չr[ j! =At=NׅI!98rY@eԂ3n)̆z|EO+ o530 荊SA9YzNOrhA0sKD;W~Tz rl2r^LxHR/jcggC@7qi\wbT5&!ȗ*mWҙ"2HA͝}|+ ]g\Rɇ5&PleҬ!75j]1$H!$78 0f12_vf|Yd=`,k6OR'kL9v ',Y"fH%ʚOY9ĖIj|ֶ9@$67˂<)Jb&n-BzH_b1f5j'ԼA5@oE…V;H(\*QbMpls$`}m#z yI)@>u%8VdPX%>2G0K}NR_&U[$@dG6K025wx+-C*CDWl*Q8XK`{T[lstH;n6 cqj?3k$X@-c=-_CH?iUCYߓUjFDB,yҤ8.wԊU:d{3ń$hc?#q3VAB:/0> stream xY˪F WxIpCwn YL d~$Ꞅ 8G*UYglir;S,CO4gvt顸&g`L_و1|;㿤Z̑Pmy:LYYBT $G.7S(/C12ѣ' A\lx,.kf #\ĤJ |7Ny# #թk)KH, K~6!;@+{TYN  C[fZfnO'8͗3?|wMJ'^90zW& &칫o%QT XzUClfV;;L=)fuym|iMV*OLSfCfZ2WTjC>r}xuQ:5)>pK-HjH\煱àsja˦dqP7vqMKżDf\_aVv[MvC rJZ)~d ë]Z<q|ft{+J{LW&9 yY-W]ۦ V^dԋܫOqT P `*'B5K抭q]+K=ܹ݊ $gD ƊM ,,Oeeq"7Lx"'rDIS1SZlރϾ);*>Htu}\D}oL'uC Ø =%# ~Oo7X_w^LH;m2o2 a]񿪪֐u/iت"- 7>=W54ϠԔMۅm}zMkxm"*̺cڳ!av?8} `ӟ 90˭g(tvSyi WUѮUd &&iXV9QɶY; FiJ)3ۘy2X(rS,ۆ۰ie@&e}~w{zkm-+mK'S;/ꀳ EjN7Z:&W1iD4iQ'veh_ڗgbb۟Ț4i#:#xxyRnZڜrsNna%zZ1<@Mש%_5l"x|RM39^:uPxR\"Û5F `Nݫ3GxȲyʴQgL3) ījas|TPnjWq)>&D9̢yĮl8t +aL5)JPJ7PjTR6C<7YK0] ޲!my:z IR6Aw#Rw-@ :9NM%M]O`UA̮q endstream endobj 203 0 obj 1904 endobj 205 0 obj <> stream xZIϯ9Y\%!{$%`,@流;ERBB&ziH Q{RH+}2N%8]'ڤaϞ#Vd[F+ӱvjKؐ9'7vWa#~Q4þhbݤv={/gRݮvکܫ`ss5n}77w;[tDR2;yD Pd0&^\IAUའlMO5l-& ԒwdCdK9.[(xN|L_,)65 sfI`7@~ΤIB Wf.xnbI$Z굇0#Yɦ$W59Ȑn^}ltݴ0N) kI+~)YY2Ή5DἋK (%32چIӣl|;b UJԮƤrgr }}6]]zwD\V22|&I:6gΔ!TbA}Y\RY} yp qǍ'0Ox)RM1RpCj 4`\>l_dO`!v3/3 ^u0^kse83lގu?P!<ˉ룰)뉜is9 敾n_»4RTt zZAnB^QdO#!)RAq*otٓ;kW I@c7쎱a ;E#m[07^l^9v[bI{Aـq5pkyHK/%`ٞe% B`>p -}:y0['L%mV!BQXTCki+짷Al!7pWV nAB?5`k$Y}qPfuqV{/]RAlhM{_2/%y߈]?R B"0Ir p\.`dUS#, `ȫ{ovQ|kbZAjQ^KG <x ir|SŠ/6a!#$ &1-"&y9Qž06&6 5qkck.vh+!m+M;]m2ԇFT"@^b 8'X8Y1I -b.QoPT'= SC0/> ̄OQ2$?h~xRiǷ3R*s lOѸ\⤷{yg۟?]>aFٽ65?ѮzaFk[fO.|eF3ZaNXh\YsP41hz?wJGOα$Jǧ.aPʩ/"]f'tJҗZG4&L/}ÂYi? >'2aOV7!uen|NQhΟfcNz_' endstream endobj 206 0 obj 2533 endobj 208 0 obj <> stream xZIϯ9Y$ )Hn # ٰ/HTO?b' :A'7& iiYo~~9V3>YâϠ[Y}<+7Ը}{|}iRд(yVj_nkʂF054y+~ 3 g4%*&`sӌ? wV8?}Qx0pV CUli? ܢF.4I WeB[`7F{![`O9C4hm#ZRS )#cmedD~ĪiVa>.38rammHߠE`;}rQB!.cdS\-r2zk.w^Mt;kljݛ)  AVCdsiQH!7JøLn@e5_$jDbE:{D<\#[#dY\h*QhKdye2-`W2d"\/ST(1KGvniI]̾0N9|mѳk(z;Cv?)dwE_??o6e nnD)D(ɋ 57"슛TQ᪮X0798O盄CK?)o'oN-/;:%E*`,}]9;Xì 1 [?k~Q)5eJ=Wk 2-MP]v"Ho3&-1\1Ÿ,rvk vI#L'asK.].YL1WL0` hٖ}GJ`:MYX=KmYg@ Yq2P뽘;z[3B.eӓg-A>~he4'Xcsrv\:B=#<P@%j. 1 9+qM@3 :3Ob"Ђ 6hś;̅3"&#FLbf׏k hIdHQ_՚=M8 Bkp9~4ZR; JyYv3|$!XϟcC14UOXU Uf~SZ״(23pFwцp[d>ӎ^;wjnkC2wc#i]s=]VBW ~lZgvy‹&BveZL{'iBgj5'bWk/P쓂@!h4HJ]$]*yb*hɓ!ةe19֭K%LqVͥ(+aF3NAct=!Ь-fk)ZFֿT|@RZeÔKMC+}-vP^GT ,kb:;vp8krka Wڳ25tܞxv TxlfC_6IOpbK% uIѮ23*SϚƯ)-pj|) LCW<0>7D|u}%ڹYOKN_ru[.߃ⴺ K8f퇵oX4W]Q]3jXl2eC gQu%Jj>[e,BmXù,*̢$t0ŕkSa`gX#EK[(O. Y^QtUνFW \Bɩz/l.\kZE禅]C6pR*܈2:ZȆrNgAdG%Pc) rJ 2^QOF`)LG;q^r{ܷ79l'."`~d\Ū m-E% "t:h q8jBpmsV  j\@]%DW(TAuZno^AfPZ} QY]Pwqnz86 鿦1yZ~Io qqT> stream xZIϯ9tX$ n)@nN`~j#E-fh$X^A| }٦p?~~_7ǯo[G ⏟ή|>L1t{~w3F{|¿&%<+?wY"op f~ G0F޾K܂>PDHD&ЯhG8?ڰoO<̭m\1󏿽\.l'#vPҏNC1DOx-fN'z`<@'hnnk哘e"8 }LQ*2=>a?dx ml ޿}eAEae3nbkmLB)>؇ysBixQ*K PVAF@""i+ ֹr DvC3{KlE"14#cD\7#VC} SBEWL2+3T攐U D$d"Atc`4*gƨ>\Nx:<=TgFh9,v"$F'%tݘTUzr7ꃌlN hjUIqKѓbK 'O(:Oq%k=hC I#0+vf{c89#SeG j/$V'$CW6 7;し2JP)Nz2>]h kv& P ud3=j+ | W 7n} 1~cLD`j#%ᗖ'QX0ncr5NLx<qva:T?Ek0SDCe DvDOע/C=D"K<z0=BH#s'L{jZHh?gc ޘ #vM”ZaxJQurb"w "]Zv w'fݻef3TΒ^~jpQ!Ò.eǜ<H} JIȭmp)Φ4(+q5C[)Zj$bnd]۴#:BUlX(ғ:x /5h J0T?[J)xlD|qUnem2C,6d,U_z:rPDRz^5/!}Lk uZ3O&N[6,h6qCJFV U6'm(%Eqz}Sn@}M}'Vt;Wrr1d ҄8F9`z; 9:^4cn:GUgTbD[ʈ9+>1 ? )C!XqFx0e?<=aG0X*y~.v)#sn73ik{(]&'[V<E!%i& ٔ0L:[%nvy Q=%y`:U5|ip7'2Qآ@́¡_fV7 ɔz bYjj~ GHڇD4F10I9o@ݘ/W/i'$WT[FsMB `n)/3XY5@LSy×\fA"qɐA8)8$ȶ> stream xYˎ+W:V+w ë6`ư7}"!0fz"̅?~Le-4bӥ_㗷 )yLO*?\۫ 7h=]Mk<;=\M=fhZ9Z޵7Wz*٣>y<5MyJ~#D׼K_ewԈjR4Ո~xZs :+AJ­evZ$Mw%ٗ^f.s3;OV5Z|V-a~k%|0c,0m_V(Qrس9PK 0AW4x95ЍL!Қ=2(:D]] 6bUqj6JF3!Awbt!8ȎJfy$$d)H/RuH<]-#P(Қ<Ĕa;hxj ٜf{9Dص{,R}D PAȀa;*5ӭl[.W,p`i!Z^cVr!lFe1L\wJ%}%ƹ w/]rvJ6*6TvHef0>9mO\bo3v7֞7|(gĉ=l6XkLG:7=|"h0…X[gd%YF:hG@<{|le E4Xvٱ&f XqzxرjqxRo##x vcEgm2yQQecPLCMS l-y[F0Vu& :LmQϬ$&'y&(zo9tX?3R,#̡ @:\_gt%;J0 >YGO1jabZ£ExG'hb-Pw0{V2ؐM@Y]_ DV{έg v:UCwZ!_d+j2}s]:X1r3ٜ\ V̶Xo.(5&n*:H'nC{e`'{mV>ss kʭ&4YʄIS!*4995vpxZCu9<2S̫ƯHΎ[A/gS _F8dXIU}!:5گ~ƒFY'gnoAϚI}CIdFs)|E6LtB| .Zr X~~Et} m@_Auԣ-M:׸H/#`cɼϛNqqJ$' 6NwMLf[twjz"&,ǗNtphX4KJrz-lZ;Okí 7&w 3*kۈro56G\ k926,>Wۻp+F+Czp'vErwVdVOENf9CΩ"gِAxn~狙!֡(sL 8Ŵ70 _ endstream endobj 215 0 obj 2078 endobj 217 0 obj <> stream xYIFWիF`V I 9A2yU-k73 ?Y]۫m̉+S<&lU{:Շ_?|Uk|=!b)%͏_{Wx3Yc=x.iZ/ hg.wXpG]q$|^#nT0ETxjW 0'CeQ3,xMauFCbXCS)6N"s$78kqf6XR򋊈T%WuV̮~0\'!HL9c3ּ)/sUpLCTR%qkuu~r$ƥ9N/M.F>ewYf9ǚ 4sS3O(HfU* BPoHmG:N &~JXʫCϪC@A{x2rv*[LŽy5r$#i7\'n`XS6|4P6NMqApv_E"oipN U\rop&ț5m>.e_u_얀ГB* C?lW6`]V]E<-`ba}!7"2s٥>ٜDmWXCW;6GiP{)j+Ν ^@aȋ[ Dt{e %D̎+eC}t%U'5&fP i^ZUIx!Νb 2+fT%!}.ێ2veեKx6&:r Ob=f1e9q] ʮTZ$Gulˮn]_)7 Mmt7^7(Rg}V mJj_:J.}vg8xȗs;Q8> stream xYK6904@CNM d|Uj=3֣^R}_IT}=SJEwUm\W_>~;ǩ{> Ac~pS|5&4gЅ<<2-QdR)ʻ5;c /cYUAv-tE7O;k; oQ ņ%}y!M,4O'Ek0!}d.{fa~/EplQvIECm4Ib|goXuCE3vV&jGCZ›<%z$7OFu_$TEÔJ'@tdzt/&9[2g0eM V'i< ^UQqioy1G{}v+4 sI.H %\"%Eb))oɩy|klM~ú=i1# -0֢UYD}$#H{dRW02["=@$O}xw=9ʍlQ6(JY8r;TNŚSF5y >&3xǰ樠d02+O%M%z B」v2ʄ,ѲyS5;\6gcq*)Bp4LG#$'64uSxkNǻ ^ ח9ww5e&]R,]º:@FnLGa2̋#pl$m5>!b HavquQt?g͕dFh+(V[_ƸMfvwSL{wsͻ$2G_6NaF7cr ~윢U}rQэd|!F:B-G:[κiKDY${7e8S&mg톷:g.kAnZ2:U08цu('C ?>3Ӿ|"\(y}'$ET)t\8V=Ѧ_۪ct^-d^$aדz}&mZqPMש18>.Sad7Uq匳`^ug.]ʪ_GpⵜB&H;+dTy L.7Ɍb36 l1g`sw&XdF+Ig8ۚk@qC/8 endstream endobj 221 0 obj 1824 endobj 223 0 obj <> stream xXI6W\gI!@}@EO݀Er,s€$Spof>^|:}0Xz u<\*Oߘ>y^NOH̻@WB@ho9]n^mv[5x9ՃlM`;LTq%[ 3w R/jPnZQcZmmMh{2O t'ғ@n+CH`-U2 Zc{ܱ#HlV] !{8Hwq k@OcmO6reb4+$R$ C{6l":Cy#&/|\͒^[frk~)E m>Q-BL,=V1SN^ KsZAE$C-yw)sΕu7Kb~tDčY VEw3!vvڰBq\;*Un1rM(3}wdC bAڬ2.6c.ײѯ=G|x Ԃ4bvDۊVc'f.#YmP`%n9,.?yA\EɪB6Zړap'_waI_I)s jE%:L&n ۲

    4UN T/-\@s!m#!c/2@Bz(Іphv 5Ab- r6!\`HI=[%켖KOR dd5r>b@}pXDͧ>GQ~h"TUJ\u=2ךmǤJR<;ԱoH_HqӨ]Ծ*32 btХg/CgUc_txoR endstream endobj 224 0 obj 1531 endobj 226 0 obj <> stream xW˪F+X,d7!U@f3--e_ ֣ޯ#jpg;۪&nC/5$~_>·{vmX5׏|}X .1z :й߫sutv V$=*Ct[ J6Q!9Dv ԉQ|AХ{a{:ƋB4hMTtࢬNxk;7MJ5*s+Sj̆PƢ_ί7Î}<d~ 4ڽrqͳ/,3pu`Y! ۭ`VHzmY Js-VC؍oCvùln 2)kDZ^c U0Vm!eb 18vُWSK"r=CT tSYnD| nN&z7nkh-BJiSHЭY 1SU2FM^C6`*gL;z&)^ρ[eKKcĺMj? 1h _@vI)K漍MGZ2 ktnv٢McTmT.uR{GЮ7 Rj\Ǐ4GY6|$$U$oVd> stream xXKFWSoXmC!d7e~V[efg<գv\}[QExߙ*9ޥ/U3~sӝ7Ibt >Q}ۊMukc]krmh#K冒M78;:QDZM tlQh}>)]M όf##'XHL\Vnh?nN͇+}х\ej(2Y]@:[@(~f%xoBup1 BM%&yɁLZ/X$j͹Q\K\ń0rC<&)r3G>p'r  hOAe$b|SdISZ52zWύan'_yw uuɨνjS%  q #VM`](B c[4yQ(;"bANQ8V 8ƮPfhh/F|- #x%'vզ5e2;w07(P0 ],cAǚ- zݒJMJʇ/TXP>RB^TU&WκLٌd;Q ȵ=׳TJU.iZTa ֚Tk6MR*$y]͋AG#1Pw }MCQ'M&pqAA\pE4yCי?j+3 u`E7]4 N[+aյ0Skۘr-2ϪEi-px7 |;c+z.9`]☾}Qf PM~K92R]xuGa#,F?˴ƒq( :B"\ҟCu,Tcɝ鴔Lڭq#^Gp}A}em7bTD* F%7|\I!×5 ˔v zr[(_\}>`5'n=іlFYc_+<4*D ڔ}84j~jYP9DeLGrD]J5ҿLO\ZK%v/69x[V t1 & lsc~~q:7( V1F-bU^o+D.w>Tq: endstream endobj 230 0 obj 1182 endobj 232 0 obj <> stream xXɊFWl(9#7@Zݒ |0>y1x.%3RqOcTI%)cyET ߕպ P}p/~ xi,>|{_}; tuNC;WAۃM4PM_n_C'>Y5^g>і.+iGn=a]i=LtmeT`%ɦ7z鯔~6V?S:b$&[h/a@U 0 G8J=pOtj6雐2IHY @ S ̧Wee sPbm:quf)#Ww)$7 FQꯡOF6%2;m 3d24ste@;u!CujYD̐S-h:q\h*D~_c6itH ̡׮3/a) 0`  6p2.æ=@a֌5p~*qu۬"#kŽ8,d<qm)++60uqI=T#l5t@ć6{(27,72sPl`ǻb,`#EƐF"*X9lҹT./[ؼ\!Djƀ7tbxJ!>v &Dkbc`Kfp.cA_ݶo8 fg7n~"_6H#i*FsTWu4c xF27>-&ciI( f)t5h8uOz]z))in$[WڧY+ʈNj $Wc ,0' 򘆅$K]L˽6LONA8@6|loY8y_?^J}"Yx?B@}`X w~" &ra\!8u[νzW/$f& endstream endobj 233 0 obj 1118 endobj 235 0 obj <> stream xXK6W\.gC0C[=H.ΐ7q9oY]qVJ6UmRW?Gq ~U> z|xEמ| @u˚²SMKkݞUaɟN\V]ǩ>,,N] ʶgwa,<1IuIvd)\X 4aTmPcÑbң߻渦8qҷ8`Խ=M0-lEY.)d%婇tLƁcM#bzBIdMm;YZ؞hKYYE:4ߝtAgIGy a܎=+F%q0|chŽZY>o.`۾s8;wo#۩ņIF3~gZa-zW4w6&nR \3mt0Ds`̀d)rL֨C< 86/}st_m).;G!-543OlK kO%;sdиfÚi}$YՎlOXvtǿC:󅱀CC9\7'#J v&`MVmWR.=A٘nu`lv0bk_N,bG)#n ZjhF!{oٙؗ(T[7WAP$.#x %')@j-#F5􌌡ԍDUS4 txU[C^a{.Ẑәg@8tK:rΌ2ki(jdFbEeA),,).mt]zA+d9xEx%vЬb#qi3P]kkE4'^;œfƓV%sһB#@/m#cNB°&U-f ȧd,;YNX\S5ҋD" 䃸.% l-NH3\ 5'ɇ=98 O60 jHs &OsjB s-n6<\ gr}l WEK kV-9lBrA/~YvR_dq 0~$4[3 mFv'uCљ(x.F^h򭖸5`MR9}2͑u9R}EQߪ|o endstream endobj 236 0 obj 1236 endobj 238 0 obj <> stream xWD ayF"%Mm X$"=ciկÏϟ[|9ӨFѓlM0І履i{i|-]5ߚo<>^ԍ>'P(7VURkO vk ӟ3|ҴP{+i$2A]<qwGng[ARLF$聞Uq[ E>[E &Nx0v*1X8u [ŰZCkw Ū+E>5.UZ=h*wZpHD LM|W R.a6{+`Λeך(T7@Nj0 9\]BKgoTNw+ Kc\E#`GHc5ι͎ 'l-WY*\ 6Xq٫峒J{ ׇ7[L6uQ +u,Vb /IjCI laNfzKf^~Цe_3 $Tep=@_`6 9Q)Z72uڥ HJu&p)m/҇BrH1q8Ւn_-O s[ aL\ݢ=k )_?T/?|wR͙|j,Dz{؝[Ę>$*OfCbV[w֒=Ʌܮ80C`r &1R'UDuq+%BM9vBl2SyXJ8л̜c]%r(]/xNn %DBYڛPv%ХvP măKT: CJk1ԢZg/SIU*w!2 q9k5)S-^'CSH/͇r7$䗦( k OTX=: } rgΎ%1d<%&jݓgԦZWU:(w WxiF?dŞy~5e %Gw=zLEG9ۢw(@3ķpwyP?؎׮^; d]?WwC5W)ce5DV޳v-~ 3[_3I%4)ݻYM$< ThsS--c\ gI endstream endobj 239 0 obj 1283 endobj 241 0 obj <> stream xX;6+T`g8|I!"8$@&? %ZϽ-I̓3}CT_O_>U}=O5oV_ߚ+XhڳBUgPz=?G0u{N9;zě3]Zni/+s.\V~zTu)E3۞#==U'\IM>Hb xzK #˨-۶-.b+WB #IK~d`_k#^%M!Kl6^٬P/ IZ?!i9C 瓉mm9[0!ge[T) );o6}MpN$D튩dn/Dz{a> S[K9(,8UNU_7B#.sQAFx T9֗3/l衺:*2/'H$I:GJ2yWZPשz*dU7.IHX1dfWWtP&BŮqH.,RC٘}/|Fԋ~gx^\G)?T]J|O' ,\:]ÀDhѬsNWN °npRd&J⌂YD2߃.XoEAޕD:](Yڱc8u85~`?Ys'ғ 1Dѥp{c6! 6f_kۘ4/ed+,9@+}+W ^o{ &.I=RHzm_iGuW(ӭq> is"@D98" ,xgbV+H q++!8@h[z+€f98fI.;5''&ca<%iDqkM$epe41T?Ⱥ}aa5%O7[q\@E({ޅHgG}xDuяǠg=-60ۍ ~Q*^F`T~QXM{e9^5ktׯq!;6ݰGj'0Xoyvn~hI;0м9nsw|× endstream endobj 242 0 obj 1321 endobj 244 0 obj <> stream xX˪F+~ @v\"dL OUC-Y a_:ON|>ݨFѓm `O~+ѿOCZK;p#tʟ:+_;5/?v%aG4bZu ^9MmuI}sP͑}liy~ 51HIriu NP[ө2*. xWMURW6Z19\6dNϺp ϒga@".B!w?B{)FhӚ6|j@Q AU8YhF݈Mw6%KYEZ˄SArdL'q#{2;…R; ?ԋJ4$AթfU[L-Y3/%dsgWа/ `'i$`5_ڈ8he 2:0q|C:!1 ǪIG6V"տJ{I4G#D+KOH=Jtܰ~hi[ͷ.o0Y[ol[&-D a* &^%yu6!E%7EPE>7W'boΕ.qۏlpv7$1OP5# ŨT܈-XH sPR7ar8Ze6q8Mx dtC 6tRu%W HXGY,g󢏕p]hFbf\pmzڸnD PױKP&{_!@]w:tXͤ[ҡF2Q}7BNPĎe.BQjÈ.08zLAJ6AAQ!=I$ LwFxA9M].W堥OB` JP? #=] 7{yV^tiXͭ/ a x#S-$7h@W[b݇3 endstream endobj 245 0 obj 1559 endobj 247 0 obj <> stream xX˪F+~I` -BCVyA2TU?Ԓ[m_n /:)z=a8?}ѿƷu{w_ogӁ~?IM  pW&ueyN6r5Gg~oP7P_@VfbNȋ)[9n5M/} mJEe7:L˓t8&macٞ,E1׌]+kIZssBlن0E*GaV=CWLtdzQV^['D<̌Zd<~ *M#f(r6ړCoWOjЈ/e:m2cmT'ղeq3 +փ!ˈ^! ۺn!p HTٗ^i3ѐ  ٙoPSZkzڒՐ^nG 7qy f6LO A+n(mv;՞ +xyJH-Jp]lP껂kUbe, rwUҽn?T; !4 wL!=t1ng)(K #B+0p~1V8Owr w>oIQc 9 W 0]nbԒt[&)erV D-aR[۲Kh90Bh0,<MG~H72y MAn@D. q wf85<`c6 fsyZߎ,*(`^B"T,!4qӜ )<> stream xX˪6Wx=*,i$dLf~?J%mwBm|=|nT:wMt ͗?}/.64m]kat ^zXiȫ6P=^ ʝ!mcˆz[oDUc.e'{DžSըn$Q@P>i[?ESQ(d^^],uэh%ly\ 9#>G! +hvne:;IyE" ufNqt ύǶi^2Gې?bxſ|:|5&JzLLB5 P.'YJD]o~F \I<w&8@ 6F<Ā]CI˜HK%VtTȵ!.ͪ1'|ܶQ5ָDu=H؅h[+W5ˀQ?YćZ_r (B$;\mQ)Oʅ٦PLÉwYkGٍ Q-QT}ԝH o1/:uv;ҍ\I6vsR&({=0S{iEOL =H""ByDŽi&nK6xK؂3q SD,1 >^<7gg !5Ȣ!2r|OmqI'W%n[z:NlzVK҇uhM-r eIK#s%D:nN,nHS2$5.c4#!ʹ*}^譶˞%qti$E:잆aGT2APRM tA5/W㺜xtR~GSng~ +8!.22{zAW'+%>T3z#{NU"աӮO#nZm]NΙJr6MpB ;{VW݃+gDϤja? h=Z5NR;#5l5P A|t:>(6 [̇Yf LF_wE뉤f+OqVwbrL":э-YlO; a)*7@ĩo/xwƊLb?1uX#HpjL" xM VrexX 8BW"6Y ~h4%$/ ӲEJw\/1ltjGqk78"lkCA@3\:v5dgx/j71]ܟDx8Xu>ܧy=:|oEuaZQy0VGi 6`a/LKjb4;3tK>ͥH$gb[X3ha\^-W qwpN%`)z"EPqný, ܤpsqDjF]님"*S`(>r)&>ZcNf&")/Wq 8/Ϳ|Ĥ endstream endobj 251 0 obj 1725 endobj 253 0 obj <> stream xXIFW^m#l)$Irr!0sTd4Mr-o.us*O.Kvoÿ/ڗUZ}[|c*BlsrƪրҪU^T{9}\jp]u_uh@_]4iQ9d*{(6N8X_781Ezwbetn E7mA@N?hxm*B;4Id\3hYؚ@l@]Uozz@dhFOEd]E27hUO B "T hhJmkXPoEI\S[QnmSeL$`#6#}q O Ѝ9dG"gFaԥ>÷'Uk> stream xYˮ6 +.p3"4hw\bf/%e[rr۹$%J$)Iau_zgv/~G8M';XçE?]E(ao"&E7}7_(~‹ 蕽FsB(Q4b"ĞARD%;b@?Mݔ@"iz ALb Yb$O(@􋾩mcgSŝ NG+5;evޣX ٮ)]@TJ'ZMj1ÝFX5NmSk>Z1xq0 .$ u}#C˚ ''7IGZg >tVi5%㻴y#?t0[B /1Z@Luv}DVEoؕvn3edY j*]XA4\Mŷ/sGSS\_{pP\z|ӑI& t)rD,X`K2FR/X ϶2L$&抩UcZd =I+‹@l.1\yEH XoEڡ=Y-lW)s@y)pųxBCn&qU%%CmuM KeKehdH Fý܋[?zޡXx/j $ߔ¤F$.FDU$B⩴hQH;.Nv|JU%o51&vO\ؗ1& W<0Y;u)ʱݗW|Wr%%zzG%B^o[1rѭ4 9.eo+WRE*)7Kڃ)gWՕm[=y|JDŽ`3:SN/-{ޫp.x%r} ).-04@+Ö h#VLzZBeٻ$GzߦLUL ZnrS,xj-"䭢,Wy7^F BzK;/8me|첧*um)jDQc0eg_4ctlԂ D$(T@?k.! G΁sm{g܉GKu ||:LIIz> 6yK,_*ЈSrō|oxKPk/;MFۭFO$w. U:h-8 Mi_ "=M.4p4f^iR LF X&k c&98Rߪ,n/2oF'V/\e endstream endobj 257 0 obj 1836 endobj 259 0 obj <> stream xXK6WO HTm &n䒿o,ɒ R8'g\Ba*wEiT_>~}WixyA A@C|ckUQP9R:4 PV]C=4%?ȩnZ҉}>򍪚P'z_ OfBuu kmTPH9+.,E_\e'iA {?#k XSb] H+umC֭lRg=v|iT5jlcmv> stream JFIFC     C   52" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?3K[ kNzuig;IhW,$da&VvW};ARіаb+'~ 㟋bk&xI*WnH~k|TONItr(^G,8ڬevm57ChIJA ]ãh:-Υa?($ҍKQyqxOpp<˯0SnJV֤{ҽj E:*t674ѿugbc1n6xm+φd_ WB[if 21og+&%i用Q17{Oا/oKG>-M %Rp68cs_W׾6iu?L[ Bl %xcEe¬r7Ǧ1+':6hk+oYI['6sOjt_u| ޔFiNߕqE\su8"Ќ Feup8x`1_18AH>q-,6v + wxl&t \pTy'RwFqi(RTҷ.ү.DRc$͒>o+==j"auY20EyϏ/]X:uZx0< xc̉X|ޔW;+-M|_p[1ltWbyp?0ֿ}|lo?|XtlRjWѿdxOP,=e5m:b՝J6\0 (JcsQu)8MͶ+yciz׸-H?Ǒ> stream x1 Om Oa Z endstream endobj 263 0 obj 25 endobj 265 0 obj <> stream xYI6WW 0HT0M M䒿߷ڃ#[?շӗJU \.-\謹d~_NV_{z?BzzU7(۞ljhUʷg}Zix_^~8 /]l*BkƜF5y@?zWĩԗ@&FP'S@5 r듸g_{gYW`:v ye K+4-CߞkQ^!Q^l "n`.=C܋B[y/gqb}bFOdqDVVy˄]T ? }i{K$9Q鷰Q.~ 6zє|)cW'7g@/@'yXX U5Q[>f\ kn)h| MFuZ [ؾ Aat*I]Bm&ߝTu4gգ7˟O+#j6cW-83~+niӵ֤/Q1,~dc_޵ ~wcJqS p_N+Zކ}hoԉ$P*x d= t_,؎`sQCsi/J(#h+#G{Ѷc(T "2qf!?'"唷%'L9 53)Ɩ`[ʭ8UB1q/%"l ,QmPbx-4@ PHPjmQ=`<ĺ+~p Ju5-ؽ?,Hitt;xT)o޽6{athH8BIuUiHBC֦afY9ёڋmn,@P}ѱ' likOsΞu #coslSYӰv" ' L k C{!3+!^~w#G$mS/ xdj됪Le"EaL[N@)`}uz-=ãmT!V-$ņ\Vsģ'qF g9&S:m7lh!o^.;q4X34u~NP%>Sٯ:SH#Ø]T$e\O$0%]B".BX+*?PՉhcK?ŒźOmcC++՚onl|bLc1&[&Pkv?k$_Tक़ אFىjƟ"! n~N֧ğAtЫQy}Oih%]knZ}\kTC5Ƨ~Bd)M=htDR.3Oh'r$):0hPś@:<ȣ'Vũڎ}(3Q{QL+󮸏mSyhNi`nzv;@P{p&1h-N\E'qȻws3bxLWPɿ endstream endobj 266 0 obj 2120 endobj 268 0 obj <> stream xYIDW2]ٖ"Kq <3H\UIbVWUeus'׻n:KǮ7_a_~?1ն^kݨ!ۼ~.:II9/;~~T4 pyOjS-FhTƌ|GҞdzq=YRa_Vc-kut k5xiOE~,Vd҈sxҺ<hݰ`T,']|E-)mHC]g#Gmrur1:߻IU"$!v6|pʚKc9h|WYAl( Q^:%}wc<)/8<<e~q!2 sG rQ=Vz~Jby;'՗3<G+7\埴<Ǻ]Y9ؼGFLX+ *hTp~_N4/m@ut`^?*!l),+'Qm.L IߤowctYiQ1!$!9ƭmʋq0ЪB 6ņ[4=9^1IZVnZ NU (?%,gQݡ7hi'/.6d*x/G.x.Ժ\z؃oe{P)mN*h0l_R=`$U+sP)w}CmNs[f믗;MqV3 %* Ö/ gݍa1{!-OF7.PndP cl 4}?@6GOc_sƩ̀QBt7E/BOUsp> stream xX˪6WxJdwn Y d69U%} -ޏS2>Le;UV~=UߧOXjoT_uEzkt5FWfW~۷a}畺WWC?6wY3@s`0c[{Ŷeυb9%bBzRNdzM=F~ʹgC<76*+շsU\DG,l H`L$ "]2%&dgVZ6;jcSxx0}֐ 4`tƚxwV5pƉo|hz|Vv 7~ VЊ{ǷS5sFՓ8Ɨ$%_mTNJ>:䴵\;A+deR.ϋA o1~Q fHvrp IQ&/a'w3c0!a$lqpA:/GBz 5N<8ګ>ѽm$ȒRX,va37Vx3 YN Jz7oqçQ"}ʯywQr&:SvO/Y5h!iњ?h"%)>s䫟U 5"as!`(@\ ?w{^ 8>gDq]%^1[BIg+cie/y5!@WdaHvA}qG]uz9 }QE~ `&ۭ:bW-\ tq-+:^uҿB >ϧќb͈]IUdP?# endstream endobj 272 0 obj 1547 endobj 274 0 obj <> stream xYK4Wdtǯ8Ri$v%!.lv'irpHx<334~oTp:wMp?M?דm5.{|lӷuk}QNu/4zA_߽~yz>2wi@ +AG_܅C7[Tu2 W@tyH8[aofÜs~Ldu_ZE^_D™H5Ns}xiy6Ȼ A6(4{yV&J268^ph/Ҭoh[ÈnyP[E#*wf6 Y0σ0 0?J8"e f΂cP ;Gp+ï̿CO,wemyG hŜd]eijp1Y YL6azgS'cC|HF<%=y\D)4qcA%<'! M8d8 `~ut}"f]R$_Bv,N-/dČtx43{8uL1c 7 QJ!m:2+3PȽ3 gWnu $Љ'S(ٍph\p1u<x"a )c=NG5᩵oD0Aȳ ' ۙ ~PR&(v;"gnU/V3`dPFU0CI:Fqnx!5W" 2UOկfUsU$Cq[Q7>D;jSާQFHJ¥{v*tacVVWx_f;IXvѤlFyuՂ)|nXUG8_U-Fr=0|xRh?gI5/c㽌~m^V]*y3[p ︌O늕\wso`.4:b endstream endobj 275 0 obj 1756 endobj 277 0 obj <> stream xXɊ$G Wi)"@7 ><%Œ[R=lLCwddHzIlh۟'8l:M8}w?;x?~9}ןڴ |pU#M"BHЫ ؃m  < 6{iGkP<5\5h=I-K= oܫtY^2;t1xDNwl9ƕy1N#;,H$1wh&M 5B2+xBg*Hf 2Ddħ ^J|HNhF˄+ՏJi`%^r[kzFu%}jSTWFM5#W 8鞛 l[g3c\Gihǫ 9!wqCpA p׍(nѓ򌼖~4Ni셼~:(Y) {"݈x_(ZíYH6Oi[4ok|&C]UM-=]Ai qJ1ziy3KJs7:URaVgcR3)IY՗jD"'mEǑVsvHU~ "\h-gƚk(v%ƗtMtHܛfNŷWT K3VG~.V+J/Ӣ\kWP~۹c(7O-?Ԣd$JjP"ݤah~t AJ5#)2իZ< ~~ ,t[ nRn DM~FRȭέL6{BVoy&!HO7E endstream endobj 278 0 obj 1561 endobj 280 0 obj <> stream xZKޟ_u8]F`R Idq*/@f3?Vђ}X}.~b..\pm/O[_1|}k_v |oәK ~~1~}K1(=w+=`0 ^L 7o|ƛxG3] ]&<̐3Sޠtwo#C`p'EC{X#<@v ӌA*ji Ƶ׵b`Bd7-#{23hO7hPD3@7 7Ac͎ fwί\q?3˽9>"gt6R%к/s> µAv4,Ĭv7+u*!PR/ZLvKEhϳZTK큝Ms( ! U7.t95ʵI&ErPV-J<,ܧzvcVg89ʔ+ܙK#.&W/mޱ-OgǺ Jپj$|8|y )O kyƒ!<ta^yI]'11:+݋vx5޾lK]}ݷܽma-` ;U.lֵ6l ۬}rŭ8'&v[T-뉽ȷLoU;<}+Y߱#2#Mҹ*b~\2q Kb/b F!K=V=q[ MU  fL[=tfu)bƉ:!5m\'|gMh}rnbC:ițWW$V\)pXXGQ;o_k A4*JC9\gku}eAܵK!Uri/`X? ?jQ,4"փc4whZ@295<tqxŷ"&q Fƴ`͢iE1ł;E?dfs) 1ߞ!+M.wJp8CD_ԑEtЄviNX'}W`܉q|q&&O׺E$ǢGz 8t/p;PH,sqIv ` nZWd縪ŕjo sZ:!f0*7xУru[O=ӂ endstream endobj 281 0 obj 2558 endobj 283 0 obj <> stream xZIFܔBP|C3`70OD䪽y$2/"##.+ًjo~o?4 z>ެ]͏i^AkТHw|Rn oϛ 9P)(jЀӭn'Yt;pLSFi4i}TQf[p[CNhpAiH`V b$ "LԕC& ѿCO7# 5_i:L7̖zm/*hy+_d F|ſ𛆽Do+v- a5 2|bxLbOБgLbHLȻ&'?Lt?z==Gk k:PL A!4m8;@Q6>S_E0|M9ԍ<{Bu|Uunf(@\Ҹ!G"wۋ]9ݎGî@'Q~r?n:EBsŶA 3] 10lb&Y~@Vdڪ2pT_@+JKUPlؑ!baŰ W 1[L}HqU3Za E"Q@źv)hW%,,CМ NO &ZOBPV$h%IYŊ~" Ըã7la@p6g!MA}{K1嗿A/}k Wi~]X isK()|sgHIM٭v4ɞkQM@@ny n/(W=UUNS(/)C,+RzLE7L5ww55ZэFwnL)Cb_g8t^0@fJZ!hEl6 b.[fivZxnfS:XBX3CgҴz\Fu!yP^r~=XP潋+ޏKаy_NIe;aϧֹ/9UJ YZQVvd CZbUO\F(TW4 .d,w#p~ 9{5hEf 7O<_Jמ-vt8<2pu CIOA8tM>Ya%",A6ܥ;P$X{c-$8[X= P!rӢf&X‚w:亜/! UC4ϜqCL6"0 onoDZF+8fk|*^č\ah Q]rb*||nɊIz~Wь(YbP%&Z0KC$4;7@Ч~Ф} Ͷ Pn!D2y}#7dzH9m(w$UMş|폹new 'Np( sb{E* 92V8@We?;m9 endstream endobj 284 0 obj 2223 endobj 286 0 obj <> stream xZMй:ÀeYEsK@/zjE%ARԧ7HXY63ߔ~i\.M5_-Djx雏o&߀k>~:p :Gλ;<:@-x}э=?޾%%?/&3w;ґzޞ|{(38;_y^4(̞<NVvB%4w5~u\]  xb6&ǸI6t{oh"I T˫{ه)*OYAM {JI/`ad_ xȀ2cPmd 7er [#APsҾ|$Q0KĹ ,@.@ =A)+ gy")ICR3zu qe[]4Mw@q pҮp74*p SIŠZ7OMpRU6 6`odơ{1]e8'.`KM!ҵjHcp+$ՌqfIКÝ(bFBC@*ݱP1X,^!i+)T؆:.XiBH+Yk/GCyW:rnfJ6欂*Zo:)>sI2G"'0/Gpp\ѓkݮлN?&Ә5w^~Lx ^ܠcnzRL7kaaZ% W-)+_8`Go^pЫɟ>E* *ua–`P\ ̸ SڜG?9$U4\̵"fHl =.g`E6\Cs>H|*Ԭ<1jbtqYIB,*YjEҩ9 ꛔ" Ay-fd9sU(<*D]~ T b(1L 2ҦIjvÌjIZs6%#igIe i]t4i#*UYߢ)$묧:ȑ9JK⸐jd8M3 W?K{<4Uëb<_Ox9Uq?+EipK}J^HdAQΚ)%_ DH/}>fO֕˜}ֻrSPޚwJc̎duj-+e-8_U")a)vNs&zoe'\5˿U9^oFu ljݮ^DAjRFb~vb,|`WwNӺE(|RΆ*콶7hb5~5 gmu c8>^)޺St?J79s8˺Zߗة Evur~+D<2SڬlYgq[(: KG`r+UTciXP_U"nZAK̥6G;;+r1O,Us2j v%8c8"uU;v,pWAiCS7bw`<6U[O6DM;22Lq6VE{=F^Kmmu5^j5QSy#Hu(hC&$f+y>#=Y݁\z=EoC)u@c"yx^#빂P sXO1̩T9ՍRX6%ZID  h0>1cLd˚Ł.pw%׈8tX~VQ})Zǂ!V]K\dCbȗ(kB}󷯞QVZ#r)-lRM!!kS:׼k׆\$J%W=|вX7j7XwX>*0ww< VINOIR2tri8P%,H9UȪBC&LQ#itЯ1^6HQp %0휰0zJ֯kwHp,DH6pQg`kcY@}$b:EJd/,('s#ܑTxsI_:{d G䌋gwJj?R`IL*.o=\CC@s^kIh3tZ7f;/~_iZ) ea/%*7U1K~^E endstream endobj 287 0 obj 2516 endobj 289 0 obj <> stream xYI69:bv-ɃBN d"YIBs[Rv}Ɯt1736s|͟:F>vO>Pۆs߼|9LŌf  X Zs34>҈@ L`t8z`E<2De￟7Kٱ!?zpwjx:Ҝ@|d7>[X,^t' $=Iqt_gYOֈd Y;`<Ft?5:;Prz`kڇ*u& yG~?I.!BA&IR(1;}bk ]?Mez2>%4H.c{R]߀RW]`@BW@w}Ë..L%0=?&3^Zu^3:oix$S0_<˂ F;h=;9 $g Êa%=]i:jKThS0PQ' >2}(O0i'ؠ0Ir }jx'rM}FO2q )h̞]nFдg No盏_z@6&ch&Z= cl̼ͮj/G.x#&a16hBȉ Ar vϴUƻ?-~7x؞F46>1/2k@)ɥQ)5pP?*d7S3!ـgoUL=aM*&" bON\Md7f)\yngu(?h.хkXaSG,5Bk@1WPq,dR %K4&m Yc' X+ܪqgЍ"|bAHMG.O>A_"b#"92aIPٸymPu8;6ac.ދN f( Oh!EOcw^b3w}D~b–739,hy:[a)0YB5}aV$W}/Kx-m8pH[z Ksb U"IfI+Pg0$^B[AS.&>īҴ6orհa4Q,Kq/]|ڃUUUB^ (Y*`l^_f4f] !AϨWJ;dl&1.󢸮^7 endstream endobj 290 0 obj 1963 endobj 292 0 obj <> stream xYK6Wd]H=lC0ĉ]][h7d#P(c4sf$+9u6gC|xn\߿NjG?~>93n=/]flin4=i8})u*ӝ̛ ӯ5e̓CLp-X &G4@;EzgҔǚi#58xj5T[ʻ1MV4@ Z?+HX1Әl4)mP* 1Ҭ6)G^MfdȨRUkZ$hVbDn-/1 ?O#)~V Xy;PW`‹yYeCl_ZZFt\.u S‹u5$YbONڜY,W's lB,!h!@}6=Q?ᅩl+1u]"5) + 1Tr$$-А|ۑEOހot|ZCDW0#X.{ oFtWW"<Y$ƦŠ zZpt)3^NY-fxN7jTæRC]Z  >,9W6#IU d'ӵn|:W/}حTQ[UR.'(% &b= 0iN꒴.oB"Κ|fm2IԤgM?3 `d݅S2'mC#N+ v^bn3UɞjzP+9\ף99GBN:iyHJmA" `u \B{nfx}Pg RFi%.tuuun}G^^ʨt91LPR IحQ)dVJ5c Y*ʲeU%caWsiG> %aA@3EBn׈x[Bt^#YAA7y𽅘c$>H {DVC[XMO!k^UZ0۹01B$#sybY%\LWRLY/rY+]|P\Ƹr=j;OGOZށo\;mڢ|Nm Y, BGdL~i Ny`hv|lA^c]^>~קE>G6v:y @!"#К;ZW޼ KUf$J${+hdVC? U5/f2w4w-n;9  endstream endobj 293 0 obj 2009 endobj 295 0 obj <> stream xXKF Wΐ --==I"Hc" cW<8GQͷ×F5hO|t]O?:ޝbG~0 Yyꪴ2#F0ʡ*D<@_N־u_VЀ?A9ٴO7/0.-ՠEz@=7b lƷpV)JS@EuA,2{oKzx>=iwTo=^wiIL#ˠn,bnw<-;5 PW U +RPvt' RU fS,?-K6bC7-"(l6CVTgփXąL&*BDlIS#¾. (4mهҭԝY {?k grW 3Tq4 1Y^&%ƈ4ڊ%Wѕ萻6,?kr;1O\kpz@+~\p ֔(MRa;?pPȂ󷿛_F8!6x_9T*Q&UȇV9ʰaPs/A'Oј_Asa}gyROQ&%6+M6ijNtZfve*aMTSB 5lz@Q%TuDntV~R]h_M3@u`i=][t;.&s|wRgӁµCLڄ8@6?iE}_sPe+iGzF6Shܛv7XLfgͺE&#׳[>\t4gƓfF(2r?3 q _61wLc,vOq#MfCA&g-+^i4z\19&$f- fN]zU7C\4=7h@),+4f6]Uo_of!v:c|qj-Ok q=&SBo<,-B'%1nR!p Q]Wzq% sF0> stream xYK6S\HdI`۶a/(B_lٲ@4h.|9ӨF᷶k/ .oe _8 o|;ByUU\Wz>QwՁUaO4sQyzTE[sU=_Սu $+n>W5Ȧ>y ]z⤆܁ M%7H[xAݒJ"VDP_zd=n(AoZȰ^хi>j*\($BT(ӂ&?˧˂ߝTsM0pX@KQ!М>4 %.h .I a!1>+ċB/)2 o"M!"K6R|7{s^-̿"yX\3u lX@%Ϭ$j!`MQ;#S%t(ƒ&σSlSm; (_KF@aOAzѠ׍V9:\7t;'']ktk#j!nvD5]( V 8vGA) 32sxBcd_Ibdd]N|5G#:$ #t;x +C44$QL&`ei”Kfvۅoy8tLwr/-a6u4j4+N]8R`GU1DCT#LR Y,>`dCJ);BU^A3X~]s*k0KRӜ:BP\W(iv\on&6LԪw$lZW+y)?DĂYjfMQĴ; jq+ɄPZkLlwܧP-ۺ^A1y&Son ʝhF rT2=Ma~^iD3jn;+kOkl@Wi 8tK3]1g@g$0{;:nbp8J%,ϸ+ ৛3?b9 8ߍ\B?hR.#VpIrsW?p{"#2RK6r1vK-k$JO*\Dt%iIR\$/Ӣb[e(UtrE>MA$>$[>fTp`L$9(|_:4(NGAMY;=uG_=Mîq*tR2R!h1}^s pYH"I%6yF#䈀Ih A&8r }]3.$P5"uu&3 eB5.P%Y![t6,J)yU^"Z3ӐE&57R:|QG Pd2y<_K{(K3@/(q(CxAxB2;`*Ұ߀/S"iwP~jr2o/vNCUecef%t8< 1Vb6j ѕQ 9_@OF̊Nxwiz7c}:mE8$7Ά2 b^Zx[s@GJk0:yPɛiu{َFL㿔4T; 14kp7p<w GB_;g# endstream endobj 299 0 obj 1952 endobj 301 0 obj <> stream xXˮ6 +.V@ۋEw@g/EJlN.`$!yDxŝ,ï?=|=VX~?>åūAwB6.]ɁiO.>8|YGgWK7* ] 5<s|kpkObM?-#T$Qq(#t{#0Ņ;멉U @^]F[!zaGhg׊FV``;ЍalahO ocW!.Y"J>zFս^ću. ٓ"wI\HBթ~O7Hgٹ쐥&MQr`l'D_ыjآKFHrtl8h})fه&%D$W'r-1294*)`j88X EVNGsg+JTgVz׸ Tآ  J"4 ʹ .x+-&U>(Iа|s]v7f>PxI$[=lrG.J/-cL;0ܜ&dCf >)9 ~r}UMo&s,iJq?[.%S Ҭ 5*eڐG nv{ww:)q.E# 9@~ &pq ',| r/3&8^hj~RTIot`31nDg󹪒HtA*m˃ uop˓-ڂϊxkdgCVXj)ck4ۛyu/4?)RMm](shI)A\+uiҫzdsjx2u+LQyn+>L>#O*]e񺴟tvæe&N32bϹQ][mum!(('\:yALEq[g[*d.='idHU2V$*d] OI8zDO*[1fˎ֪+ۿ0ر'@I ʦ1)HC;}Noύ/UWٮFy)|Dg+pN7LU(F6ߋaay[K{t3=c4FI%Ԉ}9 k endstream endobj 302 0 obj 1424 endobj 304 0 obj <> stream xXIGWh4ܜ|C)8_{}&-W{+?>P='Ot釯~ԾBVUy~udoxYKQݐ\0UC76?}{z>lRg2y3O%"G &d">{2}'VMm-6o?k\OVZbP~K{X#˱V O=ut?S}Y@RM^׽G}OWD1^}^&I8Nl[9Ԭz7;(ΕYr>tGy#`*q6[d7Jd?xjăcvoik-]ʼB)sSvW,FdJ\.bދ+N@yhT!U+L؇ "L#Y:8T b2DŽ+Fg`%6yk.@e9P}JY kXF5 N,[}#YF8W.2 9;>A4X515>"bLJlumVמKf@^OLڀ*YiG,<+X>ODim%^2!]RR )V+BE3sT\ܚĥ&IO?>9_*$&<a\Fo*:{5+gח7jWeW5:iT./aI\Bw,.{pZX'ym`~f p#3uCjrCU!H6ک E XW 8cȮ֘홣hSIf mK3Eh&@%SISY&i)Ռpw#Ho۝xJD!@Z#ʽH\y ﷎Bu))lKs80/lȮf`”XcV#9*&}d`97lZDד?)78K;Ḱr*Ao¤aޏizi``)R}a$> stream xXˊF+U, dw,BVyA nTU,B0]]uݑχ8<.iӯj9|>~^1a*ů4_!n^N.tO.a.# ^=^Zq!'w Tpt7S|@޽$q%OhuީА\rŸgdyD#ĭ;cMt䢻bSX?6&J(Ԧ >!~܅Y?نc\dm~*2>E(!WrDn&IեS!Ʉ`q)K06}B*p)q#r!Iϲ%v1,rZHŨXMџB0re 75!L{?- +&)%1YEaV-Ie^ȁzPGMiuՈ_CٶFjRZfNƘ׻}Wx״i*wйU9$ਥ ᐑ <АguGH $@$o:6; ec!UrjP A(Z nPɕ:D*hC+r14*\gc=%4˱E@SDbteB}*;SpkTxO8Z ZY}}bFĵj \ +~Zjm&,_կB,ꬕc7A-WG-.F&biC1#{ǁ=Eh26ԇQ+^~3Qͪ*nz2S -:AN+/bR}ʆ)xpkS)@_pkwMŔDlzpe2Yn%5#ɑna8I`vy:{Bf&Uh kҋA̔h 9ʽ[3َAN@$ n )k)sGʏ`]*&64k4 ^f[-yZ)՛@ok^dǦU^`/IsU{Nw wamHʂSuߴ@ʴ L˗**iֺk;m.fH沄(51,.9+hw3*TL<Y'5)M<+_Mz,/]"^ZI8pĥBep̱2 ~ZC)u[@#uOzn(D 3_Pk,Ea^;7x䎛a}UC>¾GAs ng+>._m%Vx}TTg\~z"a[q;WLxX^r+r..<)|%qT?,g㲧4ҷw>Ql7ʼ}h  endstream endobj 308 0 obj 1431 endobj 310 0 obj <> stream xZIF9=$˖-3 S6`0o%?\jUim[E~$?npuQ /[׷Oÿ?~zz,>v~|zP2Fk/ ꥦ6n<_ KYGߡx1N?xwZT=:iGw,5uv4=-jf qENz5e.=k\,`ЍHp/LP$|h~¨ 3$ P .5}z|=p@h;f{7`AdMiNPUyϤhF"$ O 63۝my`R 7u.Vr7uj+J^xlmN2[qwh0]x ͊FUd)!zW&`\:ͳTY? %Dg'*lZx Z.̀P }V%1)ȋ8Iqc}?#Bsk?h6:lwKD`;Pu|~٫ȻS$Bim.WzͭB.;dޚ/pimߢRVɬڇw,B{5+LpV("jR@c};*Tik.}~ x_txe#@䨖<;4GI4 0Y2 zZ($>OKRj?[O;pmoӫUH`oXɆrhրzS`Y`3pBW ':%=5_p#NBs&A&#hWAR @A!wg״:\PWv0j1؂xpR 1(˜K5ۇyX:dv+IiU6\ jDk(I_ Au<['T8Wj =Svɉ\jj[>cP7+N>xJw>jOI2ƃD'ln< PO% &ݭ[~& endstream endobj 311 0 obj 2185 endobj 313 0 obj <> stream xY[6~ϯs!FW!NB߶=Їҧޠt ݗiFdKqz8M|di4Oh; |2Ȯp/~˟ i[:?_UhƳIO7$>M[ |%7ثptaL5JP-0G5Jښ6` pUyMfY~ & |}l!oQaDޓ_޾?oOU[qQwtUIFCRhoI!E2TBKH$d#JJ Ge)!<0+}0}q[6iCrƷbg7as vy+1 Kw.Sj K:sf(ihڨwQ10"!+qg>ٔsMXHz od LY] \,[7>t0`tTbCh-VW>^u0|CKn۩ht;>,DAP_||E)cM2`͍jki6ǛŀFf_ -奘 haSyULNff*TNrFo{ȋ&pWhֳt3BUr,PzV 6I@Ib w)JY}Tk[\AWA=ww_WX 䑭0ĮsOd]&>8V> stream xYKF Wx]H: 'vtq/(H#I $=3HGY\z+3z o~y>Nv1㏫q>H\`y§+FyVL~k}D(r-8p;O^Jr#\AgO&58kGgsTp Y?<7%OҍUI8={ ,V以I,~_-XR %;V'T0BW>[}t 1X)9D9GIpձ&_I+&Ԡ +(# q_OnZ<PTmYR&bg~bF 2&e,ԯ A`eUxXP_4'Ƴ*CR!+=e6vvre7S$H ۆ=QB ߆OXLJ Ƣ>6qNJdU)1 ~°ӅlR&CHKү[6M .bL(9haGc=^\VM~Q=I[0?V-%hesTS#IivfPdZLJ} %,-⾥ZL->ՠc)aJ[& Kz}ZQB+0ߨ)' ?7C j- %Q4 zXm {V?!U-NvRb{fҚ4BnqEX}XRhv/9Q%f|%i0'e[YLVk?> stream xYIFWիF`V I 9A2%~@O}9Qoe*ЄjOoy)xjoշT?掿h;rƚ+ѐ7^[g4WhzPmzp1SM8'3(8xKp>)   {<y]r!ֆߙX (5S3 srP' QVӌq5޴*@t6M; ۣ=[65ֿ<߄<*0¼fH&tsuޱaV=lc<KhGdzlR 7'2Of?X #yg v~ F]A]}[pf .κn8bRXhK&OP3jD%ˆMO%HTM|0T}ểa~gՏ ;_-`e&$J'^yOCz{)l9K'`UjnqDLhJf3y4<ݏf!xYD &AsR8`'EBzj/bτׂLƂtQrF=* '$ummp0Q(6Pfn* z~.*oQ#E6MGBz#_WbNMz]HA: A $}GST` vV-7&`Y |GE^sNC ̈jQap37&lQ~ֲ IS j ՊjaݕJ,}mRcOnH.ePqEAdWත'$M/? A@ED ('a!npSx/JC%< ϜlԦ3(FlZ\Sx֬J,{bAuM9j2p# ld|*kx3 \rޛEaپ!% 3:v P) ž7ʀz1n{4NZf7t㷡PvɢAF]+(ߵ|/ A@+N%W"ig+D܍O,dK w\m_aKYKMme[OʩM|3oHc_>}l2\|LSoWGȼ:B))cD[@ hn]qrۏ0ob,ede3}8m3M $#g׌Ȓ+`c4mpqzi[奔 p q>rv=IF_lVIr{y0ȅk-!f +uEKTfʳEkSa<+АT N'*9Q1"dZ³Z NΡBЉ&7U9> stream xXM690ҧ16$BNI6؄K~J-nw-T^I*uӗF5lk|߱yOQ67&Ӏj?]U9ʩ P~jٳ+ dȨh~0*k`}:fJl0CUiBac*1pϔk}z0;b*8JTX mפ7e:[ywܠgS\75q5pȔQg_aFi l0WV1c* n7wu E.~}iӦ\ $QM@&ZM F9.59o)U"&$8hB5 i*+O U@ngJa.6 aAVQ5WQ3ؗ(&3}` Zqȃa(^9~A`?7jEDq}>݈|HR2#g)\BFdP䍃a$x niNqlݘ֭0{ .R- +8>|g&Z:zꬓ&ެGEE%qK(VL':kߕψ B'z"a$֤>(4ኹh jA]a)6[F-!1`ԇ?iU;_47+_tp1a2 1qkn ƀPMSx,״%W3i vY/dX`tYH-#8 4DѮ=" OHws9'ě!e;t$[ۇ=b쾰NUWg2w^ ڙ$9|b8ȑm}f! g1ߚ}flF 6Pk7< RQ,R!@ F7ϴYH{Y}LB '9D2_ ],7|XAS;~6`]$n7Xn~۫q( +]c*T'^e1<8B]J/VW`LY)< z],X~+߫(kE޻>-:3C endstream endobj 323 0 obj 1597 endobj 325 0 obj <> stream xZˎ Wh`zI FR r~^m_\ܞVK"yCV ~TMwϷW6}97@u`kaߖϷvyw88>0ӣ ,t~{;PweEpWoFT**TD=*9(BqTtf@Sj"}heЯFI=q'f| xJs6ƛml`ؠFz5[u:s?la<#Ro`gfxd֤ )J$y0x6HQ]͠lGEvњ+2_6 9(5#5ko4$n14G&-ͱ`ݥ}/t:*fXD-|MwW !u0Tv \'e>#*fԄ_!?(xq" X@GaUnNnEPE[O˔I &JX-=ewwj-(u.T~V1/#1);R]dZTTܝ]qynxp);Qq; ~z ݇!!%A.*Q*#|S9vg+zLr#Y`CH*d kR\Ll1V'c<@ ``Iv<;TGKر˒9܊uD)\EQ(!!F6j6BLiFȏGuஏ=g\L( UnAD1DkpUp'OHsֆUD2u!ؖ۾xz`n,i=PioV9Snuʡ TZ(u+e}x3Xft mCT19q3fVԑrK 7e4@i]E⭢ ?l/x;3!;Q1|-H9T :jZqfq L7΍޹DrBPKn> ̇gB&+O4 cQFm kħ`"s%Ē~c/G8b@b]{f!Qc0/w>aUb6X\g5]ϕswAe rc8ޮ , /sz8nNpٝ*-$ZiTrb`WNKAVMuX|ՠ|O \ftz3W[um&_Uig圗fBZz?N_մwڅ$7g1RGS5e@ sS8{8?aj-ht]W,>p^]jvA&gKH-Mu~ǀsfT-V`k|gBcV2+bX\TB;"]%ԩzJO="6ٴr%62 0o{ʡ}:=N눔X\,di{*7;Fsg؛ ]בkч[mRzO reB;}0d;LfyO,tg y&Z/ {<=Փ/f:aI) .72=>!f-{_ȑ#:qj2`6#MTn1Tgfx͍1*TጋSyq'_?C endstream endobj 326 0 obj 2393 endobj 328 0 obj <> stream xXγ6)"-Uȅ/}R_J7}b1UzF._UEw`t\_qk-^~8+?>^5~8j\ rFWM(WH6xR@;U9]~kSiw74~eQ3ư38糇Z扌l%zB;k7 }e9N=;5# JyPB#S7=<~u2q6Js`4Eg@܏ew v~~ނoNWkƋIpNsZ*]Sb.,#DOQ?**6%H:C hPO@@*$A7xsl-(ny^|-OϽ g-3JJo&GBPnF՞} ^Sb‚F8ubMP#w)t$ 'XϾJsx/sa]c;H]L҆#hO3bCw3. ѩ\ K}+SОHfoCٲw ѓp$5=|.6yBNXlJ4r%HW ,IV-f( pTpu>V͸s@_>_Ɏ0јQmCB~-ÜGRߍBzjyAPZʙdLtoȶӣ^ΛѠsw>8^kP&G_)FWF3B(GV@MR `ʂirTmT >s -;Tyr*ub '+sA֮+nC+mL/ >h6؃[feV a&)y K7li[bAz2s9L8CUWH\!vL]jRisP#6%N̺&h%E? *ǹ=ms$>z]T"N@j+wj]KX_TducbJ_rJJ™Ę)yMcAKe[82K &B^s@2.BX/j2F<οO0UCʴB>yƊXZwJJ,Ia:cAW\VuѪ9 ZաzτWcmПLzU(2g@4f->^Jp^m xcWۖ`Q^IVU?:~־06b_icqJi9rTip "4E3ʹ[ꍀrᆳj]joftE܆֙wwkX8wUjq g2@%>YX,0/WUte/jxk57X엌Ȳ]b*Õ;պDsX42> stream xXF)tة$mC!l2e^?Uݲ?`R 7,>_-~rQQZŧ/?}Sӟ~q?oUqvBq ˇ b!*C$bz@  : eX`1 K~ !X< dcQ)a6-)NjY{`iM֔7=1;#1>31PY !8xH~JWV#%+qp>hYk*ꛫa V^)4žEHڰ]ò2;Ba> ZrH0Fy%;ٮ߂ݞNd7m~OԤR[[+'E5f^or8RZN̖mqe&ne4MLX]Nys E:ĴD'ۀ{[[&sQ8_t @g|b'BpJ[, Mj"(Cv1!7e=c+xYD$-I'q4ʠ~#9M|HvŜG9'~-+q n&>]BK'nv!,L1RAgJ@3=yB`H(g+n ٥zKè{&Urܓ?A2DED^2ZtzzcRh:;K ?/ R{Se&םp|Fŗw2Ym D%{ ˎq?uET7sdVl GY uy::*Sm Cܫda_nتe7Sw6&Ɓ nN:26i()N[}a:H+Nr.F)e EQ+%;Rq`rN~SeAJO림a*{ .{#4"|&vH-f(4[#~G2Ʈp—tنĩіR^.pQ{-r/~T1R|b bS> stream xZˊF W:0RlCchOہ dq*/I ߏJlW}oB虶]UHuǗ./7_'ß}_@Y|˗foʪA?IC>M~5ކa - KuXoz~P wt㫿 m[6tf|u7pg\B2.j Ocތd3t.#6ڄaYtosT_o6;b ol1fc1y$@!,xVE`&kQ}(0Oc!qLQqY3"(=|I N=3+qoHϰߓ ҒTQ:Stxnʨ g TˍsFb]RB›􍚄 ] 6֓ p@v^\$GX-Xa!4bQ@8*"̴w lU?nc/J{tڃ%1gq2qv pD|%Fv6k x@,6SUy= :"ç$~je,6 jJlTpf8p`I"RΒ-iho?ހI%nDattvXG; >` DYe\zL'y(JozQW@ &?w;4n(lMR^Xy_mi*9|)ֹԨ6 u]tS2ɳ͜ꈆ=p"V4v]>\udC|ZSNuTUFzT_q q- jU*z"wh15l'm/zyXs=IDK,;_$K3FYsdz,)ђ Aoxry'~n-Bcņ.1G*vkl:Hx,@@o0s=jusX9W{%s73BRʁW5;]I# Q-I Cb'ATzדl@L]tDW uN `,ˈCnĔQ |rFh^O"u&cĞAլ4;Fd0<$Vg$ɚOR*R=ìă u8hG#CnO v Ce*G },2c R{eH,al7bV?XVN@rTbEx-f 8%K[U_&LbV>,3ss0 |6#IĴJ] )r=oI*ȱ>z[&{OeȢS7G y8TueHAiO8}Mc)Ǭ ooBGaOQn~7si #xO|]٦Gmpf4l lҪ5OIL& mL6<ӰҵŰͳsN16xR.e xi: ao3u{vv\:! ئi^v,1ím i}6q:1%ƣ|",U9uGĻPB.MVq1dEc!;b<ƚ=,69+|n%(bwyC`w1X%E dA{EߵQZL+6]ª;ƪ3)uuWoA{͡H"1)#qayõHmhǫr{ v9 \w-e;`p`o^YH:$&9?ⳛo8ܜ~U:Ky|ɉ~U#7dT_X8~wVo JPO1sO4Z4HlہR'jNZIFs){15_5>17 ،_M]p>ֽ\r:41-VUD+ 6Jn[)u&@H3[9NEs^#p:3ƸW; gw'^P?4f!)C4A.JKqGO^QM(';b82c{f v[N8 @e|,gN}> stream xXɎF+x 76%Ars2@ANـ z&R#`$qZ^ZtPJkIW)T?MO|./5^{z7PEz395gۣ>+mKxǑm]neTg=|_rIH"sLAԄ5M.ߠZ A;,Mkkuٲ00Z IhiuDw.&OM;"RVv X(d]*Y|/{a~L̕ W f6J4لˆ 70$0g{a0^ӆs? DfΑ rMrJDΦ~ ҅ahЙc63t_tHܗ=WI'_.giWl~t,CPRIJSpҐ q:H0~ht:38YP56fdDۂЩp0v|q`U(q-nCf7C_ցͳ"S$̋DqwTG"%11dFv Z!)"(o:,4P+B\Qq_:w:%fi=Xa~o<'}d3jBw2evJLfl=v_OqtHtOW̩ڀԙSל~PznJTasb q{o]?/#rx3kQءD,BVǎk=MV7z4C+ٚ}+QI&1T`ͧyi[Y%S:׌,e;J^R˦m%QdVe' zkr]+` j%I.YB"QKTկ04o:ZyqmЅf6J+cO`/Yn\#[m񩹷ć *rs&)vvHW]cݍ>TP^WF|h#Kz|r񗍜 }jMu:Bޠ6T*-,^f;Ji[iJKX:4M9UBi E2I0Oza4n_٭x.e  '5-$fb&RF!O0v3V)x?B%Igl]*V-=|a]*Oyc'-I*T\9s ,in#j9ȍ n}4PȽA`[eƃA;֣Bm6Qs\(3dW:HC|QS~6pg6N@E*rO߉}Bm^꧎+xx3g !4z-c0MA?lSKc}>כ N= b 7蠷#k("b+Y+l;opӏny9iQO"fEW۱&uՆ:ui {ܳ[~PȮh(ø.:=i^/aŧ--> stream xYK69Jmrd % dTVۖ=, =nY*U}Q7h\kTvm>q> 57Ϧռr׿/k+G@i`ԃUz@ea[U+G;998jw9jɑ58FfVZV~7kR*a :]+3Vwz UU7hb:$ǝis ++2N ˚ {[^]%x7Ӟx5ԘjĝsIꅩ\A` Zfap8fu! 7 [i={x i{bэD/P[i51ys&ږԾ#K}zwK@ͯUۊ hDe II5{ i`jc y5t$Y7&DTHgvd ٖ Okt'G,fEꪤ%:SW_#'EݓsE͞-d#5]'I&(y/%)xbSD(Qb5sPŚ{}MTT$EĽ'Hoj舆O5N{)hes$*@0#[TL_jm-%Vb z^zO~a+ #ݔ%K|C 3F!F(3Y6GN1R;N2aSȖIf mYw9uc)戴A%Ï9RI@,*ywÀ_Snrq&!Һ@K pe4`鎻_Q0ըNT[vEZw"wH M3ۖ85C>RТٴomqKux{K8$T;< }ԧno.hq=!% {諳TGi,f=N2? U:_ѨZU)&&=`d >V§sl%sLHSXlbLR.<0q'̧=͈_ %}eQ`3p*> stream xZK 9@{4 X$I" `?,$!hmIU,u׷5(fwd2 gߖ78<|eao^j+^ݕQWuû7p`|+S#,*֎?`NZ,ATa# 9A [1#ͱ.na>BZ#BLu ?AM~wj&+>IAĆ>(vd9~jvj݁{\|Dna;}nQu0E~| 1{}}GeSFyГE߯}6afMa $xDŽ2\Ӈâ'֫Ybk?rɏp񑖨,vTKO)07OQKYfݗ eI> /̫k6F*$ Ӣql> ͹d;Ou ؔX\q=b5JX#GJ$ W26pAsg 'j k9];'Ýf+9KtIr*p+jH jl:~&K̓62$.c-mLz;hP76ku~w@ 9b??ԩgR:;(nh1(G]#p#:@ 8Ak45d;?f F8\_v!X,b_Bz) Zv4@hgFVAuXE]+%ؗ+SKfru: Dg9'R, !meѐN S#bݖJi{*95b鱫Z9Ԇw] qk0m0i+rEɭp*aO)ɦfw7R[7F(P?!B[SWO /jHr:.2K}EKs%4g=>9n <휦9I,YR`p#]OWKF`b?Rd.(%bبqYnRu7eypAևn * <~sb}Ő^ 3Bh  ֞4֋>yO[®|)3f .VGgɣEe,B6VZJ-Y0=h+rB;6â]G 02sʁW>WӸd&2M3\Fp^ddEHX*<1nAIwt?2u<*Lih5ku3uu7k (r}Ulb) 1s9h`KZVVuW NFUHw*(zASzf4dUSxm(Kw L s*ݔWx;Cٌ|M^lB']q }:9NlɊ?R WfBQN\u ΀\}KƒB͔l,\q: YGp彫s,Ɔϴ@RN=Uk7IMnmՄ$1&+)V-()h Uu%w4CKmgÓ"ȟmCGr9Rg[HՊUv`sak;J"mՓ6Z;~w!S(q+94M;z&)&iNXU>kA5v:lkl^*?Gzީy:IWA*#&}Hcç}! MJ%P_ I3eetжxHpN ++K~&kj6e*_?JR.FmLzV7d^5 >nP{K՞6fWnB~9 ffYhHo z`yKw!y!"nykOv7:sXn_i^Ƶ[ ie endstream endobj 344 0 obj 2218 endobj 346 0 obj <> stream xX6CeIE e El$EQ&E߶Dr83 NY/׺>7ӏߝ5S<9K!XdΠ_i rߠ@ݔ.4.MNim=B7540R|WKi(z&5o2-y?F)׵  :LuqiW0f[p|+[@z " ⳁ]FWSqHſ @B# %7!yZP$= O<i^M{k{&rv5, ^B('xGVg}PdWK5TD \%1!VjN+\ jk%o^h] P  ۲VrJBğЙYw8t3*]QqAa[3hIiEфX7bW |3?O[س `C![fȳ$`h́.>iÀ&7\\HP񝦈9J0EVEVzWȄ[H8Iv&`v$IhRJkzGDV(mN8#/s+ DDIRJ||yXX!3&ӎGr7_]Gˇ`fSRyWzaAk{H6j0")`Dfl&* Ț%CMgIFẑ^!wLw2\HdyKdIؕ ̋ kepFLP56l)]IeKέ[>HLOE~iUfs?VWWR|Sp }F-%K3ǖy%Q=2r!߾ UJ%jMp_~ޞ'WGsC8*=]. A% "2 IG #¶vMTsuޫm.,:(97)wpIq Q67.5O|(lpb4h0QsQ$5o*mNֆC¬jQ6)H-|BB0"6nbF!$6D_4xu)tڥp3Mck^df=7ge'Ry/awR~,"rh QD5:[[Cf6pch*ɽv5jswD®x0 } 031*r jbs^fov endstream endobj 347 0 obj 1555 endobj 349 0 obj <> stream xYIDWUؖ"Kvb#qqb\SK3x륶s|oXTnU_7Kv>o?_,~P7`6n>߾oo6Wu 0y O&]MmZBg[{;G<֕o}BbM%jD "t͂Exav0$oa>Ko鉅@D9O$4BPӯeq(.]K~7uJ 8o)wp3cwekA tY30Z,`4Ʀ,Hmd#o߳ߙVh%'cWE ()i\ brKʹJz+`,T`ba{?c-[D<x$ 8Ydy2$g'9UNur= Y4y#ÖK0ЍCD[~`E}^ޔp  EkC,UYY COi6oIn4bQ``7,lx}Z_];# DXIVFlNPHLN'0HVuznғWy1KI@@J AƞgQ"ㆬ>DPu'c@W ΰ2NEn =6\Xπa a"`YՊuIf;)̺ iz 7oQy }ՆXj^Pxٱ F. Pbnei&޷_]Lqr͇pi⻕vD3ٚyc ѽR=v4794[}in^ʣ|8Pbê)0!8Z$PeGS;KUzN!As+fX7\N]);i9ʪe71VYqtY={yg?$y^srZv 昔v,">T!ZtLmb*₺+:]U *+O>_g7 (-zRz A9^bp䂎pEp)<.jl/4ޏEmHI=&EӶ@ʩu48;>kczqXC>Ͽc%tl G81]> stream xYɊFWxS&I m-{АE./,y~T*#4TÝ=Umnppí|d 1~~4ivdU6 zD<*jBSyʜ2aΕr8VЙ0O$}9fk6rRG3nE8T{61iU8 jϻn;}.⮇lz;q,Xb٨'emPi}(ijQEv+6R&qSD"+&dqm"3Jr5puUU$yzSz Taٍl$/Ǻ%fE8TMW9T76YJBi^PթwW YXsg]9HZq XEJj\Z&~+#ƺ;y-7 "،$WKƈaSx悑umvy#QuHNb|L+8=NMN/pgA9|:$҇w9 (7S MS8#"k+\e٠r|U 9v~.D +"yh(]+c:@X:kef%v Eux0hm6%|he6}k7i#< w!ykDvDP"EZׯRdPR)( `#a }ި3 AN[4}偪Q=$?$n/`t;n$QpR3݆6.aaB 8󑥙`P1ԌN6kV\J(ʟuH{Ht,$؆u:)[,>D*}lV }W8k׌>P%xK:6 l%bGG- qw'+R[{^ a=ƒ~mQE^CVDqڧ+OpX})tDtv CFgT ?謈k#a#B -gwo_(p#5 U!6azܜ75~W'}zEӽFqƙ`p}r awgW URԢ-o roϥIȻn>s.,Pa`>`C̨"%_S^hڙ6B8_4ť TqLqE7x," I3М@j{ۏrJ 5?rn룘gχ:d>ȹ:LV)!҇X85⎡vQϔn++C] o:ufMz/J3ZF:j^/kI endstream endobj 353 0 obj 1740 endobj 355 0 obj <> stream xYK 9@Պz M@vA&e~>,?2iLUے(CJͯo?71-jӵk~_~[?ކϷ1Զ?j~\CwK7Nք%S#nҾ ~m|+*7d ݌5=ODx0x}τEɒ{~ot\˳}X^R(.ձ-D:FL;`Z¶3d֍x*2Q$[)#T-nR<]@ch&.k>}T;8Esqh<3A֥mY' ;hSuo5! 50ZC@- f^38` "N u&``19':(m!0TT?%CZ7S<=6vK`:>M y(YoP+}t”5^Aeؒfˉ,sYiM{zXsxvBޙXA&$  ec&Ӌ[56e"͒<pq~_L\r_L%7^Pf:oW91T /x IՐy2+i7DTʹgrJW%K0,\,٧v^geJ-rs~:ҵAfwAvsy~7*&aVcCɷT,Z&(D;Km+p^XNY}!P?NXا]fj-IePm5YҠ`oȚ|.="bGJ?Q2PPcmZK;>\['U|~>%#(j攲;|xA+b \EA%mq@). D]vHHww&uME)Zoc29(mmvcN[PGv7zyT=XcaUI[SofB?4@?oMj-` {kq~3穱!=aōSʬI(_\f68ruZB  @in(__Ct9~:؅nս"18ś}mtLyUM58UkorA`+C[V Ҷm%v,y"$)gckTD(5!1G^sImϔk/ma0,N8moc~3B~([Art%/̽4<S=&垨;Kת9izrqۻVg>l\Nm1> stream xXI6_s_TZmx-ICMN d"Y: üeTjP}]Jk]W{]}W_ }ֿB]MK*ojzQ^˂xM?^OomPBIthYT}RqԤ; 8^jNK y8I[mUo=AaCUoMBhi @fCFOg i`/{GM-x$hkd'V%AAԀ X:yr#td]܇ntlAit=ی&r )4 [m:k@{S|EZ |)dmVGn6HNUG.E"+Ud< GN^=&3%o,m ,%w Sx&C#̸i#FF%xr?Š`]X9J~tS/ 榪@W|g~a0Ss\y"*?^k)g8hT; -) #byJ^\YKfrYZ&q9 Gg%1|ftU%& u슌[&L Fawsg g䣍gYXuDz ގ{(I'¦|?f'۟#łܗ3 ٔ^ %P3iBs)zASN Xy.cu+ē\Qs.k.W:vԮjr]1FM쟈) G{Oo|]ِڕVҢڒ"HviQ<`ϣENK$oaƛ ZTvi$TeuQFr[B妲&(R56ӵ&uR#Clk C-J+a!+vQ@!Ud+704,/Y:"ސdۇL&=s+buג"וǕbܧh%xecz2w7V> stream xXI6 W\ .I-Àz6@E@2b[v%o9$G 7eUIX_+ sqQJ(ǟk†j$PUhDsj nͯ/!aOY 5 "ihQw!{~jDPˆNt57]VaK,P1FԠ@7Wu(AB7'dW]hܶAY{7׍KCGf~k8H-jv024QNL7U"ٺ3yS+xDwC Cj]F(o^5ƉхMT~OFX*L8A6WU nF^"!780XLҾ&Ӌn&Uw8UQS8jAܚ@LK¡Z[ a2Lޅᇳp\8iC(ZX1 i>/y9 pg?7Kg*O`?.P\TTW 22vk_]h!-;lNߙ١Moj+@M Yckn)cJ^eD'Te dܭ@4arA^0op2VRAa|P!O@se[A22fH@X@T(Υ #9>1s0T?fZ1%>Rae.-"uyGf+ˇ)[bz;b~(} endstream endobj 362 0 obj 1399 endobj 364 0 obj <> stream xXK690UaC{@˞ d/Sdٲ^vzeCϗ(f;{_kgzᅶ5ow6Vg ?mDjO>E=Qh- ~jfbzB?hF X^0|%ܳV*|xIѧ ϴ2U/FQ@J"/Nl69Ď{j?x^/6U:[%-p :֔MC QQL (dwZ5δ`KДxQ׶p.yƣ| t3Z4VҞhyoΛia^Zү49mrv0dtp_BG6ى+;vRa,WŭVʛoer)HIZ:)|3$V:h]&o~-NKY{#6v/(jyօ"jjPR ЩoaEN[GšUkOXK-dնVnCa`Ά5_keMqU)!(~@Pfm%m%Wަѽ*hBaBeRyX}QPڭ) GhZohLm^WQ? kj"ߘ- ބ7 }3߀k7htސChJ/4`c: *ݜc;Ui– D܆ yS2ǁb( TzםK%GuC}5AyD1*҂ L'7k1| ؃,Q8\Zy9mVd ft8P3`'NV'?v"ύXF(/ĖsQd^$T$REslj1be`!H@:CsA K$L{U5G.[bqcfT4;$ac@J`̟.mN84U ER Liq%fkn(BqZ Gթ:f\ESaϹ[f%aYXnc\kCylbCp`@\QU-#|]gf^5{&e6 ^D!ѷI2.Jwc՜*le;-[@کH4$ěbjGUi?E\&dxyU組+l_KT*Lo9i87Ǜu.A ړ5LC?Դm fH-,* Hbq2e]K|W@9̀9.Uƹ̅fRE2*A^rΥ\5/9=VE1k]%rlTa>0EP;9&T6"bFV*%ZڠF*VU,KDYI9ʡ]_־v9`=FI."/Gѣ6|ytf_"s{PV\<0/Np$\~o7^Cȝ)α9c''ӧLu+fJ&EmuSn`by/D3^ʇT"'u7!r.T5Zq9f?k(ٟA:Ut#pn[ ǧnV^:kU` endstream endobj 365 0 obj 1701 endobj 367 0 obj <> stream xY[4_kaL-,S_B'g&IwEeo$sx搙F_?*U)tU[՟?]=/Cov%7WeۼdwD}O' =AIΕu"vҡC,OcGE< | hF%ri%B< /hzSyQ9)RO%2ij=*q \+bA]I9 WҮvFT#S Xr"{FxYtW$=L4gieؽ'KqHN:4"*Lx=L퉊B}Q?lc48 Ci`p$ Ƅ-Wb kih#-YCaĹ÷06cZ#9(%b]onxS29g03(s &7Ѳ~tFo4ۦT ѸhU|63sQj3Yˢ^78RWFn=cˊRP-43$~w*o2R̍>.'Y&^_'9Z+7 sinpkȶ0uZyΤƬzYtml{CX^Wv&7] Gˢ(oqŧƏh҂9 gۓR{/6̶ϭ8לԛv.tq_=FsDZb)~ e)d˲7t8I,eOGw(> stream xY[6}ϯs!F7vlmOmPI[R|%rQ'*)TpjwEeT?MwvpCeOuqvz|HQHy5QZ]Wոq_+O=U0;q:Hh)Jh|nG4\֗۟v07~k/`a!Xc] qN^g[xt|`R c-봶uPB$]L>;O~1;[ֻ9S]/p*2U8fF^\̨ ww͞}rL풗#+f %'f 0/k`$ߢ z¶ g92,"'1譮te}ޕ>+4UT~-E{a_V *g]^>q_JDu_noC*)H8XtVE q9s?0F%βt9g:-[k~ժ rD3<Aɽ罰OJn^[SQwc/awv"[?<(kBc&:wN0=moA b Ӂ;/wAGa QiǕ\WGk:&cE=z•"4˱ +X-R2$tf|ډ4 aocvP=2FqՊCulՀғ $ ses({- dcpaJN)K"@!qLtbZ(4 CdRPLlA)QyM8B5A-" B ȣZ:)_\8A~efȞTS= Sb]&7 b)`>NB{'psd*@ 2QHac~;L< Q֏\:.D2F Ä[7fͳ. {L/Jft"PV+eU$4pZͪd XT|hS:myD~ɬzfeֈ " o=} ӂ-y}FY2X݁̄>g=`?Yr-p##:b̮UF{-&%m+|>SW'~ǎtн{U*y\BW;NϢK8IFwj>ፒ ) ?޸42J(U*[},H)Us]?ѷm\#7rE܅XMӵ#Ɵkpψ8_$d/H~PM܉&^>!C/ ԰ endstream endobj 371 0 obj 1838 endobj 373 0 obj <> stream xYˊ6W:^1ˁn2% $ds?Ӗ ԩS%'uRMOx痷:%coo7qh,N~bNO~jr_aA]UiP Wu|iNbӞ@ͫz7JCy0*knA ,~i>ihPO3<IA!3$v ~Ҫ>~ !)W w h,A#:UfF(W0"h-# .rWcg?^э̡Iۡ#L%h_lw@O d7߇M(oBU25; >75gALX.MX$n@J~qm\5XZX~%p$\@o#Ƀ8 GbIYʄkP bW 2F6ibD !4Q8M?kD 2pBPVn@ dO؇>% !&uxeQd& wfTE Ʊ֋vgC !\ Ca|RzcƭNIl@vBXlEO7HJd2`O(!&sb16Q|}u-D1 &Zpv) [lsDNj0a[Bw1HA83d6X>[)iU 1qDRjQɴ->",H,5[cK_v4Zk5 ʠiZKbS(㛘M_Lq#s`C1Q?^Q%ȻཏRm JVE$?+A@>od8w=`1Lv\l`G$CYU= QTCYIݶ@Fhqz ْu]UhG(KR4sLJj5s&;& )SG`W6R %*-Nh!uV_H4>8 MQ㨁 \fOz+k^]~WYS<̈1:J˴ E AȄ^d¸-厉uEkW%R>P *fChԧ,^u ܋!;dRedjT*MWlܣh(TM>?shV-Fl- otgegY!;aTJT]뮢jx̮I:ڵgNi ^?;%hM0czx >{q«8h3)&]xGX+zH>Ƥ~'0S47~q4 sR^}y"Z.E]|#2iۡp'I]|IW"{5 ^ٍt|aѼ `PeAa6J{?0T~͛:d5Ɠ?q~{tѷ7[XC > stream x}Pj0̮^6 )B\)&|g AΎffVGn`}sv|jo:94iiBё<ۃ5fy~uCwa@/aT(ArVU|OnECf O䫲:+Rzq*> stream x{y\yfaaI&,a !BBcZ@4Cb&qW֠V[0D &XkZX|L[w}_grs{{mxI -RM~A[65on>Q"u]nɿ!)#2 [m߼ۚ[m'J>欇bإu۩hTw|A amycMW>m(iWWgOה&*(]m]s_X6% :C46WT IQMDwi=dMP,i4Ⱦ$7}R,:Tղ-t+KiB+ &@ײ›з&/#vi@?/UFtWR}K ;JWQ-e, |?E ߣE_UPEWGתMo+)y(Mhr{? ~%Ng^fQ| Yʍ3jZmҴl=>JGWP;vϦdT4 o菢~[;Qzf8{>,I~3^Q;y7t)LeIW1!_SVg%j5)2fZnkz1se~rr/3QVT6duksdx>*1AX ew9]ʮb7]>Cs|9omr~)"ɏ"rW, erҁ9#aU=}(VͭNU{mC~ӷMi+WfnN3gg35ḇYfev;F.Q[| y[`զ^inŊ>F`ӗӨ̵+Hzg;Sql0b)5/T1o*'{c=¥02ڋ}NÎyUrm:;=gIvuVލa#|wp',}#(bOZi>dŊ6v17y}9݅#93hWCY6Oňw.b A9DXuaΤ^.E~>q 9czqƌZ0~j5~+xv󶳹IdhPL1&iMa,>aɜZk~xʯ K!_WoЌR^,RAЪ=45iF}MUp7ȿ- b A2^Ȥ8YmHWU*dU7uK뫫}|-j5_i8҄a ""lh6?w퐓6[Js#!q w<'p{ӕjO&}}Wi{}򬚦 }-X\hz]!511Btf+kҤl/G)Z[Q檌-:k{  Q!v6'%i.ee""(CkIs+.mse.i`@Xv#fQSs arO ?dMsTcr~JBu2Qj@%bY5E e rj`H! g">X]C:Eع>hmz7䕢gxɏJ/_ k?3%z||Cw[vvz)Z}QHZTًb,֓@Cc% X4Jc~`r{īfb'k5}M}Ck7uU7/P]F͵ z6ʩrϮ^:v!ʆiƣ.|B+ZhQ-CUvD;e*2H:F-CxoO٘2$2c Z1\i+Y6aCeg9?)[|!;eV/ W2n7{^YW\&en~>5嵸O\t^So̕&%v'ye0\-vSÓPxd0S,y ݞj5z1rĂX}}LUZaH0k)(Hõۗ{fGr6~ָ'G'MBBjddV%8ɧSܦl92hZμc/4۱6Vl{[~_z#Z~݄nZTǴ;%KiAL?8q"Jv?sZvK̺Xd`YŠ^覱vkG-tt3e澱?س޳wo{JO o =$wjz:bkZi2$X6s|\XβSHצ#4AOɜV]cybClzf@ٱx./([<EވgR!kYV^&S65| r(}_2R0' cM[:``=fjK|cms.y/ZbF/5Ҙ?vcL{ÒL%%܉I.N.Qb,xcní4SC̅ RA33v&L5 =ףdW&&Nn1\N*tԴ e]k.5&WxdnCb?i,s~yPby *d,ٟJA 쒬m$.'#Lڋm^\%45{tlťf/u ;<ƮAWsP .`3^7;m:=s6f4sM쒩{mOL{>7bߌ͖Hӧ'bGɇdqT8Knwx=dvO"CǓlvq-?V_] Y˟+t2le)b%cbp[K \0$+%ht l-,Q0E+3cf²3j|+X?ۥiLdikTե$KFKHtMÔ~i077CD{t;-NMm=66'&v͙?|-ˌjQ4[AwA9lgf OIÎbLguLmb;1^JˤX\L*[SB):u8u%n=0uqwU4wGK 7>i$ };Ҍ$#ـjHil[jZE=&.ܑ ѓyyB C>' wѤ,y:+)ƭ#`1')xg!KKhXJ>c챳ۯ}Pf4[3dWBUw~׬ug^yӯ #"pOiWq}j Oe'~"N'5F13HeY/f3TY-!CT(Ы:emK86gJO@*˕I:1Ee?ܨXc_ʘ{[R>1oQYx- e4[yTV)öD⦝h;?* ?K9IvWTFmJ% Fec7z7QY%Sao"Tao/ʰJ9]5GwǾ+*#RJ4g2~Xy"?2cY 89lBOȈߑ.e9/GITEB7Fes"*c\u0iT3b:%5,зK詠 j sRlz3wLݰhm%QdMXͧUOOtLJ୐BʅvjAo';i|M?q¶सVL.g ٷFn::1$s.VLHUr ,;-ALdfDo\NZ+5:Km򡫓#u˞v9¾59 2+ {9 +WZj5(uJ}o̥A-c-QL[,=u7*(joCtQDqtd%+1""9"maۂzeFZec&bra?\Thܧ k-wZWϩf0>?ǵ53%(K?2VhșwMЭ-jK֭koi ek;[wnhꚃ-ގV͚7WؼUiӂպΎZ{6Un=m=ZW[`U[6m.!|tKmWwgkoKPC[#FohۊDkAtvlتO6;qti*f#f)sb@(6\vc-:[''92n 3PzZkffجo59C3pa D| ^fC~0vܞ'E45)W+*O:pr$nfɛo7/4l4IVp2||2ODOSz<ѻJJ'D4fyO?>Ĭ{Y ruOTS "u:Wo꼓OٿwښODS+ZllN;  =K?*~IoSBh / 9k:g` qr⪁A c[><(@?[ n.yPyl G"g/$Y#W" Nthi=JAW/TㅇQR (à0HA`.Q/Q@9puvLԉPX?٣܇+)^gErqNr0+A"©Bu NF@noF0 ̒)9a AB 'C2A~`RpYȑ q # ST,\@LiS:O^e;T)kV8Ah'+ycګT()I{*%ҥYo7W/R<ġبܪXBE^퀢_=':L.:\Xr{XlɊ[xei"F,wHG!8HP JAJQJr/vW`vw=I8 #pf/QP\/==*\*qx aR}X>Շ#eTQv@eBB0-hXIU$oa*VaO|/x b+dKφ37+*ӣBbJQE 2# 4|'x 2|%ğ#"#dl_,Ci?RLeAw0{qCS^V>Q?)8%BA;wݺT ¬‚- ̥ڃZ_dp-%z@:h7&1'1/N;qR]R"\ǤTί% A;@;A6Ѕ@KM ڂӤ . 蒈. K" h & $ & hoMQDu@IDu@Q'u@Q':::D@@@KD!@Q(@QDDQDDh@h@h@hI&N @8pJ'N  Q FbT"FbQbQe@9R G9 9@rDBr#ѩe28f;hh'H`Gv XC" 000$~ 藈~ _"e/{i%ފ{-ɦK>|;)4 EҥoRɷP'yV:*Rp,uYtP虪òIJDzŴ2j>f>k&Q-tcn"Kcb%b=q;Ǟc y"TyiT8zf,t9!v0¦@AJAEP+uy3.r@>&< &&Xanc>g1NN.pB9`C%`? Vİ')G<'r yAX{lo[ ʙvv(eo$*+|9-w̖la;;YQԴHwXf;OX[)G,<3S \D@zqޣy?H,-mH;5Vރ? D!_,I P_CjCQ=ɻ[ m.6fA=(¤V}[g`Y!iYC2V܈҂"T=5t%ycݖ-%22&ZV5kZVʭdu ߒN̪Rvrq?L2Z^#-TV3>[bKW&%3kvE17P;d /3JƮoW1ZQ?BuEFW\>L^q]CyR6{&̫:ť)z xN.7` !<ָDe0wp[u0 P?vqG2W`4C5aF9ZI0yR)̰Fla v6ʖvٱ6i2a7V]5i&Mifdj ;[Z5V/X_M^x ^ґ'L&%&%r,Fl\6\ջY m&ccZM_Mk[ f۪*m`ֳ~VtW г+۪BY檆Ic]31V}) gbStWr1VBU˱EXa9>bQM龆gBQ |OR\W6*(]g.GI˳}/)7:_I%aTk,5|W׋R1SYnUWAIlI=O@Q֘X,:E:pB 0z,޺,oU!86;@x[B332%_3K"|E/J<+v.//5}JVB@x" (wP9p@dO$'G/HDu;덂dgEDZ endstream endobj 1236 0 obj 9096 endobj 1237 0 obj <> endobj 1238 0 obj <> stream x]n < )Jkɇ.0vb@eI[7?V9#xRZ:XfQQb[ ^Omyջ.ҌpDIpJy=l`1Ea S _$թ!~ .]QZ.q=j)e:@&+I|q2Ii]e⦋\e~\'~#*WI~6bs.lƏ+ FUzy endstream endobj 1239 0 obj <> endobj 1240 0 obj <> stream xToEfe'nHvkyPJUcBI%H8PZ!e !*!UP4v/=pPe^DY/IT?`~=~5j !GҘ\_bX ?P{a!,=Zg FZ-\j4y#O/^3C^% fiW+n@flȿ=|ϭ`y;3|t yycE@<6xV p sr !נAʠ)NMjlt]gmavFMc)bD` j. ۙΔ[dYe Fp7d۬AUhIP->%Ɍ蚅(BK1CŅBFܷAcXV]T,zbyoq%ކ(b$~Ign<9)s{%&(1|4+e3ccqrx.{cb<;gwaarB_p~)vwgW=k l_>`xo?aPFWڢ rzz/N^LG B:؍E>P_DKFv&% w.ԯ9؍SOn;؃VgFz"t`$DNmdr鄙ZK}a͘\}2t=Rz!+h `q,Ld`] )XCdai3` ƃ CߡX=vSX!}!Ϊ&"!:̇ 5@pE ì@_Sw endstream endobj 1241 0 obj 1154 endobj 1242 0 obj <> endobj 1243 0 obj <> stream x]AO 96&f&=?´؁L)VM<@x7kQ13.qe0H|pPewMJ oKƹ16ү-78=8Y;{@ޯ~Mg j[8=O6=u.;"_mKd USU-4[? }Xd-ISSNc2K2{?'ŴSe}~my endstream endobj 1244 0 obj <> endobj 1245 0 obj <> stream x}y|Uz^tMY1#"dܗGPAqÕQ\¦TqwƇ8Fч3߹՝7w,s`2Aʼs,;¼ ϗG}]pY^a BZr®]D6u-3miF"h-C=/_6kҒ5v";e[~熺9.翀z#B\fΟy,~`ٖP7C?1CQKa5Z`4-V vt%P8eT2SU]SohlkҪ 6bcN;L8iS6mg~s3ބ(P@IbP SJg ݢSb\t# ja G tԌ֣;hjh (ТBh9_0AjDohifRaq UU[ +PJΚ0BU[ja.n&ﲏv0W,܅(cp.5FV{xJvV=M{XB{pEl$pohzEO16\W~ y!BR4&1<Μ<Ƽ_\{ ].Ck: >@a2y yPt: a*:8`_%L ,rQGFt' ڇނk~c` T|߀oGDCgJ%w wȇdiD'|+i܊DR$`ܓF^,"(E#ǣipח.zFQb 02T|ckC0d B3) vx϶#%uPT,:;m0h:O;/Co; -½yoǁ ()0Cu̫ޞ?%nB0hA$, jf yzff+Pϻ+\O§x6^e_/Q}oû#a8`Rd5YOȻSLsc>g96V%aN]sGskȿ`*.| q: Wנн@=}s- wT {<4</Ex1 oOxM0}% wM|ߑ2q&0L 3f%s-D2/3 > gWѩ(&a;rRλ6ZyAgK /[}^ރp7ikPg=X m ijlTWe*+ҩdY"F!9r:Ds6l2:eF鑑QN63#saNٝ24xL<[=LxG.tR}t(_?"2CV:lr('#݋FȝxrѐNqFM:}B|,+t sp{ <(׊aD8#mmWݖ~( &֩i1 NGw-]64g7.]xEnUxCn{Lҧx29q۬: ek"lejfСpm.\+qeUC!Mm M , 0Ϩ)\R )NԪXIidƍ!ә+]8}u ȴ?S\!==݈!2ݼ$xbST]v0\}1{)dHPun:^O1XD0>Q*5sϕWq:@rb{rD# _ni _n ;}u@/ٚ!iC7$#DdkЃ4I}fvq:6'/iIjsBκ笭&x\md.w vλqOɍsfvٰ&_gR~'.qJ͉ƦT]sfwG.sC ¢x,KGEK\G+  ЫV>lsԐd2O/I J{i_N+eIc`ӃKKWxnm<]{yAxj@2˜\:6ěS</>Ÿ*ù"^*DVB)Xn C[hqU0ҜoqZۼb0@`nS;`qHކXУ,A8LVVӇ|sʹ|?^yI_߃Z\4})kzZe^#^4}GO^о'h e>%m ,!"+t(pKa!Ut*MnEVleZM0_VC1.Fbgbp(\XC-uj5F-މ"SK o4e K]>BrUJj=G{TL{Z{ 9pc/ 3]m 0.<-' 4CקZ=4z?e|*W9;ANfvGGG;o{;vlSvIF(cYu{Cͥ~p+C:_&0^4QI$Ѹvj5iw5 Fk!&CkKE2( ;@Ia'6C\%'qHl$/<:IcWa'GLnh~-uWF^2<"Hb foj5 # ;DU25ND Ay( bTE8Q%IԢ#k?=`0ss@-eoBmy,xfsw5rpɒ-=2[9?B~{5jL6&l%mf^J"Z-Cɮ֝I ~)Sc+ehYY,OhST.E-&N'O+ /\v~'m~]@s"p+ٹW9<L #AoDX9nc8IҢ c\3>4܈҇qӇc x=^Dom7DooB.af)Jd!}dzy^eoG. 0[u0ʧzi){^~*xnBnɋ܉+Jԭa)2ZhsuP'ߋfUR臹DBL˒D]NI[yBY*sxkܦpH  =EBu$#r{bb* z[<8~#qOK 1jNV-$ыJ>͂ބCIi+9A.\=i1Wl֍qlL\JpC?h),}/a0ayZ*hol$J-(B 9܇{4*@\≛w=#sLvpk}æ=`,>Ji=._v1E~f^ރi  \FKbLXhF|?[탺mtxt=*bP$nQt`3-- aX0W.A&s.S4XoD3 tX6`,worn>a1V h3sFy5R{t\ }fptlgFe Oͳ~rcy3:̠$_Y> YZVA#YϱiGK+z0 x/;^UǼxo5Zb}]֥Ǻq8,Ӈ1'<%59مS@.@yk!$^v1y^B>'v4. Tt65Sxyt]d*yk4< 2zAD'O-BN^쌊au/RhIyK筓YBW_@2z*pnaHlk5ZlClͶ6fiz64L;ߧFF4U*j2dhKaMY}A"FYf ;bk*̅IxT ±bc-WKjGejk2Q m\p jmkSZm ^YQiAɡQ  L,0Z˩몜+y<ȉ8Wu~eQ-L4NjQ[澬Ϥ >u_f`0j}*feId4S,&X .ӔQQjofDW!և ..ܡ:zmW1wrpݡ"l,2X6DɆY2ln!3G;O\8lZP]ڦ6B%F52w=۩P )SF.y[-6͟_s*?͡[q0XDX%ܪۮE}H0}^n(va/u4l+SMSJD+PGGhH'&ʡJ]\0 90D0d!{Ce^0騲/U+ ՟uU1bN<@ vVY>X(En/M3QOPdFBZQuNÉjpͣ\*&U|2ewMT%sOǿuޣ\-(18,Y2r y(8xFIF‚rjPݰa^mjuA7qR'/ $EnFF*A0z HN‹2|+;bdŢJX*l 'c8yqh{7)Z3_M377`~Aݴ"82-[H NS9Nmhw*c3z tjx<}hRj$E,͓Η~MŰEk6LhfOIIb6" ς >XYV#;&X\O~s>O IE/Q-`Od PnUQeDn2Irt 6qs Y!Fg0C6-z#SYv԰K"#J3o\8Nf;'O[[) T]vZD;LOL٣~?B;j\jjL'NS5v|PtxY31'#[L\YWE+K5fU[Ùp FK^/uU0|xM/RoG^zt{{o>a0H j`4 ;s$Isw*pE5FuLgP#S'5 Lro CN_cԑ(IѦ5IQhVse`j=by2Y-kƆ&[B;$%NH~ eر~HlHvqtq&qSDDѫD4!LT Q3Js3Z ZUVUVUfٺBɚ)(b:NG'gĒx,EcѨ\vED"^5\x.]H)'H(Ra);bѩu;F˲,UY&KሿedC6: ZT ߍVj..bQ U֡Vud+S`/hnwAk(RM1wU2ԀX\(᠟>pΏY^l/fE@[m|N0%; _"c; ߢlJ8* GM,֘{c+,ZHeAǸ/)UZxΡښ߆/̯b+zyUF_0nћMS ); U fJZPGDqؗCcQ9s+e^jALaa)1 yr=g!YXڥnG%NRRYI%  vȼ4rRLQ^AZ[|P B#?'^Y KCK#Ƚ)z=zlzFT6^hpO5Nd\#b\mAeP(Kr8gˁg PNys5h.+k岹$*+34.\MnNj 9f rbӏizF@ A=.tGb͟O/kc,洇wbCQwABu4(oH!;{ϠDk %P[AV!BOhDmn)E8,X\|. 's 4.p fOl[[ /:xF'50 p'X(F7BK۰Њi[1M i%[+I[6HjDh Pۺ /lDC~A@! I&8 5Ai쪍ʸh-e5]Q:#Q;Jm؋)+J{ZRVM0 9.Nh:J[Q`b,  :5i8Y99jW0(%~nRJ}jۭ,+ >Zͪ@ Xg +D/yX&< OV)Ӡ+{Jj@ AU"8AÜ FP5PZ|*&[d_V}Çk?5%&\ճ euTʀEaLi[[ˁfB&c2׳:ŴM4[I!~L5{]eͪ쥟[Ѣ\Lm)E4͉ȉ54~8J'=z:/_{]o߾a gny{=_x*-6oܻoݍ|K~ uΰ/ @Y G+yclL5ۑ=(ҼDvq'S yGU!2nOY;~CCn:nveVQTZ\tG Z*6I}^4Z<҄k}N/;)n +- M'ieyxQ8qv'Îk[FF3!{xx5{6cV} [tQE~P$y?ZB$ooF=S: ȐPc/Qgf+ztBM];t%@/Ty|S%㋦SwwM=^];/uAZZqMtmL?[-7.˄evXy|5VM-' R#m9!#ɾ7-f"f|RByu-vYR !5*Dʬ5rŸ;q}qSAsj`e^j֙UJ"x'6~?ᵼ'( `ukP^RK9=J{KZrpI@vhSrnj (jWԭsuL{9b4I jF-A#9 w\u\Wt{%gM:[Ó.nqϚK)k檋  WwYܤ\pR>dڋ8WzVyk0xi4H6Fs8^2ѻѻ{{īNe#n;±T/ a4k.n} ;ע۟\nyt{U5Uc61 i{~5(a1{p :qIi(04Z0Hұ R  M\{"Ơ2H z+QUMdhA`jB/j)C@ >MDx꾠X BM5a":_x-G:%Gr{- Q6X$ibvt[f_|$ 1݂5eEܵ#oW]TbvPvl`4j="?j= ^owظȡr̬[X}A5K [}gz뮯{woT|mqC髃TdmJ":v~@dfuMj6nsC\ iH%II d*IBbkԻxywKQ٨Xm[i"o=1gؠ7 V2kO~,wehxlqڦ1g/F>ֲM7Lc6r>5D=(I={(Fk#T]Uua_y@Qf"B%'9!PTdΗ6_ooop>o痪h7 V??RF?"^t@}%OyL5ZNcR?(JAߢSn/]0?`-AG7z ?(ዼ}_I~!xL6^SjZ-~! Zu;_(* ITQQ弱4dGk U "dq'k/!6`&㩑<.'.U4z9`Olsr6e U4[F5X.Fz Cˇ=~jWO]u}Wl`[zo>2ɳ*Pa<=Ԗ^  F >G^&؄^/vzY5)X7RI(etYY*Y]-ӱHTPwT z8T~K>ySX,FAm]Whz/lVX-=!=+46} M{* p0˾Ծ~.U,!:w7^DWlX/bAy[qɉnU%^(KR2{W ZcD -Nhu|@r3žɆ!o0ARa+5(ʎ/hԚ*G5pͬcoBa3j/! )} "ԋ8 8q 8s|݁n\ɍE8ݣz?7yX?nn`IBpBcC}[{1D 87~?[YmA%6` O p2`FݨngLez 7ш"z17.%՘"Ȟ)J&RF1}~4ЈP Qf ` 1ll #%D}<1̬=n@PH(h/&f%&HNhJ"M(B-6/q0qں_?gacc a]i{_Y|ia<5<MՊ; xkJ b4ՂͭrS+}aJRQ4_C=p$ϿuM-MuKQw x90j{dnrTTR<5oKbpD,ϬĊm)T^ĄT_ബk!,ؒ,"Ixԋ[ݣ_+=OށR`ښtGqq3G,.\XysM]*?~?Ln7%b]R&+GX'E"OhЩ"m"ևuQ,$yیGS]̽1dTjy ~*7 ):cb 21U^埔MAay_H_nX<{poO 3wb)?YȏqoܷP}g`7x|L2\+7cN2fj7}`iN"qs"GijjB eZ[ T`݂pE}y1!os>_XWC1+BlEE;)(ӒA=KCW.d׻U}a͡.ZPc5Yp/  3"&KS8҅/Pe/Gag9`@$%ߕ[_ 4ŕ^63{o0aWNR~]XeT_OD%{]u[VݱkV/mA基d nx{ 7. \ft̨IRxDr:Jڗp:sptٗپ3wn1O|XctJFUh#ҠĘNiT^\5 ꇮQFoQ4b\Wᇭ bNꦉAؖh4t47r;-<}R~TVlZHpWvR 9G,[!1i“$PsTeI$LT?.U{{pݞU_3a|EF>׍xb1oQW?"I3@q8o~P5b\79pAJ‚V)>㨸b~؛.~y-KkUC!-~hBF_?!? 5}d +`z}o:MK |YE<I0.Ɩx< ͉ҍ=m'4ϿT0W| /J5†4ĭHEGR-ء#zΠ! b 3QR ,kD bp 5zr:^Q,Gv??I1hr'Dj$T]TTS}/Qnx6@,]J]Dtsj#dTڟvo)I^;wl(q7o۲W\u𸓌-s~A0Pk9IՇnxl$v^uʎGA4SfŇCzLAԻf{&LNq%Y?J57C}_Sgmw*른 cρ{5Jx-fh0D/"x=-c(6S瑭H?3G܊iMH9&3ڑb$\K.PnK#5-J>Rб=N/%$ZKv˝v(A~Z\C? ~l@)RO3@ B䄯'}VUo%V3AjG5h >L߄XCCPXڗsuv>rӖ_Ј|nEo KQzUcz(P?}y|Tyyk23oLfM2$& "D$@PB @0HkPP-Xw[b"jZjkߺָTJ՚w7ߧ{;{߻snR>sC,Zxs7L ds ΗΨJNJU섾JC;0Uɇ{ 4TWpDCU0SJT&H:ēh8FusT[q%":2K=t*M[8l @3" T<AM֪3ˬdlUWmQaU6uuа`rqB8zLI bS&GPvZݻzyuw ̟?@:ڨXWk]]@tW}{{ﺫwBp/q&J%Kḡ/%Dm l~6FEX#Q} Җ[;;|; n*ը#l ఏinʟp"ˍ ")+c=v>Q*zUR!#b"[2URZ"͝U !ZFsp  8`}*Xk7yKat%K555UJ REnKyĚxrSuJ]:v:[揿$f-^nnU[HfM7/oo-\=e*vŢY˺}`DAa7!`䇐3Ïm0ZuBކm;\RWD)rTf0cm"rv2myU_wNCOQ=~qoX5fq96qg5YܚDz'oek_b:?+;f#qsxɝoCTI3G9GZ{F#O{½ hAUꆪ ke$FLD$j'iit$;*Cs ى9xNœa`;Z-,{-LjH`ekfO3 Чx~TmNjm~)xWY̯J^u;y(L siTM0`@4>Vr71v{F` >¤OBT.;HM7?Ü*yޥ9 )Oߺa/]"Y }L9(OwJ;00ce@Y 8{=%KlK|[!?hʀ pY&iRbf#ks}~-AQ`~") c(NMJݓL,AMN+ bTM 7"֩,X0 g2Qr #ۉ0  z_v9ފsGOe bJbd;jyuuY9)*g1bt.g99žW, j 3i$ga>bʃPW"̧29," FdU-):jTLą}> ʞoS.7,7.7-7s/1`3EhL=B{%Sicγö~Q/m-Z7c4J;Ilݒ탢'(7$j_ʂf[Ҭ%ѩeTcREiݒ:탢Ž̍IQD5jǿYZON3E3E#iԆʕY/\_a<0L&uNX? )^'vѤSLT&KN1\pE}Y23'R9lERppMt%mm/>Ĉ$4mC2z phZl bx'lp=Ck6!0U6c_Kդ=>X𲩯~5lү~iRdʽxT(dG<܆OPs '-Q%9o>Ss}(c'} V1,dZSyꘌ 4;4zp9ǤzV+.r]Ñ iEZʖTG@x"EM\ڿFm_l\r)yu$<k RҸhp,xoCi-Ӈw Ы0 55>E2V[K$Je<9AVCDQvEĦ x9 ڪbUY1f/j`r.o#W s-5`[77<+5hwlH|͗Qyއt(TvCك~SmOl/_ݍ|עH`<>ۛoswV0^.tgϷa- 1>_)d>ҡaoCnw>)XfeE=ָ^`(\p~jLQMd.DwQ ted5D;jȝ6a_Wv,;}TB༌^xY[Ջd{nZƼ1*cxC IE1Txp$(-D< \4'!R>řbfYi\ 6C}Uͣ쨨 o+g02ֈw';/\V1 "ʷD\X&o5EgoJܨIԳm#z|lSG:e6mJ+ L 8&eug%i v,iP,֓)iKܻK-λ~[[{lc?z+`nxd~DzGɚ+nz饛V~лu+n}\}ƶQ9?} tTH;9R!(J_ejRlm:̘Ah:MhN/ eF;zUJG$>4wl" 0Wv2wB^tJ))h؋3%B쩬ǴQ~VVеRc73tcw 1c3[)'9On jl<[ +˓PSu?_黮%>j`~+m}H;l!6Fa@!W"F>#DE0uS0q0\_^ZQegkXWm UO52yv˦hr$P.s 24I%y~{v&? NJD`q0 ™&n M0۔g݄'eYafLc̓}`~: 0no+2F 應+zoitS-z7u\.aQ E'iֻG^U*mةdQ<<[١TCy#N|!:|?PƟ+j%Vԡ$WT?^b50>viD!W${:lH3ͱʚכ[Xo7xAkW_f:I/YQYtg*U2.% P 7s廂fl6)y>F] e(2J"C! S#Epn`:Na񽢞r_DAz^/D%Phd?) 2F\h(g@#u2U;L8zI"[DiPnQ;3H-Bڅ+dY %$-DL5,1UVtiY{j594:j3{)#v"d߷kMN&%UotQۏ(2gkxBSsU;HѮ~'˿S9\9v ֘:'OH\:&y;pVkb33G}Fdݸ@+G^6b[Q}*agx M35ZD}_6ub99oO?ż$(λp-s:pˣi s#/jq(0 O@fKd&[F,%3ydE4LtQHUCǙ>O甯MSCE*=EdGK TκHu܅PK E<<|!a#p#牨0=[&l;-C<-L|Mdy h*[nN" i'qaaAua$Fy 6N^o8Q:oo5&Fd{n:1zOZ.x{riވ|:KÕ,\X |cQ.σ<қ컮}F,1uu: #vr"+S!aJZ_u $j敤k:KWwi66tUdW#aӰo81y~>L|mjsy=ӎ'c !aS®pS8NgaaGUD8Κ},))h"L&52[CL=Q/+ddd2b1nȉī2XSq kv=:n1WF :HsNZwtvJZNe⑬12cF1go :bQdSL:=(o%;s phzļ#]mJ6?:{ʨ7槌2+ s̀9 xjd҇§ȑ:#'2ĨqH[㍢ dg4)_i''n`90)SDqu_3?^ٔ*۪2t3@={1 oӯV^$mg9JIĠgX#'贌A׋BR/90GΌ>iaMZxWO0K%KsOnd < &-_t[[s`tY!8>X+Ouc3[ϗlFh5_2󻱋kHr{\A]ܲF%1h| (JTX{r5/ ы֔~SqMÍ?hi*XZ(&KkZy,Ԥ1BJrO&w%˫@<DJ DSjب<ْ0v1VjJh+;?\FCԻPj.9uFOe4FZiz|suCq r{MD!mr͕UYrE֮Ul;89;{Y޴%x\zKAYC Loj[yW^̍DVaڜ&E[J9p?y= Ne\Av_V3vh3v귣x;C?/iSC25?8q~uQڜɬ!f\FaYWyqzFak41BϚqUId7s='50UhSWk cxq})Cy5(;d奻tw5Cì!UbQJ+U|5Vě/Tbf NUH'/?l{=&?V/*Uؐ*$B ngM(U̔]Ⲹ;ۨtVpKke[f1ߗN\Y~Ne(L7 q_J ¢C>CY>?%46Qc|?Ы8b5ξ$Ubh|)\)}vbiji8s&ي!!աq\sF3j%Xm'=u)$WHD&HxxkF313[YX#AM,!S3x<{ ݫ"ZŢuug7Hb]W ][ 1գQ7&tC`X%|f_f0Gcn GBQ(,V3$ t} rG !av[4w} >Ff`NB 9Z8813R2 +kvlW#"j(n'=O,ꦟW/;HΣ8Y32k*_Ε;% WFOѻh-Do$jE&X;C0?ZPAMANNM\3"O+ǕKW՗iFG_daxԸ8b^ieKؾ8Nܮݚx.V4"0 _]b1E9Y#ů^rk x%WZ]vMu8UwaP U.TcGiw?ϻ伫gmug? }P2NdgbX1elw Y}G9y_eU%X=+p .JD$X4Rc%#,*$,CYˑN# RUy䐽.Jk\9Is,Q̥r7SV2T!P 2 e$ʐCK0!C 2.P e<.P?PXES3@a"cb\Ia 擄»)l ϦyfMPLVo(l?SIyfnBRKa'^p.&5Q&0O_i^Z-4<.nLQj6 \ԇ6DFi~JQ1iz!\5p WvW%Ia3\P.p+[^H|kZj?y%!8Tzꇘp!¯I碯Ie:uιPBNIk]izV<|IhU\y)mZ W'@R|ҷ!9 zi4}67/yLi ҧ$}df73]/JFeWA.+iJZ \ڕԛYEi_E7Z-WzVJiuS|7'}:"׹kYiKi2U45_8W߹~vMSʀI]i~ٚAϼ*Z7țz7͔t״R5 mwBߦ;ʪܾ }6v M}{6^aAϚ‚-ݫJ6t vo]нfsoW)Q[ !Y =+VNh l¹mSKZսRo>гAEzW  J>Vm0I|]"m_%tvmwm6tC(6 ]=$h3]~zo敃䁶YvʽlXٻy:' S]=@7 B6 ۄHOн~k2 Ys>%_ճa=oߔiqIi͠O\ד\Wm55Sx̣By o̓ª-=+ ލg }vѦMk*dq4/ڡ pGG=({Px>Cw#LJII}Cz bً`Pbrrv${6rQWR}NQ8%/{'>]gаB΃k^Φ\v /3A8=^φfχkbj72$YoghgjB"{b%k_M"!BXV_ ~ lm="[G߱ :(:H>O|:`$*'k )๊ "!-s @(Hy 07ybZBn;shHfҧ-@GhK ܕGLfRDprP ՕӰ23UOPLh8^5{@)@' p 0 0  J%tB%*^pSR!`"p{"@czo )O+VN?凧-?E!=^?DmNp2e WO|A_ov;[w3| ˾؉,ٗ23'/y"8to9\T!ႚ+m`8io]K'j_gK.՞T[T;W12Mƴ1maL6v|1ҢgHriib j03W`Ax2p&sZ8&)~X5E"(P^7^kxrbv+Fxr ;ڑmKʑ25kk>\({9j~'q￳e`%PX(STl>T}QvzWmonC" (Π0U.D yl>ei)Mt5iP5 MQ|Ƨx,&tN)(_=t偙yZ+(j¯(a?^vuW92='|]6m9✙OLlv]H$%yzOY$'H^Ofh^CQc{LxQ/7 hms\7!(RkHTq8M(Re1Ј3{`@ \2@B?0@BZC7/Ƥo-f3+Imx͐2j9pD lT `dyH)PɁ endstream endobj 1246 0 obj 30987 endobj 1247 0 obj <> endobj 1248 0 obj <> stream x]͎0}"bD|mǃfXGeLbhY͹綕$ˋewxmy*O]ߎv\sNʶk&r/K^};?<_}ȥ#6<s.VU.Wݺ}߳eS8Υn.suD̯ȁ9 G\3WȉY4Yrya3 Y"2 X13?lw'x?aF?i_7 z2I3?/x[?]Bc-Bz["GSj?`7?|GOߛ_o~כk{?x<{XWcl_Ї@ĺ 4[@9:=̯2?Xo?3~AM?b?1g_`Gxh~hyo_зH-ҿ9mXZC_*^ϷpX٩c l>q> 3_p0J'OM endstream endobj 1249 0 obj <> endobj 1250 0 obj <> stream x̼y|՝ݣ{dݖ,ɖd[&8v'! @@J(iL9BJܖR(tspC-ДRn\nl҂=!D+*'X+TڍPݍ0:shG?DP Aǐm/#l0bPrbFoz@qԍ-N'@Ta7rjiQ z_ 2)/戴#'WU^w;8\هB]dF1}Y :=o G; es`C, ; |;|9Y vcogbkG5S_ur "TBʣK 5nD7NoQ3E;V ru;ڍ'b3L`˘[ẋ9μƼzuVv875?zY s_~>1Y?7)4Z5uԳS,lGPJCOA/w ># @O1f0/@C Vyp-ċZ 5x-V|'NQUTWU=zOz«BEjssH^F q3o^H /S1K٫;S;++gOٍx9 c|{)U̟_8;^ʼ7FQQ[̿{l͕Q~5 X^s9ry3t9ag2zUbw8sab;hm'[x a0^aFnw WY-#}QƎ{S2)q1Pߠ0;SKw11i@M~zz)BgcSBEee\6Ԅe{эaB W tB߶p0u@ WW?PnWe,f8Gue oE!Nzb9wvJ=.2ߙnC/cm><彻rrQ '.܃:`.\ىVWW]T5m|Ory/ = (%\?D;,Ua>`=Fyˎ̾J;mP%hC*Oh0.er ^ăԥlRy^bkKs!kjf d}"F¡Kr:lVY4 zVT<2:C]hm (XsVA E]i5ܚ ԼT535(Gcx^H}vO4=BH)m-~skӆ}:mGmC Ԩ34;gb`m6@Fݡٝl҃Q6ҹfhٞ`!5;օ֎$:gFU|9 )KcLDkk.eo٣NJ_dqKGﶳz2رMݻAALG|%2|w 8Ș$IJG5Cv\ 1.v+G*'Sޱ7-yB}kf{Ў 7p)' }:ZBo8;qəg4ETg8dIoJKZюuP 05QMG E(C#XG疬"I(9h|:=L:`E3iА4ƌD">s- 9^[hg?R2ɾQ<~b_F O?9z SvnhŎǗTw/ u/^+wmsrgR&|L ]? u^?P 8je=L_5xXEgZ&^=i(]bjا /UNhk1%8'N;X0eܱC{γ. V;vt;֌U׆d1^;=]w 66m/o_O/Y{tWt߷/ z@i)CJI!$<b?=GS1hz ucLL.c)Jѱl@= xycOAg#c~zEZ$aRg9X@|%II 'Q 4f9rs\g 0K(h^`} b?!ߋ|2FNYȧ jF);~,1[EqbLOܲQƬG&A5nnJ>Up2?R сlo4'rZWxF=5o0iK_3zW.7766qeGLGħG/^{oMaTa~L& ~ƨh^ǡfnyM,:h31a1Em D:qcW&pw SјAbcH1ʊxAVrO'$8!'`E <]n'۷I~xt[٘-G'8?m▣B;7f`99}8(6,44vT3 t nکe\~X^2bK~_xmQ,"wg޾Dt0w7Px9+(>Yfӫ$9 B^~AY"H "MyG? &0:MѐP)l`:cp/4f}*1EUl6Z57T0CHTS<$N$EqROw:̀WKoN&=8ǝu+Ob8# {Xq8^(~a~NU-fefCA_kĊ0#?=zܯЏOy~SJ&)(}sdTƃ8az7hNEW\9SRm H8+gaw2V[ V15}} 4"SW1 Y&m=*DZB2ҥH.)$>?HAb +3OTɓ\R:blS 1kz Vx4241AHSuJ/ZC}5U>?DI ˧H$h55B_>9H!e *c a:#!(K[ o%iXůjgtEqJnnKҌԪ+Rר77nQ?(Ɛћ_8f UN]Y~)B࢘f,8˥fLzO.Ўh~1-Pfc2#= 3((GA>\w \e'CJCf 5ab;5f;6+r ԑ|TF B3rf7M72Fr\a P], 6'7+F T vGZordWKjC~)K\|қ̈́k\u˫o޿8DC׸]ۗ[j#@:e@]5H* LԚnR%7HcO)B™'@+ XKQYJDB9B`Dh OJ`Fi{H1h{ XL5# pPTЌbf_P, GTx&hrfE{h_QҤ9AB"ZIHEڂ8H80M4I' 9% -5 KC@3UQ%ӪD)::ʍoe*:@V,<ƚs]C_M`cJ:TgX5#:X4j6Z֌h=WvyZ4`8hiohFĆ \CR$"XDl{n.kD0ժ']^,݂ YlFTdPi4*^tiv]CpCnڬ #gI| "pd$)Sf8#"yyh'LXaX`EpŎ_* %NHI"O&)ZIpɲ81&i.R%Rr0b)xkKks+ҨjFUAWg"0xq]h_Vu^ƅXA Lt8oƒh"`G\N!P6H"OitXlacItB銒+:hwZXʖ8k!@)}0Έ0h!RSgwڪeuR2P-vR3;D51sn>oW?Z2h$3 fx-ZI.ml^޺ͮ]8եM#[^yM0=[J&Rgƿb>?O0X$HR ^gd=^r"X\g>#{"]!<乢BHu+ MG!y>A5TWz³2TG#g6ʁվw|Hn(ADױmGEuɩGǁ >ӓ?30Ia^4 #nQ A6d!9n8n  ""i_Hdi) z:TrqꄨeJ^tzr.(cC%4 5~0^Ja6U `kft53n<ވ BCߡ,c2>/}c`h ;lnq7H##eF{VAXFYxQ?hA-Bf31 HA &$q84$^zQj4AA\.S5+sl ه^4XNT&QDAF @ M_K>%G l?$a Bdt"1?$ǎ,-MS˲Z*Q5w^ ;ޢCWڎyu,xI}:Q4֋+UnQy.`$AITΆ;Roﱿmvo9 +x|k%\KELVDMѱձ:NljUzm5+5D=>V19R,Y#İ(e#{ʈ'KcNR9 -xF;%l2;zf>0G_Ӆzh[M_PT$TsZN[i9 )FM..\4MsN__U$xT3`$QM~6/q&yѵy̌_^{mbGzíMM*s"awħXBuzV[iJVe%5&J+N29l'J&L8oMt~VCt tXg`6<φ/VuSF« y_iTÁ?cgi8KqxL5#/ƫmzcKx~a~RLbvf1 lgke U@Y%6/n d=֧3QCsX#h[[OXU~ۧMU| %BIPo NbBn 9oQ%gmr¢т9Thgco\LpNk'}3r1F/!:G;H:T̛&Щ5b*!(p JVՐ"4ǐaR[cQ~H4iCT×\duUXZ7' TV)XY|\=Vu XI1y4dwiH9]K̚UM(2Ej!EH V2O/yS B DP2.c٧ wW 1+55HxoT=aF!A<[۪qC"4V.wr:CoU<%.uRDN/X- YB: $RL{^op’,JT#jnˏHGҀ4"NI?tsiX,g,YxuU!NM¶kM҉3g|8k#~7n6N򠽾~TpR^^R+)^2B@֙r}?pi]q(]S)PQG刘4B?1vKHtK_# ,^ʥU:F|/,!2A7Q0~axK%R.7h8x|\>5-x^.-KMҐwNyD!X~\}Ii,pTH0)d!"fdp!F9$ OO K}o玈FDJۥgJ_h06N )`#׸ov3=nǍcXXN4U*RT DY‰`  USOZj][~`дV܊DD–$ "pSE^H}bUÄgETU͚TiJΏ~wඟ4fͺPho ZC?ê_] }S?~YGL "đݦ ~_<3JKd}hG3'/$`|{_V3 [jKzFc88u ÐQG0xP2ת&0l@(q&>VbQTǒFlBI $ĈJ"?#`8Ȩ"m_>>Z裖V5b 'IxZ'ORZ𩪥aĉ89WykC2L(Dj Uj-U V-2D"89 Z9m|"4*%BK7N͏L-,HH|{U5=833@ &ٻP(#F#L'IxEuk^:Gܴ%,"eڟӔ]YQd򥌠B'j-ʼ<RX,8UH/`h'*LR `M‚\3q n\8ųJɫ+ٻ&g|n;YMy#\DF+,F&G:$j jUSOA]&=wǴ1mu[Tw }G&| $~ 4qv@⟊@^&^F%ll2m"uU M;U/QGt$9^KS;*Q2,,ivھ):G9h Gkh>сĴ'5B@BO0P) Vhzrhx-~(/>#7U)?NFQN}xC< Ħ/Yr?o_wާqp* u>l␍mz_|sVؾڀ1F7fMF>얱C)I B`9e! {g` w*T7ho0`qtW]IdHEEv}:*6UTVYG,j ꕛ^ m•ښ^>}m}wWYnDȁ|=9U6&HuA%^pט7&X'<`+&1C3{jRsqUWf@=>f+Z=>BB P¯&" yS|ZFDRŀ%T'ܓ{Tȫb: #STSy&1O>YR,ٸ$-#w4.̮xN JꙺQ >us8tt㊙JmRMbT)S%☏%ZYfR))$]KD)':k'rBeɫV|>A3:lԶ%SLfW&uTTLcIƁx\,]M#(9 |FF~7y,3pAG=_^[ Xδhhkߛ3,#9HǺ ]^$_,_JAރȏGuQ5e[g}1,7;鸔Z S ]PO61x#aGEM<):[kJ‰ɡ2qKg6 ;ԱHT 3^JtEmQU /d93h wgdɝ4`ssԩ}]sU.:sQE xF+q Qr He6XEQ߬B*T"4:f]]]mmt9ߌӘ@)ua:ݻM-mZ̥K|I,[x1m[$.2wEĻJrHOuVVqycq!ɨțDٔ s &6ضLtr2MIGCi2+m"PnZ}LFC2J },/huz}NjBIJˑ1csġmq?bBB8䊤\ljD, I'R,gP"ҬxGb}Qlr( $ӡ2u;AUNu@8R{ k.XH)dHXOdACHkT HN@D<x`%R6C~y~K52d`۩Xh*N)"qB.Dڋj{1pՎ6(&3bNuų|΃>k^4mI X{|bln!O~, EqscqٖKz\Vonh]]9cxRXa:RCScpft:G2K1&m/W>px#zPR"Ec h(TX{4iͭ+n :5""EβbQfӳf=GtF!R+?R={$<$$\j̳b75_d^ǯ3' :7: exR,ccYc 2 R8wޫ:y_=D{9{yڣ'NCӄ$ʼnd}_EiZZ--* NP &,  p!+SS;Ks>~A?udu>Qg{& it⦄ y>i# ],݃˼,)?/aSʲRsv:1)eA:l% 79RUȖ5m@7Mf׵htkv7'#ަѦ_:_ƛ|C:4@uOe#sߴ%P!vʸ/8|Ǚ;>I`k'D ev ѱQO.‹m w)Ǜ[ݬ[-vvxoDmܵk 7@v666-mɇsŐ3 _Η`)NˁD!7dJ\֕gy s sV˓0\i^*-u-u5](Q-FVKXuDH'Hdۆ,C{{3gֿo;f@Ac'ۭ 5z=]A'mz17rQ T!< odCq1VuyQ!E̘13ol~51؟5XC*3鿥+i6 FIt6=O.T]X2u-:=A#C WQ"6DG'ܟX􆳂5ե490Es8l@BV۠!>9l2&#P3H&:;TWNw2q]](hueMT _U~fEBv9?Su{}4b) 'gӝ{jF>3'D"CWmFK[lZp_tSm{/޺xf{˥Wߵ5|ɟ7oYtikX\ |T{3glMEpgQ٨Vg#³&$$CM4}DHN$?9Vk,I"d Y@ @a@mXĎJUj>W“ڭ٭_V[a%iVO\p{^}BGOp,LGOǰ[1K~;Ƣ[#]O;:%28SF3Iu咈Ȑe~ hy%voA68݀ L#&4WJX6cX6Ğ2jiKl?IvUW_$|i ;5NŰwháPؠ iW_s8$@t0-k yOdѬj/"G6罸jl|3gqSx2^ŵa{tF#ψww== z`fIV^E e;SO>qU]Eh ܞ<7-(EoMQ/Zk$:h"\pukc!:l-$k-K-U1 )YD4  ib1w Pn;E})S\U - ,yz#p8v6YcF/_Ե\O_i\f ya,ZcSZue_ssq⑶{&4 Th !i~Bib%ċ(&BIZ+5]k)QV׬9hYp=g--~oqt E.Вf$IzzRHAH^k!TtoGH>3mL0}ٚUjr}mTӔZLS\be,]:exѲ˶.c-Wi")О~ 9<R1qrMAK&kGi/ t_u/,]\瘩W,S$-K̢Y47kǫ@ -41}һ8Iib@"O,={ z1&DgPW= wlCn N7/<#դaY-'~~%o[ϙ_gNc`(gXЬ вYKf- b"FBdda")V'8^D#fe< 3 %N[-xei!e+f,,Y /YȠBf!6G~ao[zD&j/d Cb7ɶda=_9d"$m-5h]ygνW/{[6hyAA|TuFЩ<+0kqAQS K\đ[jr}}UOGM^vԦ#;ŐH+T7=/FŗjlÞ=ʟc95Lt`h }`,jw[ vu90)C BR+7ˡZ> O8HOG~~?:"~$4}ަ'&ṕ/0dǎe9'pfZp=I(J-mm Y6>?ې⹇C(QUhI=K3$d3f@W Pb (vXȨi2)b'(xu=nYQl66YĜ4L*zcY$e^Š ҁz\@ ayDf@J=.y?/3l`u814Q6WijYyh dyo~\en>ZaV3]u.-o1-WXs-qԼ1 Wak% B߀ŦH^!IM6gYxཨ4t^%1FgX/>O&\Ț~ę\'0>Y3n%az&NU?y4f˨l:Qb&sVV#s?gۆZL$o`pW1..16Grbdƕv}qSۥ^D5OK+<!HHCoG-Ab<5a>>e!srT;.sq#fq-ǯWeW)œȫ^>ʸ.EQv`c z(Geɭs%\j̲=,bĊ,Cp4VW$8#{UOQkэ kN MDr褘fCerPu^ˆR ٺDk*Ǧ⅂Ƒ;&'Z7Bܗwht>fI@G/XZxq@k<; 1Kj PڔL{M 44x(4Æ&&d`75kF!OcH:}y\r%ga€đH8^U[u0{ykHSS'ou߽# ]3_:bF^-̲oEUou  BS{r=Ti-ZVZ.pqwwhdI{ [%)VјVѸHѲbb K΍%{(Ba^`bwV[p76̫bvQrU#ҫXF<Č"벦\M+94Q<m%}E t]D #nV=vPZbiJpV/ `Y2֙K5̀5Y] +&|>#ܡ9K"ϋk2G<Êpf$+w0/1ya'W~@|I;'(,G]$uRr)|(PrAWv􇵼)eYՊ{|% [ ]q[-A6>h5OV]>3wG Qxvhs1x|̭878tHQY`\pJ|XјVѸ' -3n :!haiD;a${;'L>@3J`x/t$5GGj#H<60'Y<6Rm;obZڊ=` mk/h,Vh!LIqcN=뇏in@h3٧l(k2#1WCp4?q8!\h1`>XWߌj̗'4W{^NpFfkigZOs* .xh1A"{YC376wb Z):+CKϲm/#م744";Egi5eP1YRH{#hęb%MÆ &K fv&0!5SPϼiLFC6 '>O ^Maު6t 2qԜ+5JGhʇPZz+7) Mփ*TEmԏ^_F@-CZ( =r)SJ@gɝHՏ__M%7ps4,h |a%.YC2Oy<}:)Dkj* q))ۄ>vz[L_!a|X=>S}3~D> 8,]GR3%(y&Nl6nonmߦޖ{6Iz6%4^'_gc%IķTU P@!({l!9" SV%d BpЭt*?tyDDDIHdL&*^JTz}dD|OZC~VY#NG GU@S5M$8ɺKS >;QCPĪBzz \pf I%(?= ݘ*GN }?W;J۝}!AD2ZfOxDF˝ Y`遞%m)|l5zp?GdFt|Y5Wx8Yf,3ϋIt&d aAs>[9I>OYՃ$ȫsQs(ױt(.԰u0Y2e}כ)w<0>OLatV?TV~l`QP \?QU#ǝ¯Z"0/9 0xA z^;{AVKk YnW?Vy72777z1sLܗLd~8`[I+aw.V3ĊF,dNCZݼu':t>Cslst_H5LϔS%d]Ƿ a(#X!=oSIUχaYJab&\{]ua,p05-MP_'}<Ķ֢o~wCK߲4anL橏p'<{dzp|eMndGDcV&yASXTGNܤrPUI3,%C#0-Tc8LK h!rpGtxM5d^>3n,:Nq.8eI+uijQ^ ?4Sf`@"Twi9/F;ڲSeͯE֍ζv焺.G׭W7VD7d7>bHu۳ϸ?x>{2>_f?~V[;w 0&Z2!!UWP3\V\ z( -d)0<_LdvcP0*\k17M ^@}r+)W&O“;)' wdI ۲>=G>_0Y@!LܘE0KM+{m6:Pl/};w㫆]ʼٍUip˲PDI3;^~&bL  7][(Wbl[x:ֲ!fׇP<PP1<X3VBQgIΌη& 8NK_ "q[;3|ITT(.{ztǯIKK=] q{A׃If434޷hba!!&wH=9IeDˁxw  c!%TvP.e6dYJ?k`]ʚ9vMj B޼fZug^'hmHZz--',W  tȧՇ=t/zGʎA[PPSNwRu%Uw:RDVcuI.Qf:*R ׽i"x #&۷o+noy&ɼN}ܘRa[#7Z&!bmH0$hpd+ j2(i%DxFvNR%e]uGl0_Ucta&2niؤx3iB1]ja!8;惼8|qu惂-Q*[g}W*Ueݱўv='r+f kk.+5Le7'ǡn9cVN޾ 㵗xϗ8uuk6/.T8y7=|ì嫰X^y6ߘfVp.bǍJ:t>ֻ(k7l2vS.:<Ǔ[&i]}Sbv-wxtzZuo;5\My9&@+jRݔk&*։@Z ;x<%ZZK]^5e-3/C,e6 K 0CUΪuYJUE{]$D))d<6G烠Տ5"|pՖSji8a ӫe7i{pO_woxedvʜ[t+0•9][7]|忻~nfWfM]9V,Y?] 2B-!-r2IHzCt@%jɊRLV4OWy7G,+_[hp.Neh I+􇈫n9C"$d2kF0UL f?~ zC~ bD4Amq@[22+kffzaCCWϕ憗m#@I7Y`ް~>l;mp[<ֺҰ*PQ#B ɂKNgDظ< β~(M&Ƈ_^5Hn9 ǠVh:~SEtn<6`(<ո -^ W2cHp7A: Jޗ2OW3_Ph#lϗâQ] w=U<5)E"}aȗτRI!b ]PhPF,'"agH[E")d5Ȳ pN2 |*cgB I5'L/eX& Q(ߓ??/-Qh^pzJ5 d!'8ڦ>rębh-i[QSS/7^ryWB| j2;i{-ၗE$>[٪W^ 9FAuUcSfZn,XC}|7&1wMONJ ߈ʨїRɏVK荒ÅwFM&gE"(?/E C"]O\T91  cbQֆU* Y&"n!֦Re|3ӨVWwٮ YQ=UփZLM$;x#?zկ)h6/&ʙѥhGp괮W^r?G{|nXUGpw=j ۟vvup &Ds04/y;LAxap̄ e,EZmU KHkm"ca#TH_dzs)-`A…]t倇 ٛąg lm!>?(MN%+7T>|T5z/7_-,Sqe1p[{'lzR`삗>w[Ϳ Ҡ!m_y^ s&ԪIu upZ^Y^7E=S%_ %\|xGC' c v~dO|{qabIP'@Š5jZbXD5T&1nAB]I d['0ۨ(;1 b]Ӹz1SK BMr Zz[N0-"D1f.E׎\K> ܳ4ID&iR H$y垕,aK偳KI]٥%^\C(VsBl"oD1Hs*s**Cz, jprQ&qUFRdQ''B 8xd~R|p+UJMsH$'6T] >۲pG@zn݀ ׫j[ZfiuZ}c&t| ;ݯ pNNB$[$q[W\Y^޴| 6In&Vo7gTqҨ|a^`^f^{V`~DcW&`2:؈sĈsłu|}vK< 3R?ڠq?qec `L>|?V{q(`谽ýa9M1׷ܷGD1UM?:b=L} ac:ML =FOde_|FKӴ&Sڡ  L89^ s Z4:񵞳|uF#L^5}5s7fSUzڮWB[ooز'Tn^nYsbo߲pk\,Qʫ[O4A9W]sў?w;]s_ٶ|Btek(E $:CH1; Q~ CsC;ClJЧz,f}dA):CQ>K!ZY}Uk 4c o>XGMx8ź}Ԛ4:‹fSS sM:#5Y.6< CW#`@&fb"ty0+r8b~xdYr4p2јU H/#Zn?l2 #pGiHμ@ϰ=zyϹiWֻTА,3+ BkZlVD65~G^'Tmk:m.g~5N1= ^% <͖l[oF1駝ئ9ϣkQbQ=; lv=ڈ㼝=_WM y[dn;#rWsRE oKeC5'ц11 %#);b3c(//J |GGw>~`vLl^2z=n^RzFkM`_z1]l64{{~6f&jE/!Q"U[zx}dpJDcY<}Fo? j% ;  8ÍBvFɷORE3IU0: K:d*8V᱃r "A9J>9]"m}Xkzj{Vz@-K~ԩJ*P둅/"ns?!\K #IqrC'38bQVVK$xC]ݟ{Dcf@hr؝{d$^HV3p-Yb:sH~0(N+4i.@so'kWSԘԓ)!*PwZ:Cc/|E _4VGyha^%"5m2C1Xc~xha_,HNA]"%Y&{DLGw"-,),p\U_p:Dr;|p?=XasV)m҅kX%LFBUM K$d[ҔA!*96ĢլEK٭ r9.\]S)r)Rud~ O6ug]1L<# N޺xϦK_Gyߐ TX9w[+'^{Hs(:>K%t=0n{_V6>ݛ7 JIJU ޗdY-SKR L`R_)3i=Lz/Ih`Zz +B4n +h#utg|jカ.[$ elh^?矐"1p{h]bjHo: cVNut\^?J Df"Z59 .*J3j:ڭ.R&*PfP,cc0l8duWJHfk9% 9,$4Sީ/Wo6*M .-3Ѻ+ 8ѾOr؛w~ NQ'*P>Ilfl'fڍʹK$y1`h}ox+-Lt⭃$ p,H:?)zvdcmE︝N;9uZqÊ1 5Vؘ2rdDjXE㥰2<=O$ÇE;bHb0+zc;c'b'c|E4Ԡ рd\lkLm08YGiQyo<"I&t~t~})Y_`L&R {vlR4EZy-׋^uۼ|{{|\aq--wϳ'[Xsx 3^ abv*LcXlf6zB˧K:pJ!ȔPfo#}*vپ>dg,͕SI hNBk2L0C>$%qJN(-RUzVN*"+t۬HVE5ʤR oJ&Tk6 F²MrDž RڞjUU5NwjS![ #ieJSm֢Zُ?c˕M+Iwt!s͕zp}xmpK+3v^jI޶3L6WW.~f\XcACWT­V`ZnL;(& O >kS%Yɡb8nsBG~]#yO( 3)"2Li'q+!$k$78>%JgkɜgiѲmg,wf~їedDsW*#_Ku>%1 nBGi0 ;y@ ώ:=6dfhȕ2o#4x>0]V־O$!U8!iA OgV=4%>V܊+k5~ʞh !5 Ya ktϣt7}#Gb:ё{s%~vyԛw˔]D,x,Rg}qƔ=B{u-hjβtC1x5vvL޶]D}h =7i:2]/v#d,G\`SvQ4La)d*,HTFV3a 5i#1OѓAtаg||?3|fnr777g=m h uƌvWYIy>{ RDcK "}WP[P2j{X2bwt W:8U8+Ô{Xs2  "SgLmō)f !EKY+nocذt:5=INy=R;Zf8Ai&mF}f K`δV[cx%euh1/߰ޝ8lsh\KH yp_}}i 䪯k/|+D] M(OLŋŮ!eM/G,e@Z,UMdV1Tmki:5?gAę^o׵79Jzq_>O/ԇ03Bk ÿ֏_<"b]7כl?LZ˜W׺ˠ|I:䉫*twuׁe=wiz.vxٳ f[]z,e4 Pix܌Y8$`77C\ďkpuY:W\FsJsYrHq !#kZ d1" M ۍGdlVh-BdE#hV|Yn3,5s1 NT1% =I1.8bi'=Sd R$))jXlz፯yqՊ.2E3uYNhRqAc͸aȫP~}]fN|IsA{H.ܴya*Ve$(U QcRм;w863`!xI}?&:_qbE=N>hkTB&4&A H %$ |ϳ[4'Fsb=!TDL1&a7R?lNikSjMu _x_-U/91Y.r}Ͷqh'=>ϗ`fGORsީgǁOI<-T~>k*k9h57#yNҽ,k]3v+s1~XֹyyTv=Cgv$ 8!5Vݨڝ ZF.Zy>aR{SUsWFN- `$n8n; ~"cR|8# .<8𽚎~rdf݅< ?܏ËZ'PV8‡aIɜdx(|~@~Fϕq#e#QquO1{ d/a;EĈ@rȓ\]VB 0)l%_?-Dܒ `;Y<ID(~>9h=Ю=mC6ېg,nܯ}TR O\X֡ Z !G`_O\;p;]S7}-O?D&n|39Ds q> Rޙ\瓀=v OLr#}ݎ)Qߤ܂I \n+u'pCYKN+˹] 8[2­p n?HU#!3Sdg 2BE{A~:Žk5 VZKC6GjyB_aNN VNG'y IɈHMj"vr0(scE҆_F*ń+IY9ʨTCe+=$> Z YjK2.Knq&zn|R;ŗVmXuSw+ۻ.+\]ymn~rh͏yo-|8tJ IkUSxfj-*EBeeNn vyXt(D߳j.u5{&\ M>VRH_$jjvj:PK9?#SiËUFZC;5|[L}- ^d[*MEAMP+HCi7eby }R^r0qZ,]ZVbx7nfo={0|J*p4~T=acKؒyd<+?IW(ɶdՖ|jE:Ư;))\4Rc69f0gel`#(\ZI;ە2yŗZ\Lc00WiޥHIHFmHwχGqq'8;GX{qx؏YGGGDH#팡X?AlOOV7) !pŨ 0+`UH%y]JRPSѺ0 {1. #a*ǽrorsn{r$B^Ήr,b/KZN]Tѫ^:u=4oԜJص)y9ZZ!6].exs"s?|qpDWlZްC&pɒDxJZ8yCw[ GK!QeQ{9B?k&[CuJ6WӹLm^ajAɇlNYs2qVOӇRl}J%X1BN\{(NJEh~[zD}9Ø+ KRj\c bƚ >b9@:Y P͐BVN Ctb#9y_K$;aFb6rA] Ϡ+Fkyrn8! 8C۪nak l! h9GUIn3ԭ*~ߋ+BBLZ i `%Em>3[UYk*W] [G9w ã,Sfv`E#Hjqg;jvp,XdS!"]Nf5[488 m`'`e@nbeUl ioOEr{AX"9_8s9یg»}TH}u3Xs隱zIa13VlYڬaRkئi3(gssTR?f2|c*sǬ vm[Gmo\8aTm:x ֵf:Kt_]_qGqZbd#IؔfC|ɈtoTBJ DiUڛBQL ؞ CqyERiiӇjw&.K$ )T?z`2f~Tgp{[U2<~k+ٴ+'S:7Irak0K9b$U>D@*f5kxzy" _9gN:*i rDg 4t[Zj~僃52Bm UO\V,QXf=fmLo]̰/e8!h0 NX 獆l["ڢQK2‡r:#.=Ds*Hå{kw]9M(gtG-Ȝ`g0H).Ux?h:,V.PX 3Ek59Y4o[Wݘj񏖶7ÛԠ]AXְ n9l q q+ VI\ڃ`xN=#<.f%B".f;r;ۺ>j$qP -u,Pz$0>sѦ{Y3ݷm%\b!wgy\>V'(='o/ڽdYm}BkNt8@!fB0Vs{9AZM&Qb6 x ͆N&M^GfcؤHA'68c%Mr}W{I[G㈗x:5x2qGqDU=3 />c*\xI+Y2ٺ+-䃳xz2ifU-6I+MbbD#2d4꬟z:tCaNO_=}O,2F f9en532 k~Ƹ ~cdƯ7ѯ=/7 /7H< fN>?MC$te.ĐVܝ$αՙWie|6c;~/[CM00[/i1(ζ,hy pˎ9h&;[BTCM r`: +`XtTsЪ1jb^$O'E zR _fS;țA,^C{ ̳IЫT]+uicŃMhA6Y^6y{ {9%-)6EyRk=k| g3w_yy W(}0&bRe#nWcKIB5,w XW`n|W(|@,6ãN<_1[OCBG&ֆùNhzz\^X$>8ih>|ED4 cxї6K@ WJl@L&nw/1qHdD@T$LuNDE 5쏞|tȩYϝr^@Iҡk~_10h4(F0@0cp|#ڨ3BVOo1 ӓQO\{2_>Ҕ$6ࢆ K|Ξ_3>=/ms}"ն5͋ NE;G>ZVƀYgiko>_@Fe0C_; ד~':p{,_`W( › oc҄xSdks}3L,Î?k>tn&Ḏp;?|{{&M;y͆zMğǿ3 k2}߈#F+ 9T1|=|g6 5aBzh|܅B>G7|xT_S`<| |܇8SWϮۧprK 'RV7nvr9m:0,(_;6zfVVwQQ/>. Q!z/3 C,aB!9afQ`îdٮ'Ӥ&kvͮZ!hnOfO[m{ڞݦtlwYɞm}hpmuy|s{:p/;:WzQ}}\vcƓ6kGG}o4NxǚݲskW~m?l^|Zv~ks;]i0HGAyG vwuw?YAKFbd7 :dK9FtYѱ,:6"iM*&lfcR-Z|xM8}U6X_?6WXbƇt,3q9dܧc|c#5ӱ -f?p?,h*ױ"m7 #dਕk>GXtapE1zh٫crPYYY:F=̪1z1z:F:F"-d䈹)5sIH8p17!w*aKKQ#ؗ 4'UEDx-',~S>ؒS#Љ_oYy%qx5/Aau Nf jV&:"5J+Nj }'1yDg> PuLt\F`MK3 =F6]cc ,QAT P0q_nf,|XoV$xQڅ4QF =Wf >usvkS]?_ky~&K7svmf)>Sڼb%$3k B3N+ЙJ3و3$FQvl~faxc]YZ i#D45FbH̟GFiamgxp(vX(3<k;BȈtgh09bt{]W(GNmúZl{8#[ 2wl5w8D c{r;üS0o?Vu$á ȨC C m/FZ2C@\b#D"'` iMZ=hE@B jCЂXh`8Dh"0 G !/_is#ZY\ FŚcx"ա) #|>fAYUXUaQLڟj(aO&Ʉ g(4eEx3I`)]ls`ˏi}~tܹsp o  ?Ob2UȀOa _{_OnB>ɟ& =/A EC Q]MC>g/<x>ѕjGtwԯ_#} "20q:TlMng|v+nFe 54+{Vf$zx} $ॠ@^ҥUyX;O'ahJ[d!d.8./+X:˝՞eI~syF,S]c99s)EeU51U5=f:l:fFˉ< rwN{Q5Km>sSpai4oׄ)Π3O_%}*\ .s=8zpa(_[dWAQk7-)wT|9g X <r."J9/u5+4+ܬ|YY O!^(y6RQnVyqψ p/-Q>-Q>,Q>(Q]+QP"ŹK.!L|;GULUvJx YUċ~Z7e!7ڊ,]HH.][ +zWiҧIKW=ˤm1PHIk'KCv=._FQ_bVSܔ㾕viel>O!~?8 I֪% +oe1VVdܒ nJ;DWӶk,ߔlʩi-r%Q{&]$|¬$-ibz7R~'ob}]-}Rs]icVUVԕV/:f-0\p4,U86C=TߴcVw)F.}VI%4oZg8+m9/SFgյFSU{^R0'.sY34k^j)X,lb,Y3I M!L dd"I[䖎)UZ:R-;S+ZR%>Rf%ٍ *TO ůF'*rO|RKbkO:{RF[C[>V_T_xMxa}:_TMELiN}o/J_KjKp9yi򞓣BI_5z^߼Q1mYJ3Jnئ&՚qM8a3JQڅRRyp~$_,I,?Q{Ӵ]L0m%f=3S:tç,]xj-;@Sgk RO ״; P[ț ڼڴ?9 ~w:7wl~odcMj\$٤H(jhY"'DQE:>AZv6H-k|8#gl}%\RhyVN/kkH) aTz g0A\R|^zU7@*XQS;/'%d8iK:ZR<ӝr\M)wG?_ K.9trMθɤ KVNZYg&ax5e'^M^?1L$P ʔHV4v{,] w. Tٟ'AA/fWʦWT_l(Ι ΍Ȧ8 5ٞ|xǴ쇠+;'3g ?,^Shw"^Q♧4%V<ɤx8 p"m\%{ .< endstream endobj 1251 0 obj 40613 endobj 1252 0 obj <> endobj 1253 0 obj <> stream x]͎@< Oϴ$®!? e>N"*{rwnZ~1OŹ1߮c E5?s9 {ߦ|9zX~ݦ^8#iW$?9u+g/I[w~/K~D~o' =IWc8k%/%"^^J˭/HXA>[UI~~qagkʧqX48B61>u@~1O( endstream endobj 1254 0 obj <> endobj 1255 0 obj <> stream xԼy|T?,wzg{&$3I& !H} YePDPܐwEVE%$i~Kqd{;Oof},ssʍ!-ڎ(]~B?C\u)P!=ׯXחދjdoXe'-B]]l] m _ +ڡkzM}pN˗,~AhO`޵^!t\h-^lUVhl+,zlA!0ar&JZ dXmtU=^? #X2QU]Lk2\Ss~LK8v\vl/, ݊S&V`aeh 켯>a=k6tjG SGAG_wE68hn^$ [.)~F>FݏvMh z P#p٘ dգ[оˠ'o/D]3vY k,J܈E+UG`h&VkTt8OC>Fcq=I#DԌZ;>.ch;xcW!/||=,zx&IEg "=pڍ~x UŁI83Mކ{E'M~x*RV;‡E[/: Dh#h}9F"zPDŝ0j>DcZWV#~}8DO d  _]#I! 7ènQ9:OПЗ4Prލ#B'~#p è [uCHDGD.᝸=5Eާgh ZnlC4=tf8wh x E*ѷ@3H/i+4Zvʺy*%ߥTg##?y-X ŒMsW7+>]|xxBT 7j@r:d5<ً@wixt9z}ߏѧ0K:dA~ix9^J}~ ï]!|1$i Ed Ned=G$Oq#_wG@+`$DCE1"}~`\ sM FCY TJ?k7*䊘bb)ErRz8{8N.0Iax+EB]4[r| h'g:HqL/9+~!r ^ -NVtAFtgq5:eAN|dh@ĝ_sO/.| 1 2 sd;ɑy KS8݈Xo?ŸЕoHFd% 1 RLJr$SA[HhDqݽ;LCn% ]oq߃}e`Z E79N_ LY#V .C[AME5=5ɂl uIf-[[䛛r L]m:JTcH8 }^tb6y^ըUJ\QQU{p"__dQ NXбE}>p>}En akOxvO(_]k yBn_߰TwHu~8n_9ׇ&\}x8!-ضL]]5P@O?,Ut ngwG틗M6}ﮮmK>CBI铷).cOvU3ȣK%KKϟGwkp}!&6w[]~5{{w6~s${C- E|}U`<}h)+~ޙsVW{C;}ˀC9.R]u7yHo(W+nj9,91`pAodn5%|1շ>Uۢ^da> gqGBʘ,z_"WYB "UW ?>(|h\8) 4٨ѥ>mnCLtElˉ-Yl-g_=,y>e+ؼsFsڼEevμUxv[gnK]\#.*mNvg֘KtPVzoBhbiݭ?4X%+f_Sv nOKᆹ9W} vz{'}z.,n4ヽo_4:]}tCM;ķN;$[g̛{{̹E`c>PR/9Z>B8(Mc"Bۥ! b$)G0Z2HJ}j [!chLZ\1Hf$㾡Hȡ˾!tOP}u~$1:5GP*0p3 ;7/~J](u$ [ՠ*ZP nD[b{nDw {897Gho)?p`D1+6!9;.ߋO.e#>#Ե8Ϋ#:ge`=r*"_(\m?*-l{gC볋+Pp":<\'‰DbC{ y?mlFD",l(ZH6rj7Pwڻ^&R IٝW.womzt8vq-U쫶hzK<|s2@yl ` tŞ* G]~Kݎ{۟4)M9٦fZ54 * !Ncat2)w(eoWWégQiېؖEb-,,Ra= 凮*t+y>/===[wL H1с[v= vtӁ.xuw2o;n{ =K p~Z?%e{I*M73;ͬ8}FLpwu^"7jИ<1?q2$ji؄Lm1 fQQGy=|ݳ1d**j&1fZa[Bz9M"*m78GՕ>bϙD[.q]?ZwkmIdoj8q0%:#r[5v5[aCtK|P <ڀl Yì729©Hv^`1g{oF2zFW.넓y|xDLEU-֭?Bfl^֙h֣c9¹HklJla+׶r Ks>oV#\MYH5Y\._BLלy^2\y3U-fXhwd̢55O1/4noIFօ]b \L4eY1KZ*2R):L%uQc%z%nvH>0G\b*Ctᇥ=OñҘ ٨JX I b@҆am59]Cm,XFyQsnHf.1\o/-|!3{GLw>F"ە d~wᕛfad&⧲uI3HxcSc5V]]cӼ ?kJeUU[[l[vw=L?Xpg6l~!ۏ4m::1~eêt:?}:UMM׌j9y sы.)f:q836=5 cN݄Qg&m4M+3^C ፧,xJmn475ctLܤό-͝|?pjG8.곋IxM`nbllmfU7OUcuO$p_`+" T ARQjVVIMQHf2w qY3յ96>,uC"1ܳcKL[VERuKl kOxy(σ )PKzdS\Fq˓gO`@A TQ*ԯ Kzx>a?z8*JJJLF*!쯐EÙ9U .Jp5cy{xh,q3(QN>quN^2/CξZrPSӅJ{ӝ:೓7c[Jk̶z{f4ՄWڜG{N'"vao\6pI7*goE#MJ^c=I6nl~NB8 zQ b,\+5&h$nSBa⢺5RBqc32jH/z `b_7^ݷwU6E9{٥Adb  دMRWlN!0ٚ.{$`0tl@b $As;@'c²]- iZ 7.W vϩ_aLo޲u|ʟ{򱀶Y-@Uŷh4 X|kq8h/ 5Crzg?Rh0iӺ_u Qcz갯Zr:Fjt:+ay9^L{+摪x3{A78:Qz y{CJ^IL3T$ 7=D%9w'0ec2&U* RT\HPKT[t.+ ǥ L YT5E -V'گzGH!)tݔKI.n- Y[Q1ϨnUK+U19c 97esZqݼ7h~ bݫlzGxK{[2烗Ín1yɘo2C*U@^y}+}gc}̥G\VX+ @RXiD!jgx GeVW${^]oa.;c^ꈰZK52%0jLH@kMW:O®xN>շwQF_'oT DkgI37_\nw o͟v0%1P FcWMdE$U5J6MNSyG,? ';5eR׆/>fcs|.9wɖC3Ac-v C20nS[=E_cr7KsS>Azd rWx\Ye+pp=Jܬ9,69l<0P/%E:0c,jM6>9a{FlU) 6ژ?zcuwvl_Xa4-+4DgJ 8$DʧgM}>ݕ|b=ۖJ0EX(1)c"F(&l6!X:[4Y ۸D3!Z#5,~Ș55Xz6āX鋑筌RD)AVޚ;Z_!P݁L BSɸ%|fܠO*Xյ%?oTIډ45_*5X* ~4ڇH HX>`ފacF/0a\GIƒ HU-2Ċ2"W= * VC( Р`@e ~hjVg  fqݔ^cYC?'.?j讑yTVŻ/\v޲j?^j8icE~V)$?!:x/!%dLó9ó'׋QOx uab/@KX.NJ^}^uS*Q5UEUlj_f18>1K:*pͫA}r@IZIOA!=,K ݒCt>Rh#9뜜ÊRj}ۧ#{B1+=r|H58y|4<._J^q36 בkjLZ^/^QQAZYm_gzwMmZůo|N`LL2[&q-~{$׫uUݢ7Z]JLFD䔑T}_i+UH#GӢ*m m`N@=%sg#c2|c]oL3 &C# *尉$,PHx4#À5rBnTY32/s`4-n-aE &xl56:IEl)9I1Fi ?Z:~Xng]뺚i7:UwuOpڌnsM3\Yi 7ZH&>֮D|Q(Wo;gSK?2)|eD#$MFI<5fԽє{#OG^_(^`@*nҭ-2\sG Y,s˭ʅqrq{,n'Y&5:&6ҝyܼ- ޅ"YEi8C^wM{_q4+P=t$:֠4ʘ sTv_Oc|1]Y3nMO/Hamp=LeJ-ٖIyn#x*՛o̪0ub'餲l1}̗ L:/&fl [uR('9V=b <#we<,)sM Y:5?|Koj1f+=h:hf3.Ss25VB:aL}-x̃>Ϣ܂%op>LTMT&l&@nlTnJm2*oL/3rRh4T^URuvLݞSJdYb]V%뫒|XvmՇ/aOO*a0J% lF@1`Fܪb`h ,E3_Z>3+%ئ*6htӪKK5ѲE*R{b{r \(0_~ o.@~]"0Naa. ,?4#tUY/xN-# " !yݾ1jsT0|Ch""}.1D^Jq%mqF-a;;>MtjM)^;^]=32<2|Vn:uPrwI}-8aZ.1oi ٪]<;%-G % IFϋc ʨ/Af]:&]e|. [yʜX8ɯ '=>q7TmYDa\#r|ɀf+T2Ee' cUL|RWc y>eB!G8kkMORtxx'f |KmKuuվ Wخ^vpoN'l <}akU_$+DZ8]upvE*qƶ&NH~K̲Ar֙ML~O^vc:cWLyl?yYϯ?3?sI?5X`嗁P<:,()jrUc8qȋE㰮Jbh=|1EF \aL\*c=7!MeJe%Zvk.B,^`MY;8"q`k5:une.ʥSɤ̝8N# ҟ}!O)p,Hz=ؐ6S`1$0u@ ۅ>Q0aamAQ}fk7)";ҏO4Si1Ml%7:StaА…d|\$!wQ^J/NF\(cg9[@#4΀SW0-뛣PU˚~w]orlĢS2бQ8Z}`xFok;)os;鍊*YR)S&]B><^^Dq@)ZLq)`gM`pMT9  RVK,BUKuuM0)F jMrU3S]J.TS ! Vj\R C*A<IK+A))qQRdg)'ŸX%݅O'%Vl1 l'Wwx|Jx&ULk3Y7.6gO'UW;:rwf]}3&RlhAckKGTz`_:p6&72dԊ]܃mɔJN M0ƊTFd+@f`e`ŢM.U_ߐͪbx}}!eč 6m&5]?]\U:ox ^D"e(U<8࿸! ebC6T2X@3d#5Ozh|C8Z`rapWuB+N<%IRZeIJ3,6Ky4ADh[$wn+v$풫;errg9SOe^nŹD>IX)f|RR?S``+c$3L&!Lv/ igUTwFNS㯴 t 79춨 |T| Ky}j-f sm^+dʊM 8Č1hjuֱߧ~R}Dcc]GR&UbNV &:BGh:-!"- j(W( !pj1:"%h™%d1CXq=W*LIwU}}Ki v_0E[26m9-,4`haz;szn:Xuԟ~t03Ƈ ?ߝl: ޳:Y{~7rF"$K\d-q*ͩ[Z K;ܢ>b93ZR_3 |Ǝ XmԸL'ܕ&4ݤ"0.vǃ1wbt%(&+R\NVx+Ӿq1MZ 1#ޅP,*RI,tT7(5vgz~A'uϋSp+I{6SnT%:YYr̜.+_ ke6(p3lJ.VlO&XC4 ܿ"4i:P8̓,پ*N~y\mut8F;үq^\NVbǴMϭ&83/Ic,f27]hVKtl\HQ  Ixq9O,/,__ j+)p:IeeElɋ18ޘhĖJz',mkmR"Z.ZSp[x]Gڏ㋐^Kr;ZLζ\Ӊuu9q z q$?.ְ|&işu\0"B!f"2(H|.3ΟvFX|40h4"0FD"d'yetSgh[7Dq-U>_ȩךuȄIݕɄ)5W#z+|oWd(rqW>ro$)z O`d;g۴k׾嬝h~ub,2&scʗ*_wSl=ML@DBZٜBf[R`;Ӣ>HP'#61^!= %錄8κW;&`2/QBf(XxTqq ~6Mvf Hk˝9.GHnz6}6̤q@r[y` ކG_i6/vۢr 4 sf[E=}]?v:lBKU{ƆFϝYrYf͊c;k~>޾ /ld5Nmaqy󤦍~dobrl/GĔkV2Yњ͂5j]NG7 Bkv0[\aGYM^E1ƽq98bbT]BZyLРV|5\vsupQJ8-;0(jĘƢxotZN}5kL:n"P(986]PkZ(…QCln'a:<S{9M"YOw;j Z"ߧIPP/2.91L@q@Mٸ#_iPrnF>/isY`JI(BW9iؚ:$}6Y|r:Q3M Q <ȒI/5Qw[m՛i2U)zvxOBlG&;t*^pH{Ō]sͅMfOdz-Iab8#:F.𓊧|GGjZzQ^\B?A6'vMqrTw0-Z4&mBB5n@ ekDdTA[<& @0P{Gæ b>ln66]gqɣq^TbxJQv6})g;럜1%+RacΔp }9j  "xi-+YY* (oT8s;DꗫG>Ҭ0[چˮnb#7@aMJZORnw2X#y=eWY~|Oq!s{WzHT!CyΖPl:.o[oku+o%p\1n$xʈ[W]JSeq曁~|]#6MWND+'%UٻV^|+l)Ӝ֬sk5ڭqZng$?q<@@qS,r#ܨ\JS_?pgٖR eT4A˩t{nܶKU#Lr;ఽsoJ-Z+>m|UnOm0ʹnzuu{w͕T*%e?FQt m6~|JU͞[{x瀇L܀ U]ʺZER W)܊i xQgBWeeFlz-bj ~HJb#54oQ~ v24O {lY&k~'p?\rM.t/h^m83w2i$owKS:\DiUH% RE9˜*?t*IW6ѵ5rkē I/J5fjiR-M*yJŔPqVzï%"~ k? «IjZ5To#Gg}^QO - MW~T! S!e bj8N6*?&JӏFFC72SJ?'Һ ؐ=YF3-U8⪪g#[]^v1ggٶƜ3Pʶ^<圫ssl̉"H1{mm_X9F5jB3gc K!CQ޼I.Kڌ`MTϾgd|+|{bh9~h tnKLj;3}/6u0 qE܈c]Ͼ3_m%U"ٻ\~)ߕk2vOGXNKP$PIFo31[2 m:K0c&m/*<6d^9$:++f\\7XX!=^)~\wH7<:T.k%J:]W-7!NUfjMV{}~E񁋨Ճg7QCP:rGax,C^}D^|?2U2Ǒ}Ȇj;Ӫt0+UjpӷU~ZUZ/.\>B#"a{QvI~$k8uȈW.1ѵI^v`=Gϱ$S96Rرquי{.w\=Գk2ąjPMCsd/Up2ΌQ:!d#]-%tuzCݫ[t:?B7 i4pL=|b튷īK//1W=%MDzR vy])(0si> zxl!=90Ki%uAz#h(>T)?Zt 8jk"tWv_Z:m'l:u&E4_IB|;o?;3wLf&;L2dfB<2 %$bH&LWPXh- J nkv_?EVu"soBh9{ssy9X~·:Bj_w~q߯OE£)1O7KNfۀ9゚Ao˫ps% Zusd#A0eMZ>PJXnP uSv1V }yy>i˳Iz[guj4j>?:]3H`' חMZ)wΨ#9ChÖ>ۂ*֟d3.  eBuU1Pi#܂H?p]%xMj@eͷl,927oyơmnv`cZJ$rh[Shb>ݙ[bbd~rtn+j5ĸ yUm,< GP4)-UUXg#)[mIgeˇ;~;! *Y+\.)OR.uACvRCh/4&a|L<8wfrq;WO!"Ն$ g#_\K{1 4UkFO4_b&̰c}q Zż?c]kJ;p~wg7&WqewfD8 ZFDo YRWtzW6{[ KlKwPλ&aۄ{lm[b)E*oe ĺ: :R++uI]'Ky8񂵲#a\Yѹ?WB?H!o%g-%yYZ6' uo=rXqDo~{š[}S~[y>_K{WϏ<'3TBmuR =^BG T!3n Y-A6W(Vĕ%!5oBϣ)$?:_f1R.g~ÂJuӎlMg,Hꭿ`g?Yw؍iE[ɉ|2wB ?ڬc)b c+7%nM|=g4/ s#S1벲oUyy] ȍx+ш4"^2>o3V[UV& KjuqyjpT(SfKRIԔ\Q)e{fu&Y;=bLU5ϝ;Y^%q@"w{asɔҹM ʤnt1ISz@:<Z<4p˳Ig`t䖌0 gr!rw5WĽb0RdNoaE#.^yIS~8jgn9S{o 9~AaP5|?߶_۷aOQ7ryN9ͅl@¿0#;ί0x֝,"1PUJ5D5`,54`‚t#:N Uj3w>*$ ƌwet4u=ewF7n0ޤ2ƌvaxi[^cFS-k=z#_+Z==ϡ224=y>zԝ02 GDEktK+[J-v*5#Jc>©BQ( u>xX8QjiV%I6-b,cb@:wx4"x0׽<&oq2lAK*RiyفYё';d_闀+1< Kӡ!'Ϟ /ѕtq##3i_)_H7BriYMtȃ/kCWuhBȿ}:.,U:/uw-_:c]okG}uރOu5V/QGŵUz"7kF`[̽Ԋ߻6." n7R{S%UgR&˖(6%( dM49|-FYd_@,[r =9UB0FoNsf?NׅgswV8z<81l ט?.םzSD9s4J{3C eX)z,(Q(m S`V(HIIID̾Q)( q,S '0tI%ڙh{1$\'>k̮\d&~xE18iF@[Sŷ֤ L'"yW)l46*LZ$̤ >@S=^u54JS\g_bpvϊ&:"N:EZ Ԇyȭ 6Ltʭ! R_0>hH PW"s,U*rKo׮OEKe^K ƣ 1 qbrMFFۤSݥ[ IiwTaQبڧRq" fc9^dzcWdXc /Q#?!1} O?쵾_!mߗf4uz{T<1em1bƄu5-ߜJ+CXXatB֊8)-6&ZG12⇽{UX=nvݟ<šΝ!tg56: '\g߃:> lز%myTJ]rΐj.AͦvS;흗YtbMjD)o64's= cuϮrs?@)VzNoL:wj5`5ܠO$~*Ѐ FZAha ÿ'XuN"]5\5 H:d5h޻|s`3e>u!PYb\D+1;gų] DCm@r`v}ɀS,rsZVgwQO /{VR'M-<&tGH5s~s5݅9f05h!q Ŭ{,)0eX7*?q/`D0?vZ?05G >dwd4r}cݫhFAng7臐iH tވu9 y@20vb+[@I‹`=abؕ8f-6vǐ$oef t)O(sQO].Ѭu.=c]/XyW7owv6NJ _<*a޽OCWpɒ=Yʚ˛˟pXG ThjzC(Z e3f9)%oMw_Kv0znPdX8&JWɰ m70ʰ})a=yfU*f0FFE 3HKYT!+N˰?a%r(~)*4]GCY)j4[9_x KA/dCՇVEar_0]!)ͰE94GaQS2̡ oa* |cTAq&^ ~+m$ƿaȯqym&g)l'xS TBa'cNA&QMY SHЙYHa?c. ,魔0KXN 09"c &4J?% IEEh *$-W֋/)/y Rnn(w-4ur0Kh!ib9#RSvN:YP;[!|$DYD3d=uRTcCKi#Ï?}7;)֎J居;@sAi3`wr@!%KheI^ VZ抴Vr/;&ʹ~rK>]'DK?oR^;'ݻ?! !iizL@{-nYվn/]:?#vtlں; ځ x [PW޸p]=N}$Qt_/2)z`5 7 vA-2m#DIIM D@@ؑL 4z.Te+rR[/;z$I_Sm|h'Av=گ:?_u~|t~2oԓ[ -/O\lY6/%Z3_ +I-x5"q[|]վr^Ps.n6j.~%)_1/MԉWBep}z~RwB ; p i|xgVx<|]p ױ'P L ̓`(NLJQpfC%4o`y G=BHY{64j .-]aG`v= <E⿫7ؗğdO0%:ƏG;>F&6 =,Z;`a6ᐅ}.{x=RAqJ' r fdǙ!r4:;dJ ކenO4v9HFPgD`z[(R7듨'OaS" .C<R <~;$ȷItd$m hD®]wqC9ށ;Sܸ%0{9%'[Ҫqq8%Υ3@劸)Lƕ҄˥6'?p,ON긳uA@u;I~(I0 $b '6C UUTj!%=d{}$KْuD)"p"^ 5mȼx,Q-;H:cnKmB;ċzRGW_$.(:Cչ`,4A\,w0;H~(U2SO0S {=žrze6ֱ լX_ɜ] `fd}:0;u`D@!%P4d%!l2g7?rUa)`ԘA<χbSZVƇHgR)WR@RwR.oM[>כJhLgj/vY%'Oݢ~IԷբQ,\h&cv_x8߈ԧ0à<$0y`Rel`8|Pds ',8Ǩ> endobj 1258 0 obj <> stream x]͎@<a3kɲגQy c)ك>S]DV1T|S8KmSXK?tsssCf$vIWޚ)+bq_8\:+{e~OnKs V=x_ϱ1\p6p ٺ,7pdaWXr?9ZMee7Q RC{+7nWh햞 ATK @#QRCW䷨5䷨5`3;%uWڟlLLZW/dbu~!G>B~B~I5x$ M~)<#!&G&B~LKZ?"K~%~K Z;<#GwْimVړx-]K#?2t4E3|o~s]XbZ!L*_ 3 endstream endobj 1259 0 obj <> endobj 1260 0 obj <> stream xܼy?\U==w;3;3{g.7,E&rx(AM@|E߰¢1x&1$KIBL4Yc$&S=&Uyzz dD[e/x{nA.[wu|+#e+Cc +߯AH8%?_bOaUp]iUFGW]~58~G@eW.[o}5C}Kaoz芥O#_FqV  (9'tu&7465O;T~ȇo{*M?ͮEriq-+1Eџ.*,Z4؍<EB,֣*$9tlBP-q AhS?@ףj8VPSCsQ!Bh7GXF mCϣqQ"c_`4;][ }14NOq^#nPP1ei ν'בAך*_Ǜ_FAГ\?Boaz,srsy|o؊A':lv l>KD& K}ƿ@+E\nD7C(3^83gv>B21]EK滚Ӭnǥ0t4 >Em藘>ti1^woGA:>?"nr;*yJcLI175a/5KJ7w?Qu@k-íh':g@w著cX0;`'p5)HEr323f[؏|L=cPiuiWix"gˣ. |:h#@9~zQ Z_V$C%L`=YOk`eZ&|=0??o'Ld$2\LYLmY #1 32?e~k&ijj^|*;].cocd~>{F?zO/ǵ YpsbMdj$vh1a^$_Nw4 DBooiċ>yUf)6q#ӪI&H p XcBWv^.~F%&/{^7-Gϡ;a&mF_wɍuNMq-BIr7_1ڿ9(=pKƇ~ /&  :BqXJ٫)2 ӥJ9T df(F?ŷ_<@13ohB.t Wajxa55KB4LEY/gGx&v@zaw(|Wh* (-GG@q 5؝r=C'Ak2?ֻ{&]Lvg^D؋@V9X+yr!?Bc/BF縀ϗ0 4V*(HhY(olj@{5z$Ǹz_ոO[IyЈ3h̛( ڵ xa8o ІP=&4{f^NІfy ܅1xj(MўY>7 Ap߿M#44(])m-榆|}]mM.NUx,*G!)۬Q0Ns!UȽKB%Ú"KK-fkXpî'g0{s=!Zݾ}[hx ӴƀsIw^03.M Mp}T[!Ж%kB:K^}Xa ^rx8[ ;}rgh6(!G2ψ>c*Š3Ԓڝf|bzG4 в&+e 15Vd{v٘(ѿ߲O-R:9Cjp|gYxi}"F׼sy E]Qf }cQ3)4`į+D)"Ċ6{<1J, Q&ec:ހ"!.%` `Z*)=S)-@D$($ $A ђ?a!(G'r/(U:`5qԼ:S0Ð4W<6GHK(E$j̴ؑ M-y5ժ9 F3?61{׻oAuUC鉿sk鶱(eL>@Mbq&FE DtYp)Y$*QQ̛Uo`ΦT_kKDXtmoWkcc/o ڼsIZb~p|eFESc6iQP iIWexq.>Mo5i/V< ḝҊZM!&et x&cohm\ܱ͑qET׈'5'|fggE:ʵ"ѓ0''4c)ޠTER&[4&gW% ™c[bKdy5j6W~؀w02 7Iֽa+vZwXX[Y+_`&>Zȩךr7>1)h%#hv[֤FIĵy& H@"2!ܠ,3EU v>Fg11?OMQ@|\Ȭdg6Gndn6hCҎ;VKS&im 9ug}qs<`4t" @N;W#aAy+nK"őF4Pe"&?㓣@lKloÊ W`±Oqz#I( }~cklf55݅ yʂ-{ ^su`/'*u3 h̻LW w XS&okte[:`_?yP;345=tt״گ= X-j_A}˜K:\#-/zVf8JV\WituU:N?UB=oUmWTz@=ok/i5D۪ݨUQ_huO;eV-6ť4\kJvb.GJ2ܒ{J}{O[1y75l\ugzr[I1SYN #: DcKQ:tUUu/&T*r,%1KjXc<PqMgwm Q9utc-sp2(ݱ'Q u4%VCJW̬zc`WjwkJXw.Lؔ}iίae髙a48qC81ԯ߬7oL>yN5Sz9G@(DsGH& Zk4@"s @4"ky>NsLd1pg6 fLI`; WM(ІEC~ F4 tFdF VRq6W;8$~R\^ zLSD!Csl{bmBi\4_uyC[[.;JK1T!UtVUʽFM DsqzPq8CYl fYq/ϙy= fdbz,oJbģRX裒YQ)4B~8DTJr8޳e4cGƟS.t7`PiN/.pة5dJةeN , XGvj[٩eZYvjevlB2 dHLźRs$S2++S12JQ_&T"W8??D]J*SMD15&l'*{ZR ZS'Ӄ9VqF4S௢\j ;:55O( ;'. Q5s '/B_uDG)i DB- Qx`12au34p!eDTM6ـWop8GWwwkq5I/V.釂mO۞˯,;l1DqL42ls=-gwj Ӹ8UΧa8û/W@__GU17(= "M7jgRZnuTU@sh0JgҐos_ Y6EzΝO4q.Tϛ4v_ހt羻&^z`ZYj ːѯgZCY_VϹULQɢA QR1ÜY-z}v?$F$)vQKU\ I@]x #"MJ/HpP vw@Hx &h,$Pө9Mŀ*@k|‹e7O rquwƌ"eԌ"h:P!J yu/N"9nˆwyP4\ٔr֩f y+Q#1 YȴXȂUr̀ Ss Wly4RE9EoFۨ C&cP$&CAmḸ{ ' x@;u r dAlӻϺHt`ҽ@< O7nq80x Ii@o1mv@~ _ouE8=At⸴'['>8Z?e6Lf =2/_z{8=e￿8e'ҾpPfW\ߕ:qMY~tHwJD@3͆v\P@D9-G(JĐbeXD"šIYYBEтQ8 % h9O(0zN+8y|qVCzOM| %8㡸8r1b;kl6/Uc ``QKia9^+UTp#qGi /mm(e~YiȃJ0 3.5i_z3ߜ#5?oڕ.Dm,fXGX)6]?[ U#(R~c٧"CaNvr +Ii B>M/V9V K[8\}e'CƄXqwh +Ms(|Xe3,i0ϚϪSW<5zE??,=}0 ^ ׾ v-5TvO8(MǞm@>:W3} 6/vV(P/Ie(C{Vv3SS"K"Y."|,Sܟy>9qY%(((JT~0G9bf6`w}["'"'#0"8J#r<D;%#E3Yc'p,S$k!Pg¦k퇱G*@8F 85Td"* ()nudCjībT'N9Qp+&24 iw8 OE#@+3aRwzlzם:/^ŗl,//ܶ}Ν5Cv]!#kȽc߬i힯RBbEJs6)J'TDn"F+2Ӣ`J˽*S1|W3 >朔{/\./vS`2@ٙ drI|LϏ dMކ*ICcFfƸŸӸQQD-3~l䍞P&G1GElL'O 5S߳b4FwoRDM*i^I)JRE;u7uԫoHBOCp#w ~`ֳOoϷs $vgl1&žKzr;,jt5u~ 5 _Bj8 qC`7ep<銏-Q͕ݙxag<&DI) $N E*u&TH+G$ud}"7u R#%`@/yiC;cqG%H5%G.ZBjح`#$ɓQD.KVՍuqҸrӔ*؄IPWyc*u7OjmMo¼1\Z}yw.>Y9#KvsAy`F9^"DiZXsZLBIp 7J7>R > Olu+\,.8x$N*>Z#z?oG-v=t<OĪ!Iy3 \叝IS%֨9%/d{sps|sjf@@bs&.n{#{ڟ<=hV:ف]5*Wc2v4!%u'"_@xwϪ9ovO,kF9_++&-.=<5Hصn6M n;)}xca_zxU{#~CA 0hȳe9'4 HZ23d&>lQ\%yDL(L@䪨T-"J  f^|6Q7Mio)-@D$ $ 4lcSmX6l,YdIVhV|>ي'[d+>l>3*qՓđızWO"eO8dκ|>s\> ?>zJ = oz{3[f1Soޞ/XpeҳdU{)^ZӾՂW=̱^mo']5S2,Dg-sG?PUkVu`\ei`BH^k,MI_X$d_r 79K8]<i" 0zK$=e.^S0`<"_k@hst1Q!M:YYYrOV'xyBKcrT@F޷%O.3Dx}o3[6&.U8x{}cM #sm~=\ZYnZ{yy Wb},[Lnaf֓]jkӂ:ъ.ѭqa향$7RC6hFNMesdQܷv O|Yr{?"a@ ZВc C>/l?N,y۫ʹTƊXLU VꝀysS\?௘.o)[o 41$HTqfS(}mnk{D_n(13U 4YV. >~`)Es|PAKZ8G\T-`+Wˍ=ۓ㴶puɃzpZL<}Mi/`E9m{Vl@B4:!Ka+/ "jG->ej/zbN޴N353#`Zpd5_qS(QD4 U IWe<<1nh 7o.贼eQG.Ln)CQT+wud]c>_&̿r*܌i߷L<_i?EN?|Zch "A(ʆjjS(XLgf;IeZ U㭏 )A쩫aFq `E3Y'UZԣtnTaM jFz:nw"qWWdg(#4I4Mΰ):kaW6u5FҺ Wk ꛫs 1`Qزi-^8;6.?JwۦNznj6u}hF{o8kj_H{ ^Ն/rŻ(-{Q8[yH9*FCm7;o׮nljy{u|zΉI-Λ\7i^sUznifdX0v',V3&8txq΂-ށ8[cWuB.З:A/~s.ri_ݝuBݙF Ľ 6o9:fRT-"deZ;y\>¢^~Bl5_rj,r. F{ޝ CɘcTj Qg+NGGB5;wm.Վ/goeaxy\υ=~SdU5=jg4AC;Iϭmu l Ɉ9dM!:Ù;w9Xڪ$$qk9^>( <_J\3='8}ezszG6}pt2NRZy*G5F&צP8:V١(-`EUjNA A*4:"K*znazNDwbfu1d]8$ ">a!!dBڤ*KUG5yRetx*g8uHDADXw|ޢ~FgOL*n(qw_n NW̭~꯱S=rvc1Vڦoi]O:,r|1g^Ɲ;"06q+`bsƋu3cG/EBT$ҢЯn-R˾+h>#<?3/{y<A''FH#$$#>P#nDU:6dvBA2HWGP1gIQzz hzBew\D,^;YQz&OMTZkSi#]I)L.R>p3DqtqPI= yM}ᄖE*K[9UJdkߊFSo rhkdZi+L6tϴ}h1jn?{1ue[qܼ5Ҭ[[ifsIƲ9#L(_ijm4=d)D_3qc!z粯l j+}N1f +wQʹoH.):1t*=#Hio=m"ROYb N7"4VmVeJC_$RKŊ$pWEmW*0' atY60oVLkhN,*}=yؼsH=@!FiE2e]LSeBtR;?i7=NB"ǀM(RWl߶y:]mty]%U^}4MU!ic9%u7E26=J5ξ{-6~d"^8 29kuuA۾ 8xX5S0B`\R@+P>H":k|>Pe7*6c=q%4$aJ.J9M~)1@NqZM lgT q[ F?@2LԞ1Y7DDA;$J-"b,b ZDg\ᄊݥ7?t^ڳ{JN 6,{/ȣW);h3\Aeƚ0Gg0ÙN\[p3BZLZrP:ZݘjL_5ykHpFOSh(5'jP@ IX(+z G2-hAY'K1%#y_Z'?FUIƹ5 Nx,~hj:,0#hz0P*Zhj@ox4;#]( Dd7^`@U(DDAh ,N)muxD7;݌;$JNI#=SMy LYWIɛ䯘?e#42IYfUdX~ΐqmuzV_@|U2R.A!nn>,}2(b=i I Au.M )`PǏԣH.=qת^Ϭ1{s3@ @0B! m值rL#ΖQ=IqM׾Ml>CΔUaTTԍ?;ZL<1+0 $+T *LXvjvP(Q.+uMnT)ZYsnR''pgYlDc=Ȭ9Ksc\,F+ٹnN$z>p,'sDzQ1˞S= +ߴ9:ht44][]][7{gUٛQ../5ޓ{=}cQM91g挼9 qJwaX5،y[f*q!U* ?e^FuIe!vjDS.{- C_"cf15k' ߐG п&mabab$: !ԃv>jņXsА#<{|׫n2Z;wzwU=Xl<[qXy|5 dͧEp`W/"-uNɌ^!s9+\ު AhJ'Koj*\5A{h4_ѽ!Zh{S!qƠ V4<}Aap=p\/Ij9 DgJHsŃ*7L8 t)P0:#;`sA];+eБ B/`Jr*'0%}E)zKgN nSr,؁r:cRtPe$8Dpd) )Ts&0̜#Y '%[!/ξ! {kVݛWfNYN7wXyv]})Cۺ5U;eM]/&2埙q_%i VMZPd)&OTdR{dRTj#_P8#CҊR+zed<Vj+z z֪ݦL8?ɣ{O=2U3ĠY$)Gioиw9XryqYrhYnULX>ȅoP!mKȗ&* ɉ2(<YƋ ~+ZzW"0PK8* &^:øVaOoI]PʄKy9dsA%fqk!)=Pg'5/ObN!`];V$OFd@ B^{440axB|f< 7Ɇd (=+[]V}?o*LYo,~ B>j FHKP'sfM,wa!/,+<".'ۘc‹i}e$ȇ|ߵ8$Rcw9\5Ms+^t:`ոFJրQhBCЖh33,z6l҄4&aR^NxGAnǢ~-*4ωZڳ;lD`oT~Da& AZp\3\^'T]ӇȔ@~yΒvkV~K_2hc`?fԎf71 tVǶnܝ|NsX?y0qz}+p٬6%uIY*ݮ)GXn256%"bZ#iUС1ڡ8L#Fu)KJ-N[W4ʴ7uO [\u5LJ[4eB_Z.m˙jl]~lk2Jo[42sCMշ~K#_LoKI%mX~UZ XSwǃ }[KNÛqa-ʿECrߪ?{."F苂Jf# 'U"\O]N'|7'0B!V ὘P(fpmsD>s{<xgrlI/,t1K+cs4ЉL)0"77KDL# 5s~0];8xk8~O&39L&df2 H&D!j $ yN(uzB[Ū ATrR_J[+E I9 A釽^k{Z眽?NO_B&A(]̨.E:RFJg,ה׆̾Pdzhm%ؤPtcF~VJ9D\'J'#; +zj]Z ::mNcis{=Sny`N3D>} N޷+ hZ*5!?iF ӑvhg^br[ЋO%pT$@>DJO &DT*KKE%R2 H15PL7('gFh]D0g81:LtN"RX Kb>Wc4hK)AsʦyU}@ټʮ$uSP'?#`Ib=hu9.C2Lfe2И!ah6PCVY$M0cse˾e^(&˾~')>b.6—:F^y^(;N5-*ox,v]<=tNe@:WaUqV>Ki/Uyw~&;0gF'?%ߛXEըd-*u:|o6苊h+9Ld|r V<] ٨yLv/H?`֕)mnwl6(<{ 9ӇmN2r< 6/% &+#KGX?EU 2>lɖLw/{//5@1P JD h #EV[Xt_%?J/?ԧ3Gb1mvqW/tsW"OiGҚÑW#V4s!_L9S'ҳ.+kUL?~9Wt4ZB{5Uu/L=w޶s {0|ۣ[Kn|ka~:5(dLl 5\dӂ̂ !psb=B?oIJ,!RfAy|dMB߼ܫ-Aǰ/X=dVl9`;f"6j7dg;NJ\%(ϳ E21L0i]"YN9rvHœ o|XrI+0es=/}R3.1S>/#>+oR5[]nmu,%?/x1Eu[yLx~;xWYVɉg϶L~VyJϞNq֫6N1s2avY3[1oH7[TW % k|㮬Ix \SO'gusrl^n|eo{l[?4US֮l&{_y%9 %ԿT̸Ti;lmגF4hE#4(%rƕrKZ fKKZ 5yc/9zʇ1d"apbQ/4cF{K/)2g#J6][ p]P`*. 䣄.UVE3kzeZζStSg}+-T_7=*%^~Yķn`S>%xXZG?,p{x͝9~rq>56:ee KV\q;n}cNj'Gٿ~/_59u@sAtd`c՟iX_js?Z_5MyCoeݿ%kj&Zj\gAJ'q%XRqF$b`eϷWU8D+/X}dF<̄ѯQwno%T,U9Gb#'*Ll䚭JTn/'~V/;mf-t[ɮLSp =RN,'ӜӚӗ3cISX 7x.u;ja0 ?O tt̝<6RiGG}dZ:V<>믭vY_E%RL,O4 WSaҺ2=Ss8EESdqemT fIB䍨MQz+a'j*e}WoK hʩO-t23}rݖDZ!TG|BArHε0`֛`!.>A3qeI6|} ߑ|TM/*-TMmqlc *UUEY!-tne{K}~upcs ܾr83yb1j~5h\V/Qb4MirĝKM4n}x<ة/E-4jųk Omp.·0n~PdK?{k7@ZX9؛ ={3g4>aV>O(㖵.pxV8α+:'3/([|{-0]J#@k.wp_}ޫ澱[uL~uׅ n oe<һ=83~<86o4N[u5kP3L6kf~ 8Ww?*Q- R~OaٮEߢ7Br A2+44! /@ g1 JKh5@  7B89!>b8<Od?nNU׵Ww7Zz!c$JtTUw`0kLs&w,"9ۏ osqOM٭97ޔבw:d(~T?W2(*]URvWdat0F򭪶$CEkan4w5}!5FR.(OG4EhJ (Ϋy\2ZJB֡xJQ OĪ|q_DT#fJ$hT*- ;*Af͸Jk[#֡ߨyy*m@KsTڂπd,P˪;~i-BzQi 8czӷ4Ji=_PiiӿU*TV4߰^AJ ToԨ4XҠ* 7ҠS TnU iPiŭ 6Yw4ǺVӬObsA9th 4ЦcF<NgBJ ҦTi6ݣoWb{6* mjW(JCy{8-r*6UMS18* q(:d7ש4hx\341i^/ǣ*3ڬJY9řҐ} I0Y,uNv@ D}ˤfR·7MBs Tv |jKJ ijT6Nk.WiHq @[!:oO򭙡9v (S'*eVC:Vn٩:kƤBZΟ׏մ$ըzz??3{UO\bkx L?$Mh@WC~ujځY1}WC..;x^tnZs^py|(5`ZiWR%lVe)g#ID{6w=VbL^*W'dz-]>צx7K^Z0K&J]R<>+um|$\.jo^UjCK}*rg7p?[R"Iәt]%RǶM,Y=ܗ,goguL @@)3 T6.ȵwGOwoLmJQ;$o/dPo(%wlg-}_PnM[j.N!l/g'Wy>r|}wri.!C? 2YC ہ ]6'S\55xٔ|t >x.\?-gP]z?uR)\WTi.n!J| ]*V|}/DFX , UBBX$4 ՗7|Zgҙ4!r8LZŋ71I3w>h_*߿wT7t5RZ0q O<-Ƃh N4 @ Z%DЀztT$ebj\pyqE?r8e`(^gO[8 GV9.J??L|t+rIh :3MC5Ӡʈ#MП Fn{ކ2?Mo3C>}z Cck|@z h/qwt5ZO1pFS!B9Jg* =B"E$]hEv]...>149j3 lT$a_u0v~/$?JR:ZVg(z g=q7}x͙ZxL7ϼI_+;^v&9Dŵx6^>@Fi-g6Q[&j7I&۴4b75iFڣwfmO;ݭݧՊV -!wapwsc=>O)1F@/o}Ƙ!<['~|OF~2^7<pͤ)鴔{ l&CL.&Иd2[ZwkkK|}#>˓>K,C~~osƄoyo -*Dvw_Z_hy`BBULTL@ c.܄G,,!Y~(Y,%| _`=qܝJXiɫdevwx ayB憾IYwt[GNp 'ϧ5GkN }'ޤeGNyj }P ƒCd"-w_ zZ <"J8OA Ġ9ē(0D0'P/k endstream endobj 1261 0 obj 26628 endobj 1262 0 obj <> endobj 1263 0 obj <> stream x]͎0y /Qb;g$ BbhD&,xRcώo=㰔âp .Xh[Hk;e=>nKZv[C=m>؇8c{L}kU9|n/5R|> endobj 1265 0 obj <> endobj 1266 0 obj <> /ProcSet[/PDF/Text/ImageC/ImageI/ImageB] >> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <>/Contents 5 0 R>> endobj 7 0 obj <>/Contents 8 0 R>> endobj 10 0 obj <>/Contents 11 0 R>> endobj 13 0 obj <>/Contents 14 0 R>> endobj 16 0 obj <>/Contents 17 0 R>> endobj 19 0 obj <>/Contents 20 0 R>> endobj 22 0 obj <>/Contents 23 0 R>> endobj 25 0 obj <>/Contents 26 0 R>> endobj 28 0 obj <>/Contents 29 0 R>> endobj 31 0 obj <>/Contents 32 0 R>> endobj 34 0 obj <>/Contents 35 0 R>> endobj 37 0 obj <>/Contents 38 0 R>> endobj 40 0 obj <>/Contents 41 0 R>> endobj 47 0 obj <>/Contents 48 0 R>> endobj 50 0 obj <>/Contents 51 0 R>> endobj 53 0 obj <>/Contents 54 0 R>> endobj 56 0 obj <>/Contents 57 0 R>> endobj 59 0 obj <>/Contents 60 0 R>> endobj 62 0 obj <>/Contents 63 0 R>> endobj 65 0 obj <>/Contents 66 0 R>> endobj 68 0 obj <>/Contents 69 0 R>> endobj 71 0 obj <>/Contents 72 0 R>> endobj 74 0 obj <>/Contents 75 0 R>> endobj 77 0 obj <>/Contents 78 0 R>> endobj 80 0 obj <>/Contents 81 0 R>> endobj 87 0 obj <>/Contents 88 0 R>> endobj 90 0 obj <>/Contents 91 0 R>> endobj 93 0 obj <>/Contents 94 0 R>> endobj 96 0 obj <>/Contents 97 0 R>> endobj 99 0 obj <>/Contents 100 0 R>> endobj 102 0 obj <>/Contents 103 0 R>> endobj 105 0 obj <>/Contents 106 0 R>> endobj 108 0 obj <>/Contents 109 0 R>> endobj 111 0 obj <>/Contents 112 0 R>> endobj 114 0 obj <>/Contents 115 0 R>> endobj 117 0 obj <>/Contents 118 0 R>> endobj 120 0 obj <>/Contents 121 0 R>> endobj 123 0 obj <>/Contents 124 0 R>> endobj 126 0 obj <>/Contents 127 0 R>> endobj 129 0 obj <>/Contents 130 0 R>> endobj 132 0 obj <>/Contents 133 0 R>> endobj 135 0 obj <>/Contents 136 0 R>> endobj 138 0 obj <>/Contents 139 0 R>> endobj 141 0 obj <>/Contents 142 0 R>> endobj 144 0 obj <>/Contents 145 0 R>> endobj 147 0 obj <>/Contents 148 0 R>> endobj 150 0 obj <>/Contents 151 0 R>> endobj 153 0 obj <>/Contents 154 0 R>> endobj 156 0 obj <>/Contents 157 0 R>> endobj 159 0 obj <>/Contents 160 0 R>> endobj 162 0 obj <>/Contents 163 0 R>> endobj 165 0 obj <>/Contents 166 0 R>> endobj 168 0 obj <>/Contents 169 0 R>> endobj 171 0 obj <>/Contents 172 0 R>> endobj 174 0 obj <>/Contents 175 0 R>> endobj 177 0 obj <>/Contents 178 0 R>> endobj 180 0 obj <>/Contents 181 0 R>> endobj 183 0 obj <>/Contents 184 0 R>> endobj 186 0 obj <>/Contents 187 0 R>> endobj 189 0 obj <>/Contents 190 0 R>> endobj 192 0 obj <>/Contents 193 0 R>> endobj 195 0 obj <>/Contents 196 0 R>> endobj 198 0 obj <>/Contents 199 0 R>> endobj 201 0 obj <>/Contents 202 0 R>> endobj 204 0 obj <>/Contents 205 0 R>> endobj 207 0 obj <>/Contents 208 0 R>> endobj 210 0 obj <>/Contents 211 0 R>> endobj 213 0 obj <>/Contents 214 0 R>> endobj 216 0 obj <>/Contents 217 0 R>> endobj 219 0 obj <>/Contents 220 0 R>> endobj 222 0 obj <>/Contents 223 0 R>> endobj 225 0 obj <>/Contents 226 0 R>> endobj 228 0 obj <>/Contents 229 0 R>> endobj 231 0 obj <>/Contents 232 0 R>> endobj 234 0 obj <>/Contents 235 0 R>> endobj 237 0 obj <>/Contents 238 0 R>> endobj 240 0 obj <>/Contents 241 0 R>> endobj 243 0 obj <>/Contents 244 0 R>> endobj 246 0 obj <>/Contents 247 0 R>> endobj 249 0 obj <>/Contents 250 0 R>> endobj 252 0 obj <>/Contents 253 0 R>> endobj 255 0 obj <>/Contents 256 0 R>> endobj 258 0 obj <>/Contents 259 0 R>> endobj 264 0 obj <>/Contents 265 0 R>> endobj 267 0 obj <>/Contents 268 0 R>> endobj 270 0 obj <>/Contents 271 0 R>> endobj 273 0 obj <>/Contents 274 0 R>> endobj 276 0 obj <>/Contents 277 0 R>> endobj 279 0 obj <>/Contents 280 0 R>> endobj 282 0 obj <>/Contents 283 0 R>> endobj 285 0 obj <>/Contents 286 0 R>> endobj 288 0 obj <>/Contents 289 0 R>> endobj 291 0 obj <>/Contents 292 0 R>> endobj 294 0 obj <>/Contents 295 0 R>> endobj 297 0 obj <>/Contents 298 0 R>> endobj 300 0 obj <>/Contents 301 0 R>> endobj 303 0 obj <>/Contents 304 0 R>> endobj 306 0 obj <>/Contents 307 0 R>> endobj 309 0 obj <>/Contents 310 0 R>> endobj 312 0 obj <>/Contents 313 0 R>> endobj 315 0 obj <>/Contents 316 0 R>> endobj 318 0 obj <>/Contents 319 0 R>> endobj 321 0 obj <>/Contents 322 0 R>> endobj 324 0 obj <>/Contents 325 0 R>> endobj 327 0 obj <>/Contents 328 0 R>> endobj 330 0 obj <>/Contents 331 0 R>> endobj 333 0 obj <>/Contents 334 0 R>> endobj 336 0 obj <>/Contents 337 0 R>> endobj 339 0 obj <>/Contents 340 0 R>> endobj 342 0 obj <>/Contents 343 0 R>> endobj 345 0 obj <>/Contents 346 0 R>> endobj 348 0 obj <>/Contents 349 0 R>> endobj 351 0 obj <>/Contents 352 0 R>> endobj 354 0 obj <>/Contents 355 0 R>> endobj 357 0 obj <>/Contents 358 0 R>> endobj 360 0 obj <>/Contents 361 0 R>> endobj 363 0 obj <>/Contents 364 0 R>> endobj 366 0 obj <>/Contents 367 0 R>> endobj 369 0 obj <>/Contents 370 0 R>> endobj 372 0 obj <>/Contents 373 0 R>> endobj 375 0 obj <>/Contents 376 0 R>> endobj 1267 0 obj <> endobj 1268 0 obj < /Dest[19 0 R/XYZ 56.7 773.3 0]/Parent 1267 0 R/Next 1269 0 R>> endobj 1269 0 obj < /Dest[37 0 R/XYZ 56.7 592.9 0]/Parent 1267 0 R/Prev 1268 0 R/Next 1270 0 R>> endobj 1270 0 obj < /Dest[37 0 R/XYZ 56.7 153.4 0]/Parent 1267 0 R/Prev 1269 0 R>> endobj 1271 0 obj < /Dest[40 0 R/XYZ 56.7 547.7 0]/Parent 1270 0 R/Next 1274 0 R>> endobj 1272 0 obj < /Dest[40 0 R/XYZ 56.7 475.4 0]/Parent 1271 0 R/Next 1273 0 R>> endobj 1273 0 obj < /Dest[40 0 R/XYZ 56.7 231 0]/Parent 1271 0 R/Prev 1272 0 R>> endobj 1274 0 obj < /Dest[47 0 R/XYZ 56.7 770.9 0]/Parent 1270 0 R/Prev 1271 0 R/Next 1301 0 R>> endobj 1275 0 obj < /Dest[47 0 R/XYZ 56.7 698.6 0]/Parent 1274 0 R/Next 1276 0 R>> endobj 1276 0 obj < /Dest[47 0 R/XYZ 56.7 448.5 0]/Parent 1274 0 R/Prev 1275 0 R/Next 1277 0 R>> endobj 1277 0 obj < /Dest[47 0 R/XYZ 56.7 199.5 0]/Parent 1274 0 R/Prev 1276 0 R/Next 1278 0 R>> endobj 1278 0 obj < /Dest[50 0 R/XYZ 56.7 785.3 0]/Parent 1274 0 R/Prev 1277 0 R/Next 1279 0 R>> endobj 1279 0 obj < /Dest[50 0 R/XYZ 56.7 695.6 0]/Parent 1274 0 R/Prev 1278 0 R/Next 1280 0 R>> endobj 1280 0 obj < /Dest[53 0 R/XYZ 56.7 708.5 0]/Parent 1274 0 R/Prev 1279 0 R/Next 1281 0 R>> endobj 1281 0 obj < /Dest[53 0 R/XYZ 56.7 273.3 0]/Parent 1274 0 R/Prev 1280 0 R/Next 1282 0 R>> endobj 1282 0 obj < /Dest[53 0 R/XYZ 56.7 197.5 0]/Parent 1274 0 R/Prev 1281 0 R/Next 1283 0 R>> endobj 1283 0 obj < /Dest[56 0 R/XYZ 56.7 650.5 0]/Parent 1274 0 R/Prev 1282 0 R/Next 1284 0 R>> endobj 1284 0 obj < /Dest[56 0 R/XYZ 56.7 215.7 0]/Parent 1274 0 R/Prev 1283 0 R/Next 1285 0 R>> endobj 1285 0 obj < /Dest[56 0 R/XYZ 56.7 139.8 0]/Parent 1274 0 R/Prev 1284 0 R/Next 1286 0 R>> endobj 1286 0 obj < /Dest[59 0 R/XYZ 56.7 747.8 0]/Parent 1274 0 R/Prev 1285 0 R/Next 1287 0 R>> endobj 1287 0 obj < /Dest[59 0 R/XYZ 56.7 658.1 0]/Parent 1274 0 R/Prev 1286 0 R/Next 1288 0 R>> endobj 1288 0 obj < /Dest[59 0 R/XYZ 56.7 439.6 0]/Parent 1274 0 R/Prev 1287 0 R/Next 1289 0 R>> endobj 1289 0 obj < /Dest[59 0 R/XYZ 56.7 363.7 0]/Parent 1274 0 R/Prev 1288 0 R/Next 1290 0 R>> endobj 1290 0 obj < /Dest[59 0 R/XYZ 56.7 287.9 0]/Parent 1274 0 R/Prev 1289 0 R/Next 1291 0 R>> endobj 1291 0 obj < /Dest[59 0 R/XYZ 56.7 143 0]/Parent 1274 0 R/Prev 1290 0 R/Next 1292 0 R>> endobj 1292 0 obj < /Dest[62 0 R/XYZ 56.7 785.3 0]/Parent 1274 0 R/Prev 1291 0 R/Next 1293 0 R>> endobj 1293 0 obj < /Dest[62 0 R/XYZ 56.7 709.4 0]/Parent 1274 0 R/Prev 1292 0 R/Next 1294 0 R>> endobj 1294 0 obj < /Dest[65 0 R/XYZ 56.7 731.5 0]/Parent 1274 0 R/Prev 1293 0 R/Next 1295 0 R>> endobj 1295 0 obj < /Dest[65 0 R/XYZ 56.7 641.9 0]/Parent 1274 0 R/Prev 1294 0 R/Next 1296 0 R>> endobj 1296 0 obj < /Dest[65 0 R/XYZ 56.7 566 0]/Parent 1274 0 R/Prev 1295 0 R/Next 1297 0 R>> endobj 1297 0 obj < /Dest[65 0 R/XYZ 56.7 448.4 0]/Parent 1274 0 R/Prev 1296 0 R/Next 1298 0 R>> endobj 1298 0 obj < /Dest[65 0 R/XYZ 56.7 289.8 0]/Parent 1274 0 R/Prev 1297 0 R/Next 1299 0 R>> endobj 1299 0 obj < /Dest[65 0 R/XYZ 56.7 144.6 0]/Parent 1274 0 R/Prev 1298 0 R/Next 1300 0 R>> endobj 1300 0 obj < /Dest[68 0 R/XYZ 56.7 271.8 0]/Parent 1274 0 R/Prev 1299 0 R>> endobj 1301 0 obj < /Dest[71 0 R/XYZ 56.7 729.2 0]/Parent 1270 0 R/Prev 1274 0 R/Next 1305 0 R>> endobj 1302 0 obj < /Dest[71 0 R/XYZ 56.7 670.7 0]/Parent 1301 0 R/Next 1303 0 R>> endobj 1303 0 obj < /Dest[71 0 R/XYZ 56.7 361.3 0]/Parent 1301 0 R/Prev 1302 0 R/Next 1304 0 R>> endobj 1304 0 obj < /Dest[74 0 R/XYZ 56.7 351.8 0]/Parent 1301 0 R/Prev 1303 0 R>> endobj 1305 0 obj < /Dest[74 0 R/XYZ 56.7 169.9 0]/Parent 1270 0 R/Prev 1301 0 R/Next 1309 0 R>> endobj 1306 0 obj < /Dest[74 0 R/XYZ 56.7 111.4 0]/Parent 1305 0 R/Next 1307 0 R>> endobj 1307 0 obj < /Dest[77 0 R/XYZ 56.7 630.2 0]/Parent 1305 0 R/Prev 1306 0 R/Next 1308 0 R>> endobj 1308 0 obj < /Dest[80 0 R/XYZ 56.7 206.9 0]/Parent 1305 0 R/Prev 1307 0 R>> endobj 1309 0 obj < /Dest[87 0 R/XYZ 56.7 649.4 0]/Parent 1270 0 R/Prev 1305 0 R/Next 1312 0 R>> endobj 1310 0 obj < /Dest[87 0 R/XYZ 56.7 590.9 0]/Parent 1309 0 R/Next 1311 0 R>> endobj 1311 0 obj < /Dest[87 0 R/XYZ 56.7 270.2 0]/Parent 1309 0 R/Prev 1310 0 R>> endobj 1312 0 obj < /Dest[90 0 R/XYZ 56.7 722.7 0]/Parent 1270 0 R/Prev 1309 0 R/Next 1375 0 R>> endobj 1313 0 obj < /Dest[90 0 R/XYZ 56.7 563.7 0]/Parent 1312 0 R/Next 1314 0 R>> endobj 1314 0 obj < /Dest[90 0 R/XYZ 56.7 358.6 0]/Parent 1312 0 R/Prev 1313 0 R/Next 1315 0 R>> endobj 1315 0 obj < /Dest[93 0 R/XYZ 56.7 785.3 0]/Parent 1312 0 R/Prev 1314 0 R/Next 1316 0 R>> endobj 1316 0 obj < /Dest[93 0 R/XYZ 56.7 557.9 0]/Parent 1312 0 R/Prev 1315 0 R/Next 1317 0 R>> endobj 1317 0 obj < /Dest[93 0 R/XYZ 56.7 281.1 0]/Parent 1312 0 R/Prev 1316 0 R/Next 1318 0 R>> endobj 1318 0 obj < /Dest[96 0 R/XYZ 56.7 785.3 0]/Parent 1312 0 R/Prev 1317 0 R/Next 1319 0 R>> endobj 1319 0 obj < /Dest[96 0 R/XYZ 56.7 667.7 0]/Parent 1312 0 R/Prev 1318 0 R/Next 1320 0 R>> endobj 1320 0 obj < /Dest[96 0 R/XYZ 56.7 510.4 0]/Parent 1312 0 R/Prev 1319 0 R/Next 1321 0 R>> endobj 1321 0 obj < /Dest[96 0 R/XYZ 56.7 296.4 0]/Parent 1312 0 R/Prev 1320 0 R/Next 1322 0 R>> endobj 1322 0 obj < /Dest[99 0 R/XYZ 56.7 785.3 0]/Parent 1312 0 R/Prev 1321 0 R/Next 1323 0 R>> endobj 1323 0 obj < /Dest[99 0 R/XYZ 56.7 616.7 0]/Parent 1312 0 R/Prev 1322 0 R/Next 1324 0 R>> endobj 1324 0 obj < /Dest[99 0 R/XYZ 56.7 485.3 0]/Parent 1312 0 R/Prev 1323 0 R/Next 1325 0 R>> endobj 1325 0 obj < /Dest[99 0 R/XYZ 56.7 328 0]/Parent 1312 0 R/Prev 1324 0 R/Next 1326 0 R>> endobj 1326 0 obj < /Dest[99 0 R/XYZ 56.7 170.8 0]/Parent 1312 0 R/Prev 1325 0 R/Next 1327 0 R>> endobj 1327 0 obj < /Dest[102 0 R/XYZ 56.7 747.8 0]/Parent 1312 0 R/Prev 1326 0 R/Next 1328 0 R>> endobj 1328 0 obj < /Dest[102 0 R/XYZ 56.7 270.3 0]/Parent 1312 0 R/Prev 1327 0 R/Next 1329 0 R>> endobj 1329 0 obj < /Dest[105 0 R/XYZ 56.7 532.1 0]/Parent 1312 0 R/Prev 1328 0 R/Next 1330 0 R>> endobj 1330 0 obj < /Dest[105 0 R/XYZ 56.7 340.8 0]/Parent 1312 0 R/Prev 1329 0 R/Next 1331 0 R>> endobj 1331 0 obj < /Dest[108 0 R/XYZ 56.7 603.1 0]/Parent 1312 0 R/Prev 1330 0 R/Next 1332 0 R>> endobj 1332 0 obj < /Dest[108 0 R/XYZ 56.7 332.4 0]/Parent 1312 0 R/Prev 1331 0 R/Next 1333 0 R>> endobj 1333 0 obj < /Dest[108 0 R/XYZ 56.7 147.5 0]/Parent 1312 0 R/Prev 1332 0 R/Next 1334 0 R>> endobj 1334 0 obj < /Dest[111 0 R/XYZ 56.7 635.1 0]/Parent 1312 0 R/Prev 1333 0 R/Next 1335 0 R>> endobj 1335 0 obj < /Dest[111 0 R/XYZ 56.7 430.1 0]/Parent 1312 0 R/Prev 1334 0 R/Next 1336 0 R>> endobj 1336 0 obj < /Dest[111 0 R/XYZ 56.7 286.6 0]/Parent 1312 0 R/Prev 1335 0 R/Next 1337 0 R>> endobj 1337 0 obj < /Dest[111 0 R/XYZ 56.7 97.8 0]/Parent 1312 0 R/Prev 1336 0 R/Next 1338 0 R>> endobj 1338 0 obj < /Dest[114 0 R/XYZ 56.7 655.4 0]/Parent 1312 0 R/Prev 1337 0 R/Next 1339 0 R>> endobj 1339 0 obj < /Dest[114 0 R/XYZ 56.7 478.2 0]/Parent 1312 0 R/Prev 1338 0 R/Next 1340 0 R>> endobj 1340 0 obj < /Dest[114 0 R/XYZ 56.7 227.7 0]/Parent 1312 0 R/Prev 1339 0 R/Next 1341 0 R>> endobj 1341 0 obj < /Dest[117 0 R/XYZ 56.7 785.3 0]/Parent 1312 0 R/Prev 1340 0 R/Next 1342 0 R>> endobj 1342 0 obj < /Dest[117 0 R/XYZ 56.7 630.5 0]/Parent 1312 0 R/Prev 1341 0 R/Next 1343 0 R>> endobj 1343 0 obj < /Dest[120 0 R/XYZ 56.7 736.4 0]/Parent 1312 0 R/Prev 1342 0 R/Next 1344 0 R>> endobj 1344 0 obj < /Dest[120 0 R/XYZ 56.7 579.2 0]/Parent 1312 0 R/Prev 1343 0 R/Next 1345 0 R>> endobj 1345 0 obj < /Dest[120 0 R/XYZ 56.7 399.2 0]/Parent 1312 0 R/Prev 1344 0 R/Next 1346 0 R>> endobj 1346 0 obj < /Dest[120 0 R/XYZ 56.7 162.5 0]/Parent 1312 0 R/Prev 1345 0 R/Next 1347 0 R>> endobj 1347 0 obj < /Dest[123 0 R/XYZ 56.7 785.3 0]/Parent 1312 0 R/Prev 1346 0 R/Next 1348 0 R>> endobj 1348 0 obj < /Dest[123 0 R/XYZ 56.7 681.8 0]/Parent 1312 0 R/Prev 1347 0 R/Next 1349 0 R>> endobj 1349 0 obj < /Dest[123 0 R/XYZ 56.7 198.7 0]/Parent 1312 0 R/Prev 1348 0 R/Next 1350 0 R>> endobj 1350 0 obj < /Dest[126 0 R/XYZ 56.7 747.8 0]/Parent 1312 0 R/Prev 1349 0 R/Next 1351 0 R>> endobj 1351 0 obj < /Dest[126 0 R/XYZ 56.7 490 0]/Parent 1312 0 R/Prev 1350 0 R/Next 1352 0 R>> endobj 1352 0 obj < /Dest[126 0 R/XYZ 56.7 291 0]/Parent 1312 0 R/Prev 1351 0 R/Next 1353 0 R>> endobj 1353 0 obj < /Dest[129 0 R/XYZ 56.7 518.8 0]/Parent 1312 0 R/Prev 1352 0 R/Next 1354 0 R>> endobj 1354 0 obj < /Dest[129 0 R/XYZ 56.7 313.7 0]/Parent 1312 0 R/Prev 1353 0 R/Next 1355 0 R>> endobj 1355 0 obj < /Dest[129 0 R/XYZ 56.7 120 0]/Parent 1312 0 R/Prev 1354 0 R/Next 1356 0 R>> endobj 1356 0 obj < /Dest[132 0 R/XYZ 56.7 652.9 0]/Parent 1312 0 R/Prev 1355 0 R/Next 1357 0 R>> endobj 1357 0 obj < /Dest[132 0 R/XYZ 56.7 562.9 0]/Parent 1312 0 R/Prev 1356 0 R/Next 1358 0 R>> endobj 1358 0 obj < /Dest[132 0 R/XYZ 56.7 394.3 0]/Parent 1312 0 R/Prev 1357 0 R/Next 1359 0 R>> endobj 1359 0 obj < /Dest[132 0 R/XYZ 56.7 152.4 0]/Parent 1312 0 R/Prev 1358 0 R/Next 1360 0 R>> endobj 1360 0 obj < /Dest[135 0 R/XYZ 56.7 541.1 0]/Parent 1312 0 R/Prev 1359 0 R/Next 1361 0 R>> endobj 1361 0 obj < /Dest[135 0 R/XYZ 56.7 397.7 0]/Parent 1312 0 R/Prev 1360 0 R/Next 1362 0 R>> endobj 1362 0 obj < /Dest[135 0 R/XYZ 56.7 126.1 0]/Parent 1312 0 R/Prev 1361 0 R/Next 1363 0 R>> endobj 1363 0 obj < /Dest[141 0 R/XYZ 56.7 702.4 0]/Parent 1312 0 R/Prev 1362 0 R/Next 1364 0 R>> endobj 1364 0 obj < /Dest[141 0 R/XYZ 56.7 545.1 0]/Parent 1312 0 R/Prev 1363 0 R/Next 1365 0 R>> endobj 1365 0 obj < /Dest[141 0 R/XYZ 56.7 388.2 0]/Parent 1312 0 R/Prev 1364 0 R/Next 1366 0 R>> endobj 1366 0 obj < /Dest[141 0 R/XYZ 56.7 284.4 0]/Parent 1312 0 R/Prev 1365 0 R/Next 1367 0 R>> endobj 1367 0 obj < /Dest[141 0 R/XYZ 56.7 104.5 0]/Parent 1312 0 R/Prev 1366 0 R/Next 1368 0 R>> endobj 1368 0 obj < /Dest[147 0 R/XYZ 56.7 634.3 0]/Parent 1312 0 R/Prev 1367 0 R/Next 1369 0 R>> endobj 1369 0 obj < /Dest[147 0 R/XYZ 56.7 477 0]/Parent 1312 0 R/Prev 1368 0 R/Next 1370 0 R>> endobj 1370 0 obj < /Dest[147 0 R/XYZ 56.7 387 0]/Parent 1312 0 R/Prev 1369 0 R/Next 1371 0 R>> endobj 1371 0 obj < /Dest[147 0 R/XYZ 56.7 232.2 0]/Parent 1312 0 R/Prev 1370 0 R/Next 1372 0 R>> endobj 1372 0 obj < /Dest[150 0 R/XYZ 56.7 560.9 0]/Parent 1312 0 R/Prev 1371 0 R/Next 1373 0 R>> endobj 1373 0 obj < /Dest[150 0 R/XYZ 56.7 289 0]/Parent 1312 0 R/Prev 1372 0 R/Next 1374 0 R>> endobj 1374 0 obj < /Dest[153 0 R/XYZ 56.7 193.7 0]/Parent 1312 0 R/Prev 1373 0 R>> endobj 1375 0 obj < /Dest[156 0 R/XYZ 56.7 717.5 0]/Parent 1270 0 R/Prev 1312 0 R/Next 1383 0 R>> endobj 1376 0 obj < /Dest[156 0 R/XYZ 56.7 678.8 0]/Parent 1375 0 R/Next 1377 0 R>> endobj 1377 0 obj < /Dest[156 0 R/XYZ 56.7 446.1 0]/Parent 1375 0 R/Prev 1376 0 R/Next 1378 0 R>> endobj 1378 0 obj < /Dest[156 0 R/XYZ 56.7 202.4 0]/Parent 1375 0 R/Prev 1377 0 R/Next 1379 0 R>> endobj 1379 0 obj < /Dest[159 0 R/XYZ 56.7 697.1 0]/Parent 1375 0 R/Prev 1378 0 R/Next 1380 0 R>> endobj 1380 0 obj < /Dest[159 0 R/XYZ 56.7 488.8 0]/Parent 1375 0 R/Prev 1379 0 R/Next 1381 0 R>> endobj 1381 0 obj < /Dest[159 0 R/XYZ 56.7 189.4 0]/Parent 1375 0 R/Prev 1380 0 R/Next 1382 0 R>> endobj 1382 0 obj < /Dest[162 0 R/XYZ 56.7 671.2 0]/Parent 1375 0 R/Prev 1381 0 R>> endobj 1383 0 obj < /Dest[162 0 R/XYZ 56.7 452.4 0]/Parent 1270 0 R/Prev 1375 0 R/Next 1425 0 R>> endobj 1384 0 obj < /Dest[162 0 R/XYZ 56.7 413.7 0]/Parent 1383 0 R/Next 1385 0 R>> endobj 1385 0 obj < /Dest[162 0 R/XYZ 56.7 239 0]/Parent 1383 0 R/Prev 1384 0 R/Next 1386 0 R>> endobj 1386 0 obj < /Dest[162 0 R/XYZ 56.7 98.4 0]/Parent 1383 0 R/Prev 1385 0 R/Next 1387 0 R>> endobj 1387 0 obj < /Dest[165 0 R/XYZ 56.7 387.1 0]/Parent 1383 0 R/Prev 1386 0 R/Next 1388 0 R>> endobj 1388 0 obj < /Dest[165 0 R/XYZ 56.7 155.8 0]/Parent 1383 0 R/Prev 1387 0 R/Next 1389 0 R>> endobj 1389 0 obj < /Dest[168 0 R/XYZ 56.7 625.5 0]/Parent 1383 0 R/Prev 1388 0 R/Next 1390 0 R>> endobj 1390 0 obj < /Dest[168 0 R/XYZ 56.7 366.6 0]/Parent 1383 0 R/Prev 1389 0 R/Next 1391 0 R>> endobj 1391 0 obj < /Dest[168 0 R/XYZ 56.7 135.3 0]/Parent 1383 0 R/Prev 1390 0 R/Next 1392 0 R>> endobj 1392 0 obj < /Dest[171 0 R/XYZ 56.7 617.8 0]/Parent 1383 0 R/Prev 1391 0 R/Next 1393 0 R>> endobj 1393 0 obj < /Dest[171 0 R/XYZ 56.7 403.1 0]/Parent 1383 0 R/Prev 1392 0 R/Next 1394 0 R>> endobj 1394 0 obj < /Dest[171 0 R/XYZ 56.7 106.2 0]/Parent 1383 0 R/Prev 1393 0 R/Next 1395 0 R>> endobj 1395 0 obj < /Dest[174 0 R/XYZ 56.7 501.5 0]/Parent 1383 0 R/Prev 1394 0 R/Next 1396 0 R>> endobj 1396 0 obj < /Dest[177 0 R/XYZ 56.7 785.3 0]/Parent 1383 0 R/Prev 1395 0 R/Next 1397 0 R>> endobj 1397 0 obj < /Dest[177 0 R/XYZ 56.7 571.3 0]/Parent 1383 0 R/Prev 1396 0 R/Next 1398 0 R>> endobj 1398 0 obj < /Dest[177 0 R/XYZ 56.7 307.6 0]/Parent 1383 0 R/Prev 1397 0 R/Next 1399 0 R>> endobj 1399 0 obj < /Dest[180 0 R/XYZ 56.7 785.3 0]/Parent 1383 0 R/Prev 1398 0 R/Next 1400 0 R>> endobj 1400 0 obj < /Dest[180 0 R/XYZ 56.7 577.7 0]/Parent 1383 0 R/Prev 1399 0 R/Next 1401 0 R>> endobj 1401 0 obj < /Dest[180 0 R/XYZ 56.7 388.2 0]/Parent 1383 0 R/Prev 1400 0 R/Next 1402 0 R>> endobj 1402 0 obj < /Dest[183 0 R/XYZ 56.7 785.3 0]/Parent 1383 0 R/Prev 1401 0 R/Next 1403 0 R>> endobj 1403 0 obj < /Dest[183 0 R/XYZ 56.7 590.8 0]/Parent 1383 0 R/Prev 1402 0 R/Next 1404 0 R>> endobj 1404 0 obj < /Dest[183 0 R/XYZ 56.7 162.6 0]/Parent 1383 0 R/Prev 1403 0 R/Next 1405 0 R>> endobj 1405 0 obj < /Dest[186 0 R/XYZ 56.7 556.8 0]/Parent 1383 0 R/Prev 1404 0 R/Next 1406 0 R>> endobj 1406 0 obj < /Dest[186 0 R/XYZ 56.7 216.9 0]/Parent 1383 0 R/Prev 1405 0 R/Next 1407 0 R>> endobj 1407 0 obj < /Dest[189 0 R/XYZ 56.7 551.8 0]/Parent 1383 0 R/Prev 1406 0 R/Next 1408 0 R>> endobj 1408 0 obj < /Dest[189 0 R/XYZ 56.7 162.8 0]/Parent 1383 0 R/Prev 1407 0 R/Next 1409 0 R>> endobj 1409 0 obj < /Dest[192 0 R/XYZ 56.7 785.3 0]/Parent 1383 0 R/Prev 1408 0 R/Next 1410 0 R>> endobj 1410 0 obj < /Dest[192 0 R/XYZ 56.7 343.2 0]/Parent 1383 0 R/Prev 1409 0 R/Next 1411 0 R>> endobj 1411 0 obj < /Dest[195 0 R/XYZ 56.7 785.3 0]/Parent 1383 0 R/Prev 1410 0 R/Next 1412 0 R>> endobj 1412 0 obj < /Dest[195 0 R/XYZ 56.7 695.6 0]/Parent 1383 0 R/Prev 1411 0 R/Next 1413 0 R>> endobj 1413 0 obj < /Dest[195 0 R/XYZ 56.7 316.3 0]/Parent 1383 0 R/Prev 1412 0 R/Next 1414 0 R>> endobj 1414 0 obj < /Dest[198 0 R/XYZ 56.7 736.4 0]/Parent 1383 0 R/Prev 1413 0 R/Next 1415 0 R>> endobj 1415 0 obj < /Dest[198 0 R/XYZ 56.7 660.6 0]/Parent 1383 0 R/Prev 1414 0 R/Next 1416 0 R>> endobj 1416 0 obj < /Dest[198 0 R/XYZ 56.7 557.1 0]/Parent 1383 0 R/Prev 1415 0 R/Next 1417 0 R>> endobj 1417 0 obj < /Dest[198 0 R/XYZ 56.7 288.5 0]/Parent 1383 0 R/Prev 1416 0 R/Next 1418 0 R>> endobj 1418 0 obj < /Dest[201 0 R/XYZ 56.7 634.3 0]/Parent 1383 0 R/Prev 1417 0 R/Next 1419 0 R>> endobj 1419 0 obj < /Dest[204 0 R/XYZ 56.7 785.3 0]/Parent 1383 0 R/Prev 1418 0 R/Next 1420 0 R>> endobj 1420 0 obj < /Dest[204 0 R/XYZ 56.7 511.8 0]/Parent 1383 0 R/Prev 1419 0 R/Next 1421 0 R>> endobj 1421 0 obj < /Dest[204 0 R/XYZ 56.7 217.5 0]/Parent 1383 0 R/Prev 1420 0 R/Next 1422 0 R>> endobj 1422 0 obj < /Dest[207 0 R/XYZ 56.7 685.8 0]/Parent 1383 0 R/Prev 1421 0 R/Next 1423 0 R>> endobj 1423 0 obj < /Dest[207 0 R/XYZ 56.7 111.1 0]/Parent 1383 0 R/Prev 1422 0 R/Next 1424 0 R>> endobj 1424 0 obj < /Dest[210 0 R/XYZ 56.7 515 0]/Parent 1383 0 R/Prev 1423 0 R>> endobj 1425 0 obj < /Dest[210 0 R/XYZ 56.7 344.2 0]/Parent 1270 0 R/Prev 1383 0 R/Next 1435 0 R>> endobj 1426 0 obj < /Dest[210 0 R/XYZ 56.7 285.7 0]/Parent 1425 0 R/Next 1427 0 R>> endobj 1427 0 obj < /Dest[210 0 R/XYZ 56.7 142.6 0]/Parent 1425 0 R/Prev 1426 0 R/Next 1428 0 R>> endobj 1428 0 obj < /Dest[213 0 R/XYZ 56.7 398.4 0]/Parent 1425 0 R/Prev 1427 0 R/Next 1429 0 R>> endobj 1429 0 obj < /Dest[213 0 R/XYZ 56.7 261 0]/Parent 1425 0 R/Prev 1428 0 R/Next 1430 0 R>> endobj 1430 0 obj < /Dest[213 0 R/XYZ 56.7 120.3 0]/Parent 1425 0 R/Prev 1429 0 R/Next 1431 0 R>> endobj 1431 0 obj < /Dest[216 0 R/XYZ 56.7 708.5 0]/Parent 1425 0 R/Prev 1430 0 R/Next 1432 0 R>> endobj 1432 0 obj < /Dest[216 0 R/XYZ 56.7 531.3 0]/Parent 1425 0 R/Prev 1431 0 R/Next 1433 0 R>> endobj 1433 0 obj < /Dest[216 0 R/XYZ 56.7 190 0]/Parent 1425 0 R/Prev 1432 0 R/Next 1434 0 R>> endobj 1434 0 obj < /Dest[219 0 R/XYZ 56.7 562.8 0]/Parent 1425 0 R/Prev 1433 0 R>> endobj 1435 0 obj < /Dest[219 0 R/XYZ 56.7 372 0]/Parent 1270 0 R/Prev 1425 0 R/Next 1460 0 R>> endobj 1436 0 obj < /Dest[219 0 R/XYZ 56.7 333.3 0]/Parent 1435 0 R/Next 1437 0 R>> endobj 1437 0 obj < /Dest[219 0 R/XYZ 56.7 112.7 0]/Parent 1435 0 R/Prev 1436 0 R/Next 1438 0 R>> endobj 1438 0 obj < /Dest[222 0 R/XYZ 56.7 602.3 0]/Parent 1435 0 R/Prev 1437 0 R/Next 1439 0 R>> endobj 1439 0 obj < /Dest[222 0 R/XYZ 56.7 265.4 0]/Parent 1435 0 R/Prev 1438 0 R/Next 1440 0 R>> endobj 1440 0 obj < /Dest[222 0 R/XYZ 56.7 155.9 0]/Parent 1435 0 R/Prev 1439 0 R/Next 1441 0 R>> endobj 1441 0 obj < /Dest[225 0 R/XYZ 56.7 659.6 0]/Parent 1435 0 R/Prev 1440 0 R/Next 1442 0 R>> endobj 1442 0 obj < /Dest[225 0 R/XYZ 56.7 331.5 0]/Parent 1435 0 R/Prev 1441 0 R/Next 1443 0 R>> endobj 1443 0 obj < /Dest[225 0 R/XYZ 56.7 222.1 0]/Parent 1435 0 R/Prev 1442 0 R/Next 1444 0 R>> endobj 1444 0 obj < /Dest[228 0 R/XYZ 56.7 470.5 0]/Parent 1435 0 R/Prev 1443 0 R/Next 1445 0 R>> endobj 1445 0 obj < /Dest[228 0 R/XYZ 56.7 361 0]/Parent 1435 0 R/Prev 1444 0 R/Next 1446 0 R>> endobj 1446 0 obj < /Dest[228 0 R/XYZ 56.7 120.1 0]/Parent 1435 0 R/Prev 1445 0 R/Next 1447 0 R>> endobj 1447 0 obj < /Dest[231 0 R/XYZ 56.7 725.5 0]/Parent 1435 0 R/Prev 1446 0 R/Next 1448 0 R>> endobj 1448 0 obj < /Dest[231 0 R/XYZ 56.7 616.1 0]/Parent 1435 0 R/Prev 1447 0 R/Next 1449 0 R>> endobj 1449 0 obj < /Dest[231 0 R/XYZ 56.7 506.6 0]/Parent 1435 0 R/Prev 1448 0 R/Next 1450 0 R>> endobj 1450 0 obj < /Dest[231 0 R/XYZ 56.7 278.6 0]/Parent 1435 0 R/Prev 1449 0 R/Next 1451 0 R>> endobj 1451 0 obj < /Dest[231 0 R/XYZ 56.7 99.8 0]/Parent 1435 0 R/Prev 1450 0 R/Next 1452 0 R>> endobj 1452 0 obj < /Dest[234 0 R/XYZ 56.7 711.7 0]/Parent 1435 0 R/Prev 1451 0 R/Next 1453 0 R>> endobj 1453 0 obj < /Dest[234 0 R/XYZ 56.7 573.3 0]/Parent 1435 0 R/Prev 1452 0 R/Next 1454 0 R>> endobj 1454 0 obj < /Dest[234 0 R/XYZ 56.7 326.9 0]/Parent 1435 0 R/Prev 1453 0 R/Next 1455 0 R>> endobj 1455 0 obj < /Dest[237 0 R/XYZ 56.7 548.7 0]/Parent 1435 0 R/Prev 1454 0 R/Next 1456 0 R>> endobj 1456 0 obj < /Dest[237 0 R/XYZ 56.7 220.6 0]/Parent 1435 0 R/Prev 1455 0 R/Next 1457 0 R>> endobj 1457 0 obj < /Dest[237 0 R/XYZ 56.7 111.2 0]/Parent 1435 0 R/Prev 1456 0 R/Next 1458 0 R>> endobj 1458 0 obj < /Dest[240 0 R/XYZ 56.7 555.8 0]/Parent 1435 0 R/Prev 1457 0 R/Next 1459 0 R>> endobj 1459 0 obj < /Dest[240 0 R/XYZ 56.7 313.2 0]/Parent 1435 0 R/Prev 1458 0 R>> endobj 1460 0 obj < /Dest[243 0 R/XYZ 56.7 743 0]/Parent 1270 0 R/Prev 1435 0 R/Next 1483 0 R>> endobj 1461 0 obj < /Dest[243 0 R/XYZ 56.7 704.3 0]/Parent 1460 0 R/Next 1462 0 R>> endobj 1462 0 obj < /Dest[243 0 R/XYZ 56.7 550.8 0]/Parent 1460 0 R/Prev 1461 0 R/Next 1463 0 R>> endobj 1463 0 obj < /Dest[246 0 R/XYZ 56.7 702.4 0]/Parent 1460 0 R/Prev 1462 0 R/Next 1464 0 R>> endobj 1464 0 obj < /Dest[246 0 R/XYZ 56.7 357 0]/Parent 1460 0 R/Prev 1463 0 R/Next 1465 0 R>> endobj 1465 0 obj < /Dest[246 0 R/XYZ 56.7 322.9 0]/Parent 1460 0 R/Prev 1464 0 R/Next 1466 0 R>> endobj 1466 0 obj < /Dest[246 0 R/XYZ 56.7 288.8 0]/Parent 1460 0 R/Prev 1465 0 R/Next 1467 0 R>> endobj 1467 0 obj < /Dest[249 0 R/XYZ 56.7 671.7 0]/Parent 1460 0 R/Prev 1466 0 R/Next 1468 0 R>> endobj 1468 0 obj < /Dest[249 0 R/XYZ 56.7 637.6 0]/Parent 1460 0 R/Prev 1467 0 R/Next 1469 0 R>> endobj 1469 0 obj < /Dest[249 0 R/XYZ 56.7 484.9 0]/Parent 1460 0 R/Prev 1468 0 R/Next 1470 0 R>> endobj 1470 0 obj < /Dest[249 0 R/XYZ 56.7 147.9 0]/Parent 1460 0 R/Prev 1469 0 R/Next 1471 0 R>> endobj 1471 0 obj < /Dest[252 0 R/XYZ 56.7 785.3 0]/Parent 1460 0 R/Prev 1470 0 R/Next 1472 0 R>> endobj 1472 0 obj < /Dest[252 0 R/XYZ 56.7 751.2 0]/Parent 1460 0 R/Prev 1471 0 R/Next 1473 0 R>> endobj 1473 0 obj < /Dest[252 0 R/XYZ 56.7 717.1 0]/Parent 1460 0 R/Prev 1472 0 R/Next 1474 0 R>> endobj 1474 0 obj < /Dest[252 0 R/XYZ 56.7 683 0]/Parent 1460 0 R/Prev 1473 0 R/Next 1475 0 R>> endobj 1475 0 obj < /Dest[252 0 R/XYZ 56.7 648.9 0]/Parent 1460 0 R/Prev 1474 0 R/Next 1476 0 R>> endobj 1476 0 obj < /Dest[252 0 R/XYZ 56.7 227.3 0]/Parent 1460 0 R/Prev 1475 0 R/Next 1477 0 R>> endobj 1477 0 obj < /Dest[255 0 R/XYZ 56.7 680.5 0]/Parent 1460 0 R/Prev 1476 0 R/Next 1478 0 R>> endobj 1478 0 obj < /Dest[255 0 R/XYZ 56.7 489.6 0]/Parent 1460 0 R/Prev 1477 0 R/Next 1479 0 R>> endobj 1479 0 obj < /Dest[258 0 R/XYZ 56.7 785.3 0]/Parent 1460 0 R/Prev 1478 0 R/Next 1480 0 R>> endobj 1480 0 obj < /Dest[258 0 R/XYZ 56.7 751.2 0]/Parent 1460 0 R/Prev 1479 0 R/Next 1481 0 R>> endobj 1481 0 obj < /Dest[258 0 R/XYZ 56.7 717.1 0]/Parent 1460 0 R/Prev 1480 0 R/Next 1482 0 R>> endobj 1482 0 obj < /Dest[258 0 R/XYZ 56.7 683 0]/Parent 1460 0 R/Prev 1481 0 R>> endobj 1483 0 obj < /Dest[258 0 R/XYZ 56.7 646.5 0]/Parent 1270 0 R/Prev 1460 0 R>> endobj 1484 0 obj < /Dest[258 0 R/XYZ 56.7 607.8 0]/Parent 1483 0 R/Next 1485 0 R>> endobj 1485 0 obj < /Dest[258 0 R/XYZ 56.7 340 0]/Parent 1483 0 R/Prev 1484 0 R/Next 1486 0 R>> endobj 1486 0 obj < /Dest[264 0 R/XYZ 56.7 785.3 0]/Parent 1483 0 R/Prev 1485 0 R/Next 1487 0 R>> endobj 1487 0 obj < /Dest[264 0 R/XYZ 56.7 458.3 0]/Parent 1483 0 R/Prev 1486 0 R/Next 1488 0 R>> endobj 1488 0 obj < /Dest[267 0 R/XYZ 56.7 785.3 0]/Parent 1483 0 R/Prev 1487 0 R/Next 1489 0 R>> endobj 1489 0 obj < /Dest[267 0 R/XYZ 56.7 353.7 0]/Parent 1483 0 R/Prev 1488 0 R/Next 1490 0 R>> endobj 1490 0 obj < /Dest[267 0 R/XYZ 56.7 136.2 0]/Parent 1483 0 R/Prev 1489 0 R/Next 1491 0 R>> endobj 1491 0 obj < /Dest[270 0 R/XYZ 56.7 594.8 0]/Parent 1483 0 R/Prev 1490 0 R/Next 1492 0 R>> endobj 1492 0 obj < /Dest[270 0 R/XYZ 56.7 320.7 0]/Parent 1483 0 R/Prev 1491 0 R/Next 1493 0 R>> endobj 1493 0 obj < /Dest[273 0 R/XYZ 56.7 785.3 0]/Parent 1483 0 R/Prev 1492 0 R/Next 1494 0 R>> endobj 1494 0 obj < /Dest[273 0 R/XYZ 56.7 273 0]/Parent 1483 0 R/Prev 1493 0 R/Next 1495 0 R>> endobj 1495 0 obj < /Dest[279 0 R/XYZ 56.7 785.3 0]/Parent 1483 0 R/Prev 1494 0 R/Next 1496 0 R>> endobj 1496 0 obj < /Dest[282 0 R/XYZ 56.7 725.1 0]/Parent 1483 0 R/Prev 1495 0 R/Next 1497 0 R>> endobj 1497 0 obj < /Dest[285 0 R/XYZ 56.7 702.4 0]/Parent 1483 0 R/Prev 1496 0 R/Next 1498 0 R>> endobj 1498 0 obj < /Dest[285 0 R/XYZ 56.7 355.6 0]/Parent 1483 0 R/Prev 1497 0 R/Next 1499 0 R>> endobj 1499 0 obj < /Dest[288 0 R/XYZ 56.7 668.3 0]/Parent 1483 0 R/Prev 1498 0 R/Next 1500 0 R>> endobj 1500 0 obj < /Dest[288 0 R/XYZ 56.7 364 0]/Parent 1483 0 R/Prev 1499 0 R/Next 1501 0 R>> endobj 1501 0 obj < /Dest[291 0 R/XYZ 56.7 674.4 0]/Parent 1483 0 R/Prev 1500 0 R/Next 1502 0 R>> endobj 1502 0 obj < /Dest[291 0 R/XYZ 56.7 584.8 0]/Parent 1483 0 R/Prev 1501 0 R/Next 1503 0 R>> endobj 1503 0 obj < /Dest[294 0 R/XYZ 56.7 747.8 0]/Parent 1483 0 R/Prev 1502 0 R/Next 1504 0 R>> endobj 1504 0 obj < /Dest[294 0 R/XYZ 56.7 347.3 0]/Parent 1483 0 R/Prev 1503 0 R/Next 1505 0 R>> endobj 1505 0 obj < /Dest[297 0 R/XYZ 56.7 785.3 0]/Parent 1483 0 R/Prev 1504 0 R/Next 1506 0 R>> endobj 1506 0 obj < /Dest[297 0 R/XYZ 56.7 463.2 0]/Parent 1483 0 R/Prev 1505 0 R/Next 1507 0 R>> endobj 1507 0 obj < /Dest[297 0 R/XYZ 56.7 297.8 0]/Parent 1483 0 R/Prev 1506 0 R/Next 1508 0 R>> endobj 1508 0 obj < /Dest[300 0 R/XYZ 56.7 753.5 0]/Parent 1483 0 R/Prev 1507 0 R/Next 1509 0 R>> endobj 1509 0 obj < /Dest[300 0 R/XYZ 56.7 463 0]/Parent 1483 0 R/Prev 1508 0 R/Next 1510 0 R>> endobj 1510 0 obj < /Dest[300 0 R/XYZ 56.7 297.6 0]/Parent 1483 0 R/Prev 1509 0 R/Next 1511 0 R>> endobj 1511 0 obj < /Dest[303 0 R/XYZ 56.7 546.8 0]/Parent 1483 0 R/Prev 1510 0 R/Next 1512 0 R>> endobj 1512 0 obj < /Dest[303 0 R/XYZ 56.7 342 0]/Parent 1483 0 R/Prev 1511 0 R/Next 1513 0 R>> endobj 1513 0 obj < /Dest[303 0 R/XYZ 56.7 159.6 0]/Parent 1483 0 R/Prev 1512 0 R/Next 1514 0 R>> endobj 1514 0 obj < /Dest[306 0 R/XYZ 56.7 632.7 0]/Parent 1483 0 R/Prev 1513 0 R/Next 1515 0 R>> endobj 1515 0 obj < /Dest[306 0 R/XYZ 56.7 438.9 0]/Parent 1483 0 R/Prev 1514 0 R/Next 1516 0 R>> endobj 1516 0 obj < /Dest[306 0 R/XYZ 56.7 95.3 0]/Parent 1483 0 R/Prev 1515 0 R/Next 1517 0 R>> endobj 1517 0 obj < /Dest[309 0 R/XYZ 56.7 445.4 0]/Parent 1483 0 R/Prev 1516 0 R/Next 1518 0 R>> endobj 1518 0 obj < /Dest[309 0 R/XYZ 56.7 252.4 0]/Parent 1483 0 R/Prev 1517 0 R/Next 1519 0 R>> endobj 1519 0 obj < /Dest[312 0 R/XYZ 56.7 650.5 0]/Parent 1483 0 R/Prev 1518 0 R/Next 1520 0 R>> endobj 1520 0 obj < /Dest[312 0 R/XYZ 56.7 430.5 0]/Parent 1483 0 R/Prev 1519 0 R/Next 1521 0 R>> endobj 1521 0 obj < /Dest[312 0 R/XYZ 56.7 237.2 0]/Parent 1483 0 R/Prev 1520 0 R/Next 1522 0 R>> endobj 1522 0 obj < /Dest[315 0 R/XYZ 56.7 613.9 0]/Parent 1483 0 R/Prev 1521 0 R/Next 1523 0 R>> endobj 1523 0 obj < /Dest[318 0 R/XYZ 56.7 725.1 0]/Parent 1483 0 R/Prev 1522 0 R/Next 1524 0 R>> endobj 1524 0 obj < /Dest[318 0 R/XYZ 56.7 250.3 0]/Parent 1483 0 R/Prev 1523 0 R/Next 1525 0 R>> endobj 1525 0 obj < /Dest[321 0 R/XYZ 56.7 387 0]/Parent 1483 0 R/Prev 1524 0 R/Next 1526 0 R>> endobj 1526 0 obj < /Dest[324 0 R/XYZ 56.7 523.2 0]/Parent 1483 0 R/Prev 1525 0 R/Next 1527 0 R>> endobj 1527 0 obj < /Dest[330 0 R/XYZ 56.7 679.7 0]/Parent 1483 0 R/Prev 1526 0 R/Next 1528 0 R>> endobj 1528 0 obj < /Dest[330 0 R/XYZ 56.7 423.7 0]/Parent 1483 0 R/Prev 1527 0 R/Next 1529 0 R>> endobj 1529 0 obj < /Dest[330 0 R/XYZ 56.7 94.6 0]/Parent 1483 0 R/Prev 1528 0 R/Next 1530 0 R>> endobj 1530 0 obj < /Dest[333 0 R/XYZ 56.7 473.7 0]/Parent 1483 0 R/Prev 1529 0 R/Next 1531 0 R>> endobj 1531 0 obj < /Dest[333 0 R/XYZ 56.7 229 0]/Parent 1483 0 R/Prev 1530 0 R/Next 1532 0 R>> endobj 1532 0 obj < /Dest[336 0 R/XYZ 56.7 785.3 0]/Parent 1483 0 R/Prev 1531 0 R/Next 1533 0 R>> endobj 1533 0 obj < /Dest[336 0 R/XYZ 56.7 632.6 0]/Parent 1483 0 R/Prev 1532 0 R/Next 1534 0 R>> endobj 1534 0 obj < /Dest[336 0 R/XYZ 56.7 417.9 0]/Parent 1483 0 R/Prev 1533 0 R/Next 1535 0 R>> endobj 1535 0 obj < /Dest[339 0 R/XYZ 56.7 713.7 0]/Parent 1483 0 R/Prev 1534 0 R/Next 1536 0 R>> endobj 1536 0 obj < /Dest[339 0 R/XYZ 56.7 472.4 0]/Parent 1483 0 R/Prev 1535 0 R/Next 1537 0 R>> endobj 1537 0 obj < /Dest[339 0 R/XYZ 56.7 368.9 0]/Parent 1483 0 R/Prev 1536 0 R/Next 1538 0 R>> endobj 1538 0 obj < /Dest[339 0 R/XYZ 56.7 191.8 0]/Parent 1483 0 R/Prev 1537 0 R/Next 1539 0 R>> endobj 1539 0 obj < /Dest[342 0 R/XYZ 56.7 645.6 0]/Parent 1483 0 R/Prev 1538 0 R/Next 1540 0 R>> endobj 1540 0 obj < /Dest[342 0 R/XYZ 56.7 416.2 0]/Parent 1483 0 R/Prev 1539 0 R/Next 1541 0 R>> endobj 1541 0 obj < /Dest[345 0 R/XYZ 56.7 603.5 0]/Parent 1483 0 R/Prev 1540 0 R/Next 1542 0 R>> endobj 1542 0 obj < /Dest[345 0 R/XYZ 56.7 513.9 0]/Parent 1483 0 R/Prev 1541 0 R/Next 1543 0 R>> endobj 1543 0 obj < /Dest[345 0 R/XYZ 56.7 141.1 0]/Parent 1483 0 R/Prev 1542 0 R/Next 1544 0 R>> endobj 1544 0 obj < /Dest[348 0 R/XYZ 56.7 660.3 0]/Parent 1483 0 R/Prev 1543 0 R/Next 1545 0 R>> endobj 1545 0 obj < /Dest[348 0 R/XYZ 56.7 570.6 0]/Parent 1483 0 R/Prev 1544 0 R/Next 1546 0 R>> endobj 1546 0 obj < /Dest[348 0 R/XYZ 56.7 488.8 0]/Parent 1483 0 R/Prev 1545 0 R/Next 1547 0 R>> endobj 1547 0 obj < /Dest[348 0 R/XYZ 56.7 258.9 0]/Parent 1483 0 R/Prev 1546 0 R/Next 1548 0 R>> endobj 1548 0 obj < /Dest[348 0 R/XYZ 56.7 169.2 0]/Parent 1483 0 R/Prev 1547 0 R/Next 1549 0 R>> endobj 1549 0 obj < /Dest[348 0 R/XYZ 56.7 93.4 0]/Parent 1483 0 R/Prev 1548 0 R/Next 1550 0 R>> endobj 1550 0 obj < /Dest[351 0 R/XYZ 56.7 662.2 0]/Parent 1483 0 R/Prev 1549 0 R/Next 1551 0 R>> endobj 1551 0 obj < /Dest[351 0 R/XYZ 56.7 558.7 0]/Parent 1483 0 R/Prev 1550 0 R/Next 1552 0 R>> endobj 1552 0 obj < /Dest[351 0 R/XYZ 56.7 482.9 0]/Parent 1483 0 R/Prev 1551 0 R/Next 1553 0 R>> endobj 1553 0 obj < /Dest[351 0 R/XYZ 56.7 179.6 0]/Parent 1483 0 R/Prev 1552 0 R/Next 1554 0 R>> endobj 1554 0 obj < /Dest[354 0 R/XYZ 56.7 572.3 0]/Parent 1483 0 R/Prev 1553 0 R/Next 1555 0 R>> endobj 1555 0 obj < /Dest[354 0 R/XYZ 56.7 295.3 0]/Parent 1483 0 R/Prev 1554 0 R/Next 1556 0 R>> endobj 1556 0 obj < /Dest[357 0 R/XYZ 56.7 561.8 0]/Parent 1483 0 R/Prev 1555 0 R/Next 1557 0 R>> endobj 1557 0 obj < /Dest[357 0 R/XYZ 56.7 211.9 0]/Parent 1483 0 R/Prev 1556 0 R/Next 1558 0 R>> endobj 1558 0 obj < /Dest[360 0 R/XYZ 56.7 719.8 0]/Parent 1483 0 R/Prev 1557 0 R/Next 1559 0 R>> endobj 1559 0 obj < /Dest[360 0 R/XYZ 56.7 342.9 0]/Parent 1483 0 R/Prev 1558 0 R/Next 1560 0 R>> endobj 1560 0 obj < /Dest[360 0 R/XYZ 56.7 109.1 0]/Parent 1483 0 R/Prev 1559 0 R/Next 1561 0 R>> endobj 1561 0 obj < /Dest[363 0 R/XYZ 56.7 601.2 0]/Parent 1483 0 R/Prev 1560 0 R/Next 1562 0 R>> endobj 1562 0 obj < /Dest[363 0 R/XYZ 56.7 367.5 0]/Parent 1483 0 R/Prev 1561 0 R/Next 1563 0 R>> endobj 1563 0 obj < /Dest[366 0 R/XYZ 56.7 702.4 0]/Parent 1483 0 R/Prev 1562 0 R/Next 1564 0 R>> endobj 1564 0 obj < /Dest[366 0 R/XYZ 56.7 317.6 0]/Parent 1483 0 R/Prev 1563 0 R/Next 1565 0 R>> endobj 1565 0 obj < /Dest[369 0 R/XYZ 56.7 418.6 0]/Parent 1483 0 R/Prev 1564 0 R/Next 1566 0 R>> endobj 1566 0 obj < /Dest[372 0 R/XYZ 56.7 640.4 0]/Parent 1483 0 R/Prev 1565 0 R/Next 1567 0 R>> endobj 1567 0 obj < /Dest[372 0 R/XYZ 56.7 434.2 0]/Parent 1483 0 R/Prev 1566 0 R>> endobj 1234 0 obj <> endobj 378 0 obj <> endobj 379 0 obj <> endobj 380 0 obj <> endobj 381 0 obj <> endobj 382 0 obj <> endobj 383 0 obj <> endobj 384 0 obj <> endobj 385 0 obj <> endobj 386 0 obj <> endobj 387 0 obj <> endobj 388 0 obj <> endobj 389 0 obj <> endobj 390 0 obj <> endobj 391 0 obj <> endobj 392 0 obj <> endobj 393 0 obj <> endobj 394 0 obj <> endobj 395 0 obj <> endobj 396 0 obj <> endobj 397 0 obj <> endobj 398 0 obj <> endobj 399 0 obj <> endobj 400 0 obj <> endobj 401 0 obj <> endobj 402 0 obj <> endobj 403 0 obj <> endobj 404 0 obj <> endobj 405 0 obj <> endobj 406 0 obj <> endobj 407 0 obj <> endobj 408 0 obj <> endobj 409 0 obj <> endobj 410 0 obj <> endobj 411 0 obj <> endobj 412 0 obj <> endobj 413 0 obj <> endobj 414 0 obj <> endobj 415 0 obj <> endobj 416 0 obj <> endobj 417 0 obj <> endobj 418 0 obj <> endobj 419 0 obj <> endobj 420 0 obj <> endobj 421 0 obj <> endobj 422 0 obj <> endobj 423 0 obj <> endobj 424 0 obj <> endobj 425 0 obj <> endobj 426 0 obj <> endobj 427 0 obj <> endobj 428 0 obj <> endobj 429 0 obj <> endobj 430 0 obj <> endobj 431 0 obj <> endobj 432 0 obj <> endobj 433 0 obj <> endobj 434 0 obj <> endobj 435 0 obj <> endobj 436 0 obj <> endobj 437 0 obj <> endobj 438 0 obj <> endobj 439 0 obj <> endobj 440 0 obj <> endobj 441 0 obj <> endobj 442 0 obj <> endobj 443 0 obj <> endobj 444 0 obj <> endobj 445 0 obj <> endobj 446 0 obj <> endobj 447 0 obj <> endobj 448 0 obj <> endobj 449 0 obj <> endobj 450 0 obj <> endobj 451 0 obj <> endobj 452 0 obj <> endobj 453 0 obj <> endobj 454 0 obj <> endobj 455 0 obj <> endobj 456 0 obj <> endobj 457 0 obj <> endobj 458 0 obj <> endobj 459 0 obj <> endobj 460 0 obj <> endobj 461 0 obj <> endobj 462 0 obj <> endobj 463 0 obj <> endobj 464 0 obj <> endobj 465 0 obj <> endobj 466 0 obj <> endobj 467 0 obj <> endobj 468 0 obj <> endobj 469 0 obj <> endobj 470 0 obj <> endobj 471 0 obj <> endobj 472 0 obj <> endobj 473 0 obj <> endobj 474 0 obj <> endobj 475 0 obj <> endobj 476 0 obj <> endobj 477 0 obj <> endobj 478 0 obj <> endobj 479 0 obj <> endobj 480 0 obj <> endobj 481 0 obj <> endobj 482 0 obj <> endobj 483 0 obj <> endobj 484 0 obj <> endobj 485 0 obj <> endobj 486 0 obj <> endobj 487 0 obj <> endobj 488 0 obj <> endobj 489 0 obj <> endobj 490 0 obj <> endobj 491 0 obj <> endobj 492 0 obj <> endobj 493 0 obj <> endobj 494 0 obj <> endobj 495 0 obj <> endobj 496 0 obj <> endobj 497 0 obj <> endobj 498 0 obj <> endobj 499 0 obj <> endobj 500 0 obj <> endobj 501 0 obj <> endobj 502 0 obj <> endobj 503 0 obj <> endobj 504 0 obj <> endobj 505 0 obj <> endobj 506 0 obj <> endobj 507 0 obj <> endobj 508 0 obj <> endobj 509 0 obj <> endobj 510 0 obj <> endobj 511 0 obj <> endobj 512 0 obj <> endobj 513 0 obj <> endobj 514 0 obj <> endobj 515 0 obj <> endobj 516 0 obj <> endobj 517 0 obj <> endobj 518 0 obj <> endobj 519 0 obj <> endobj 520 0 obj <> endobj 521 0 obj <> endobj 522 0 obj <> endobj 523 0 obj <> endobj 524 0 obj <> endobj 525 0 obj <> endobj 526 0 obj <> endobj 527 0 obj <> endobj 528 0 obj <> endobj 529 0 obj <> endobj 530 0 obj <> endobj 531 0 obj <> endobj 532 0 obj <> endobj 533 0 obj <> endobj 534 0 obj <> endobj 535 0 obj <> endobj 536 0 obj <> endobj 537 0 obj <> endobj 538 0 obj <> endobj 539 0 obj <> endobj 540 0 obj <> endobj 541 0 obj <> endobj 542 0 obj <> endobj 543 0 obj <> endobj 544 0 obj <> endobj 545 0 obj <> endobj 546 0 obj <> endobj 547 0 obj <> endobj 548 0 obj <> endobj 549 0 obj <> endobj 550 0 obj <> endobj 551 0 obj <> endobj 552 0 obj <> endobj 553 0 obj <> endobj 554 0 obj <> endobj 555 0 obj <> endobj 556 0 obj <> endobj 557 0 obj <> endobj 558 0 obj <> endobj 559 0 obj <> endobj 560 0 obj <> endobj 561 0 obj <> endobj 562 0 obj <> endobj 563 0 obj <> endobj 564 0 obj <> endobj 565 0 obj <> endobj 566 0 obj <> endobj 567 0 obj <> endobj 568 0 obj <> endobj 569 0 obj <> endobj 570 0 obj <> endobj 571 0 obj <> endobj 572 0 obj <> endobj 573 0 obj <> endobj 574 0 obj <> endobj 575 0 obj <> endobj 576 0 obj <> endobj 577 0 obj <> endobj 578 0 obj <> endobj 579 0 obj <> endobj 580 0 obj <> endobj 581 0 obj <> endobj 582 0 obj <> endobj 583 0 obj <> endobj 584 0 obj <> endobj 585 0 obj <> endobj 586 0 obj <> endobj 587 0 obj <> endobj 588 0 obj <> endobj 589 0 obj <> endobj 590 0 obj <> endobj 591 0 obj <> endobj 592 0 obj <> endobj 593 0 obj <> endobj 594 0 obj <> endobj 595 0 obj <> endobj 596 0 obj <> endobj 597 0 obj <> endobj 598 0 obj <> endobj 599 0 obj <> endobj 600 0 obj <> endobj 601 0 obj <> endobj 602 0 obj <> endobj 603 0 obj <> endobj 604 0 obj <> endobj 605 0 obj <> endobj 606 0 obj <> endobj 607 0 obj <> endobj 608 0 obj <> endobj 609 0 obj <> endobj 610 0 obj <> endobj 611 0 obj <> endobj 612 0 obj <> endobj 613 0 obj <> endobj 614 0 obj <> endobj 615 0 obj <> endobj 616 0 obj <> endobj 617 0 obj <> endobj 618 0 obj <> endobj 619 0 obj <> endobj 620 0 obj <> endobj 621 0 obj <> endobj 622 0 obj <> endobj 623 0 obj <> endobj 624 0 obj <> endobj 625 0 obj <> endobj 626 0 obj <> endobj 627 0 obj <> endobj 628 0 obj <> endobj 629 0 obj <> endobj 630 0 obj <> endobj 631 0 obj <> endobj 632 0 obj <> endobj 633 0 obj <> endobj 634 0 obj <> endobj 635 0 obj <> endobj 636 0 obj <> endobj 637 0 obj <> endobj 638 0 obj <> endobj 639 0 obj <> endobj 640 0 obj <> endobj 641 0 obj <> endobj 642 0 obj <> endobj 643 0 obj <> endobj 644 0 obj <> endobj 645 0 obj <> endobj 646 0 obj <> endobj 647 0 obj <> endobj 648 0 obj <> endobj 649 0 obj <> endobj 650 0 obj <> endobj 651 0 obj <> endobj 652 0 obj <> endobj 653 0 obj <> endobj 654 0 obj <> endobj 655 0 obj <> endobj 656 0 obj <> endobj 657 0 obj <> endobj 658 0 obj <> endobj 659 0 obj <> endobj 660 0 obj <> endobj 661 0 obj <> endobj 662 0 obj <> endobj 663 0 obj <> endobj 664 0 obj <> endobj 665 0 obj <> endobj 666 0 obj <> endobj 667 0 obj <> endobj 668 0 obj <> endobj 669 0 obj <> endobj 670 0 obj <> endobj 671 0 obj <> endobj 672 0 obj <> endobj 673 0 obj <> endobj 674 0 obj <> endobj 675 0 obj <> endobj 676 0 obj <> endobj 677 0 obj <> endobj 678 0 obj <> endobj 679 0 obj <> endobj 680 0 obj <> endobj 681 0 obj <> endobj 682 0 obj <> endobj 683 0 obj <> endobj 684 0 obj <> endobj 685 0 obj <> endobj 686 0 obj <> endobj 687 0 obj <> endobj 688 0 obj <> endobj 689 0 obj <> endobj 690 0 obj <> endobj 691 0 obj <> endobj 692 0 obj <> endobj 693 0 obj <> endobj 694 0 obj <> endobj 695 0 obj <> endobj 696 0 obj <> endobj 697 0 obj <> endobj 698 0 obj <> endobj 699 0 obj <> endobj 700 0 obj <> endobj 701 0 obj <> endobj 702 0 obj <> endobj 703 0 obj <> endobj 704 0 obj <> endobj 705 0 obj <> endobj 706 0 obj <> endobj 707 0 obj <> endobj 708 0 obj <> endobj 709 0 obj <> endobj 710 0 obj <> endobj 711 0 obj <> endobj 712 0 obj <> endobj 713 0 obj <> endobj 714 0 obj <> endobj 715 0 obj <> endobj 716 0 obj <> endobj 717 0 obj <> endobj 718 0 obj <> endobj 719 0 obj <> endobj 720 0 obj <> endobj 721 0 obj <> endobj 722 0 obj <> endobj 723 0 obj <> endobj 724 0 obj <> endobj 725 0 obj <> endobj 726 0 obj <> endobj 727 0 obj <> endobj 728 0 obj <> endobj 729 0 obj <> endobj 730 0 obj <> endobj 731 0 obj <> endobj 732 0 obj <> endobj 733 0 obj <> endobj 734 0 obj <> endobj 735 0 obj <> endobj 736 0 obj <> endobj 737 0 obj <> endobj 738 0 obj <> endobj 739 0 obj <> endobj 740 0 obj <> endobj 741 0 obj <> endobj 742 0 obj <> endobj 743 0 obj <> endobj 744 0 obj <> endobj 745 0 obj <> endobj 746 0 obj <> endobj 747 0 obj <> endobj 748 0 obj <> endobj 749 0 obj <> endobj 750 0 obj <> endobj 751 0 obj <> endobj 752 0 obj <> endobj 753 0 obj <> endobj 754 0 obj <> endobj 755 0 obj <> endobj 756 0 obj <> endobj 757 0 obj <> endobj 758 0 obj <> endobj 759 0 obj <> endobj 760 0 obj <> endobj 761 0 obj <> endobj 762 0 obj <> endobj 763 0 obj <> endobj 764 0 obj <> endobj 765 0 obj <> endobj 766 0 obj <> endobj 767 0 obj <> endobj 768 0 obj <> endobj 769 0 obj <> endobj 770 0 obj <> endobj 771 0 obj <> endobj 772 0 obj <> endobj 773 0 obj <> endobj 774 0 obj <> endobj 775 0 obj <> endobj 776 0 obj <> endobj 777 0 obj <> endobj 778 0 obj <> endobj 779 0 obj <> endobj 780 0 obj <> endobj 781 0 obj <> endobj 782 0 obj <> endobj 783 0 obj <> endobj 784 0 obj <> endobj 785 0 obj <> endobj 786 0 obj <> endobj 787 0 obj <> endobj 788 0 obj <> endobj 789 0 obj <> endobj 790 0 obj <> endobj 791 0 obj <> endobj 792 0 obj <> endobj 793 0 obj <> endobj 794 0 obj <> endobj 795 0 obj <> endobj 796 0 obj <> endobj 797 0 obj <> endobj 798 0 obj <> endobj 799 0 obj <> endobj 800 0 obj <> endobj 801 0 obj <> endobj 802 0 obj <> endobj 803 0 obj <> endobj 804 0 obj <> endobj 805 0 obj <> endobj 806 0 obj <> endobj 807 0 obj <> endobj 808 0 obj <> endobj 809 0 obj <> endobj 810 0 obj <> endobj 811 0 obj <> endobj 812 0 obj <> endobj 813 0 obj <> endobj 814 0 obj <> endobj 815 0 obj <> endobj 816 0 obj <> endobj 817 0 obj <> endobj 818 0 obj <> endobj 819 0 obj <> endobj 820 0 obj <> endobj 821 0 obj <> endobj 822 0 obj <> endobj 823 0 obj <> endobj 824 0 obj <> endobj 825 0 obj <> endobj 826 0 obj <> endobj 827 0 obj <> endobj 828 0 obj <> endobj 829 0 obj <> endobj 830 0 obj <> endobj 831 0 obj <> endobj 832 0 obj <> endobj 833 0 obj <> endobj 834 0 obj <> endobj 835 0 obj <> endobj 836 0 obj <> endobj 837 0 obj <> endobj 838 0 obj <> endobj 839 0 obj <> endobj 840 0 obj <> endobj 841 0 obj <> endobj 842 0 obj <> endobj 843 0 obj <> endobj 844 0 obj <> endobj 845 0 obj <> endobj 846 0 obj <> endobj 847 0 obj <> endobj 848 0 obj <> endobj 849 0 obj <> endobj 850 0 obj <> endobj 851 0 obj <> endobj 852 0 obj <> endobj 853 0 obj <> endobj 854 0 obj <> endobj 855 0 obj <> endobj 856 0 obj <> endobj 857 0 obj <> endobj 858 0 obj <> endobj 859 0 obj <> endobj 860 0 obj <> endobj 861 0 obj <> endobj 862 0 obj <> endobj 863 0 obj <> endobj 864 0 obj <> endobj 865 0 obj <> endobj 866 0 obj <> endobj 867 0 obj <> endobj 868 0 obj <> endobj 869 0 obj <> endobj 870 0 obj <> endobj 871 0 obj <> endobj 872 0 obj <> endobj 873 0 obj <> endobj 874 0 obj <> endobj 875 0 obj <> endobj 876 0 obj <> endobj 877 0 obj <> endobj 878 0 obj <> endobj 879 0 obj <> endobj 880 0 obj <> endobj 881 0 obj <> endobj 882 0 obj <> endobj 883 0 obj <> endobj 884 0 obj <> endobj 885 0 obj <> endobj 886 0 obj <> endobj 887 0 obj <> endobj 888 0 obj <> endobj 889 0 obj <> endobj 890 0 obj <> endobj 891 0 obj <> endobj 892 0 obj <> endobj 893 0 obj <> endobj 894 0 obj <> endobj 895 0 obj <> endobj 896 0 obj <> endobj 897 0 obj <> endobj 898 0 obj <> endobj 899 0 obj <> endobj 900 0 obj <> endobj 901 0 obj <> endobj 902 0 obj <> endobj 903 0 obj <> endobj 904 0 obj <> endobj 905 0 obj <> endobj 906 0 obj <> endobj 907 0 obj <> endobj 908 0 obj <> endobj 909 0 obj <> endobj 910 0 obj <> endobj 911 0 obj <> endobj 912 0 obj <> endobj 913 0 obj <> endobj 914 0 obj <> endobj 915 0 obj <> endobj 916 0 obj <> endobj 917 0 obj <> endobj 918 0 obj <> endobj 919 0 obj <> endobj 920 0 obj <> endobj 921 0 obj <> endobj 922 0 obj <> endobj 923 0 obj <> endobj 924 0 obj <> endobj 925 0 obj <> endobj 926 0 obj <> endobj 927 0 obj <> endobj 928 0 obj <> endobj 929 0 obj <> endobj 930 0 obj <> endobj 931 0 obj <> endobj 932 0 obj <> endobj 933 0 obj <> endobj 934 0 obj <> endobj 935 0 obj <> endobj 936 0 obj <> endobj 937 0 obj <> endobj 938 0 obj <> endobj 939 0 obj <> endobj 940 0 obj <> endobj 941 0 obj <> endobj 942 0 obj <> endobj 943 0 obj <> endobj 944 0 obj <> endobj 945 0 obj <> endobj 946 0 obj <> endobj 947 0 obj <> endobj 948 0 obj <> endobj 949 0 obj <> endobj 950 0 obj <> endobj 951 0 obj <> endobj 952 0 obj <> endobj 953 0 obj <> endobj 954 0 obj <> endobj 955 0 obj <> endobj 956 0 obj <> endobj 957 0 obj <> endobj 958 0 obj <> endobj 959 0 obj <> endobj 960 0 obj <> endobj 961 0 obj <> endobj 962 0 obj <> endobj 963 0 obj <> endobj 964 0 obj <> endobj 965 0 obj <> endobj 966 0 obj <> endobj 967 0 obj <> endobj 968 0 obj <> endobj 969 0 obj <> endobj 970 0 obj <> endobj 971 0 obj <> endobj 972 0 obj <> endobj 973 0 obj <> endobj 974 0 obj <> endobj 975 0 obj <> endobj 976 0 obj <> endobj 977 0 obj <> endobj 978 0 obj <> endobj 979 0 obj <> endobj 980 0 obj <> endobj 981 0 obj <> endobj 982 0 obj <> endobj 983 0 obj <> endobj 984 0 obj <> endobj 985 0 obj <> >> endobj 986 0 obj <> endobj 987 0 obj <> endobj 988 0 obj <> endobj 989 0 obj <> endobj 990 0 obj <> endobj 991 0 obj <> endobj 992 0 obj <> endobj 993 0 obj <> endobj 994 0 obj <> endobj 995 0 obj <> endobj 996 0 obj <> endobj 997 0 obj <> endobj 998 0 obj <> endobj 999 0 obj <> endobj 1000 0 obj <> endobj 1001 0 obj <> endobj 1002 0 obj <> endobj 1003 0 obj <> endobj 1004 0 obj <> endobj 1005 0 obj <> endobj 1006 0 obj <> endobj 1007 0 obj <> endobj 1008 0 obj <> endobj 1009 0 obj <> endobj 1010 0 obj <> endobj 1011 0 obj <> endobj 1012 0 obj <> endobj 1013 0 obj <> endobj 1014 0 obj <> endobj 1015 0 obj <> endobj 1016 0 obj <> endobj 1017 0 obj <> endobj 1018 0 obj <> endobj 1019 0 obj <> endobj 1020 0 obj <> endobj 1021 0 obj <> endobj 1022 0 obj <> endobj 1023 0 obj <> endobj 1024 0 obj <> endobj 1025 0 obj <> endobj 1026 0 obj <> endobj 1027 0 obj <> endobj 1028 0 obj <> endobj 1029 0 obj <> endobj 1030 0 obj <> endobj 1031 0 obj <> endobj 1032 0 obj <> endobj 1033 0 obj <> endobj 1034 0 obj <> endobj 1035 0 obj <> endobj 1036 0 obj <> endobj 1037 0 obj <> endobj 1038 0 obj <> endobj 1039 0 obj <> endobj 1040 0 obj <> endobj 1041 0 obj <> endobj 1042 0 obj <> endobj 1043 0 obj <> endobj 1044 0 obj <> endobj 1045 0 obj <> endobj 1046 0 obj <> endobj 1047 0 obj <> endobj 1048 0 obj <> endobj 1049 0 obj <> endobj 1050 0 obj <> endobj 1051 0 obj <> endobj 1052 0 obj <> endobj 1053 0 obj <> endobj 1054 0 obj <> endobj 1055 0 obj <> endobj 1056 0 obj <> endobj 1057 0 obj <> endobj 1058 0 obj <> endobj 1059 0 obj <> endobj 1060 0 obj <> endobj 1061 0 obj <> endobj 1062 0 obj <> endobj 1063 0 obj <> endobj 1064 0 obj <> endobj 1065 0 obj <> endobj 1066 0 obj <> endobj 1067 0 obj <> endobj 1068 0 obj <> endobj 1069 0 obj <> endobj 1070 0 obj <> endobj 1071 0 obj <> endobj 1072 0 obj <> endobj 1073 0 obj <> endobj 1074 0 obj <> endobj 1075 0 obj <> endobj 1076 0 obj <> endobj 1077 0 obj <> endobj 1078 0 obj <> endobj 1079 0 obj <> endobj 1080 0 obj <> endobj 1081 0 obj <> endobj 1082 0 obj <> endobj 1083 0 obj <> endobj 1084 0 obj <> endobj 1085 0 obj <> endobj 1086 0 obj <> endobj 1087 0 obj <> endobj 1088 0 obj <> endobj 1089 0 obj <> endobj 1090 0 obj <> endobj 1091 0 obj <> endobj 1092 0 obj <> endobj 1093 0 obj <> endobj 1094 0 obj <> endobj 1095 0 obj <> endobj 1096 0 obj <> endobj 1097 0 obj <> >> endobj 1098 0 obj <> >> endobj 1099 0 obj <> endobj 1100 0 obj <> endobj 1101 0 obj <> endobj 1102 0 obj <> endobj 1103 0 obj <> endobj 1104 0 obj <> >> endobj 1105 0 obj <> endobj 1106 0 obj <> endobj 1107 0 obj <> endobj 1108 0 obj <> endobj 1109 0 obj <> endobj 1110 0 obj <> endobj 1111 0 obj <> endobj 1112 0 obj <> endobj 1113 0 obj <> endobj 1114 0 obj <> endobj 1115 0 obj <> endobj 1116 0 obj <> endobj 1117 0 obj <> endobj 1118 0 obj <> endobj 1119 0 obj <> endobj 1120 0 obj <> endobj 1121 0 obj <> endobj 1122 0 obj <> endobj 1123 0 obj <> endobj 1124 0 obj <> endobj 1125 0 obj <> endobj 1126 0 obj <> endobj 1127 0 obj <> endobj 1128 0 obj <> endobj 1129 0 obj <> endobj 1130 0 obj <> endobj 1131 0 obj <> endobj 1132 0 obj <> endobj 1133 0 obj <> endobj 1134 0 obj <> endobj 1135 0 obj <> endobj 1136 0 obj <> endobj 1137 0 obj <> endobj 1138 0 obj <> endobj 1139 0 obj <> endobj 1140 0 obj <> endobj 1141 0 obj <> endobj 1142 0 obj <> endobj 1143 0 obj <> endobj 1144 0 obj <> endobj 1145 0 obj <> endobj 1146 0 obj <> endobj 1147 0 obj <> endobj 1148 0 obj <> endobj 1149 0 obj <> >> endobj 1150 0 obj <> >> endobj 1151 0 obj <> endobj 1152 0 obj <> endobj 1153 0 obj <> endobj 1154 0 obj <> endobj 1155 0 obj <> endobj 1156 0 obj <> endobj 1157 0 obj <> endobj 1158 0 obj <> endobj 1159 0 obj <> endobj 1160 0 obj <> endobj 1161 0 obj <> endobj 1162 0 obj <> endobj 1163 0 obj <> endobj 1164 0 obj <> endobj 1165 0 obj <> endobj 1166 0 obj <> endobj 1167 0 obj <> endobj 1168 0 obj <> endobj 1169 0 obj <> endobj 1170 0 obj <> endobj 1171 0 obj <> endobj 1172 0 obj <> endobj 1173 0 obj <> endobj 1174 0 obj <> endobj 1175 0 obj <> >> endobj 1176 0 obj <> endobj 1177 0 obj <> endobj 1178 0 obj <> endobj 1179 0 obj <> endobj 1180 0 obj <> endobj 1181 0 obj <> endobj 1182 0 obj <> endobj 1183 0 obj <> endobj 1184 0 obj <> endobj 1185 0 obj <> endobj 1186 0 obj <> endobj 1187 0 obj <> endobj 1188 0 obj <> endobj 1189 0 obj <> endobj 1190 0 obj <> endobj 1191 0 obj <> endobj 1192 0 obj <> endobj 1193 0 obj <> endobj 1194 0 obj <> endobj 1195 0 obj <> endobj 1196 0 obj <> endobj 1197 0 obj <> endobj 1198 0 obj <> endobj 1199 0 obj <> endobj 1200 0 obj <> >> endobj 1201 0 obj <> endobj 1202 0 obj <> endobj 1203 0 obj <> endobj 1204 0 obj <> endobj 1205 0 obj <> >> endobj 1206 0 obj <> endobj 1207 0 obj <> endobj 1208 0 obj <> endobj 1209 0 obj <> endobj 1210 0 obj <> endobj 1211 0 obj <> endobj 1212 0 obj <> endobj 1213 0 obj <> endobj 1214 0 obj <> >> endobj 1215 0 obj <> endobj 1216 0 obj <> endobj 1217 0 obj <> endobj 1218 0 obj <> endobj 1219 0 obj <> endobj 1220 0 obj <> endobj 1221 0 obj <> endobj 1222 0 obj <> endobj 1223 0 obj <> endobj 1224 0 obj <> endobj 1225 0 obj <> endobj 1226 0 obj <> endobj 1227 0 obj <> endobj 1228 0 obj <> endobj 1229 0 obj <> >> endobj 1230 0 obj <> >> endobj 1231 0 obj <> >> endobj 1232 0 obj <> >> endobj 1233 0 obj <> >> endobj 1568 0 obj <> endobj 1569 0 obj < /Producer /CreationDate(D:20121212174110+01'00')>> endobj xref 0 1570 0000000000 65535 f 0000427367 00000 n 0000000019 00000 n 0000002433 00000 n 0000427902 00000 n 0000002454 00000 n 0000004854 00000 n 0000428477 00000 n 0000004875 00000 n 0000007512 00000 n 0000429052 00000 n 0000007533 00000 n 0000009932 00000 n 0000429629 00000 n 0000009954 00000 n 0000012371 00000 n 0000430206 00000 n 0000012393 00000 n 0000014624 00000 n 0000430727 00000 n 0000014646 00000 n 0000016252 00000 n 0000431344 00000 n 0000016274 00000 n 0000017535 00000 n 0000431881 00000 n 0000017557 00000 n 0000019056 00000 n 0000432434 00000 n 0000019078 00000 n 0000020441 00000 n 0000432923 00000 n 0000020463 00000 n 0000021978 00000 n 0000433500 00000 n 0000022000 00000 n 0000023292 00000 n 0000434069 00000 n 0000023314 00000 n 0000026052 00000 n 0000434304 00000 n 0000026074 00000 n 0000028677 00000 n 0000028699 00000 n 0000029737 00000 n 0000029758 00000 n 0000030148 00000 n 0000434573 00000 n 0000030169 00000 n 0000032492 00000 n 0000434770 00000 n 0000032514 00000 n 0000035382 00000 n 0000434920 00000 n 0000035404 00000 n 0000037628 00000 n 0000435090 00000 n 0000037650 00000 n 0000040092 00000 n 0000435240 00000 n 0000040114 00000 n 0000041728 00000 n 0000435390 00000 n 0000041750 00000 n 0000044022 00000 n 0000435540 00000 n 0000044044 00000 n 0000046095 00000 n 0000435737 00000 n 0000046117 00000 n 0000048630 00000 n 0000435887 00000 n 0000048652 00000 n 0000050748 00000 n 0000436057 00000 n 0000050770 00000 n 0000052732 00000 n 0000436207 00000 n 0000052754 00000 n 0000054038 00000 n 0000436395 00000 n 0000054060 00000 n 0000055233 00000 n 0000055255 00000 n 0000101137 00000 n 0000101160 00000 n 0000101868 00000 n 0000436565 00000 n 0000101889 00000 n 0000103735 00000 n 0000436735 00000 n 0000103757 00000 n 0000106219 00000 n 0000436950 00000 n 0000106241 00000 n 0000108596 00000 n 0000437183 00000 n 0000108618 00000 n 0000110400 00000 n 0000437380 00000 n 0000110422 00000 n 0000111892 00000 n 0000437569 00000 n 0000111915 00000 n 0000113898 00000 n 0000437721 00000 n 0000113921 00000 n 0000115615 00000 n 0000437873 00000 n 0000115638 00000 n 0000117307 00000 n 0000438054 00000 n 0000117330 00000 n 0000118876 00000 n 0000438235 00000 n 0000118899 00000 n 0000120616 00000 n 0000438407 00000 n 0000120639 00000 n 0000122467 00000 n 0000438559 00000 n 0000122490 00000 n 0000123969 00000 n 0000438749 00000 n 0000123992 00000 n 0000125725 00000 n 0000438921 00000 n 0000125748 00000 n 0000128029 00000 n 0000439111 00000 n 0000128052 00000 n 0000129641 00000 n 0000439319 00000 n 0000129664 00000 n 0000131434 00000 n 0000439536 00000 n 0000131457 00000 n 0000133443 00000 n 0000439688 00000 n 0000133466 00000 n 0000135219 00000 n 0000439840 00000 n 0000135242 00000 n 0000136889 00000 n 0000440012 00000 n 0000136912 00000 n 0000138096 00000 n 0000440164 00000 n 0000138119 00000 n 0000139810 00000 n 0000440345 00000 n 0000139833 00000 n 0000142288 00000 n 0000440526 00000 n 0000142311 00000 n 0000144996 00000 n 0000440698 00000 n 0000145019 00000 n 0000146965 00000 n 0000440879 00000 n 0000146988 00000 n 0000148735 00000 n 0000441031 00000 n 0000148758 00000 n 0000150406 00000 n 0000441183 00000 n 0000150429 00000 n 0000152408 00000 n 0000441335 00000 n 0000152431 00000 n 0000154057 00000 n 0000441525 00000 n 0000154080 00000 n 0000155551 00000 n 0000441706 00000 n 0000155574 00000 n 0000157287 00000 n 0000441887 00000 n 0000157310 00000 n 0000159151 00000 n 0000442059 00000 n 0000159174 00000 n 0000161223 00000 n 0000442267 00000 n 0000161246 00000 n 0000163249 00000 n 0000442457 00000 n 0000163272 00000 n 0000165441 00000 n 0000442629 00000 n 0000165464 00000 n 0000167557 00000 n 0000442810 00000 n 0000167580 00000 n 0000170094 00000 n 0000442962 00000 n 0000170117 00000 n 0000172463 00000 n 0000443143 00000 n 0000172486 00000 n 0000174743 00000 n 0000443378 00000 n 0000174766 00000 n 0000176745 00000 n 0000443568 00000 n 0000176768 00000 n 0000179376 00000 n 0000443812 00000 n 0000179399 00000 n 0000182207 00000 n 0000444011 00000 n 0000182230 00000 n 0000184576 00000 n 0000444210 00000 n 0000184599 00000 n 0000186752 00000 n 0000444382 00000 n 0000186775 00000 n 0000188631 00000 n 0000444563 00000 n 0000188654 00000 n 0000190553 00000 n 0000444735 00000 n 0000190576 00000 n 0000192182 00000 n 0000444907 00000 n 0000192205 00000 n 0000193465 00000 n 0000445079 00000 n 0000193488 00000 n 0000194745 00000 n 0000445251 00000 n 0000194768 00000 n 0000195961 00000 n 0000445423 00000 n 0000195984 00000 n 0000197295 00000 n 0000445575 00000 n 0000197318 00000 n 0000198676 00000 n 0000445747 00000 n 0000198699 00000 n 0000200095 00000 n 0000445899 00000 n 0000200118 00000 n 0000201752 00000 n 0000446080 00000 n 0000201775 00000 n 0000203482 00000 n 0000446252 00000 n 0000203505 00000 n 0000205305 00000 n 0000446424 00000 n 0000205328 00000 n 0000206900 00000 n 0000446605 00000 n 0000206923 00000 n 0000208834 00000 n 0000446757 00000 n 0000208857 00000 n 0000210201 00000 n 0000210224 00000 n 0000212915 00000 n 0000213123 00000 n 0000446956 00000 n 0000213144 00000 n 0000215339 00000 n 0000447164 00000 n 0000215362 00000 n 0000217344 00000 n 0000447354 00000 n 0000217367 00000 n 0000218989 00000 n 0000447535 00000 n 0000219012 00000 n 0000220843 00000 n 0000447725 00000 n 0000220866 00000 n 0000222502 00000 n 0000447877 00000 n 0000222525 00000 n 0000225158 00000 n 0000448130 00000 n 0000225181 00000 n 0000227479 00000 n 0000448401 00000 n 0000227502 00000 n 0000230093 00000 n 0000448591 00000 n 0000230116 00000 n 0000232154 00000 n 0000448763 00000 n 0000232177 00000 n 0000234261 00000 n 0000448935 00000 n 0000234284 00000 n 0000236056 00000 n 0000449125 00000 n 0000236079 00000 n 0000238106 00000 n 0000449306 00000 n 0000238129 00000 n 0000239628 00000 n 0000449458 00000 n 0000239651 00000 n 0000241614 00000 n 0000449657 00000 n 0000241637 00000 n 0000243143 00000 n 0000449829 00000 n 0000243166 00000 n 0000245426 00000 n 0000450019 00000 n 0000245449 00000 n 0000247228 00000 n 0000450227 00000 n 0000247251 00000 n 0000249200 00000 n 0000450399 00000 n 0000249223 00000 n 0000251055 00000 n 0000450589 00000 n 0000251078 00000 n 0000252750 00000 n 0000450741 00000 n 0000252773 00000 n 0000255241 00000 n 0000450931 00000 n 0000255264 00000 n 0000256830 00000 n 0000451083 00000 n 0000256853 00000 n 0000258247 00000 n 0000451255 00000 n 0000258270 00000 n 0000260517 00000 n 0000451481 00000 n 0000260540 00000 n 0000262380 00000 n 0000451671 00000 n 0000262403 00000 n 0000264331 00000 n 0000451879 00000 n 0000264354 00000 n 0000266647 00000 n 0000452069 00000 n 0000266670 00000 n 0000268300 00000 n 0000452221 00000 n 0000268323 00000 n 0000270302 00000 n 0000452401 00000 n 0000270325 00000 n 0000272140 00000 n 0000452553 00000 n 0000272163 00000 n 0000274207 00000 n 0000452732 00000 n 0000274230 00000 n 0000276157 00000 n 0000452919 00000 n 0000276180 00000 n 0000277654 00000 n 0000453122 00000 n 0000277677 00000 n 0000279453 00000 n 0000453301 00000 n 0000279476 00000 n 0000281331 00000 n 0000453480 00000 n 0000281354 00000 n 0000283267 00000 n 0000453651 00000 n 0000283290 00000 n 0000285564 00000 n 0000453830 00000 n 0000285587 00000 n 0000285945 00000 n 0000505615 00000 n 0000505734 00000 n 0000505855 00000 n 0000505976 00000 n 0000506097 00000 n 0000506218 00000 n 0000506339 00000 n 0000506460 00000 n 0000506581 00000 n 0000506702 00000 n 0000506823 00000 n 0000506944 00000 n 0000507065 00000 n 0000507186 00000 n 0000507307 00000 n 0000507428 00000 n 0000507549 00000 n 0000507670 00000 n 0000507789 00000 n 0000507910 00000 n 0000508030 00000 n 0000508151 00000 n 0000508272 00000 n 0000508393 00000 n 0000508514 00000 n 0000508635 00000 n 0000508756 00000 n 0000508877 00000 n 0000508998 00000 n 0000509119 00000 n 0000509240 00000 n 0000509361 00000 n 0000509482 00000 n 0000509603 00000 n 0000509724 00000 n 0000509845 00000 n 0000509966 00000 n 0000510087 00000 n 0000510206 00000 n 0000510327 00000 n 0000510447 00000 n 0000510568 00000 n 0000510689 00000 n 0000510810 00000 n 0000510929 00000 n 0000511050 00000 n 0000511171 00000 n 0000511290 00000 n 0000511409 00000 n 0000511529 00000 n 0000511650 00000 n 0000511771 00000 n 0000511892 00000 n 0000512012 00000 n 0000512133 00000 n 0000512254 00000 n 0000512375 00000 n 0000512494 00000 n 0000512615 00000 n 0000512736 00000 n 0000512855 00000 n 0000512976 00000 n 0000513097 00000 n 0000513218 00000 n 0000513339 00000 n 0000513460 00000 n 0000513580 00000 n 0000513701 00000 n 0000513822 00000 n 0000513941 00000 n 0000514062 00000 n 0000514183 00000 n 0000514304 00000 n 0000514425 00000 n 0000514546 00000 n 0000514665 00000 n 0000514786 00000 n 0000514907 00000 n 0000515028 00000 n 0000515149 00000 n 0000515270 00000 n 0000515391 00000 n 0000515512 00000 n 0000515633 00000 n 0000515751 00000 n 0000515872 00000 n 0000515993 00000 n 0000516112 00000 n 0000516233 00000 n 0000516354 00000 n 0000516475 00000 n 0000516596 00000 n 0000516717 00000 n 0000516838 00000 n 0000516959 00000 n 0000517078 00000 n 0000517199 00000 n 0000517320 00000 n 0000517441 00000 n 0000517560 00000 n 0000517679 00000 n 0000517799 00000 n 0000517920 00000 n 0000518041 00000 n 0000518162 00000 n 0000518281 00000 n 0000518402 00000 n 0000518523 00000 n 0000518644 00000 n 0000518763 00000 n 0000518884 00000 n 0000519005 00000 n 0000519126 00000 n 0000519247 00000 n 0000519368 00000 n 0000519489 00000 n 0000519610 00000 n 0000519731 00000 n 0000519851 00000 n 0000519972 00000 n 0000520093 00000 n 0000520214 00000 n 0000520335 00000 n 0000520456 00000 n 0000520575 00000 n 0000520696 00000 n 0000520817 00000 n 0000520938 00000 n 0000521059 00000 n 0000521180 00000 n 0000521301 00000 n 0000521422 00000 n 0000521543 00000 n 0000521664 00000 n 0000521783 00000 n 0000521904 00000 n 0000522023 00000 n 0000522144 00000 n 0000522265 00000 n 0000522386 00000 n 0000522505 00000 n 0000522626 00000 n 0000522747 00000 n 0000522868 00000 n 0000522989 00000 n 0000523108 00000 n 0000523229 00000 n 0000523350 00000 n 0000523469 00000 n 0000523590 00000 n 0000523711 00000 n 0000523830 00000 n 0000523949 00000 n 0000524069 00000 n 0000524190 00000 n 0000524311 00000 n 0000524430 00000 n 0000524551 00000 n 0000524672 00000 n 0000524793 00000 n 0000524914 00000 n 0000525035 00000 n 0000525156 00000 n 0000525275 00000 n 0000525396 00000 n 0000525517 00000 n 0000525638 00000 n 0000525759 00000 n 0000525880 00000 n 0000526001 00000 n 0000526122 00000 n 0000526243 00000 n 0000526364 00000 n 0000526485 00000 n 0000526606 00000 n 0000526727 00000 n 0000526846 00000 n 0000526967 00000 n 0000527088 00000 n 0000527209 00000 n 0000527330 00000 n 0000527451 00000 n 0000527572 00000 n 0000527692 00000 n 0000527811 00000 n 0000527932 00000 n 0000528053 00000 n 0000528174 00000 n 0000528295 00000 n 0000528416 00000 n 0000528537 00000 n 0000528658 00000 n 0000528779 00000 n 0000528900 00000 n 0000529021 00000 n 0000529142 00000 n 0000529261 00000 n 0000529382 00000 n 0000529503 00000 n 0000529622 00000 n 0000529741 00000 n 0000529862 00000 n 0000529983 00000 n 0000530102 00000 n 0000530221 00000 n 0000530341 00000 n 0000530462 00000 n 0000530583 00000 n 0000530704 00000 n 0000530825 00000 n 0000530946 00000 n 0000531067 00000 n 0000531188 00000 n 0000531309 00000 n 0000531428 00000 n 0000531549 00000 n 0000531670 00000 n 0000531789 00000 n 0000531908 00000 n 0000532029 00000 n 0000532150 00000 n 0000532271 00000 n 0000532392 00000 n 0000532513 00000 n 0000532634 00000 n 0000532755 00000 n 0000532876 00000 n 0000532997 00000 n 0000533118 00000 n 0000533239 00000 n 0000533360 00000 n 0000533481 00000 n 0000533601 00000 n 0000533722 00000 n 0000533843 00000 n 0000533964 00000 n 0000534085 00000 n 0000534206 00000 n 0000534327 00000 n 0000534448 00000 n 0000534569 00000 n 0000534690 00000 n 0000534811 00000 n 0000534931 00000 n 0000535049 00000 n 0000535169 00000 n 0000535289 00000 n 0000535409 00000 n 0000535529 00000 n 0000535649 00000 n 0000535769 00000 n 0000535889 00000 n 0000536009 00000 n 0000536129 00000 n 0000536249 00000 n 0000536367 00000 n 0000536485 00000 n 0000536604 00000 n 0000536724 00000 n 0000536844 00000 n 0000536962 00000 n 0000537082 00000 n 0000537202 00000 n 0000537322 00000 n 0000537442 00000 n 0000537560 00000 n 0000537680 00000 n 0000537800 00000 n 0000537920 00000 n 0000538040 00000 n 0000538160 00000 n 0000538280 00000 n 0000538400 00000 n 0000538518 00000 n 0000538638 00000 n 0000538758 00000 n 0000538878 00000 n 0000538998 00000 n 0000539116 00000 n 0000539236 00000 n 0000539356 00000 n 0000539476 00000 n 0000539596 00000 n 0000539716 00000 n 0000539836 00000 n 0000539956 00000 n 0000540076 00000 n 0000540196 00000 n 0000540316 00000 n 0000540436 00000 n 0000540556 00000 n 0000540676 00000 n 0000540796 00000 n 0000540916 00000 n 0000541036 00000 n 0000541154 00000 n 0000541272 00000 n 0000541392 00000 n 0000541512 00000 n 0000541630 00000 n 0000541748 00000 n 0000541866 00000 n 0000541987 00000 n 0000542108 00000 n 0000542229 00000 n 0000542350 00000 n 0000542471 00000 n 0000542590 00000 n 0000542711 00000 n 0000542832 00000 n 0000542949 00000 n 0000543070 00000 n 0000543189 00000 n 0000543310 00000 n 0000543431 00000 n 0000543550 00000 n 0000543671 00000 n 0000543792 00000 n 0000543912 00000 n 0000544031 00000 n 0000544146 00000 n 0000544267 00000 n 0000544388 00000 n 0000544509 00000 n 0000544630 00000 n 0000544751 00000 n 0000544871 00000 n 0000544992 00000 n 0000545111 00000 n 0000545232 00000 n 0000545353 00000 n 0000545474 00000 n 0000545594 00000 n 0000545713 00000 n 0000545834 00000 n 0000545954 00000 n 0000546070 00000 n 0000546191 00000 n 0000546312 00000 n 0000546433 00000 n 0000546552 00000 n 0000546673 00000 n 0000546792 00000 n 0000546913 00000 n 0000547034 00000 n 0000547153 00000 n 0000547273 00000 n 0000547394 00000 n 0000547515 00000 n 0000547636 00000 n 0000547757 00000 n 0000547878 00000 n 0000547999 00000 n 0000548120 00000 n 0000548241 00000 n 0000548362 00000 n 0000548483 00000 n 0000548604 00000 n 0000548725 00000 n 0000548846 00000 n 0000548967 00000 n 0000549088 00000 n 0000549209 00000 n 0000549328 00000 n 0000549449 00000 n 0000549569 00000 n 0000549690 00000 n 0000549811 00000 n 0000549932 00000 n 0000550053 00000 n 0000550174 00000 n 0000550295 00000 n 0000550416 00000 n 0000550537 00000 n 0000550658 00000 n 0000550779 00000 n 0000550898 00000 n 0000551019 00000 n 0000551140 00000 n 0000551261 00000 n 0000551382 00000 n 0000551501 00000 n 0000551618 00000 n 0000551737 00000 n 0000551856 00000 n 0000551973 00000 n 0000552092 00000 n 0000552213 00000 n 0000552334 00000 n 0000552455 00000 n 0000552574 00000 n 0000552693 00000 n 0000552814 00000 n 0000552933 00000 n 0000553053 00000 n 0000553174 00000 n 0000553295 00000 n 0000553416 00000 n 0000553535 00000 n 0000553656 00000 n 0000553777 00000 n 0000553896 00000 n 0000554017 00000 n 0000554138 00000 n 0000554259 00000 n 0000554378 00000 n 0000554496 00000 n 0000554617 00000 n 0000554738 00000 n 0000554857 00000 n 0000554978 00000 n 0000555099 00000 n 0000555220 00000 n 0000555341 00000 n 0000555462 00000 n 0000555581 00000 n 0000555702 00000 n 0000555823 00000 n 0000555944 00000 n 0000556065 00000 n 0000556186 00000 n 0000556307 00000 n 0000556428 00000 n 0000556549 00000 n 0000556670 00000 n 0000556787 00000 n 0000556908 00000 n 0000557027 00000 n 0000557148 00000 n 0000557269 00000 n 0000557390 00000 n 0000557509 00000 n 0000557628 00000 n 0000557747 00000 n 0000557868 00000 n 0000557987 00000 n 0000558108 00000 n 0000558227 00000 n 0000558348 00000 n 0000558469 00000 n 0000558588 00000 n 0000558709 00000 n 0000558828 00000 n 0000558949 00000 n 0000559070 00000 n 0000559191 00000 n 0000559312 00000 n 0000559433 00000 n 0000559554 00000 n 0000559675 00000 n 0000559796 00000 n 0000559916 00000 n 0000560037 00000 n 0000560158 00000 n 0000560279 00000 n 0000560400 00000 n 0000560521 00000 n 0000560640 00000 n 0000560761 00000 n 0000560882 00000 n 0000561003 00000 n 0000561124 00000 n 0000561245 00000 n 0000561366 00000 n 0000561487 00000 n 0000561608 00000 n 0000561729 00000 n 0000561850 00000 n 0000561969 00000 n 0000562090 00000 n 0000562211 00000 n 0000562330 00000 n 0000562451 00000 n 0000562572 00000 n 0000562688 00000 n 0000562809 00000 n 0000562928 00000 n 0000563049 00000 n 0000563168 00000 n 0000563285 00000 n 0000563406 00000 n 0000563527 00000 n 0000563646 00000 n 0000563765 00000 n 0000563884 00000 n 0000564005 00000 n 0000564126 00000 n 0000564247 00000 n 0000564368 00000 n 0000564487 00000 n 0000564604 00000 n 0000564725 00000 n 0000564846 00000 n 0000564967 00000 n 0000565088 00000 n 0000565208 00000 n 0000565329 00000 n 0000565446 00000 n 0000565567 00000 n 0000565688 00000 n 0000565807 00000 n 0000565926 00000 n 0000566047 00000 n 0000566168 00000 n 0000566289 00000 n 0000566410 00000 n 0000566529 00000 n 0000566650 00000 n 0000566771 00000 n 0000566892 00000 n 0000567013 00000 n 0000567134 00000 n 0000567255 00000 n 0000567373 00000 n 0000567494 00000 n 0000567615 00000 n 0000567734 00000 n 0000567853 00000 n 0000567974 00000 n 0000568095 00000 n 0000568216 00000 n 0000568337 00000 n 0000568458 00000 n 0000568579 00000 n 0000568700 00000 n 0000568821 00000 n 0000568942 00000 n 0000569061 00000 n 0000569181 00000 n 0000569302 00000 n 0000569421 00000 n 0000569542 00000 n 0000569661 00000 n 0000569780 00000 n 0000569901 00000 n 0000570020 00000 n 0000570141 00000 n 0000570262 00000 n 0000570383 00000 n 0000570504 00000 n 0000570625 00000 n 0000570746 00000 n 0000570867 00000 n 0000570988 00000 n 0000571109 00000 n 0000571229 00000 n 0000571350 00000 n 0000571471 00000 n 0000571592 00000 n 0000571713 00000 n 0000571834 00000 n 0000571955 00000 n 0000572076 00000 n 0000572197 00000 n 0000572318 00000 n 0000572439 00000 n 0000572559 00000 n 0000572677 00000 n 0000572797 00000 n 0000572917 00000 n 0000573037 00000 n 0000573157 00000 n 0000573277 00000 n 0000573397 00000 n 0000573517 00000 n 0000573637 00000 n 0000573757 00000 n 0000573877 00000 n 0000573997 00000 n 0000574117 00000 n 0000574237 00000 n 0000574357 00000 n 0000574477 00000 n 0000574597 00000 n 0000574717 00000 n 0000574835 00000 n 0000574955 00000 n 0000575073 00000 n 0000575193 00000 n 0000575313 00000 n 0000575433 00000 n 0000575553 00000 n 0000575671 00000 n 0000575791 00000 n 0000575911 00000 n 0000576031 00000 n 0000576151 00000 n 0000576269 00000 n 0000576389 00000 n 0000576509 00000 n 0000576629 00000 n 0000576749 00000 n 0000576869 00000 n 0000576985 00000 n 0000577105 00000 n 0000577223 00000 n 0000577342 00000 n 0000577462 00000 n 0000577580 00000 n 0000577698 00000 n 0000577818 00000 n 0000577938 00000 n 0000578058 00000 n 0000578176 00000 n 0000578292 00000 n 0000578414 00000 n 0000578534 00000 n 0000578656 00000 n 0000578849 00000 n 0000578971 00000 n 0000579091 00000 n 0000579211 00000 n 0000579331 00000 n 0000579453 00000 n 0000579575 00000 n 0000579697 00000 n 0000579817 00000 n 0000579937 00000 n 0000580057 00000 n 0000580179 00000 n 0000580301 00000 n 0000580421 00000 n 0000580541 00000 n 0000580664 00000 n 0000580783 00000 n 0000580906 00000 n 0000581027 00000 n 0000581147 00000 n 0000581270 00000 n 0000581392 00000 n 0000581515 00000 n 0000581638 00000 n 0000581761 00000 n 0000581883 00000 n 0000582004 00000 n 0000582125 00000 n 0000582248 00000 n 0000582368 00000 n 0000582491 00000 n 0000582613 00000 n 0000582736 00000 n 0000582857 00000 n 0000582978 00000 n 0000583101 00000 n 0000583224 00000 n 0000583347 00000 n 0000583468 00000 n 0000583590 00000 n 0000583710 00000 n 0000583833 00000 n 0000583951 00000 n 0000584074 00000 n 0000584197 00000 n 0000584320 00000 n 0000584443 00000 n 0000584566 00000 n 0000584687 00000 n 0000584811 00000 n 0000584933 00000 n 0000585056 00000 n 0000585178 00000 n 0000585300 00000 n 0000585423 00000 n 0000585544 00000 n 0000585665 00000 n 0000585786 00000 n 0000585905 00000 n 0000586023 00000 n 0000586142 00000 n 0000586264 00000 n 0000586385 00000 n 0000586506 00000 n 0000586629 00000 n 0000586752 00000 n 0000586874 00000 n 0000586997 00000 n 0000587119 00000 n 0000587240 00000 n 0000587361 00000 n 0000587482 00000 n 0000587601 00000 n 0000587722 00000 n 0000587843 00000 n 0000587964 00000 n 0000588085 00000 n 0000588205 00000 n 0000588326 00000 n 0000588447 00000 n 0000588567 00000 n 0000588685 00000 n 0000588808 00000 n 0000588931 00000 n 0000589054 00000 n 0000589177 00000 n 0000589299 00000 n 0000589422 00000 n 0000589545 00000 n 0000589668 00000 n 0000589789 00000 n 0000589910 00000 n 0000590031 00000 n 0000590154 00000 n 0000590275 00000 n 0000590396 00000 n 0000590515 00000 n 0000590636 00000 n 0000590757 00000 n 0000590878 00000 n 0000591001 00000 n 0000591124 00000 n 0000591247 00000 n 0000591370 00000 n 0000591493 00000 n 0000591616 00000 n 0000591739 00000 n 0000591862 00000 n 0000591981 00000 n 0000592104 00000 n 0000592227 00000 n 0000592350 00000 n 0000592515 00000 n 0000592672 00000 n 0000592796 00000 n 0000592917 00000 n 0000593039 00000 n 0000593162 00000 n 0000593285 00000 n 0000593457 00000 n 0000593580 00000 n 0000593701 00000 n 0000593823 00000 n 0000593944 00000 n 0000594065 00000 n 0000594186 00000 n 0000594309 00000 n 0000594432 00000 n 0000594555 00000 n 0000594677 00000 n 0000594800 00000 n 0000594921 00000 n 0000595041 00000 n 0000595162 00000 n 0000595283 00000 n 0000595406 00000 n 0000595528 00000 n 0000595651 00000 n 0000595774 00000 n 0000595897 00000 n 0000596020 00000 n 0000596141 00000 n 0000596261 00000 n 0000596383 00000 n 0000596505 00000 n 0000596628 00000 n 0000596751 00000 n 0000596874 00000 n 0000596995 00000 n 0000597118 00000 n 0000597241 00000 n 0000597362 00000 n 0000597485 00000 n 0000597608 00000 n 0000597731 00000 n 0000597850 00000 n 0000597969 00000 n 0000598088 00000 n 0000598211 00000 n 0000598332 00000 n 0000598455 00000 n 0000598578 00000 n 0000598699 00000 n 0000598820 00000 n 0000598984 00000 n 0000599234 00000 n 0000599355 00000 n 0000599478 00000 n 0000599599 00000 n 0000599717 00000 n 0000599838 00000 n 0000599961 00000 n 0000600082 00000 n 0000600205 00000 n 0000600325 00000 n 0000600447 00000 n 0000600569 00000 n 0000600691 00000 n 0000600812 00000 n 0000600933 00000 n 0000601056 00000 n 0000601179 00000 n 0000601300 00000 n 0000601423 00000 n 0000601544 00000 n 0000601667 00000 n 0000601788 00000 n 0000601910 00000 n 0000602033 00000 n 0000602155 00000 n 0000602314 00000 n 0000602437 00000 n 0000602560 00000 n 0000602683 00000 n 0000602801 00000 n 0000602923 00000 n 0000603045 00000 n 0000603167 00000 n 0000603287 00000 n 0000603408 00000 n 0000603530 00000 n 0000603651 00000 n 0000603771 00000 n 0000603894 00000 n 0000604015 00000 n 0000604135 00000 n 0000604258 00000 n 0000604379 00000 n 0000604501 00000 n 0000604623 00000 n 0000604746 00000 n 0000604867 00000 n 0000604989 00000 n 0000605111 00000 n 0000605233 00000 n 0000605399 00000 n 0000605519 00000 n 0000605640 00000 n 0000605761 00000 n 0000605880 00000 n 0000606035 00000 n 0000606154 00000 n 0000606276 00000 n 0000606398 00000 n 0000606520 00000 n 0000606639 00000 n 0000606756 00000 n 0000606876 00000 n 0000606996 00000 n 0000607166 00000 n 0000607287 00000 n 0000607408 00000 n 0000607528 00000 n 0000607646 00000 n 0000607764 00000 n 0000607884 00000 n 0000608004 00000 n 0000608124 00000 n 0000608243 00000 n 0000608362 00000 n 0000608481 00000 n 0000608601 00000 n 0000608718 00000 n 0000608835 00000 n 0000608999 00000 n 0000609166 00000 n 0000609333 00000 n 0000609500 00000 n 0000504573 00000 n 0000285967 00000 n 0000295154 00000 n 0000295178 00000 n 0000295377 00000 n 0000295698 00000 n 0000295887 00000 n 0000297131 00000 n 0000297155 00000 n 0000297350 00000 n 0000297643 00000 n 0000297810 00000 n 0000328888 00000 n 0000328913 00000 n 0000329113 00000 n 0000329818 00000 n 0000330374 00000 n 0000371078 00000 n 0000371103 00000 n 0000371307 00000 n 0000372020 00000 n 0000372582 00000 n 0000397945 00000 n 0000397970 00000 n 0000398184 00000 n 0000398780 00000 n 0000399234 00000 n 0000425953 00000 n 0000425978 00000 n 0000426187 00000 n 0000426734 00000 n 0000427139 00000 n 0000427236 00000 n 0000453982 00000 n 0000454046 00000 n 0000454259 00000 n 0000454470 00000 n 0000454687 00000 n 0000454890 00000 n 0000455011 00000 n 0000455130 00000 n 0000455356 00000 n 0000455485 00000 n 0000455652 00000 n 0000455795 00000 n 0000455954 00000 n 0000456109 00000 n 0000456264 00000 n 0000456403 00000 n 0000456546 00000 n 0000456697 00000 n 0000456836 00000 n 0000457015 00000 n 0000457158 00000 n 0000457301 00000 n 0000457456 00000 n 0000457627 00000 n 0000457774 00000 n 0000457911 00000 n 0000458054 00000 n 0000458233 00000 n 0000458408 00000 n 0000458563 00000 n 0000458716 00000 n 0000458879 00000 n 0000459018 00000 n 0000459161 00000 n 0000459302 00000 n 0000459539 00000 n 0000459700 00000 n 0000459847 00000 n 0000460000 00000 n 0000460221 00000 n 0000460354 00000 n 0000460513 00000 n 0000460650 00000 n 0000460887 00000 n 0000461028 00000 n 0000461189 00000 n 0000461407 00000 n 0000461556 00000 n 0000461719 00000 n 0000461878 00000 n 0000462025 00000 n 0000462200 00000 n 0000462359 00000 n 0000462546 00000 n 0000462733 00000 n 0000462908 00000 n 0000463075 00000 n 0000463242 00000 n 0000463401 00000 n 0000463574 00000 n 0000463733 00000 n 0000463901 00000 n 0000464069 00000 n 0000464277 00000 n 0000464441 00000 n 0000464609 00000 n 0000464797 00000 n 0000464945 00000 n 0000465109 00000 n 0000465289 00000 n 0000465481 00000 n 0000465640 00000 n 0000465812 00000 n 0000465992 00000 n 0000466156 00000 n 0000466308 00000 n 0000466500 00000 n 0000466680 00000 n 0000466852 00000 n 0000467032 00000 n 0000467228 00000 n 0000467380 00000 n 0000467544 00000 n 0000467736 00000 n 0000467908 00000 n 0000468054 00000 n 0000468204 00000 n 0000468356 00000 n 0000468536 00000 n 0000468710 00000 n 0000468870 00000 n 0000469030 00000 n 0000469178 00000 n 0000469338 00000 n 0000469502 00000 n 0000469690 00000 n 0000469838 00000 n 0000470002 00000 n 0000470190 00000 n 0000470354 00000 n 0000470518 00000 n 0000470710 00000 n 0000470870 00000 n 0000471048 00000 n 0000471210 00000 n 0000471390 00000 n 0000471562 00000 n 0000471716 00000 n 0000471882 00000 n 0000472128 00000 n 0000472282 00000 n 0000472446 00000 n 0000472614 00000 n 0000472798 00000 n 0000472970 00000 n 0000473206 00000 n 0000473332 00000 n 0000473579 00000 n 0000473737 00000 n 0000473903 00000 n 0000474082 00000 n 0000474250 00000 n 0000474410 00000 n 0000474578 00000 n 0000474754 00000 n 0000474918 00000 n 0000475074 00000 n 0000475238 00000 n 0000475410 00000 n 0000475554 00000 n 0000475730 00000 n 0000475914 00000 n 0000476066 00000 n 0000476218 00000 n 0000476374 00000 n 0000476530 00000 n 0000476694 00000 n 0000476850 00000 n 0000477006 00000 n 0000477190 00000 n 0000477390 00000 n 0000477546 00000 n 0000477714 00000 n 0000477874 00000 n 0000478026 00000 n 0000478202 00000 n 0000478402 00000 n 0000478594 00000 n 0000478770 00000 n 0000478942 00000 n 0000479098 00000 n 0000479306 00000 n 0000479490 00000 n 0000479694 00000 n 0000479874 00000 n 0000480058 00000 n 0000480214 00000 n 0000480378 00000 n 0000480522 00000 n 0000480756 00000 n 0000480902 00000 n 0000481070 00000 n 0000481258 00000 n 0000481404 00000 n 0000481560 00000 n 0000481708 00000 n 0000481860 00000 n 0000482006 00000 n 0000482192 00000 n 0000482409 00000 n 0000482559 00000 n 0000482723 00000 n 0000482883 00000 n 0000483047 00000 n 0000483223 00000 n 0000483387 00000 n 0000483551 00000 n 0000483743 00000 n 0000483915 00000 n 0000484125 00000 n 0000484293 00000 n 0000484465 00000 n 0000484629 00000 n 0000484789 00000 n 0000484957 00000 n 0000485124 00000 n 0000485284 00000 n 0000485460 00000 n 0000485628 00000 n 0000485800 00000 n 0000485960 00000 n 0000486128 00000 n 0000486292 00000 n 0000486446 00000 n 0000486659 00000 n 0000486829 00000 n 0000486997 00000 n 0000487173 00000 n 0000487343 00000 n 0000487535 00000 n 0000487703 00000 n 0000487879 00000 n 0000488055 00000 n 0000488215 00000 n 0000488375 00000 n 0000488547 00000 n 0000488739 00000 n 0000488939 00000 n 0000489105 00000 n 0000489273 00000 n 0000489433 00000 n 0000489593 00000 n 0000489753 00000 n 0000489913 00000 n 0000490089 00000 n 0000490257 00000 n 0000490405 00000 n 0000490594 00000 n 0000490748 00000 n 0000490874 00000 n 0000491042 00000 n 0000491182 00000 n 0000491346 00000 n 0000491526 00000 n 0000491690 00000 n 0000491826 00000 n 0000491994 00000 n 0000492166 00000 n 0000492328 00000 n 0000492492 00000 n 0000492680 00000 n 0000492820 00000 n 0000492980 00000 n 0000493132 00000 n 0000493282 00000 n 0000493458 00000 n 0000493614 00000 n 0000493742 00000 n 0000493902 00000 n 0000494086 00000 n 0000494266 00000 n 0000494442 00000 n 0000494602 00000 n 0000494768 00000 n 0000494920 00000 n 0000495092 00000 n 0000495286 00000 n 0000495438 00000 n 0000495626 00000 n 0000495810 00000 n 0000496021 00000 n 0000496173 00000 n 0000496313 00000 n 0000496477 00000 n 0000496637 00000 n 0000496797 00000 n 0000496961 00000 n 0000497121 00000 n 0000497293 00000 n 0000497463 00000 n 0000497623 00000 n 0000497795 00000 n 0000497951 00000 n 0000498110 00000 n 0000498286 00000 n 0000498424 00000 n 0000498604 00000 n 0000498748 00000 n 0000498896 00000 n 0000499056 00000 n 0000499224 00000 n 0000499416 00000 n 0000499588 00000 n 0000499756 00000 n 0000499916 00000 n 0000500064 00000 n 0000500224 00000 n 0000500376 00000 n 0000500536 00000 n 0000500744 00000 n 0000500916 00000 n 0000501084 00000 n 0000501256 00000 n 0000501443 00000 n 0000501627 00000 n 0000501787 00000 n 0000501967 00000 n 0000502131 00000 n 0000502319 00000 n 0000502511 00000 n 0000502703 00000 n 0000502883 00000 n 0000503059 00000 n 0000503231 00000 n 0000503407 00000 n 0000503575 00000 n 0000503779 00000 n 0000503927 00000 n 0000504119 00000 n 0000504271 00000 n 0000504435 00000 n 0000609667 00000 n 0000609788 00000 n trailer < <65AFD3308881ED6409275EDE3C0839C2> ] /DocChecksum /CDCD8A05E31059E30A474B9E9560272B >> startxref 609977 %%EOF mudlet-2.1/src/doc/Mudlet_API_Reference_HTML.html0000644000175000017500000151117512070466512021143 0ustar csmallcsmall

    Mudlet Lua Function API Reference



    Contents

    Alphabetical Function Index

    Mudlet System Variables

    Function Categories

    Basic Essentials

    send

    echo

    Database Functions

    db:add

    db:aggregate

    db:AND

    db:between

    db:create

    db:delete

    db:eq

    db:exp

    db:fetch

    db:gt

    db:get_database

    db:gte

    db:in_

    db:is_nil

    db:is_not_nil

    db:like

    db:lt

    db:lte

    db:merge_unique

    db:not_between

    db:not_eq

    db:not_in

    db:not_like

    db:OR

    db:set

    db:update

    Date & Time Functions

    datetime:parse

    getTime

    getTimestamp

    Display Functions

    display

    showColors

    wrapLine

    File System Functions

    io.exists

    lfs.attributes

    Mapper Functions

    addAreaName

    addMapEvent

    addMapMenu

    addRoom

    addSpecialExit

    centerview

    clearRoomUserData

    clearSpecialExits

    createMapLabel

    createMapper

    createRoomID

    deleteArea

    deleteMapLabel

    deleteRoom

    getAreaRooms

    getAreaTable

    getCustomEnvColorTable

    getMapLabel

    getMapLabels

    getModulePriority

    getPath

    getRoomArea

    getRoomAreaName

    getRoomCoordinates

    getRoomEnv

    getRoomExits

    getRoomIDbyHash

    getRoomName

    getRooms

    getRoomsByPosition

    getRoomUserData

    getRoomWeight

    getSpecialExits

    getSpecialExitsSwap

    gotoRoom

    hasExitLock

    hasSpecialExitLock

    highlightRoom

    loadMap

    lockExit

    lockRoom

    lockSpecialExit

    removeMapEvent

    roomExists

    roomLocked

    saveMap

    searchRoom

    setAreaName

    setCustomEnvColor

    setExit

    setGridMode

    setModulePriority

    setRoomArea

    setRoomChar

    setRoomCoordinates

    setRoomEnv

    setRoomIDbyHash

    setRoomName

    setRoomUserData

    setRoomWeight

    speedwalk

    unHighlightRoom

    Miscellaneous Functions

    feedTriggers

    expandAlias

    feedTriggers

    getMudletHomeDir

    playSoundFile

    registerAnonymousEventHandler

    spawn

    Mudlet Object Functions

    appendCmdLine

    clearCmdLine

    createStopWatch

    disableAlias

    disableKey

    disableTimer

    disableTrigger

    enableAlias

    enableKey

    enableTimer

    enableTrigger

    exists

    getButtonState

    invokeFileDialog

    isActive

    isPrompt

    killAlias

    killTimer

    killTrigger

    permAlias

    permGroup

    permRegexTrigger

    permSubstringTrigger

    permTimer

    printCmdLine

    raiseEvent

    remember

    resetStopWatch

    setConsoleBufferSize

    setTriggerStayOpen

    startStopWatch

    stopStopWatch

    tempAlias

    tempBeginOfLineTrigger

    tempColorTrigger

    tempExactMatchTrigger

    tempLineTrigger

    tempRegexTrigger

    tempTimer

    tempTrigger

    tempButton

    Networking Functions

    disconnect

    downloadFile

    getNetworkLatency

    openUrl

    reconnect

    sendAll

    sendGMCP

    sendIrc

    sendTelnetChannel102

    String Functions

    string.byte

    string.char

    string.cut

    string.dump

    string.enclose

    string.ends

    string.find

    string.findPattern

    string.format

    string.genNocasePattern

    string.gfind

    string.gmatch

    string.gsub

    string.len

    string.lower

    string.match

    string.rep

    string.reverse

    string.split

    string.starts

    string.sub

    string.title

    string.trim

    string.upper

    Table Functions

    table.complement

    table.concat

    table.contains

    table.foreach

    table.intersection

    table.insert

    table.index_of

    table.is_empty

    table.load

    table.maxn

    table.n_union

    table.n_complement

    table.n_intersection

    table.pickle

    table.remove

    table.save

    table.sort

    table.size

    table.setn

    table.unpickle

    table.update

    table.union

    UI Functions

    appendBuffer

    bg

    calcFontSize

    cecho

    cinsertText

    clearUserWindow

    clearWindow

    copy

    createBuffer

    createConsole

    createGauge

    createLabel

    createMiniConsole

    decho

    deleteLine

    deselect

    echoLink

    echoUserWindow

    echoPopup

    fg

    getBgColor

    getColorWildcard

    getColumnNumber

    getCurrentLine

    getFgColor

    getLineCount

    getLines

    getLineNumber

    getMainConsoleWidth

    hasFocus

    getMainWindowSize

    getStopWatchTime

    handleWindowResizeEvent

    hasFocus

    hecho

    hideToolBar

    hideWindow

    insertLink

    insertPopup

    insertText

    isAnsiBgColor

    isAnsiFgColor

    moveCursor

    moveCursorEnd

    moveGauge

    moveWindow

    openUserWindow

    paste

    pasteUserWindow

    prefix

    replace

    replaceAll

    resizeWindow

    selectCaptureGroup

    selectSection

    selectString

    setBgColor

    setBold

    setFgColor

    setGauge

    setItalics

    setMiniConsoleFontSize

    setTextFormat

    setUnderline

    setWindowWrap

    showCaptureGroups

    showMultimatches

    showWindow

    replaceWildcard

    resetFormat

    selectCurrentLine

    setBackgroundColor

    setBackgroundImage

    setBorderBottom

    setBorderColor

    setBorderLeft

    setBorderRight

    setBorderTop

    setLabelClickCallback

    setLink

    setLabelStyleSheet

    setPopup

    showToolBar

    wrapLine






    Alphabetical Function Index

    A, B, C, D, E, F, G, H, I, K, L, M, O, P, R, S, T, U, W



    A

    addAreaName

    addMapEvent

    addMapMenu

    addRoom

    addSpecialExit

    appendBuffer

    appendCmdLine

    B

    Bg

    C

    calcFontSize

    cecho

    centerview

    cinsertText

    clearCmdLine

    clearRoomUserData

    clearSpecialExits

    clearUserWindow

    clearWindow

    copy

    createBuffer

    createConsole

    createGauge

    createLabel

    createMapLabel

    createMapper

    createMiniConsole

    createRoomID

    createStopWatch

    D

    datetime:parse

    db:add

    db:aggregate

    db:AND

    db:between

    db:create

    db:delete

    db:eq

    db:exp

    db:fetch

    db:get_database

    db:gt

    db:gte

    db:in_

    db:is_

    db:is_not_nil

    db:like

    db:lt

    db:lte

    db:merge_unique

    db:not_between

    db:not_eq

    db:not_in

    db:not_like

    db:OR

    db:set

    db:update

    decho

    deleteArea

    deleteLine

    deleteMapLabel

    deleteRoom

    deselect

    disableAlias

    disableKey

    disableTimer

    disableTrigger

    disconnect

    display

    downloadFile

    E

    echo

    echoLink

    echoPopup

    echoUserWindow

    enableAlias

    enableKey

    enableTimer

    enableTrigger

    exists

    expandAlias

    F

    feedTriggers

    feedTriggers

    fg

    G

    getAreaRooms

    getAreaTable

    getBgColor

    getButtonState

    getColorWildcard

    getColumnNumber

    getCurrentLine

    getCustomEnvColorTable

    getFgColor

    getLineCount

    getLineNumber

    getLines

    getMainConsoleWidth

    getMainWindowSize

    getMapLabel

    getMapLabels

    getModulePriority

    getMudletHomeDir

    getNetworkLatency

    getPath

    getRoomArea

    getRoomAreaName

    getRoomCoordinates

    getRoomEnv

    getRoomExits

    getRoomIDbyHash

    getRoomName

    getRooms

    getRoomsByPosition

    getRoomUserData

    getRoomWeight

    getSpecialExits

    getSpecialExitsSwap

    getStopWatchTime

    getTime

    getTimestamp

    gotoRoom

    H

    handleWindowResizeEvent

    hasExitLock

    hasFocus

    hasFocus

    hasSpecialExitLock

    hecho

    hideToolBar

    hideWindow

    highlightRoom

    I

    insertLink

    insertPopup

    insertText

    invokeFileDialog

    io.exists

    isActive

    isAnsiBgColor

    isAnsiFgColor

    isPrompt

    K

    killAlias

    killTimer

    killTrigger

    L

    lfs.attributes

    loadMap

    lockExit

    lockRoom

    lockSpecialExit

    M

    moveCursor

    moveCursorEnd

    moveGauge

    moveWindow

    O

    openUrl

    openUserWindow

    P

    paste

    pasteUserWindow

    permAlias

    permGroup

    permRegexTrigger

    permSubstringTrigger

    permTimer

    playSoundFile

    prefix

    printCmdLine

    R

    raiseEvent

    reconnect

    registerAnonymousEventHandler

    remember

    removeMapEvent

    replace

    replaceAll

    replaceWildcard

    resetFormat

    resetStopWatch

    resizeWindow

    roomExists

    roomLocked

    S

    saveMap

    searchRoom

    selectCaptureGroup

    selectCurrentLine

    selectSection

    selectString

    send

    sendAll

    sendGMCP

    sendIrc

    sendTelnetChannel102

    setAreaName

    setBackgroundColor

    setBackgroundImage

    setBgColor

    setBold

    setBorderBottom

    setBorderColor

    setBorderLeft

    setBorderRight

    setBorderTop

    setConsoleBufferSize

    setCustomEnvColor

    setExit

    setFgColor

    setGauge

    setGridMode

    setItalics

    setLabelClickCallback

    setLabelStyleSheet

    setLink

    setMiniConsoleFontSize

    setModulePriority

    setPopup

    setRoomArea

    setRoomChar

    setRoomCoordinates

    setRoomEnv

    setRoomIDbyHash

    setRoomName

    setRoomUserData

    setRoomWeight

    setTextFormat

    setTriggerStayOpen

    setUnderline

    setWindowWrap

    showCaptureGroups

    showColors

    showMultimatches

    showToolBar

    showWindow

    spawn

    speedwalk

    startStopWatch

    stopStopWatch

    string.byte

    string.char

    string.cut

    string.dump

    string.enclose

    string.ends

    string.find

    string.findPattern

    string.format

    string.genNocasePattern

    string.gfind

    string.gmatch

    string.gsub

    string.len

    string.lower

    string.match

    string.rep

    string.reverse

    string.split

    string.starts

    string.sub

    string.title

    string.trim

    string.upper

    T

    table.complement

    table.concat

    table.contains

    table.foreach

    table.index_of

    table.insert

    table.intersection

    table.is_empty

    table.load

    table.maxn

    table.n_complement

    table.n_intersection

    table.n_union

    table.pickle

    table.remove

    table.save

    table.setn

    table.size

    table.sort

    table.union

    table.unpickle

    table.update

    tempAlias

    tempBeginOfLineTrigger

    tempButton

    tempColorTrigger

    tempExactMatchTrigger

    tempLineTrigger

    tempRegexTrigger

    tempTimer

    tempTrigger

    U

    UnHighlightRoom

    W

    wrapLine

    wrapLine





    Mudlet System Variables


    Mudlet defines several global Lua variables that are accessible from anywhere.

    Built-in Lua Variables

    Variable Name

    Description

    comand

    This variable holds the current user command. This is typically used in alias scripts.

    line

    This variable holds the content of the current line as being processed by the trigger engine. The engine runs all triggers on each line as it arrives from the MUD.

    matches[n]

    This Lua table is being used by Mudlet in the context of triggers that use Perl regular expressions.

    matches[1] holds the entire match, matches[2] holds the first capture group, matches[n] holds the nth-1 capture group. If the trigger uses the Perl style /g switch to evaluate all possible matches of the given regex within the current line, matches[n+1] will hold the second entire match, matches[n+2] the first capture group of the second match and matches[n+m] the m-th capture group of the second match.

    multimatches[n][m]

    This table is being used by Mudlet in the context of multiline triggers that use Perl regular expression. It holds the table matches[n] as described above for each Perl regular expression based condition of the multiline trigger. multimatches[5][4] may hold the 3rd capture group of the 5th regex in the multiline trigger. This way you can examine and process all relevant data within a single script.

    Function Categories

    Basic Essential Functions: These functions are generic functions used in normal scripting. These deal with mainly everyday things, like sending stuff and echoing to the screen.

    Database Functions: A collection of functions for helping deal with the database.

    Date & Time Functions: A collection of functions for handling Date & Time.

    Display Functions: A collection of functions for displaying or formatting information on the screen.

    File System Functions: A collection of functions for interacting with the file system.

    Mapper Functions: A collection of functions that manipulate the mapper and it's related features.

    Miscellaneous Functions: Need verbiage here

    Scripting Object Functions: Need verbiage here

    Networking Functions: A collection of functions for managing networking.

    String Functions: These functions are used to manipulate strings.

    Table Functions: These functions are used to manipulate tables. Through them you can add to tables, remove values, check if a value is present in the table, check the size of a table, and more.

    UI Functions: These functions are used to construct custom user GUIs. They deal mainly with miniconsole/label/gauge creation and manipulation.

    Basic Essentials

    These functions are generic functions used in normal scripting. These deal with mainly everyday things, like sending stuff and echoing to the screen.

    send

    send( command, show on screen )
    This sends "command" directly to the network layer, skipping the alias matching. The optional second argument of type boolean (print) determines if the outgoing command is to be echoed on the screen.

    See also: sendAll()

    Note: If you want your command to be checked as if it's an alias, use expandAlias() instead - send() will ignore them.

    send( "Hello Jane" ) --echos the command on the screen
    send( "Hello Jane", true ) --echos the command on the screen
    send( "Hello Jane", false ) --does not echo the command on the screen
    
    -- use a variable in the send:
    send("kick "..target)

    echo

    echo( windowName, text )
    This function appends text at the end of the current line. The current cursor position is ignored. Use moveCursor() and insertText() if you want to print at a different cursor position.
    If the first argument is omitted the main console is used, otherwise the mini console windowName.

    Example:

    echo( "Hello world\n" ) -- writes "Hello world" to the main screen.
    echo( "info", "Hello this is the info window" ) -- writes text to the mini console named "info" if such a window exists

    Database Functions

    These database functions make using a database with Mudlet easier. They are optional, if you are an expert in SQL, you can use LuaSQL's sqlite driver directly within Mudlet - see it's manual here.

    db:add

    db:add(sheet reference, table1, …, tableN)
    Adds one or more new rows to the specified sheet. If any of these rows would violate a UNIQUE index, a lua error will be thrown and execution will cancel. As such it is advisable that if you use a UNIQUE index, you test those values before you attempt to insert a new row.
    Example
    --Each table is a series of key-value pairs to set the values of the sheet, 
    --but if any keys do not exist then they will be set to nil or the default value.
    db:add(mydb.enemies, {name="Bob Smith", city="San Francisco"})
    db:add(mydb.enemies,
         {name="John Smith", city="San Francisco"},
         {name="Jane Smith", city="San Francisco"},
         {name="Richard Clark"})
    As you can see, all fields are optional.

    db:aggregate

    db:aggregate(field reference, aggregate function, query)
    Returns the result of calling the specified aggregate function on the field and its sheet. The query is optional.
    The supported aggregate functions are:
    • COUNT - Returns the total number of records that are in the sheet or match the query.

    • AVG - Returns the average of all the numbers in the specified field.

    • MAX - Returns the highest number in the specified field.

    • MIN - Returns the lowest number in the specified field.

    • TOTAL - Returns the value of adding all the contents of the specified field.

    Example
    local mydb = db:get_database("my database")
    echo(db:aggregate(mydb.enemies.name, "count"))

    db:AND

    db:AND(sub-expression1, …, sub-expressionN)
    Returns a compound database expression that combines all of the simple expressions passed into it; these expressions should be generated with other db: functions such as db:eq, db:like, db:lt and the like.
    This compound expression will only find items in the sheet if all sub-expressions match.

    db:between

    db:between(field reference, lower_bound, upper_bound)
    Returns a database expression to test if the field in the sheet is a value between lower_bound and upper_bound. This only really makes sense for numbers and Timestamps.

    db:create

    db:create(database name, schema table)
    Creates and/or modifies an existing database. This function is safe to define at a top-level of a Mudlet script: in fact it is reccommended you run this function at a top-level without any kind of guards. If the named database does not exist it will create it. If the database does exist then it will add any columns or indexes which didn’t exist before to that database. If the database already has all the specified columns and indexes, it will do nothing.
    The database will be called Database_<sanitized database name>.db and will be stored in the Mudlet configuration directory.
    Database tables are called sheets consistantly throughout this documentation, to avoid confusion with Lua tables.
    The schema table must be a Lua table array containing table dictionaries that define the structure and layout of each sheet
    Example
    local mydb = db:create("combat_log",
            {
                    kills = {
                    name = "",
                    area = "",
                    killed = db:Timestamp("CURRENT_TIMESTAMP"),
                    _index = { {"name", "area"} }
                    },
                    enemies = {
                            name = "",
                            city = "",
                            reason = "",
                            enemied = db:Timestamp("CURRENT_TIMESTAMP"),
                            _index = { "city" },
                            _unique = { "name" },
                            _violations = "IGNORE"
                    }
            })
    The above will create a database with two sheets; the first is kills and is used to track every successful kill, with both where and when the kill happened. It has one index, a compound inde tracking the combination of name and area. The second sheet has two indexes, but one is unique: it isn’t possible to add two items to the enemies sheet with the same name.
    For sheets with unique indexes, you may specify a _violations key to indicate how the db layer handle cases where the unique index is violated. The options you may use are: * FAIL - the default. A hard error is thrown, cancelling the script. * IGNORE - The command that would add a record that violates uniqueness just fails silently. * REPLACE - The old record which matched the unique index is dropped, and the new one is added to replace it.
    Returns a reference of an already existing database. This instance can be used to get references to the sheets (and from there, fields) that are defined within the database. You use these references to construct queries.
    If a database has a sheet named enemies, you can obtain a reference to that sheet by simply doing:
    local mydb = db:get_database("my database")
    local enemies_ref = mydb.enemieslocal name_ref = mydb.enemies.name

    db:delete

    db:delete(sheet reference, query)
    Deletes rows from the specified sheet. The argument for query tries to be intelligent:
    • If it is a simple number, it deletes a specific row by _row_id

    • If it is a table that contains a _row_id (e.g., a table returned by db:get) it deletes just that record.

    • Otherwise, it deletes every record which matches the query pattern which is specified as with b:get.

    • If the query is simply true, then it will truncate the entire contents of the sheet.

    Example
    enemies = db:fetch(mydb.enemies)
    db:delete(mydb.enemies, enemies[1])
    
    db:delete(mydb.enemies, enemies[1]._row_id)
    db:delete(mydb.enemies, 5)
    db:delete(mydb.enemies, db:eq(mydb.enemies.city, "San Francisco"))
    db:delete(mydb.enemies, true)
    Those deletion commands will do in order:
    1. one When passed an actual result table that was obtained from db:fetch, it will delete the record for that table.

    2. two When passed a number, will delete the record for that _row_id. This example shows getting the row id from a table.

    3. three As above, but this example just passes in the row id directly.

    4. four Here, we will delete anything which matches the same kind of query as db:fetch uses-- namely, anyone who is in the city of San Francisco.

    5. five And finally, we will delete the entire contents of the enemies table.

    db:eq

    db:eq(field reference, value)
    Returns a database expression to test if the field in the sheet is equal to the value.

    db:exp

    db:exp(string)
    Returns the string as-is to the database.
    Use this function with caution, but it is very useful in some circumstances. One of the most common of such is incrementing an existing field in a db:set() operation, as so:
    db:set(mydb.enemies, db:exp("kills + 1"), db:eq(mydb.enemies.name, "Ixokai"))
    This will increment the value of the kills field for the row identified by the name Ixokai.
    But there are other uses, as the underlining database layer provides many functions you can call to do certain things. If you want to get a list of all your enemies who have a name longer then 10 characters, you may do:
    db:fetch(mydb.enemies, db:exp("length(name) > 10"))
    Again, take special care with this, as you are doing SQL syntax directly and the library can’t help you get things right.

    db:fetch

    db:fetch(sheet reference, query, order_by, descending)
    Returns a table array containing a table for each matching row in the specified sheet. All arguments but sheet are optional. If query is nil, the entire contents of the sheet will be returned.
    Query is a string which should be built by calling the various db: expression functions, such as db:eq, db:AND, and such. You may pass a SQL WHERE clause here if you wish, but doing so is very dangerous. If you don’t know SQL well, its best to build the expression.
    Query may also be a table array of such expressions, if so they will be AND’d together implicitly.
    The results that are returned are not in any guaranteed order, though they are usually the same order as the records were inserted. If you want to rely on the order in any way, you must pass a value to the order_by field. This must be a table array listing the columns you want to sort by. It can be { "column1" }, or { "column1", "column2" }
    The results are returned in ascending (smallest to largest) order; to reverse this pass true into the final field.
    Example
    db:fetch(mydb.enemies, nil, {"city", "name"})
    db:fetch(mydb.enemies, db:eq(mydb.enemies.city, "San Francisco"))
    db:fetch(mydb.kills,
         {db:eq(mydb.kills.area, "Undervault"),
         db:like(mydb.kills.name, "%Drow%")}
    )
    The first will fetch all of your enemies, sorted first by the city they reside in and then by their name.
    The second will fetch only the enemies which are in San Francisco.
    The third will fetch all the things you’ve killed in Undervault which have Drow in their name.

    db:gt

    db:gt(field reference, value)
    Returns a database expression to test if the field in the sheet is greater than to the value.

    db:get_database

    db:get_database(database_name)
    Returns your database name.
    Example
    local mydb = db:get_database("my database")

    db:gte

    db:gte(field reference, value)
    Returns a database expression to test if the field in the sheet is greater than or equal to the value.

    db:in_

    db:in_(field reference, table array)
    Returns a database expression to test if the field in the sheet is one of the values in the table array.
    First, note the trailing underscore carefully! It is required.
    The following example illustrates the use of in_:
    local mydb = db:get_database("my database")
    local areas = {"Undervault", "Hell", "Purgatory"}
    
    db:fetch(mydb.kills, db:in_(mydb.kills.area, areas))
    This will obtain all of your kills which happened in the Undervault, Hell or Purgatory. Every db:in_ expression can be written as a db:OR, but that quite often gets very complex.

    db:is_nil

    db:is_nil(field reference, value)
    Returns a database expression to test if the field in the sheet is nil.

    db:is_not_nil

    db:is_not_nil(field reference, value)
    Returns a database expression to test if the field in the sheet is not nil.

    db:like

    db:like(field reference, pattern)
    returns a database expression to test if the field in the sheet matches the specified pattern.
    LIKE patterns are not case-sensitive, and allow two wild cards. The first is an underscore which matches any single one character. The second is a percent symbol which matches zero or more of any character.
    LIKE with "_" is therefore the same as the "." regular expression.
    LIKE with "%" is therefore the same as ".*" regular expression.

    db:lt

    db:lt(field reference, value)
    Returns a database expression to test if the field in the sheet is less than the value.

    db:lte

    db:lte(field reference, value)
    Returns a database expression to test if the field in the sheet is less than or equal to the value.

    db:merge_unique

    db:merge_unique(sheet reference, table array)
    Merges the specified table array into the sheet, modifying any existing rows and adding any that don’t exist.
    This function is a convenience utility that allows you to quickly modify a sheet, changing existing rows and add new ones as appropriate. It ONLY works on sheets which have a unique index, and only when that unique index is only on a single field. For more complex situations you’ll have to do the logic yourself.
    The table array may contain tables that were either returned previously by db:fetch, or new tables that you’ve constructed with the correct fields, or any mix of both. Each table must have a value for the unique key that has been set on this sheet.
    For example, consider this database
    local mydb = db:create("peopledb",
         {
              friends = {
                   name = "",
                   race = "",
                   level = 0,
                   city = "",
                   _index = { "city" },
                   _unique = { "name" }
              }
    );
    Here you have a database with one sheet, which contains your friends, their race, level, and what city they live in. Let’s say you want to fetch everyone who lives in San Francisco, you could do:
    local results = db:fetch(mydb.friends, db:eq(mydb.friends.city, "San Francisco"))
    The tables in results are static, any changes to them are not saved back to the database. But after a major radioactive cataclysm rendered everyone in San Francisco a mutant, you could make changes to the tables as so:
    for _, friend in ipairs(results) do
         friend.race = "Mutant"
    end
    If you are also now aware of a new arrival in San Francisco, you could add them to that existing table array:
    results[#results+1] = {name="Bobette", race="Mutant", city="San Francisco"}
    And commit all of these changes back to the database at once with:
    db:merge_unique(mydb.friends, results)
    The db:merge_unique function will change the city values for all the people who we previously fetched, but then add a new record as well.

    db:not_between

    db:not_between(field reference, lower_bound, upper_bound)
    Returns a database expression to test if the field in the sheet is not a value between lower_bound and upper_bound. This only really makes sense for numbers and Timestamps.

    db:not_eq

    db:not_eq(field reference, value)
    Returns a database expression to test if the field in the sheet is NOT equal to the value.

    db:not_in

    db:not_in(field reference, table array)
    Returns a database expression to test if the field in the sheet is not one of the values in the table array.
    See also: db:in_

    db:not_like

    db:not_like(field reference, pattern)
    Returns a database expression to test if the field in the sheet does not match the specified pattern.
    LIKE patterns are not case-sensitive, and allow two wild cards. The first is an underscore which matches any single one character. The second is a percent symbol which matches zero or more of any character.
    LIKE with "_" is therefore the same as the "." regular expression.
    LIKE with "%" is therefore the same as ".*" regular expression.

    db:OR

    db:OR(sub-expression1, sub-expression2)
    Returns a compound database expression that combines both of the simple expressions passed into it; these expressions should be generated with other db: functions such as db:eq, db:like, db:lt and the like.
    This compound expression will find any item that matches either the first or the second sub-expression.

    db:set

    db:set(field reference, value, query)
    The db:set function allows you to set a certain field to a certain value across an entire sheet. Meaning, you can change all of the last_read fields in the sheet to a certain value, or possibly only the last_read fields which are in a certain city. The query argument can be any value which is appropriate for db:fetch, even nil which will change the value for the specified column for EVERY row in the sheet.
    For example, consider a situation in which you are tracking how many times you find a certain type of egg during Easter. You start by setting up your database and adding an Eggs sheet, and then adding a record for each type of egg.
    Example
    local mydb = db:create("egg database", {eggs = {color = "", last_found = db.Timestamp(false), found = 0}})
            db:add(mydb.eggs,
                    {color = "Red"},
                    {color = "Blue"},
                    {color = "Green"},
                    {color = "Yellow"},
                    {color = "Black"}
            )
    Now, you have three columns. One is a string, one a timestamp (that ends up as nil in the database), and one is a number.
    You can then set up a trigger to capture from the mud the string, "You pick up a (.*) egg!", and you end up arranging to store the value of that expression in a variable called "myegg".
    To increment how many we found, we will do this:
    myegg = "Red" -- We will pretend a trigger set this.
            db:set(mydb.eggs.found, db:exp("found + 1"), db:eq(mydb.eggs.color, myegg))
            db:set(mydb.eggs.last_found, db.Timestamp("CURRENT_TIMESTAMP"), db:eq(mydb.eggs.color, myegg))
    This will go out and set two fields in the Red egg sheet; the first is the found field, which will increment the value of that field (using the special db:exp function). The second will update the last_found field with the current time.
    Once this contest is over, you may wish to reset this data but keep the database around. To do that, you may use a more broad use of db:set as such:
    db:set(mydb.eggs.found, 0)
    db:set(mydb.eggs.last_found, nil)

    db:update

    db:update(sheet reference, table)
    This function updates a row in the specified sheet, but only accepts a row which has been previously obtained by db:fetch. Its primary purpose is that if you do a db:fetch, then change the value of a field or tow, you can save back that table.
    Example
    local mydb = db:get_database("my database")
    local bob = db:fetch(mydb.friends, db:eq(mydb.friends.name, "Bob"))[1]
    bob.notes = "He's a really awesome guy."
    db:update(mydb.friends, bob)
    This obtains a database reference, and queries the friends sheet for someone named Bob. As this returns a table array containing only one item, it assigns that one item to the local variable named bob. We then change the notes on Bob, and pass it into db:update() to save the changes back.

    Date & Time Functions

    A collection of functions for handling Date & Time.

    datetime:parse

    datetime:parse(source, format, as_epoch)
    Parses the specified source string, according to the format if given, to return a representation of the date/time. If as_epoch is provided and true, the return value will be a Unix epoch — the number of seconds since 1970. This is a useful format for exchanging date/times with other systems. If as_epoch is false, then a Lua time table will be returned. Details of the time tables are provided in the Lua Manual.
    Supported Format Codes
    %b = Abbreviated Month Name
    %B = Full Month Name
    %d = Day of Month
    %H = Hour (24-hour format)
    %I = Hour (12-hour format, requires %p as well)
    %p = AM or PM
    %m = 2-digit month (01-12)
    %M = 2-digit minutes (00-59)
    %S = 2-digit seconds (00-59)
    %y = 2-digit year (00-99), will automatically prepend 20 so 10 becomes 2010 and not 1910.
    %Y = 4-digit year.

    getTime

    getTime(returntype, format)
    returntype takes a boolean value (in Lua anything but false or nil will translate to true). If false, the function will return a table in the following format:
    { 'min': #, 'year': #, 'month': #, 'day': #, 'sec': #, 'hour': #, 'msec': # }

    If true, it will return the date and time as a string using a format passed to the format arg or the default of "yyyy.MM.dd hh:mm:ss.zzz" if none is supplied:

    2012.02.18 00:52:52.489

    Format expressions:

    h               the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
    hh              the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
    H               the hour without a leading zero (0 to 23, even with AM/PM display)
    HH              the hour with a leading zero (00 to 23, even with AM/PM display)
    m               the minute without a leading zero (0 to 59)
    mm              the minute with a leading zero (00 to 59)
    s               the second without a leading zero (0 to 59)
    ss              the second with a leading zero (00 to 59)
    z               the milliseconds without leading zeroes (0 to 999)
    zzz             the milliseconds with leading zeroes (000 to 999)
    AP or A         use AM/PM display. AP will be replaced by either "AM" or "PM".
    ap or a         use am/pm display. ap will be replaced by either "am" or "pm".
    
    d               the day as number without a leading zero (1 to 31)
    dd              the day as number with a leading zero (01 to 31)
    ddd             the abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses QDate::shortDayName().
    dddd            the long localized day name (e.g. 'Monday' to 'Qt::Sunday'). Uses QDate::longDayName().
    M               the month as number without a leading zero (1-12)
    MM              the month as number with a leading zero (01-12)
    MMM             the abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses QDate::shortMonthName().
    MMMM            the long localized month name (e.g. 'January' to 'December'). Uses QDate::longMonthName().
    yy              the year as two digit number (00-99)
    yyyy            the year as four digit number

    All other input characters will be ignored. Any sequence of characters that are enclosed in single quotes will be treated as text and not be used as an expression. Two consecutive single quotes ('') are replaced by a single single quote in the output.

    Example
    -- Get time as a table
    @getTime()
    
    -- Get time with default string
    @getTime(true)
    
    -- Get time without date and milliseconds
    @getTime(true, "hh:mm:ss")

    getTimestamp

    getTimestamp( optional console_name, lineNumber )
    Returns the timestamp string as it’s seen when you enable the timestamps view (blue i button bottom right).

    Note: Available since 1.1.0-pre1

    Example
    --Echo the timestamp of the current line in a trigger:
    echo(getTimestamp(getLineCount()))

    Display Functions

    A collection of functions for displaying or formatting information on the screen.

    display

    display(value)
    This function will do it's best to show whatever you ask it (a number, string, table, function). This function can be useful for seeing what values does a table have, for example. Note that this doesn't handle recursive references and will loop infinitely at the moment (Mudlet 2.0-test4). If a value is a string, it'll be in single quotes, and if it's a number, it won't be quoted.
    Example
    -- ask it to display a table
    display({a = "somevalue", 1,2,3})
    -- or some other target
    display(target)

    showColors

    showColors(columns)
    shows the named colors currently available in Mudlet's color table. These colors are stored in color_table, in table form. The format is color_table.colorName = {r,g,b}
    See Also: bg(), fg(), cecho()
    Parameters
    • columns:

    Number of columns to print the color table in. Passed as an integer number.
    Example
    showColors(4)

    The output for this is:

    wrapLine

    wrapLine( windowName, lineNumber )
    Wrap line lineNumber of mini console (window) windowName. This function will interpret \n characters, apply word wrap and display the new lines on the screen. This function may be necessary if you use deleteLine() and thus erase the entire current line in the buffer, but you want to do some further echo() calls after calling deleteLine(). You will then need to re-wrap the last line of the buffer to actually see what you have echoed and get you \n interpreted as newline characters properly. Using this function is no good programming practice and should be avoided. There are better ways of handling situations where you would call deleteLine() and echo afterwards.
    Example
    --This will effectively have the same result as a call to deleteLine() but the buffer line will not be entirely removed. 
    --Consequently, further calls to echo() etc. sort of functions are possible without using wrapLine() unnecessarily.
    
    selectString(line,1);
    replace("");

    File System Functions

    A collection of functions for interacting with the file system.

    io.exists

    io.exists()
    Checks to see if a given file or folder exists.
    If it exists, it’ll return the Lua true boolean value, otherwise false.
    Note: Behavior varies based on the user's operating system. Windows requires a specific file, while Linux will accept directories.
    See lfs.attributes() for a cross-platform solution.
    Example
    -- This example works on Linux only
    if io.exists("/home/vadi/Desktop") then
      echo("This folder exists!")
    else
      echo("This folder doesn't exist.")
    end
    
    -- This example will work on both Windows and Linux.
    if io.exists("/home/vadi/Desktop/file.tx") then
      echo("This file exists!")
    else
      echo("This file doesn't exist.")
    end

    lfs.attributes

    lfs.attributes(path)
    Returns a table with detailed information regarding a file or directory, or nil if path is invalid.
    Example
    fileInfo = lfs.attributes("/path/to/file_or_directory")
    if fileInfo then
        if fileInfo.mode == "directory" then
            echo("Path points to a directory.")
        elseif fileInfo.mode == "file" then
            echo("Path points to a file.")
        else
            echo("Path points to: "..fileInfo.mode)
        end
        display(fileInfo) -- to see the detailed information
    else
        echo("The path is invalid (file/directory doesn't exist)")
    end

    Mapper Functions

    These are functions that are to be used with the Mudlet Mapper. The mapper is designed to be MUD-generic - it only provides the display and pathway calculations, to be used in Lua scripts that are tailored to the MUD you're playing. For a collection of pre-made scripts and general mapper talk, visit the mapper section of the forums.

    To register a script as a mapping one with Mudlet (so Mudlet knows the profile has one and won't bother the user when they open the map), please do this in your script:

    mudlet = mudlet or {}; mudlet.mapper_script = true

    addAreaName

    areaID = addAreaName(areaName)
    Adds a new area name and returns the new area ID for the new name. If the name already exists, -1 is returned.
    See also: deleteArea(), addRoom()
    Example
    local newID = addAreaName("My house")
    
    if newID == -1 then echo("That area name is already taken:(\n")
    else echo("Created new area with the ID of "..newid..".\n") end

    addMapEvent

    addMapEvent(uniquename, event name, parent, display name, arguments)
    Adds a new entry to an existing mapper right-click entry. You can add one with addMapMenu. If there is no display name, it will default to the unique name (which otherwise isn't shown and is just used to differentiate this entry from others). event name is the Mudlet event that will be called when this is clicked on, and arguments will be passed to the handler function.
    See also: addMapMenu(), removeMapEvent(), getMapEvents()
    Example
    addMapEvent("room a", "onFavorite") -- will make a label "room a" on the map menu's right click that calls onFavorite
    
    addMapEvent("room b", "onFavorite", "Favorites", "Special Room!", 12345, "arg1", "arg2", "argn")

    The last line will make a label "Special Room!" under the "Favorites" menu that on clicking will send all the arguments.

    addMapMenu

    addMapEvent(uniquename, parent, display name)
    Adds a new submenu to the right-click menu that opens when you right-click on the mapper. You can then add more submenus to it, or add entries with addMapEvent().
    See also: addMapEvent(), removeMapEvent(), getMapEvents()
    Example
    addMapMenu("Favorites") -- will create a menu, favorites
    
    addMapMenu("Favorites1234343", "Favorites", "Favorites")

    The last line will create a submenu with the unique id Favorites123.. under Favorites with the display name of Favorites.

    addRoom

    addRoom(roomID)
    Creates a new room with the given ID, returns true if the room was successfully created.

    Note: If you're not using incremental room IDs but room IDs stitched together from other factors or in-game hashes for room IDs - and your room IDs are starting off at 250+million numbers, you need to look into incrementally creating Mudlets room IDs with createRoomID() and associating your room IDs with Mudlets via setRoomIDbyHash() and getRoomIDbyHash(). The reason being is that Mudlet's A* pathfinding implementation from boost cannot deal with extremely large room IDs because the resulting matrices it creates for pathfinding are enormously huge.

    See also: createRoomID()
    Example
    local newroomid = createRoomID()
    addRoom(newroomid)

    addSpecialExit

    addSpecialExit(roomIDFrom, roomIDTo, command)
    Creates a one-way from one room to another, that will use the given command for going through them.
    See also: [#clearSpecialExits|clearSpecialExits()]]
    Example
    -- sample alias pattern: ^spe (\d+) (.*?)$
    -- mmp.currentroom is your current room ID in this example
    addSpecialExit(mmp.currentroom,tonumber(matches[2]), matches[3])
    echo("\n SPECIAL EXIT ADDED TO ROOMID:"..matches[2]..", Command:"..matches[3])
    centerview(mmp.currentroom)

    centerview

    centerview (roomID)
    Centers the map view onto the given room ID. The map must be open to see this take effect. This function can also be used to see the map of an area if you know the number of a room there and the area and room are mapped.

    clearRoomUserData

    clearRoomUserData(roomID)
    Clears all user data from a given room.
    See also: setRoomUserData()
    Example
    clearRoomUserData(341)

    clearSpecialExits

    clearSpecialExits(roomID)
    Removes all special exits from a room.
    See also: addSpecialExit()
    Example
    clearSpecialExits(1337)
    
    if #getSpecialExits(1337) == 0 then -- clearSpecialExits will neve fail on a valid room ID, this is an example
      echo("All special exits successfully cleared from 1337.\n")
    end

    createMapLabel

    labelID = createMapLabel(areaID, text, posx, posy, fgRed, fgGreen, fgBlue, bgRed, bgGreen, bgBlue)
    Creates a visual label on the map for all z-levels at given coordinates, with the given background and foreground colors. It returns a label ID that you can use later for deleting it.
    The coordinates 0,0 are in the middle of the map, and are in sync with the room coordinates - so using the x,y values of getRoomCoordinates() will place the label near that room.
    See also: deleteMapLabel
    Example
    local labelid = createMapLabel( 50, "my map label", 0, 0, 255,0,0,23,0,0)

    createMapper

    createMapper(x, y, width, height)
    Creates a miniconsole window for mapper to render in, the with the given dimensions. You can only create one at a time at the moment.
    Example
    createMapper(0,0,300,300) -- creates a 300x300 mapper top-right of Mudlet
    setBorderLeft(305) -- adds a border so text doesn't underlap the mapper display

    createRoomID

    usableId = createRoomID()
    Returns the lowest possible room ID you can use for creating a new room. If there are gaps in room IDs your map uses it, this function will go through the gaps first before creating higher IDs.
    See also: addRoom()

    deleteArea

    deleteArea(areaID)
    Deletes the given area, permanently. This will also delete all rooms in it!
    See also: addAreaName()
    Example
    deleteArea(23)

    deleteMapLabel

    deleteMapLabel(areaID, labelID)
    Deletes a map label from a specfic area.
    See also: createMapLabel()
    Example
    deleteMapLabel(50, 1)

    deleteRoom

    deleteRoom(roomID)
    Deletes an individual room, and unlinks all exits leading to and from it.
    Example
    deleteRoom(335)

    getAreaRooms

    getAreaRooms(area id)
    Returns an indexed table with all rooms IDs for a given area ID (room IDs are values), or nil if no such area exists.

    Note: On Mudlet versions prior to the 2.0 final release, this function would raise an error.

    Example
    -- using the sample findAreaID() function defined in the getAreaTable() example, 
    -- we'll define a function that echo's us a nice list of all rooms in an area with their ID
    function echoRoomList(areaname)
      local id, msg = findAreaID(areaname)
      if id then
        local roomlist, endresult = getAreaRooms(id), {}
    
        -- obtain a room list for each of the room IDs we got
        for _, id in ipairs(roomlist) do
          endresult[id] = getRoomName(id)
        end
    
        -- now display something half-decent looking
        cecho(string.format(
          "List of all rooms in%s (%d):\n", msg, table.size(endresult)))
    
        for roomid, roomname in pairs(endresult) do
          cecho(string.format(
            "%6s:%s\n", roomid, roomname))
        end
      elseif not id and msg then
        echo("ID not found; " .. msg)
      else
        echo("No areas matched the query.")
      end
    end

    getAreaTable

    getAreaTable()
    Returns a key(area name)-value(area id) table with all known areas and their IDs. There is an area with the name of and an ID of 0 included in it, you should ignore that.
    Example
    -- example function that returns the area ID for a given area
    
    function findAreaID(areaname)
      local list = getAreaTable()
    
      -- iterate over the list of areas, matching them with substring match. 
      -- if we get match a single area, then return it's ID, otherwise return
      -- 'false' and a message that there are than one are matches
      local returnid, fullareaname
      for area, id in pairs(list) do
        if area:find(areaname, 1, true) then
          if returnid then return false, "more than one area matches" end
          returnid = id; fullareaname = area
        end
      end
    
      return returnid, fullareaname
    end
    
    -- sample use:
    local id, msg = findAreaID("blahblah")
    if id then
      echo("Found a matching ID: " .. id")
    elseif not id and msg then
      echo("ID not found; " .. msg)
    else
      echo("No areas matched the query.")
    end

    getCustomEnvColorTable

    envcolors = getCustomEnvColorTable()
    Returns a table with customized environments, where the key is the environment ID and the value is a indexed table of rgb values.
    Example
    {
      envid1 = {r,g,b},
      envid2 = {r,g,b}
    }

    getMapLabel

    labelinfo = getMapLabels(areaID, labelID)
    Returns a key-value table describing that particular label in an area. Keys it contains are the X, Y, Z coordinates, Height and Width, and the Text it contains. If the label is an image label, then Text will be set to the no text string.
    Example
    lua getMapLabels(1658987)
    table {
      1: 'no text'
      0: 'test'
    }
    
    lua getMapLabel(1658987, 0)
    table {
      'Y': -2
      'X': -8
      'Z': 11
      'Height': 3.9669418334961
      'Text': 'test'
      'Width': 8.6776866912842
    }
    
    lua getMapLabel(1658987, 1)
    table {
      'Y': 8
      'X': -15
      'Z': 11
      'Height': 7.2520666122437
      'Text': 'no text'
      'Width': 11.21900844574
    }



    getMapLabels

    arealabels = getMapLabels(areaID)
    Returns an indexed table (that starts indexing from 0) of all of the labels in the area, plus their label text. You can use the label id to deleteMapLabel() it.
    Example
    display(getMapLabels(43))
    table {
      0: ''
      1: 'Waterways'
    }
    
    deleteMapLabel(43, 0)
    display(getMapLabels(43))
    table {
      1: 'Waterways'
    }

    getModulePriority

    priority = getModulePriority(module name)
    Returns the priority of a module as an integer. This determines the order modules will be loaded in - default is 0. Useful if you have a module that depends on another module being loaded first, for example.
    See also: setModulePriority()
    Example
    getModulePriority("mudlet-mapper")

    getPath

    getPath(roomID from, roomID to)
    Returns a boolean true/false if a path between two room IDs is possible. If it is, the global speedWalkPath table is set to all of the directions that have to be taken to get there, and the global speedWalkDir table is set to all of the roomIDs you'll encounter on the way.
    Example
    -- check if we can go to a room - if yes, go to it
    if getPath(34,155) then
      gotoRoom(155)
    else
      echo("\nCan't go there!")
    end

    getRoomArea

    areaID = getRoomArea(roomID)
    Returns the area ID of a given room ID. To get the area name, you can check the area ID against the data given by getAreaTable() function, or use the getRoomAreaName() function.

    Note: If the room ID does not exist, this function will raise an error.

    Example
    display("Area ID of room #100 is: "..getRoomArea(100))
    
    display("Area name for room #100 is: "..getRoomAreaName(getRoomArea(100)))

    getRoomAreaName

    areaname = getRoomAreaName(areaID)
    Returns the area name for a given area id.
    Example
    echo(string.format("room id #455 is in%s.", getRoomAreaName(getRoomArea(455))))

    getRoomCoordinates

    x,y,z = getRoomCoordinates(room ID)
    Returns the room coordinates of the given room ID.
    Example
    local x,y,z = getRoomCoordinates(roomID)
    echo("Room Coordinates for "..roomID..":")
    echo("\n     X:"..x)
    echo("\n     Y:"..y)
    echo("\n     Z:"..z)

    getRoomEnv

    envID = getRoomEnv(roomID)
    Returns the environment ID of a room. The mapper does not store environment names, so you'd need to keep track of which ID is what name yourself.
    Example
    funtion checkID(id)
      echo(strinf.format("The env ID of room #%d is%d.\n", id, getRoomEnv(id)))
    end

    getRoomExits

    getRoomExits (roomID)
    Returns the currently known non-special exits for a room in an key-index form: exit = exitroomid, ie:
    Example
    table {
      'northwest': 80
      'east': 78
    }

    getRoomIDbyHash

    roomID = getRoomIDbyHash(hash)
    Returns a room ID that is associated with a given hash in the mapper. This is primarily for MUDs that make use of hashes instead of room IDs (like Avalon.de MUD). -1 is returned if no room ID matches the hash.
    Example
    -- example taken from http://forums.mudlet.org/viewtopic.php?f=13&t=2177
    _id1 = getRoomIDbyHash( "5dfe55b0c8d769e865fd85ba63127fbc" );
    if _id1 == -1 then 
      _id1 = createRoomID()
      setRoomIDbyHash( _id1, "5dfe55b0c8d769e865fd85ba63127fbc" )
      addRoom( _id )
      setRoomCoordinates( _id1, 0, 0, -1 )
    end

    getRoomName

    roomName = getRoomName(roomID)
    Returns the room name for a given room id.
    Example
    echo(string.format("The name of the room id #455 is%s.", getRoomname(455))

    getRooms

    rooms = getRooms()
    Returns the list of all rooms in the map in an area in roomid - room name format.
    Example
    -- simple, raw viewer for rooms in an area
    display(getRooms())

    getRoomsByPosition

    getRoomsByPosition(areaID, x,y,z)
    Returns an indexed table of all rooms at the given coordinates in the given area, or an empty one if there are none. This function can be useful for checking if a room exists at certain coordinates, or whenever you have rooms overlapping.
    Example
    -- sample script to determine a room nearby, given a relative direction from the current room
    local otherroom
    if matches[2] == "" then
      local w = matches[3]
      local ox, oy, oz, x,y,z = getRoomCoordinates(mmp.currentroom)
      local has = table.contains
      if has({"west", "left", "w", "l"}, w) then
        x = (x or ox) - 1; y = (y or oy); z = (z or oz)
      elseif has({"east", "right", "e", "r"}, w) then
        x = (x or ox) + 1; y = (y or oy); z = (z or oz)
      elseif has({"north", "top", "n", "t"}, w) then
        x = (x or ox); y = (y or oy) + 1; z = (z or oz)
      elseif has({"south", "bottom", "s", "b"}, w) then
        x = (x or ox); y = (y or oy) - 1; z = (z or oz)
      elseif has({"northwest", "topleft", "nw", "tl"}, w) then
        x = (x or ox) - 1; y = (y or oy) + 1; z = (z or oz)
      elseif has({"northeast", "topright", "ne", "tr"}, w) then
        x = (x or ox) + 1; y = (y or oy) + 1; z = (z or oz)
      elseif has({"southeast", "bottomright", "se", "br"}, w) then
        x = (x or ox) + 1; y = (y or oy) - 1; z = (z or oz)
      elseif has({"southwest", "bottomleft", "sw", "bl"}, w) then
        x = (x or ox) - 1; y = (y or oy) - 1; z = (z or oz)
      elseif has({"up", "u"}, w) then
        x = (x or ox); y = (y or oy); z = (z or oz) + 1
      elseif has({"down", "d"}, w) then
        x = (x or ox); y = (y or oy); z = (z or oz) - 1
      end
    
      local carea = getRoomArea(mmp.currentroom)
      if not carea then mmp.echo("Don't know what area are we in.") return end
    
      otherroom = select(2, next(getRoomsByPosition(carea,x,y,z)))
    
      if not otherroom then
        mmp.echo("There isn't a room to the "..w.." that I see - try with an exact room id.") return
      else
        mmp.echo("The room "..w.." of us has an ID of "..otherroom)
      end

    getRoomUserData

    data = getRoomUserData(roomID, key (as a string))
    Returns the user data stored at a given room with a given key, or "" if none is stored. Use setRoomUserData() function for setting the user data.
    Example
    display(getRoomUserData(341, "visitcount"))

    getRoomWeight

    room weight = getRoomWeight(roomID)
    Returns the weight of a room. By default, all new rooms have a weight of 1.
    See also: setRoomWeight()
    Example
    display("Original weight of room 541: "..getRoomWeight(541)
    setRoomWeight(541, 3)
    display("New weight of room 541: "..getRoomWeight(541)

    getSpecialExits

    exits = getSpecialExits(roomID)
    Returns a roomid - command table of all special exits in the room. If there are no special exits in the room, the table returned will be empty.
    Example
    getSpecialExits(1337)
    
    -- results in:
    --[[
    table {
      12106: 'faiglom nexus'
    }
    ]]

    getSpecialExitsSwap

    exits = getSpecialExitsSwap(roomID)
    Very similar to getSpecialExits() function, but returns the rooms in the command - roomid style.

    gotoRoom

    gotoRoom (roomID)
    Speedwalks you to the given room from your current room if it is able and knows the way. You must turn the map on for this to work, else it will return "(mapper): Don't know how to get there from here :(".

    hasExitLock

    status = hasExitLock(roomID, direction)
    Returns true or false depending on whenever a given exit leading out from a room is locked. direction right now is a number that corresponds to the direction:
     exitmap = {
       n = 1,
       north = 1,
       ne = 2,
       northeast = 2,
       nw = 3,
       northwest = 3,
       e = 4,
       east = 4,
       w = 5,
       west = 5,
       s = 6,
       south = 6,
       se = 7,
       southeast = 7,
       sw = 8,
       southwest = 8,
       u = 9,
       up = 9,
       d = 10,
       down = 10,
       ["in"] = 11,
       out = 12
     }
    Example
    -- check if the east exit of room 1201 is locked
    display(hasExitLock(1201, 4))
    See also: lockExit()

    hasSpecialExitLock

    status = hasSpecialExitLock(from roomID, to roomID, command)
    Returns true or false depending on whenever a given exit leading out from a room is locked. command is the action to take to get through the gate.
    -- lock a special exit from 17463 to 7814 that uses the 'enter feather' command
    lockSpecialExit(17463, 7814, 'enter feather', true)
    
    -- see if it is locked: it will say 'true', it is
    display(hasSpecialExitLock(17463, 7814, 'enter feather'))

    highlightRoom

    highlightRoom( id, r1,g1,b1,r2,g2,b2, radius, alpha1, alpha2)
    Highlights a room with the given color, which will override it's environment color. If you use two different colors, then there'll be a shading from the center going outwards that changes into the other color. highlightRadius is the radius for the highlight circle - if you don't want rooms beside each other to over lap, use 1 as the radius. alphaColor1 and alphaColor2 are transparency values from 0 (completely transparent) to 255 (not transparent at all).
    See also: unHighlightRoom()

    Note: Available since Mudlet 2.0 final release

    -- color room #351 red to blue
    local r,g,b = unpack(color_table.red)
    local br,bg,bb = unpack(color_table.blue)
    highlightRoom(351, r,g,b,br,bg,bb, 1, 255, 255)

    loadMap

    boolean = loadMap(file location)
    Loads the map file from a given location. The map file must be in Mudlet's format (not XML or any other) - saved with saveMap().
    Returns a boolean for whenever the loading succeeded. Note that the mapper must be open, or this will fail.
    See also: saveMap()
      loadMap("/home/user/Desktop/Mudlet Map.dat")

    lockExit

    lockExit(roomID, direction, lock = true/false)
    Locks a given exit from a room (which means that unless all exits in the incoming room are locked, it'll still be accessible). Direction at the moment is only set as a number, and here's a listing of them:
     exitmap = {
       n = 1,
       north = 1,
       ne = 2,
       northeast = 2,
       nw = 3,
       northwest = 3,
       e = 4,
       east = 4,
       w = 5,
       west = 5,
       s = 6,
       south = 6,
       se = 7,
       southeast = 7,
       sw = 8,
       southwest = 8,
       u = 9,
       up = 9,
       d = 10,
       down = 10,
       ["in"] = 11,
       out = 12
     }
    Example
    -- lock the east exit of room 1201 so we never path through it
    lockExit(1201, 4, true)
    See also: hasExitLock()

    lockRoom

    lockRoom (roomID, lock = true/false)
    Locks a given room id from future speed walks (thus the mapper will never path through that room).
    See also: roomLocked()
    Example
    lockRoom(1, true) -- locks a room if from being walked through when speedwalking.
    lockRoom(1, false) -- unlocks the room, adding it back to possible rooms that can be walked through.

    lockSpecialExit

    lockSpecialExit (from roomID, to roomID, special exit command, lock = true/false)
    Locks a given special exit, leading from one specific room to another that uses a certain command from future speed walks (thus the mapper will never path through that special exit).
    See also: hasSpecialExitLock(), lockExit(), lockRoom()
    Example
    lockSpecialExit(1,2,'enter gate', true) -- locks the special exit that does 'enter gate' to get from room 1 to room 2
    lockSpecialExit(1,2,'enter gate', false) -- unlocks the said exit

    removeMapEvent

    removeMapEvent (event name)
    Removes the given menu entry from a mappers right-click menu. You can add custom ones with addMapEvent().
    See also: addMapEvent(), addMapMenu(), getMapEvents()
    Example
    addMapEvent("room a", "onFavorite") -- add one to the general menu
    removeMapEvent("room a") -- removes the said menu

    roomExists

    roomExists(roomID)
    Returns a boolean true/false depending if the room with that ID exists (is created) or not.

    roomLocked

    locked = roomLocked(roomID)
    Returns true or false whenever a given room is locked.
    See also: lockRoom()
    Example
    echo(string.format("Is room #4545 locked?%s.", roomLocked(4545) and "Yep" or "Nope"))

    saveMap

    saveMap(location)
    Saves the map to a given location, and returns true on success. The location folder needs to be already created for save to work.
    See also: loadMap()
    Example
    local savedok = saveMap(getMudletHomeDir().."/my fancy map.dat")
    if not savedok then
      echo("Couldn't save:(\n")
    else
      echo("Saved fine!\n")
    end

    searchRoom

    searchRoom (room name)
    Searches for rooms that match (by case-insensitive, substring match) the given room name. It returns a key-value table in form of roomid = roomname, like so:
    Example
    display(searchRoom("master"))
    
    --[[ would result in:
    table {
      17463: 'in the branches of the Master Ravenwood'
      3652: 'master bedroom'
      10361: 'Hall of Cultural Masterpieces'
      6324: 'Exhibit of the Techniques of the Master Artisans'
      5340: 'office of the Guildmaster'
      (...)
      2004: 'office of the guildmaster'
      14457: 'the Master Gear'
      1337: 'before the Master Ravenwood Tree'
    }
    ]]

    If no rooms are found, then an empty table is returned.

    setAreaName

    setAreaName(areaID, newName)
    Renames an existing area to the new name.
    Example
    setAreaName(2, "My city")

    setCustomEnvColor

    setCustomEnvColor(environmentID, r,g,b,a)
    Creates, or overrides an already created custom color definition for a given environment ID. Note that this will not work on the default environment colors - those are adjustable by the user in the preferences. You can however create your own environment and use a custom color definition for it.

    Note: Numbers 1-16 and 257-272 are reserved by Mudlet. 257-272 are the default colors the user can adjust in mapper settings, so feel free to use them if you'd like - but don't overwrite them with this function.

    Example
    setRoomEnv(571, 200) -- change the room's environment ID to something arbitrary, like 200
    local r,g,b = unpack(color_table.blue)
    setCustomEnvColor(200, r,g,b, 255) -- set the color of environmentID 200 to blue

    setExit

    setExit(from roomID, to roomID, direction)
    Creates a one-way exit from one room to another using a standard direction - which can be either one of n, ne, nw, e, w, s, se, sw, u, d, in, out, or a number which represents a direction.
    Returns false if the exit creation didn't work.
    Example
    -- alias pattern: ^exit (\d+) (\w+)$
    
    if setExit(mmp.currentroom, tonumber(matches[2]),matches[3]) then
    echo("\nExit set to room:"..matches[2]..", Direction:"..string.upper(matches[3]))
    centerview(mmp.currentroom)
    else
    mmp.echo("Failed to set the exit.") end

    This function can also delete exits from a room if you use it like so: setExit(from roomID, -1, direction)

    Which will delete an outgoing exit in the specified direction from a room.

    -- locate the room on the other end, so we can unlink it from there as well if necessary
    local otherroom
    if getRoomExits(getRoomExits(mmp.currentroom)[dir])[mmp.ranytolong(dir)] then
      otherroom = getRoomExits(mmp.currentroom)[dir]
    end
    
    if setExit(mmp.currentroom, -1, dir) then
      if otherroom then
        if setExit(otherroom, -1, mmp.ranytolong(dir)) then
          mmp.echo(string.format("Deleted the%s exit from%s (%d).",
            dir, getRoomName(mmp.currentroom), mmp.currentroom))
         else mmp.echo("Couldn't delete the incoming exit.") end
      else
        mmp.echo(string.format("Deleted the one-way%s exit from%s (%d).",
          dir, getRoomName(mmp.currentroom), mmp.currentroom))
      end
    else
      mmp.echo("Couldn't delete the outgoing exit.")
    end
    You can use these numbers for setting the directions as well:
    exitmap = {
      n = 1,
      north = 1,
      ne = 2,
      northeast = 2,
      nw = 3,
      northwest = 3,
      e = 4,
      east = 4,
      w = 5,
      west = 5,
      s = 6,
      south = 6,
      se = 7,
      southeast = 7,
      sw = 8,
      southwest = 8,
      u = 9,
      up = 9,
      d = 10,
      down = 10,
      ["in"] = 11,
      out = 12
    }

    setGridMode

    setGridMode(area, true/false)
    Enables grid/wilderness view mode for an area - this will cause the rooms to lose their visible exit connections, like you'd see on compressed ASCII maps, both in 2D and 3D view mode.
    Example
    setGridMode(55,true) -- set area with ID 55 to be in grid mode

    setModulePriority

    setModulePriority(module name, priority #)
    Sets the module priority on a given module as a number - the module priority determines the order modules are loaded in, which can be helpful if you have ones dependent on each other. This can also be set from the module manager window.
    See also: getModulePriority()
    setModulePriority("mudlet-mapper", 1)

    setRoomArea

    setRoomArea(roomID, newAreaID)
    Assigns the given room to a new area. This will have the room be visually moved into the area as well.

    setRoomChar

    setRoomChar(roomID, character)
    Designed for an area in grid mode, this will set a single character to be on a room. You can use "_" to clear it.
    Example
    setRoomChar(431, "#")
    
    setRoomChar(123. "$")

    setRoomCoordinates

    setRoomCoordinates(roomID, x, y, z)
    Sets the given room ID to be at the following coordinates visually on the map, where z is the up/down level.

    Note: 0,0,0 is the center of the map.

    Example
    -- alias pattern: ^set rc (-?\d+) (-?\d+) (-?\d+)$
    local x,y,z = getRoomCoordinates(previousRoomID)
    local dir = matches[2]
    
    if dir == "n" then
      y = y+1
    elseif dir == "ne" then
      y = y+1
      x = x+1
    elseif dir == "e" then
      x = x+1
    elseif dir == "se" then
      y = y-1
      x = x+1
    elseif dir == "s" then
      y = y-1
    elseif dir == "sw" then
      y = y-1
      x = x-1
    elseif dir == "w" then
      x = x-1
    elseif dir == "nw" then
      y = y+1
      x = x-1
    elseif dir == "u" or dir == "up" then
      z = z+1
    elseif dir == "down" then
      z = z-1
    end
    setRoomCoordinates(roomID,x,y,z)
    centerview(roomID)
    You can make them relative as well:
    -- alias pattern: ^src (\w+)$
    
    local x,y,z = getRoomCoordinates(previousRoomID)
    local dir = matches[2]
    
    if dir == "n" then
      y = y+1
    elseif dir == "ne" then
      y = y+1
      x = x+1
    elseif dir == "e" then
      x = x+1
    elseif dir == "se" then
      y = y-1
      x = x+1
    elseif dir == "s" then
      y = y-1
    elseif dir == "sw" then
      y = y-1
      x = x-1
    elseif dir == "w" then
      x = x-1
    elseif dir == "nw" then
      y = y+1
      x = x-1
    elseif dir == "u" or dir == "up" then
      z = z+1
    elseif dir == "down" then
      z = z-1
    end
    setRoomCoordinates(roomID,x,y,z)
    centerview(roomID)

    setRoomEnv

    setRoomEnv(roomID, newEnvID)
    Sets the given room to a new environment ID. You don't have to use any functions to create it - can just set it right away.
    Example
    setRoomEnv(551, 34) -- set room with the ID of 551 to the environment ID 34

    setRoomIDbyHash

    setRoomIDbyHash(roomID, hash)
    Sets the hash to be associated with the given roomID. See also getRoomIDbyHash().

    setRoomName

    setRoomName(roomID, newName)
    Renames an existing room to a new name.
    Example
    setRoomName(534, "That evil room I shouldn't visit again.")
    lockRoom(534, true) -- and lock it just to be safe

    setRoomUserData

    setRoomUserData(roomID, key (as a string), value (as a string))
    Stores information about a room under a given key. Similar to Lua's key-value tables, except only strings may be used here. One advantage of using userdata is that it's stored within the map file itself - so sharing the map with someone else will pass on the user data. You can have as many keys as you'd like.
    Returns true if successfully set.
    See also: clearRoomUserData()



    Example
    -- can use it to store room descriptions...
    setRoomUserData(341, "description", "This is a plain-looking room.")
    
    -- or whenever it's outdoors or not...
    setRoomUserData(341, "ourdoors", "true")
    
    -- how how many times we visited that room
    local visited = getRoomUserData(341, "visitcount")
    visited = (tonumber(visited) or 0) + 1
    setRoomUserData(341, "visitcount", tostring(visited))
    
    -- can even store tables in it, using the built-in yajl.to_string function
    setRoomUserData(341, "some table", yajl.to_string({name = "bub", age = 23}))
    display("The denizens name is: "..yajl.to_value(getRoomUserData(341, "some table")).name)

    setRoomWeight

    setRoomWeight(roomID, weight)
    Sets a weight to the given roomID. By default, all rooms have a weight of 0 - the higher the weight is, the more likely the room is to be avoided for pathfinding. For example, if travelling across water rooms takes more time than land ones - then you'd want to assign a weight to all water rooms, so they'd be avoided if there are possible land pathways.
    To completely avoid a room, make use of lockRoom().
    See also: getRoomWeight()



    Example
    setRoomWeight(1532, 3) -- avoid using this room if possible, but don't completely ignore it

    speedwalk

    speedwalk(dirString, backwards, delay)
    A speedwalking function will work on cardinal+ordinal directions (n, ne, e, etc.) as well as u (for up), d (for down), in and out. It can be called to execute all directions directly after each other, without delay, or with a custom delay, depending on how fast your mud allows you to walk. It can also be called with a switch to make the function reverse the whole path and lead you backwards.
    Call the function by doing: speedwalk("YourDirectionsString", true/false, delaytime)
    The delaytime parameter will set a delay between each move (set it to 0.5 if you want the script to move every half second, for instance). It is optional: If you don't indicate it, the script will send all direction commands right after each other. (If you want to indicate a delay, you -have- explicitly indicate true or false for the reverse flag.)
    The "YourDirectionsString" contains your list of directions and steps (e.g.: "2n, 3w, u, 5ne"). Numbers indicate the number of steps you want it to walk in the direction specified after it. The directions must be separated by anything other than a letter that can appear in a direction itself. (I.e. you can separate with a comma, spaces, the letter x, etc. and any such combinations, but you cannot separate by the letter "e", or write two directions right next to each other with nothing in-between, such as "wn". If you write a number before every direction, you don't need any further separator. E.g. it's perfectly acceptable to write "3w1ne2e".) The function is not case-sensitive.
    If your Mud only has cardinal directions (n,e,s,w and possibly u,d) and you wish to be able to write directions right next to each other like "enu2s3wdu", you'll have to change the pattern slightly. (See the link at the beginning of my post for something like that.)
    Likewise, if your Mud has any other directions than n, ne, e, se, s, sw, w, nw, u, d, in, out, the function must be adapted to that.
    Example
    speedwalk("16d1se1u")
    -- Will walk 16 times down, once southeast, once up. All in immediate succession.
    
    speedwalk("2ne,3e,2n,e")
    -- Will walk twice northeast, thrice east, twice north, once east. All in immediate succession.
    
    speedwalk("IN N 3W 2U W", false, 0.5)
    -- Will walk in, north, thrice west, twice up, west, with half a second delay between every move.
    
    speedwalk("5sw - 3s - 2n - w", true)
    -- Will walk backwards: east, twice south, thrice, north, five times northeast. All in immediate succession.
    
    speedwalk("3w, 2ne, w, u", true, 1.25)
    -- Will walk backwards: down, east, twice southwest, thrice east, with 1.25 seconds delay between every move.

    Note: The probably most logical usage of this would be to put it in an alias. For example, have the pattern ^/(.+)$ execute: speedwalk(matches[2], false, 0.7) And have ^//(.+)$ execute: speedwalk(matches[2], true, 0.7)

    Or make aliases like: ^banktohome$ to execute

    speedwalk("2ne,e,ne,e,3u,in", true, 0.5)

    unHighlightRoom

    unHighlightRoom(roomID)
    Unhighlights a room if it was previously highlighted and restores the rooms original environment color.
    See also: highlightRoom()

    Note: Available since Mudlet 2.0 final release

    Example
    unHighlightRoom(4534)

    Miscellaneous Functions

    feedTriggers

    feedTriggers( text )
    This function will have Mudlet parse the given text as if it came from the MUD - one great application is trigger testing. You can use \n to represent a new line - you also want to use it before and after the text you’re testing, like so:
    feedTriggers("\nYou sit yourself down.\n")
    The function also accept ANSI color codes that are used in MUDs. A sample table can be found here.
    Example
    feedTriggers("\nThis is \27[1;32mgreen\27[0;37m, \27[1;31mred\27[0;37m, \27[46mcyan background\27[0;37m," ..
    "\27[32;47mwhite background and green foreground\27[0;37m.\n")

    expandAlias

    expandAlias(command,true/false)
    Runs the command as if it was from the command line - so aliases are checked and if none match, it's sent to the the game. If the second argument is false, it will hide the command from being echoed back in your buffer. Defaults to true.
    Example
    expandAlias("t rat")
    
    -- don't echo the command
    expandAlias("t rat", false)

    Note: If you want to be using the matches table after calling expandAlias, you should save it first as local oldmatches = matches before calling expandAlias, since expandAlias will overwrite it after using it again.

    feedTriggers

    feedTriggers( text )
    This function will have Mudlet parse the given text as if it came from the MUD - one great application is trigger testing. You can use \n to represent a new line - you also want to use it before and after the text you’re testing, like so:
    feedTriggers("\nYou sit yourself down.\n")
    The function also accept ANSI color codes that are used in MUDs. A sample table can be found here.
    Example
    feedTriggers("\nThis is \27[1;32mgreen\27[0;37m, \27[1;31mred\27[0;37m, \27[46mcyan background\27[0;37m," ..
    "\27[32;47mwhite background and green foreground\27[0;37m.\n")

    getMudletHomeDir

    getMudletHomeDir()
    Returns the current home directory of the current profile. This can be used to store data, save statistical information, or load resource files from packages.
    Example
    -- save a table
    table.save(getMudletHomeDir().."/myinfo.dat", myinfo)
    
    -- or access package data. The forward slash works even on Windows fine
    local path = getMudletHomeDir().."/mypackagename"



    playSoundFile

    playSoundFile(fileName)
    This function plays a sound file. On 2.0, it can play most sound formats and up to 4 sounds simulaneously.
    Parameters
    • fileName:

    Exact path of the sound file.
    Example
    -- play a sound in Windows
    playSoundFile([[C:\My folder\boing.wav]])
    
    -- play a sound in Linux
    playSoundFile([[/home/myname/Desktop/boingboing.wav]])
    
    -- play a sound from a package
    playSoundFile(getMudletHomeDir().. [[/mypackage/boingboing.wav]])

    registerAnonymousEventHandler

    registerAnonymousEventHandler(event name, function name)
    Registers a function to an event handler, not requiring you to set one up via s cript.
    At the moment, it's not possible to use handlers inside namespaces, or unregister them.
    Example
    -- example taken from the God Wars 2 (http://godwars2.org) Mudlet UI - forces the window to keep to a certain size
    function keepStaticSize()
      setMainWindowSize(1280,720)
    end -- keepStaticSize
    
    registerAnonymousEventHandler("sysWindowResizeEvent", "keepStaticSize")



    spawn

    spawn(read function, process to spawn)
    Spawns a process and opens a communicatable link with it - read function is the function you'd like to use for reading output from the process, and t is a table containing functions specific to this connection - send(data), true/false = isRunning(), and close().
    Example
    -- simple example on a program that quits right away, but prints whatever it gets using the 'display' function
    local f = spawn(display, "ls")
    display(f.isRunning())
    f.close()

    Mudlet Object Functions

    appendCmdLine

    appendCmdLine()
    Appends text to the main input line.
    Example
    -- adds the text "55 backpacks" to whatever is currently in the input line
    appendCmdLine("55 backpacks")
    
    -- makes a link, that when clicked, will add "55 backpacks" to the input line
    echoLink("press me", "appendCmdLine'55 backpack'", "Press me!")

    clearCmdLine

    clearCmdLine()
    Clears the input line of any text that's been entered.
    Example
    -- don't be evil with this!
    clearCmdLine()

    createStopWatch

    createStopWatch()
    This function creates a stop watch. It is high resolution time measurement tool. Stop watches can be started, stopped, reset and asked how much time has passed since the stop watch has been started.

    Note: it's best to re-use stopwatch IDs if you can - Mudlet at the moment does not delete them, so creating more and more would use more memory.

    Returns: The ID of a high resolution clock with milliseconds to measure time more accurately.
    Example
    In a global script you create all stop watches that you need in your system and store the respective stopWatch-IDs in global variables:
    fightStopWatch = createStopWatch() -- you store the watchID in a global variable to access it from anywhere
    Then you can start the stop watch in some trigger/alias/script with:
    startStopWatch( fightStopWatch )
    To stop the watch and measure its time in e.g. a trigger script you can write:
    fightTime = stopStopWatch( fightStopWatch )
    echo( "The fight lasted for " .. fightTime .. " seconds." )
    resetStopWatch( fightStopWatch )
    You can also measure the elapsed time without having to stop the stop watch with getStopWatchTime.

    disableAlias

    disableAlias(name)
    Disables/deactivates the alias by it’s name. If several aliases have this name, they’ll all be disabled.
    Parameters
    • name:

    The name of the alias. Passed as a string.
    Examples
    --Disables the alias called 'my alias'
    disableAlias("my alias")

    disableKey

    disableKey(name)
    Disables key a key (macro) or a key group. When you disable a key group, all keys within the group will be implicitly disabled as well.
    Parameters
    • name:

    The name of the key or group to identify what you'd like to disable.
    Examples
    -- you could set multiple keys on the F1 key and swap their use as you wish by disabling and enabling them
    disableKey("attack macro")
    disableKey("jump macro")
    enableKey("greet macro")

    disableTimer

    disableTimer(name)
    Disables a timer from running it’s script when it fires - so the timer cycles will still be happening, just no action on them. If you’d like to permanently delete it, use killTrigger instead.
    Parameters
    • name:

    Expects the timer ID that was returned by tempTimer on creation of the timer or the name of the timer in case of a GUI timer.
    Example
    --Disables the timer called 'my timer'
    disableTimer("my timer")

    disableTrigger

    disableTrigger(name)
    Disables a trigger that was previously enabled.
    Parameters
    • name:

    Expects the trigger ID that was returned by tempTrigger or other temp*Trigger variants, or the name of the trigger in case of a GUI trigger.
    Example
    -- Disables the trigger called 'my trigger'
    disableTrigger("my trigger")

    enableAlias

    enableAlias(name)
    Enables/activates the alias by it’s name. If several aliases have this name, they’ll all be enabled.
    Parameters
    • name:

    Expects the alias ID that was returned by tempTrigger on creation of the alias or the name of the alias in case of a GUI alias.
    Example
    --Enables the alias called 'my alias'
    enableAlias("my alias")

    enableKey

    enableKey(name)
    Enables a key (macro) or a group of keys (and thus all keys within it that aren't explicitly deactivated).
    Parameters
    • name:

    The name of the group that identifies the key.
    -- you could use this to disable one key set for the numpad and activate another
    disableKey("fighting keys")
    enableKey("walking keys")

    enableTimer

    enableTimer(name)
    Enables or activates a timer that was previously disabled.
    Parameters
    • name:

    Expects the timer ID that was returned by tempTimer on creation of the timer or the name of the timer in case of a GUI timer.
    -- enable the timer called 'my timer' that you created in Mudlets timers section
    enableTimer("my timer")
    -- or disable & enable a tempTimer you've made
    timerID = tempTimer(10, [[echo("hi!")]])
    
    -- it won't go off now
    disableTimer(timerID)
    -- it will continue going off again
    enableTimer(timerID)

    enableTrigger

    enableTrigger(name)
    Enables or activates a trigger that was previously disabled.
    Parameters
    • name:

    Expects the trigger ID that was returned by tempTrigger or by any other temp*Trigger variants, or the name of the trigger in case of a GUI trigger.
    -- enable the trigger called 'my trigger' that you created in Mudlets triggers section
    enableTrigger("my trigger")
    -- or disable & enable a tempTrigger you've made
    triggerID = tempTrigger("some text that will match in a line", [[echo("hi!")]])
    
    -- it won't go off now when a line with matching text comes by
    disableTrigger(triggerID)
    
    -- and now it will continue going off again
    enableTrigger(triggerID)

    exists

    exists(name, type)
    Tells you how many things of the given type exist.
    Parameters
    • name:

    The name or the id returned by tempTimer to identify the item.
    • type:

    The type can be 'alias', 'trigger', or 'timer'.
    Example
    echo("I have " .. exists("my trigger", "trigger") .. " triggers called 'my trigger'!")
    You can also use this alias to avoid creating duplicate things, for example:
    -- this code doesn't check if an alias already exists and will keep creating new aliases
    permAlias("Attack", "General", "^aa$", [[send ("kick rat")]])
    
    -- while this code will make sure that such an alias doesn't exist first
    -- we do == 0 instead of 'not exists' because 0 is considered true in Lua
    if exists("Attack", "alias") == 0 then
        permAlias("Attack", "General", "^aa$", [[send ("kick rat")]])
    end

    getButtonState

    getButtonState()
    This function can only be used inside a toggle button script
    Returns 2 if button is checked, and 1 if it's not.
    Example
    checked = getButtonState();
    if checked == 1 then
        hideExits()
    else
        showExits()
    end;

    invokeFileDialog

    invokeFileDialog(fileOrFolder, dialogTitle)
    Opens a file chooser dialog, allowing the user to select a file or a folder visually. The function returns the selected path or "" if there was none chosen.
    Parameters
    • fileOrFolder: true for file selection, false for folder selection.

    • dialogTitle: the code to do when the timer is up - wrap it in [[ ]], or provide a Lua function

    Examples
    function whereisit()
      local path = invokeFileDialog(false, "Where should we save the file? Select a folder and click Open")
    
      if path == "" then return nil else return path end
    end

    isActive

    isActive(name, type)
    You can use this function to check if something, or somethings, are active.
    Parameters
    • name:

    The name or the id returned by tempTimer to identify the item.
    • type:

    The type can be 'alias', 'trigger', or 'timer'.
    Example
    echo("I have " .. isActive("my trigger", "trigger") .. " currently active trigger(s) called 'my trigger'!")

    isPrompt

    isPrompt()
    Returns true or false depending on if the current line being processed is a prompt. This infallible feature is available for MUDs that supply GA events (to check if yours is one, look to bottom-right of the main window - if it doesn’t say <No GA>, then it supplies them).
    Example use could be as a Lua function, making closing gates on a prompt real easy.
    Example
    -- make a trigger pattern with 'Lua function', and this will trigger on every prompt!
    return isPrompt()

    killAlias

    killAlias(name)
    Deletes an alias with the given name. If several aliases have this name, they'll all be deleted.
    Parameters
    • name:

    The name or the id returned by tempTimer to identify the alias.
    --Deletes the alias called 'my alias'
    killAlias("my alias")

    killTimer

    killTimer(id)
    Deletes a tempTimer.

    Note: Non-temporary timers that you have set up in the GUI cannot be deleted with this function. Use disableTimer() and enableTimer() to turn them on or off.

    Parameters
    Returns true on success and false if the timer id doesn’t exist anymore (timer has already fired) or the timer is not a temp timer.
    Example
    -- create the timer and remember the timer ID
    timerID = tempTimer(10, [[echo("hello!")]])
    
    -- delete the timer
    if killTimer(timerID) then echo("deleted the timer") else echo("timer is already deleted") end

    killTrigger

    killTrigger(id)
    Deletes a tempTrigger.
    Parameters
    • id:

    The ID returned by tempTimer to identify the item. ID is a string and not a number.
    Returns true on success and false if the trigger id doesn’t exist anymore (trigger has already fired) or the trigger is not a temp trigger.

    permAlias

    permAlias(name, parent, regex, lua code)
    Creates a persistent alias that stays after Mudlet is restarted and shows up in the Script Editor.
    Parameters
    • name:

    The name you’d like the alias to have.
    • parent:

    The name of the group, or another alias you want the trigger to go in - however if such a group/alias doesn’t exist, it won’t do anything. Use "" to make it not go into any groups.
    • regex:

    The pattern that you’d like the alias to use.
    • lua code:

    The script the alias will do when it matches.
    Example
    -- creates an alias called "new alias" in a group called "my group"
    permAlias("new alias", "my group", "^test$", [[echo ("say it works! This alias will show up in the script editor too.")]])

    Note: Mudlet by design allows duplicate names - so calling permAlias with the same name will keep creating new aliases. You can check if an alias already exists with the exists function.

    permGroup

    permGroup(name, itemtype)
    Creates a new group of a given type at the root level (not nested in any other groups). This group will persist through Mudlet restarts.
    Parameters
    • name:

    The name of the new group you want to create.
    • itemtype:

    The name of the timer, trigger, or alias.

    Note: Added to Mudlet in the 2.0 final release.

    --create a new trigger group
    permGroup("Combat triggers", "trigger")
    
    --create a new alias group only if one doesn't exist already
    if exists("Defensive aliases", "alias") == 0 then
      permGroup("Defensive aliases", "alias")
    end

    permRegexTrigger

    permRegexTrigger(name, parent, pattern, lua code)
    Creates a persistent trigger with a regex pattern that stays after Mudlet is restarted and shows up in the Script Editor.
    Parameters
    • name is the name you’d like the trigger to have.

    • parent is the name of the group, or another trigger you want the trigger to go in - however if such a group/trigger doesn’t exist, it won’t do anything. Use "" to make it not go into any groups.

    • pattern table is a table of patterns that you’d like the trigger to use - it can be one or many.

    • lua code is the script the trigger will do when it matches.

    Example
    -- Create a regex trigger that will match on the prompt to record your status
    permRegexTrigger("Prompt", "", {"^(\d+)h, (\d+)m"}, [[health = tonumber(matches[2]; mana = tonumber(matches[3])]]

    Note: Mudlet by design allows duplicate names - so calling permRegexTrigger with the same name will keep creating new triggers. You can check if a trigger already exists with the exists() function.

    permSubstringTrigger

    permSubstringTrigger( name, parent, pattern, lua code )
    Creates a persistent trigger with a substring pattern that stays after Mudlet is restarted and shows up in the Script Editor.
    Parameters
    • name is the name you’d like the trigger to have.

    • parent is the name of the group, or another trigger you want the trigger to go in - however if such a group/trigger doesn’t exist, it won’t do anything. Use "" to make it not go into any groups.

    • pattern table is a table of patterns that you’d like the trigger to use - it can be one or many.

    • lua code is the script the trigger will do when it matches.

    Example
    -- Create a trigger to highlight the word "pixie" for us
    permSubstringTrigger("Highlight stuff", "General", {"pixie"},
    [[selectString(line, 1) bg("yellow") resetFormat()]])
    
    -- Or another trigger to highlight several different things
    permSubstringTrigger("Highlight stuff", "General", {"pixie", "cat", "dog", "rabbit"},
    [[selectString(line, 1) fg ("blue") bg("yellow") resetFormat()]])

    Note: Mudlet by design allows duplicate names - so calling permSubstringTrigger with the same name will keep creating new triggers. You can check if a trigger already exists with the exists() function.

    permTimer

    permTimer(name, parent, seconds, lua code)
    Creates a persistent timer that stays after Mudlet is restarted and shows up in the Script Editor.
    Parameters
    • name

    Is the name of the timer.
    • parent

    Is the name of the timer group you want the timer to go in..
    • seconds

    Is a number specifying a delay after which the timer will do the lua code you give it as a string.
    • lua code is the code with string you are doing this to.

    Example
    permTimer("my timer", "first timer group", 4.5, [[send ("my timer that's in my first timer group fired!")]])

    Note: Mudlet by design allows duplicate names - so calling permTimer with the same name will keep creating new timers. You can check if a timer already exists with the exists() function.

    printCmdLine

    printCmdLine(text)
    Replaces the current text in the input line, and sets it to the given text.
    printCmdLine("say I'd like to buy ")

    raiseEvent

    raiseEvent(event_name, arg-1, … arg-n)
    Raises the event event_name. The event system will call the main function (the one that is called exactly like the script name) of all such scripts that have registered event handlers. If an event is raised, but no event handler scripts have been registered with the event system, the event is ignored and nothing happens. This is convenient as you can raise events in your triggers, timers, scripts etc. without having to care if the actual event handling has been implemented yet - or more specifically how it is implemented. Your triggers raise an event to tell the system that they have detected a certain condition to be true or that a certain event has happened. How - and if - the system is going to respond to this event is up to the system and your trigger scripts don’t have to care about such details. For small systems it will be more convenient to use regular function calls instead of events, however, the more complicated your system will get, the more important events will become because they help reduce complexity very much.
    The corresponding event handlers that listen to the events raised with raiseEvent() need to use the script name as function name and take the correct number of arguments.



    Example
    raiseEvent("fight") a correct event handler function would be: myScript( event_name ). In this example raiseEvent uses minimal arguments, name the event name. There can only be one event handler function per script, but a script can still handle multiple events as the first argument is always the event name. So you can call your own special handlers for individual events. The reason behind this is that you should rather use many individual scripts instead of one huge script that has all your function code etc. Scripts can be organized very well in trees and thus help reduce complexity on large systems.

    remember

    remember("variable")
    This function flags a variable to be saved by Mudlet's variable persistence system.
    Parameters
    • variable

    Variable that you are saving. Can be a table or regular variable. Name must be passed as a string.
    Example
    remember("table_Weapons")
    remember("var_EnemyHeight")

    Variables are automatically unpacked into the global namespace when the profile is loaded.
    They are saved to "SavedVariables.lua" when the profile is closed or saved.

    resetStopWatch

    resetStopWatch(watchID)
    This function resets the time to 0:0:0.0, but does not start the stop watch. You can start it with startStopWatchcreateStopWatch

    setConsoleBufferSize

    setConsoleBufferSize( consoleName, linesLimit, sizeOfBatchDeletion )
    Sets the maximum number of lines can a buffer (main window or a miniconsole) can hold.
    Parameters
    • consoleName:

    The name of the window
    • linesLimit:

    Sets the amount of lines the buffer should have.

    Note: Mudlet performs extremely efficiently with even huge numbers, so your only limitation is your computers memory (RAM).

    • sizeOfBatchDeletion:

    Specifies how many lines should Mudlet delete at once when you go over the limit - it does it in bulk because it's efficient to do so.
    Example
    -- sets the main windows size to 5 million lines maximum - which is more than enough!
    setConsoleBufferSize("main", 5000000, 1000)

    setTriggerStayOpen

    setTriggerStayOpen(name, number)
    Sets for how many more lines a trigger script should fire or a chain should stay open after the trigger has matched - so this allows you to extend or shorten the fire length of a trigger. The main use of this function is to close a chain when a certain condition has been met.
    Parameters
    • name: The name of the trigger which has a fire length set (and which opens the chain).

    • number: 0 to close the chain, or a positive number to keep the chain open that much longer.

    Examples
    -- if you have a trigger that opens a chain (has some fire length) and you'd like it to be closed 
    -- on the next prompt, you could make a trigger inside the chain with a Lua function pattern of:
    return isPrompt()
    -- and a script of:
    setTriggerStayOpen("''Parent trigger name''", 0)
    -- to close it on the prompt!

    startStopWatch

    startStopWatch( watchID )
    Starts the stop watch. → createStopWatch()

    stopStopWatch

    stopStopWatch( watchID )
    Stops the stop watch and returns the elapsed time in milliseconds in form of 0.001. → createStopWatch()
    Returns time as a number

    tempAlias

    aliasID = tempAlias(regex, code to do)
    Creates a temporary alias - temporary in the sense that it won't be saved when Mudlet restarts (unless you re-create it). The alias will go off as many times as it matches, it is not a one-shot alias. The function returns an ID for subsequent enableAlias(), disableAlias() and killAlias() calls.
    Parameters
    • regex: Alias pattern in regex.

    • code to do: The code to do when the alias fires - wrap it in [[ ]].

    Examples
    myaliasID = tempAlias("^hi$", [[send ("hi") echo ("we said hi!")]])
    
    -- you can also delete the alias later with:
    killAlias(myaliasID)

    tempBeginOfLineTrigger

    tempBeginOfLineTrigger(part of line, code to do)
    Creates a trigger that will go off whenever the part of line it's provided with matches the line right from the start (doesn't matter what the line ends with). This trigger isn't temporary in the sense that it'll go off only once (it'll go off as often as it matches), but rather it won't be saved when Mudlet is closed. The function returns the trigger ID for subsequent enableTrigger(), disableTrigger() and killTrigger() calls. The trigger will go off multiple times until you disable or destroy it.
    Parameters
    • part of line: Start of the line that you'd like to match.

    • code to do: The code to do when the trigger fires - wrap it in [[ ]].

    Examples
    mytriggerID = tempBeginOfLineTrigger("Hello", [[echo("We matched!")]])
    
    --[[ now this trigger will match on any of these lines:
    Hello
    Hello!
    Hello, Bob!
    
    but not on:
    Oh, Hello
    Oh, Hello!
    ]]

    tempColorTrigger

    tempColorTrigger(foregroundColor, backgroundColor, code)
    Makes a color trigger that triggers on the specified foreground and background color. Both colors need to be supplied in form of these simplified ANSI 16 color mode codes. The function returns the trigger ID for subsequent enableTrigger(), disableTrigger() and killTrigger() calls. The trigger will go off multiple times until you disable or destroy it.
    Parameters
    • foregroundColor: The foreground color you'd like to trigger on.

    • backgroundColor: The background color you'd like to trigger on.

    • code: The code you'd like the trigger to run, as a string.

    Color codes
    0 = default text color
    1 = light black
    2 = dark black
    3 = light red
    4 = dark red
    5 = light green
    6 = dark green
    7 = light yellow
    8 = dark yellow
    9 = light blue
    10 = dark blue
    11 = light magenta
    12 = dark magenta
    13 = light cyan
    14 = dark cyan
    15 = light white
    16 = dark white
    Examples
    -- This script will re-highlight all text in blue foreground colors on a black background with a red foreground color
    -- on a blue background color until another color in the current line is being met. temporary color triggers do not 
    -- offer match_all or filter options like the GUI color triggers because this is rarely necessary for scripting. 
    -- A common usage for temporary color triggers is to schedule actions on the basis of forthcoming text colors in a particular context.
    tempColorTrigger(9,2,[[selectString(matches[1],1); fg("red"); bg("blue");]] );

    tempExactMatchTrigger

    tempExactMatchTrigger(exact line, code to do)
    Creates a trigger that will go off whenever the line from the game matches the provided line exactly (ends the same, starts the same, and looks the same). You don't need to use any of the regex symbols here (^ and $). This trigger isn't temporary in the sense that it'll go off only once (it'll go off as often as it matches), but rather it won't be saved when Mudlet is closed. The function returns the trigger ID for subsequent enableTrigger(), disableTrigger() and killTrigger() calls. The trigger will go off multiple times until you disable or destroy it.
    Parameters
    • exact line: Exact line you'd like to match.

    • code to do: The code to do when the trigger fires - wrap it in [[ ]].

    Examples
    mytriggerID = tempExactMatchTrigger("You have recovered balance on all limbs.", [[echo("We matched!")]])

    tempLineTrigger

    tempLineTrigger( from, howMany, LuaCode )
    Temporary trigger that will fire on n consecutive lines following the current line. This is useful to parse output that is known to arrive in a certain line margin or to delete unwanted output from the MUD - the trigger does not require any patterns to match on. The function returns the trigger ID for subsequent enableTrigger(), disableTrigger() and killTrigger() calls. The trigger will go off multiple times until you disable or destroy it.
    Returns trigger ID as a string.

    Note: You can use this ID to enable/disable or kill this trigger later on.

    Example
    --Will fire 3 times with the line from the MUD.
    tempLineTrigger( 1, 3, ) 
    
    --Will fire 20 lines after the current line and fire twice on 2 consecutive lines.
    tempLineTrigger( 20, 2, )

    tempRegexTrigger

    tempRegexTrigger(regex, code to do)
    Creates a temporary regex trigger that executes the code whenever it matches. The function returns the trigger ID for subsequent enableTrigger(), disableTrigger() and killTrigger() calls. The trigger will go off multiple times until you disable or destroy it.
    Parameters
    • regex: The regular expression that lines will be matched on.

    • code to do: The code to do when the timer is up - wrap it in [[ ]].

    Examples
    -- create a non-duplicate trigger that matches on any line and calls a function
    html5log = html5log or {}
    if html5log.trig then killTrigger(html5log.trig) end
    html5log.trig = tempRegexTrigger("^", "html5log.recordline()")

    tempTimer

    tempTimer(time, code to do)
    Creates a temporary one-shot timer and returns the timer ID, which you can use with enableTimer(), disableTimer() and killTimer() functions. You can use 2.3 seconds or 0.45 etc. After it has fired, the timer will be deactivated and destroyed, so it will only go off once. See the Technical Manual here for a more detailed introduction to tempTimer.
    Parameters
    • time: The time in seconds for which to set the timer for - you can use decimals here for precision. The timer will go off x given seconds after you make it.

    • code to do: The code to do when the timer is up - wrap it in [[ ]], or provide a Lua function.

    Examples
    -- wait half a second and then run the command
    tempTimer( 0.5, [[send("kill monster")]] )
    
    -- or an another example - two ways to 'embed' variable in a code for later:
    local name = matches[2]
    tempTimer(2, [[send("hello, ]]..name..[[!")]])
    -- or:
    tempTimer(2, function()
      send("hello, "..name)
    end)

    Note: Double brackets, e.g: [[ ]] can be used to quote strings in Lua. The difference to the usual `" " quote syntax is that `[[ ]] also accepts the character ". Consequently, you don’t have to escape the " character in the above script. The other advantage is that it can be used as a multiline quote, so your script can span several lines.

    Note: Lua code that you provide as an argument is compiled from a string value when the timer fires. This means that if you want to pass any parameters by value e.g. you want to make a function call that uses the value of your variable myGold as a parameter you have to do things like this:

    tempTimer( 3.8, [[echo("at the time of the tempTimer call I had ]] .. myGold .. [[ gold.")]] )
    
    -- tempTimer also accepts functions (and thus closures) - which can be an easier way to embed variables and make the code for timers look less messy:
    
    local variable = matches[2]
    tempTimer(3, function () send("hello, " .. variable) end)

    tempTrigger

    tempTrigger(substring, code to do)
    Creates a temporary substring trigger that executes the code whenever it matches. The function returns the trigger ID for subsequent enableTrigger(), disableTrigger() and killTrigger() calls. The trigger will go off multiple times until you disable or destroy it.
    Parameters
    • substring:: The substring to look for - this means a part of the line. If your provided text matches anywhere within the line from the game, the trigger will go off.

    • code to do: The code to do when the timer is up - wrap it in [[ ]].

    Example:

    -- this example will highlight the contents of the "target" variable.
    -- It will also delete the previous trigger it made when you call it again, so you're only ever highlighting one name
    if id then killTrigger(id) end
    id = tempTrigger(target, [[selectString("]] .. target .. [[", 1) fg("gold") resetFormat()]])
    -- a simpler trigger to replace "hi" with "bye" whenever you see it
    tempTrigger("hi", [[selectString("hi", 1) replace("bye")]])

    tempButton

    tempButton(group name, button text, orientation)
    Creates a temporary button.
    Parameters
    • group name:: The toolbar to place the button into.

    • button text: The text to place on the button.

    • orientation: a number, 0 - horizontal orientation for the button, or 1 - vertical orientation for the button.

    Networking Functions

    A collection of functions for managing networking.

    disconnect

    disconnect()
    Disconnects you from the game right away. Note that this will not properly log you out of the game.
    Example
    disconnect()

    downloadFile

    downloadFile(saveto, url)
    Downloads the resource at the given url into the saveto location on disk. This does not pause the script until the file is downloaded - instead, it lets it continue right away and downloads in the background. When a download is finished, the sysDownloadDone event is raised (with the saveto location as the argument), or when a download fails, the sysDownloadError event is raised with the reason for failure. You may call downloadFile multiple times and have multiple downloads going on at once - but they aren’t guaranteed to be downloaded in the same order that you started them in.

    Note: Requires Mudlet 2.0+

    Example
    -- this example will check the Imperian homepage to see how many players are on right now
    
    -- in an alias, download the Imperian homepage for stats processing
    downloadFile(getMudletHomeDir().."/page.html", "http://www.imperian.com/")
    
    -- then create a new script with the name of downloaded_file, add the event handler
    -- for sysDownloadDone, and use this to parse the webpage and display the amount
    function downloaded_file(_, filename)
      -- is the file that downloaded ours?
      if not filename:match("page", 1, true) then return end
    
      -- parse our ownloaded file for the player count
      io.input(filename)
      local s = io.read("*all")
      local pc = s:match([[<a href='players.php%?search=who'>(%d+)</a>]])
      display("Imperian has "..tostring(pc).." players on right now.")
      io.open():close()
      os.remove(filename)
    end

    getNetworkLatency

    getNetworkLatency()
    Returns the last measured response time between the sent command and the server reply e.g. 0.058 (=58 milliseconds lag) or 0.309 (=309 milliseconds). Also known as server lag.
    Example

    Need example

    openUrl

    openUrl (url)
    Opens the default OS browser for the given URL.
    Example
    openUrl("http://google.com")
    openUrl("www.mudlet.org")

    reconnect

    reconnect()
    Force-reconnects (so if you're connected, it'll disconnect) you to the game.
    Example
    -- you could trigger this on a log out message to reconnect, if you'd like
    reconnect()

    sendAll

    sendAll(list of things to send, [echo back or not])
    send()'s a list of things to the game. If you'd like the commands not to be shown, include false at the end.
    Example
    -- instead of using many send() calls, you can use one sendAll
    sendAll("outr paint", "outr canvas", "paint canvas")
    -- can also have the commands not be echoed
    sendAll("hi", "bye", false)

    sendGMCP

    sendGMCP(command)
    Sends a GMCP message to the server. The IRE document on GMCP has information about what can be sent, and what tables it will use, etcetera.
    See Also: Scripting Manual: GMCP Scripting
    Example
    --This would send "Core.KeepAlive" to the server, which resets the timeout
    sendGMCP("Core.KeepAlive")
    
    --This would send a request for the server to send an update to the gmcp.Char.Skills.Groups table.
    sendGMCP("Char.Skills.Get {}")
    
    --This would send a request for the server to send a list of the skills in the 
    --vision group to the gmcp.Char.Skills.List table.
    
    sendGMCP([[Char.Skills.Get { "group": "vision"}]])
    
    --And finally, this would send a request for the server to send the info for 
    --hide in the woodlore group to the gmcp.Char.Skills.Info table
    
    sendGMCP([[Char.Skills.Get { "group": "woodlore", "name": "hide"}]])

    sendIrc

    sendIrc(channel, message)
    Sends a message to an IRC channel or person. You must have the IRC window open, and if speaking to a channel, be joined in that channel. IRC currently only works on the freenode network and password-protected channels aren't supported.
    Parameters
    • channel:

    The channel to send the message to. Can be #<channelname> to send to a channel, or <person name> to send to a person. Passed as a string.
    • message:

    The message to send. Passed as a string.
    Example
    --This would send "hello from Mudlet!" to the channel #mudlet on freenode.net
    sendIrc("#mudlet", "hello from Mudlet!")
    --This would send "identify password" in a private message to Nickserv on freenode.net
    sendIrc("Nickserv", "identify password")

    sendTelnetChannel102

    sendTelnetChannel102(msg)
    Sends a message via the 102 subchannel back to the MUD (that's used in Aardwolf). The msg is in a two byte format - see `help telopts` in Aardwolf on how that works.
    Example
    -- turn prompt flags on:
    sendTelnetChannel102("\52\1")
    
    -- turn prompt flags off:
    sendTelnetChannel102("\52\2")

    String Functions

    string.byte

    string.byte(string [, i [, j]])
    mystring:byte([, i [, j]])
    Returns the internal numerical codes of the characters s[i], s[i+1], ···, s[j]. The default value for i is 1; the default value for j is i.
    Note that numerical codes are not necessarily portable across platforms.
    See also: string.char
    Example
    --The following call will return the ASCII values of "A", "B" and "C" 
    a, b, c = string.byte("ABC", 1, 3)
    
    echo(a .. " - " .. b .. " - " .. c) -- echos "65 - 66 - 67"

    string.char

    string.char(···)
    Receives zero or more integers. Returns a string with length equal to the number of arguments, in which each character has the internal numerical code equal to its corresponding argument.

    Note: Numerical codes are not necessarily portable across platforms.

    See also: string.byte
    Example
    --The following call will return the string "ABC" corresponding to the ASCII values 65, 66, 67
    mystring = string.char(65, 66, 67)

    string.cut

    string.cut(string, maxLen)
    Cuts string to the specified maximum length.
    Returns the modified string.
    Parameters
    • string:

    The text you wish to cut. Passed as a string.
    • maxLen:

    The maximum length you wish the string to be. Passed as an integer number.
    Example
    --The following call will return 'abc' and store it in myString
    mystring = string.cut("abcde", 3)
    --You can easily pad string to certain length. Example below will print 'abcde     ' e.g. pad/cut string to 10 characters.
    local s = "abcde"
    s = string.cut(s .. "          ", 10)   -- append 10 spaces
    echo("'" .. s .. "'")

    string.dump

    string.dump()
    Need information here!!!
    Example

    Need example

    string.enclose

    string.enclose(String)
    Wraps a string with [[ ]]
    Returns the altered string.
    Parameters
    • String:

    The string to enclose. Passed as a string.
    Example
    --This will echo '[[Oh noes!]]' to the main window
    echo("'" .. string.enclose("Oh noes!") .. "'")

    string.ends

    string.ends(String, Suffix)
    Test if string is ending with specified suffix.
    Returns true or false.
    See also: string.starts
    Parameters
    • String:

    The string to test. Passed as a string.
    • Suffix:

    The suffix to test for. Passed as a string.
    Example
    --This will test if the incoming line ends with "in bed" and if not will add it to the end.
    if not string.ends(line, "in bed") then
      echo("in bed\n")
    end

    string.find

    string.find()
    Need description
    Example

    Need example

    string.findPattern

    string.findPattern(text, pattern)
    Return first matching substring or nil.
    Parameters
    • text:

    The text you are searching the pattern for.
    • pattern:

    The pattern you are trying to find in the text.
    Example

    Following example will print: "I did find: Troll" string.

    local match = string.findPattern("Troll is here!", "Troll")
    if match then
       echo("I did find: " .. match)
    end
    This example will find substring regardless of case.
    local match = string.findPattern("Troll is here!", string.genNocasePattern("troll"))
    if match then
        echo("I did find: " .. match)
    end
    • Return value:

    nil or first matching substring

    See also: string.genNocasePattern()

    string.format

    string.format()
    Need description here.
    Example

    Need example

    string.genNocasePattern

    string.genNocasePattern(s)
    Generate case insensitive search pattern from string.
    Parameters
    • s:

    Example
    Following example will generate and print "123[aA][bB][cC]" string.
    echo(string.genNocasePattern("123abc"))
    • Return value:

    case insensitive pattern string

    string.gfind

    string.gfind()
    Need description here.
    Example

    Need example

    string.gmatch

    string.gmatch()
    Need description here.
    Example

    Need example

    string.gsub

    string.gsub()
    Need description here.
    Example

    Need example

    string.len

    string.len(String)
    mystring:len()
    Receives a string and returns its length. The empty string "" has length 0. Embedded zeros are counted, so "a\000bc\000" has length 5.
    Parameters
    • String:

    The string you want to find the length of. Passed as a string.
    Example

    Need example

    string.lower

    string.lower(String)
    mystring:lower()
    Receives a string and returns a copy of this string with all uppercase letters changed to lowercase. All other characters are left unchanged. The definition of what an uppercase letter is depends on the current locale.
    See also: string.upper
    Example

    Need example

    string.match

    string.match()
    Need description here.
    Example

    Need example

    string.rep

    string.rep(String, n)
    mystring:rep(n)
    Returns a string that is the concatenation of n copies of the string String.
    Example

    Need example

    string.reverse

    string.reverse(string)
    mystring:reverse()
    Returns a string that is the string string reversed.
    Parameters
    • string:

    The string to reverse. Passed as a string.
    Example
    mystring = "Hello from Lua"
    echo(mystring:reverse()) -- displays 'auL morf olleH'

    string.split

    string.split(string, delimiter)
    myString:split(delimiter)
    Splits a string into a table by the given delimiter. Can be called against a string (or variable holding a string) using the second form above.
    Returns a table containing the split sections of the string.
    Parameters
    • string:

    The string to split. Parameter is not needed if using second form of the syntax above. Passed as a string.
    • delimiter:

    The delimiter to use when splitting the string. Passed as a string.
    Example
    -- This will split the string by ", " delimiter and print the resulting table to the main window.
    names = "Alice, Bob, Peter"
    name_table = string.split(names, ", ")
    display(name_table)
    
    --The alternate method
    names = "Alice, Bob, Peter"
    name_table = names:split(", ")
    display(name_table)
    Either method above will print out:
    table {
    1: 'Alice'
    2: 'Bob'
    3: 'Peter'
    }

    string.starts

    string.starts(string, prefix)
    Test if string is starting with specified prefix.
    Returns true or false
    See also: string.ends
    Parameters
    • string:

    The string to test. Passed as a string.
    • prefix:

    The prefix to test for. Passed as a string.
    Example
    --The following will see if the line begins with "You" and if so will print a statement at the end of the line
    if string.starts(line, "You") then
      echo("====oh you====\n")
    end

    string.sub

    string.sub()
    Need description here.
    Example

    Need example

    string.title

    string.title(string)
    string:title()
    Capitalizes the first character in a string.
    Returns the altered string.
    Parameters
    • string:

    The string to modify. Not needed if you use the second form of the syntax above.
    Example
    --Variable testname is now Anna.
    testname = string.title("anna")
    --Example will set test to "Bob".
    test = "bob"
    test = test:title()

    string.trim

    string.trim(string)
    Trims string, removing all 'extra' white space at the beginning and end of the text.
    Returns the altered string.
    Parameters
    • string:

    The string to trim. Passed as a string.
    Example
    --This will print 'Troll is here!', without the extra spaces.
    local str = string.trim("  Troll is here!  ")
    echo("'" .. str .. "'")

    string.upper

    string.upper(string)
    mystring:upper()
    Receives a string and returns a copy of this string with all lowercase letters changed to uppercase. All other characters are left unchanged. The definition of what a lowercase letter is depends on the current locale.
    Parameters
    • string:

    The string you want to change to uppercase
    Example
    -- displays 'RUN BOB RUN'
    local str = string.upper("run bob run")
    See also: string.lower

    Table Functions

    table.complement

    table.complement (set1, set2)
    Returns a table that is the relative complement of the first table with respect to the second table. Returns a complement of key/value pairs.
    Parameters
    • table1:

    • table2:

    table.concat

    table.concat(table, delimiter, startingindex, endingindex)
    Joins a table into a string. Each item must be something which can be transformed into a string.
    Returns the joined string.
    See also: string.split
    Parameters
    • table:

    The table to concatenate into a string. Passed as a table.
    • delimiter:

    Optional string to use to separate each element in the joined string. Passed as a string.
    • startingindex:

    Optional parameter to specify which index to begin the joining at. Passed as an integer.
    • endingindex:

    Optional parameter to specify the last index to join. Passed as an integer.
    Examples
    --This shows a basic concat with none of the optional arguments
    testTable = {1,2,"hi","blah",}
    testString = table.concat(testTable)
    --testString would be equal to "12hiblah"
    
    --This example shows the concat using the optional delimiter
    testString = table.concat(testTable, ", ")
    --testString would be equal to "1, 2, hi, blah"
    
    --This example shows the concat using the delimiter and the optional starting index
    testString = table.concat(testTable, ", ", 2)
    --testString would be equal to "2, hi, blah"
    
    --And finally, one which uses all of the arguments
    testString = table.concat(testTable, ", ", 2, 3)
    --testString would be equal to "2, hi"

    table.contains

    table.contains (t, value)
    Determines if a table contains a value as a key or as a value (recursive).
    Returns true or false
    Parameters
    • t:

    The table in which you are checking for the presence of the value.
    • value:

    The value you are checking for within the table.
    Example
    local test_table = { "value1", "value2", "value3", "value4" }
    if table.contains(test_table, "value1") then 
       echo("Got value 1!")
    else
       echo("Don't have it. Sorry!")
    end

    This example would always echo the first one, unless you remove value1 from the table.

    table.foreach

    table.intersection

    table.insert

    table.insert(table, [pos,] value)
    Inserts element value at position pos in table, shifting up other elements to open space, if necessary. The default value for pos is n+1, where n is the length of the table, so that a call table.insert(t,x) inserts x at the end of table t.
    See also: table.remove
    Parameters
    • table:

    The table in which you are inserting the value
    • pos:

    Optional argument, determining where the value will be inserted.
    • value:

    The variable that you are inserting into the table. Can be a regular variable, or even a table or function*.

    Note: Inserting a function into a table is not good coding practice, and will not turn out how you think it would.

    table.index_of

    table.is_empty

    table.is_empty(table)
    Check if a table is devoid of any values.
    Parameters
    • table:

    The table you are checking for values.

    table.load

    table.load(location, table)
    Load a table from an external file into mudlet.
    See also: table.save
    Parameters
    • location:

    Where you are loading the table from. Can be anywhere on your computer.
    • table:

    The table that you are loading into - it must exist already.
    Example:
    -- This will load the table mytable from the lua file mytable present in your Mudlet Home Directory.
    mytable = {}
    table.load(getMudletHomeDir().."/mytable.lua", mytable) -- using / is OK on Windows too.
    -- You can load a table from anywhere on your computer, but it's preferable to have them consolidated somewhere connected to Mudlet.

    table.maxn

    table.maxn(Table)
    Returns the largest positive numerical index of the given table, or zero if the table has no positive numerical indices. (To do its job this function does a linear traversal of the whole table.)

    table.n_union

    table.n_complement

    table.n_intersection

    table.pickle

    table.remove

    table.remove(table, value_position)
    Remove a value from an indexed table, by the values position in the table.
    See also: table.insert
    Parameters
    • table

    The indexed table you are removing the value from.
    • value_position

    The indexed number for the value you are removing.
    Example
    testTable = { "hi", "bye", "cry", "why" }
    table.remove(testTable, 1) -- will remove hi from the table
    -- new testTable after the remove
    testTable = { "bye", "cry", "why" }
    -- original position of hi was 1, after the remove, position 1 has become bye
    -- any values under the removed value are moved up, 5 becomes 4, 4 becomes 3, etc

    Note: To remove a value from a key-value table, it's best to simply change the value to nil.

    testTable = { test = "testing", go = "boom", frown = "glow" }
    table.remove(testTable, test) -- this will error
    testTable.test = nil -- won't error
    testTable["test"] = nil -- won't error

    table.save

    table.save(location, table)
    Save a table into an external file in location.
    See also: table.load
    Parameters
    • location:

    Where you want the table file to be saved. Can be anywhere on your computer.
    • table:

    The table that you are saving to the file.
    Example:
    -- Saves the table mytable to the lua file mytable in your Mudlet Home Directory
    table.save(getMudletHomeDir().."/mytable.lua", mytable)

    table.sort

    table.sort(Table [, comp])
    Sorts table elements in a given order, in-place, from Table[1] to Table[n], where n is the length of the table.
    If comp is given, then it must be a function that receives two table elements, and returns true when the first is less than the second (so that not comp(a[i+1],a[i]) will be true after the sort). If comp is not given, then the standard Lua operator < is used instead.
    The sort algorithm is not stable; that is, elements considered equal by the given order may have their relative positions changed by the sort.

    table.size

    table.size (t)
    Gets the actual size of non-index based tables.
    Returns a number.
    Parameters
    • t:

    The table you are checking the size of.

    Note: For index based tables you can get the size with the # operator: This is the standard Lua way of getting the size of index tables i.e. ipairs() type of tables with numerical indices. To get the size of tables that use user defined keys instead of automatic indices (pairs() type) you need to use the function table.size() referenced above.

    local test_table = { "value1", "value2", "value3", "value4" }
    myTableSize = #test_table
    -- This would return 4.
    local myTable = { 1 = "hello", "key2" = "bye", "key3" = "time to go" }
    table.size(myTable)
    -- This would return 3.

    table.setn

    table.unpickle

    table.update

    table.union

    UI Functions

    appendBuffer

    appendBuffer(name)
    Pastes the previously copied rich text (including text formats like color etc.) into user window name.
    See also: paste()
    Parameters
    • name:

    The name of the user window to paste into. Passed as a string.
    Example
    --selects and copies an entire line to user window named "Chat"
    selectCurrentLine()
    copy()
    appendBuffer("Chat")

    bg

    bg(colorName)
    Changes the background color of the text. Useful for highlighting text.
    See Also: fg(), setBgColor()
    Parameters
    • colorName:

    The name of the color to set the background to.
    Example
    --This would change the background color of the text on the current line to magenta
    selectCurrentLine()
    bg("magenta")

    calcFontSize

    calcFontSize(fontSize)
    Used to calculate the number of pixels wide and high a character would be on a mini console at fontSize.
    Returns two numbers, width/height
    See Also: setMiniConsoleFontSize(), getMainWindowSize()
    Parameters
    • fontSize:

    The font size you are wanting to calculate pixel sizes for. Passed as an integer number.
    Example
    --this snippet will calculate how wide and tall a miniconsole designed to hold 4 lines of text 20 characters wide 
    --would need to be at 9 point font, and then changes miniconsole Chat to be that size
    local width,height = calcFontSize(9)
    width = width * 20
    height = height * 4
    resizeWindow("Chat", width, height)

    cecho

    cecho(window, text)
    Echoes text that can be easily formatted with colour tags.
    See Also: decho(), hecho()
    Parameters
    • window:

    Optional - the window name to echo to - can either be none or "main" for the main window, or the miniconsoles name.
    • text:

    The text to display, with color names inside angle brackets <>, ie <red>. If you'd like to use a background color, put it after a double colon : - <:red>. You can use the <reset> tag to reset to the default color. You can select any from this list:
    Example
    cecho("Hi! This text is <red>red, <blue>blue, <green> and green.")
    
    cecho("<:green>Green background on normal foreground. Here we add an <ivory>ivory foreground.")
    
    cecho("<blue:yellow>Blue on yellow text!")
    
    cecho("myinfo", "<green>All of this text is green in the myinfo miniconsole.")

    cinsertText

    cinsertText(window, text)
    inserts text at the current cursor position, with the possibility for color tags.
    See Also: cecho()
    Parameters
    • window:

    Optional - the window name to echo to - can either be none or "main" for the main window, or the miniconsoles name.
    • text:

    The text to display, with color names inside angle brackets <>, ie <red>. If you'd like to use a background color, put it after a double colon : - <:red>. You can use the <reset> tag to reset to the default color. You can select any from this list:
    Example
    cinsertText("Hi! This text is <red>red, <blue>blue, <green> and green.")
    
    cinsertText("<:green>Green background on normal foreground. Here we add an <ivory>ivory foreground.")
    
    cinsertText("<blue:yellow>Blue on yellow text!")
    
    cinsertText("myinfo", "<green>All of this text is green in the myinfo miniconsole.")

    clearUserWindow

    clearUserWindow(name)
    Clears the window or miniconsole with the name given as argument.
    Parameters
    • name:

    The name of the user window to clear. Passed as a string.
    Example
    --This would clear a user window, or miniconsole with the name "Chat"
    clearUserWindow("Chat")

    clearWindow

    clearWindow([optional name])
    Clears the window or miniconsole with the name given as argument (removes all text from it). If you don't give it a name, it will clear the main window.
    See also: clearUserWindow()
    Parameters
    • name:

    The name of the user window to clear. Passed as a string.
    Example
    --This would clear a label, user window, or miniconsole with the name "Chat"
    clearWindow("Chat")
    -- this can clear your whole main window - needs 2.0-test3+
    clearWindow()

    copy

    copy()
    Copies the current selection to the clipboard. This function operates on rich text, i. e. the selected text including all its format codes like colors, fonts etc. in the clipboard until it gets overwritten by another copy operation. example: This script copies the current line on the main screen to a user window (mini console) named chat and gags the output on the main screen.
    See Also: selectString(), selectCurrentLine()
    Parameters
    None
    Example
    selectString( line )
    copy()
    appendBuffer("chat")
    replace("This line has been moved to the chat window!")

    createBuffer

    createBuffer(name)
    Creates a named buffer for formatted text, much like a miniconsole, but the buffer is not intended to be shown on the screen - use it for formatting text or storing formatted text.
    Parameters
    • name:

    The name of the buffer to create.
    Example
    --This creates a named buffer called "scratchpad"
    createBuffer("scratchpad")

    createConsole

    createConsole(consoleName, fontSize, charsPerLine, numberOfLines, Xpos, Ypos)
    Makes a new miniconsole. The background will be black, and the text color white.
    Parameters
    • consoleName:

    The name of your new miniconsole. Passed as a string.
    • fontSize:

    The font size to use for the miniconsole. Passed as an integer number.
    • charsPerLine:

    How many characters wide to make the miniconsole. Passed as an integer number.
    • numberOfLines:

    How many lines high to make the miniconsole. Passed as an integer number.
    • Xpos:

    X position of miniconsole. Measured in pixels, with 0 being the very left. Passed as an integer number.
    • Ypos:

    Y position of miniconsole. Measured in pixels, with 0 being the very top. Passed as an integer number.
    Example
    -- this will create a console with the name of "myConsoleWindow", font size 8, 80 characters wide, 
    -- 20 lines high, at coordinates 300x,400y
    createConsole("myConsoleWindow", 8, 80, 20, 200, 400)

    createGauge

    createGauge(name, width, Xpos, Ypos, gaugeText, r, g, b)
    createGauge(name, width, Xpos, Ypos, gaugeText, colorName)
    Creates a gauge that you can use to express completion with. For example, you can use this as your healthbar or xpbar.
    See also: moveGauge(), setGauge(), setGaugeText()
    Parameters
    • name:

    The name of the gauge. Must be unique, you can not have two or more gauges with the same name. Passed as a string.
    • width:

    The width of the gauge, in pixels. Passed as an integer number.
    • height:

    The height of the gauge, in pixels. Passed as an integer number.
    • Xpos:

    X position of gauge. Measured in pixels, with 0 being the very left. Passed as an integer number.
    • Ypos:

    Y position of gauge. Measured in pixels, with 0 being the very top. Passed as an integer number.
    • gaugeText:

    Text to display on the gauge. Passed as a string, unless you do not wish to have any text, in which case you pass nil
    • r:

    The red component of the gauge color. Passed as an integer number from 0 to 255
    • g:

    The green component of the gauge color. Passed as an integer number from 0 to 255
    • b:

    The blue component of the gauge color. Passed as an integer number from 0 to 255
    • colorName:

    the name of color for the gauge. Passed as a string.
    Example
    -- This would make a gauge at that's 300px width, 20px in height, located at Xpos and Ypos and is green.
    -- The second example is using the same names you'd use for something like [[fg]]() or [[bg]]().
    createGauge("healthBar", 300, 20, 30, 300, nil, 0, 255, 0)
    createGauge("healthBar", 300, 20, 30, 300, nil, "green")
    
    
    -- If you wish to have some text on your label, you'll change the nil part and make it look like this:
    createGauge("healthBar", 300, 20, 30, 300, "Now with some text", 0, 255, 0)
    -- or
    createGauge("healthBar", 300, 20, 30, 300, "Now with some text", "green")
    Note
    --If you want to put text on the back of the gauge when it's low, use an echo with the gaugeName_back.
    echo("gaugeName_back", "This is a test of putting text on the back of the gauge!")

    createLabel

    createLabel(name, Xpos, Ypos, width, height, fillBackground)
    Creates a highly manipulable overlay which can take some css and html code for text formatting. Labels are clickable, and as such can be used as a sort of button. Labels are meant for small variable or prompt displays, messages, images, and the like. You should not use them for larger text displays or things which will be updated rapidly and in high volume, as they are much slower than miniconsoles.
    Returns true or false.
    See also: hideWindow(), showWindow(), resizeWindow(), setLabelClickCallback(), setTextFormat(), setTextFormat(), setMiniConsoleFontSize(), setBackgroundColor(), getMainWindowSize(), calcFontSize()
    Parameters
    • name:

    The name of the label. Must be unique, you can not have two or more labels with the same name. Passed as a string.
    • Xpos:

    X position of the label. Measured in pixels, with 0 being the very left. Passed as an integer number.
    • Ypos:

    Y position of the label. Measured in pixels, with 0 being the very top. Passed as an integer number.
    • width:

    The width of the label, in pixels. Passed as an integer number.
    • height:

    The height of the label, in pixels. Passed as an integer number.
    • fillBackground:

    Whether or not to display the background. Passed as either 1 or 0. 1 will display the background color, 0 will not.
    Example
    --This example creates a transparent overlay message box to show a big warning message "You are under attack!" in the middle 
    --of the screen. Because the background color has a transparency level of 150 (0-255, with 0 being completely transparent 
    --and 255 non-transparent) the background text can still be read through. The message box will disappear after 2.3 seconds.
    local width, height = getMainWindowSize();
    createLabel("messageBox",(width/2)-300,(height/2)-100,250,150,1);
    resizeWindow("messageBox",500,70);
    moveWindow("messageBox", (width/2)-300,(height/2)-100 );
    setBackgroundColor("messageBox", 150,100,100,200);
    echo("messageBox", [[<p style="font-size:35px"><b><center><font color="red">You are under attack!</font></center></b></p>]] );
    showWindow("messageBox");
    tempTimer(2.3, [[hideWindow("messageBox")]] ) -- close the warning message box after 2.3 seconds

    createMiniConsole

    createMiniConsole(name, posX, posY, width, height)
    Opens a miniconsole window inside the main window of Mudlet. This is the ideal fast colored text display for everything that requires a bit more text, such as status screens, chat windows, etc.
    Returns true or false.
    See also: createLabel(), hideWindow(), showWindow(), resizeWindow(), setTextFormat(), moveWindow(), setMiniConsoleFontSize(), handleWindowResizeEvent(), setBorderTop(), setWindowWrap(), getMainWindowSize(), calcFontSize()
    Parameters
    • name:

    The name of the miniconsole. Must be unique, you can not have two or more miniconsoles with the same name. Passed as a string.
    • Xpos:

    X position of the miniconsole. Measured in pixels, with 0 being the very left. Passed as an integer number.
    • Ypos:

    Y position of the miniconsole. Measured in pixels, with 0 being the very top. Passed as an integer number.
    • width:

    The width of the miniconsole, in pixels. Passed as an integer number.
    • height:

    The height of the miniconsole, in pixels. Passed as an integer number.
    Example
    --This script would create a mini text console called "sys" and write with yellow foreground color and blue background color 
    --"Hello World".
    
    
    -- set up the small system message window in the top right corner
    -- determine the size of your screen
    WindowWidth = 0;
    WindowHeight = 0;
    WindowWidth, WindowHeight = getMainWindowSize();
    
    createMiniConsole("sys",WindowWidth-650,0,650,300)
    setBackgroundColor("sys",85,55,0,255)
    setMiniConsoleFontSize("sys", 8)
    -- wrap lines in window "sys" at 40 characters per line
    setWindowWrap("sys", 40)
    -- set default font colors and font style for window "sys"
    setTextFormat("sys",0,35,255,50,50,50,0,0,0)
    
    echo("sys","Hello world!")

    decho

    decho ([name of console,] text)
    Color changes can be made using the format <FR,FG,FB:BR,BG,BB> where each field is a number from 0 to 255. The background portion can be omitted using <FR,FG,FB> or the foreground portion can be omitted using <:BR,BG,BB>. Arguments 2 and 3 set the default fore and background colors for the string using the same format as is used within the string, sans angle brackets, e.g. decho("<50,50,0:0,255,0>test").
    Parameters
    • text:

    The text that you’d like to echo with embedded color tags. Tags take the RGB values only, see below for an explanation.
    • name of console

    Optional name of the console to echo to. Defaults to main.
    Example
    decho("<50,50,0:0,255,0>test")
    
    decho("miniconsolename", "<50,50,0:0,255,0>test")

    deleteLine

    deleteLine()
    Deletes the current line under the user cursor. This is a high speed gagging tool and is very good at this task, but is only meant to be use when a line should be omitted entirely in the output. If you echo() to that line it will not be shown, and lines deleted with deleteLine() are simply no longer rendered. For replacing text, replace() is the proper option - doing selectCurrentLine(); replace(""); cecho("new line!\n") is better.
    See Also: replace(), wrapLine()

    Note: you do not need to put anything between () - it just deletes the line it is used on.

    Example
    -- deletes the line - just put this command into the big script box. Keep the case the same -
    -- it has to be deleteLine(), not Deleteline(), deleteline() or anything else
    deleteLine()
    
    --This example creates a temporary line trigger to test if the next line is a prompt, and if so gags it entirely.
    --This can be useful for keeping a pile of prompts from forming if you're gagging chat channels in the main window
    --Note: isPrompt() only works on servers which send a GA signal with their prompt.
    tempLineTrigger(1, 1, [[if isPrompt() then deleteLine() end]])
    
    -- example of deleting multiple lines:
    deleteLine()                            -- delete the current line
    moveCursor(0,getLineNumber()-1)  -- move the cursor back one line
    deleteLine()                            -- delete the previous line now

    deselect

    deselect([optional window name])
    This is used to clear the current selection (to no longer have anything selected). Should be used after changing the formatting of text, to keep from accidentally changing the text again later with another formatting call.
    Parameters
    • name:

    The name of the buffer/miniConsole to stop having anything selected in. This is an optional argument, if name is not provided the main window will have its selection cleared.
    Example
    --This will change the background on an entire line in the main window to red, and then properly clear the selection to keep further 
    --changes from effecting this line as well.
    selectCurrentLine()
    bg("red")
    deselect()

    echoLink

    echoLink([windowName], text, command, hint, [bool use_current_format or defaultLinkFormat])
    Echos a piece of text as a clickable link, at the end of the current selected line - similar to echo().
    Parameters
    • text:

    text to display in the echo. Same as a normal echo().
    • command:

    lua code to do when the link is clicked.
    • hint:

    text for the tooltip to be displayed when the mouse is over the link.
    • window:

    if true, then the link will use the current selection style (colors, underline, etc). If missing or false, it will use the default link style - blue on black underlined text.
    Example
    -- echo a link named 'press me!' that'll send the 'hi' command to the game
    echoLink("press me!", [[send("hi")]], "This is a tooltip")
    
    -- do the same, but send this link to a miniConsole
    echoLink("my miniConsole", "press me!", [[send("hi")]], "This is a tooltip")

    echoUserWindow

    echoUserWindow(windowName)
    This function will print text to both mini console windows, dock windows and labels. It is outdated however - echo() instead.

    echoPopup

    echoPopup([window], text, {commands}, {hints}, [current or default format])
    Creates text with a left-clickable link, and a right-click menu for more options at the end of the current line, like echo. The added text, upon being left-clicked, will do the first command in the list. Upon being right-clicked, it'll display a menu with all possible commands. The menu will be populated with hints, one for each line.
    Parameters
    • window:

    Optional - the window to echo to - use either main or omit for the main window, or the miniconsoles name otherwise.
    • name:

    the name of the console to operate on. If not using this in a miniConsole, use "main" as the name.
    • {lua code}:

    a table of lua code strings to do. ie,
    {[[send("hello")]], [[echo("hi!"]]}
    • {hints}:

    a table of strings which will be shown on the popup and right-click menu. ie,
    {"send the hi command", "echo hi to yourself"}
    • current or default format:

    a boolean value for using either the current formatting options (colour, underline, italic) or the link default (blue underline).
    Example
    -- Create some text as a clickable with a popup menu:
    echoPopup("activities to do", {[[send "sleep"]], [[send "sit"]], [[send "stand"]]}, {"sleep", "sit", "stand"})

    fg

    fg(colorName)
    If used on a selection, sets the foreground color to colorName - otherwise, it will set the color of the next text-inserting calls (echo(), insertText, echoLink(), and others)
    See Also: bg(), setBgColor()
    Parameters
    • colorName:

    The name of the color to set the foreground to - list of possible names:
    Example
    --This would change the color of the text on the current line to green
    selectCurrentLine()
    fg("green")
    resetFormat()
    
    --This will echo red, green, blue in their respective colors
    fg("red")
    echo("red ")
    fg("green")
    echo("green ")
    fg("blue")
    echo("blue ")
    resetFormat()

    getBgColor

    getBgColor(windowName)
    This function returns the rgb values of the background color of the first character of the current selection on mini console (window) windowName. If windowName is omitted Mudlet will use the main screen.
    Parameters
    • windowName:

    A window to operate on - either a miniconsole or the main window.
    Example
    local r,g,b;
    selectString("troll",1)
    r,g,b = getBgColor()
    if r == 255 and g == 0 and b == 0 then
        echo("HELP! troll is highlighted in red letters, the monster is aggressive!\n");
    end

    getColorWildcard

    getColorWildcard(ansi color number)
    This function, given an ANSI color number (list), will return all strings on the current line that match it.
    Parameters
    • ansi color number:

    A color number (list) to match.
    Example
    -- we can run this script on a line that has the players name coloured differently to easily capture it from 
    -- anywhere on the line
    local match = getColorWildcard(14)
    
    if match then
      echo("\nFound "..match.."!")
    else
      echo("\nDidn't find anyone.")
    end

    getColumnNumber

    getColumnNumber()
    Gets the absolute column number of the current user cursor.
    Parameters
    None
    Example

    Need example

    getCurrentLine

    getCurrentLine()
    Returns the content of the current line under the user cursor in the buffer. The Lua variable line holds the content of getCurrentLine() before any triggers have been run on this line. When triggers change the content of the buffer, the variable line will not be adjusted and thus hold an outdated string. line = getCurrentLine() will update line to the real content of the current buffer. This is important if you want to copy the current line after it has been changed by some triggers. selectString( line,1 ) will return false and won't select anything because line no longer equals getCurrentLine(). Consequently, selectString( getCurrentLine(), 1 ) is what you need.
    Parameters
    None
    Example

    Need example

    getFgColor

    getFgColor(windowName)
    This function returns the rgb values of the color of the first character of the current selection on mini console (window) windowName. If windowName is omitted Mudlet will use the main screen.
    Parameters
    • windowName:

    A window to operate on - either a miniconsole or the main window.
    Example
    local r,g,b;
    selectString("troll",1)
    r,g,b = getFgColor()
    if r == 255 and g == 0 and b == 0 then
        echo("HELP! troll is written in red letters, the monster is aggressive!\n");
    end

    getLineCount

    getLineCount()
    Gets the absolute amount of lines in the current console buffer
    Parameters
    None
    Example

    Need example

    getLines

    getLines(from_line_number, to_line_number)
    Returns a section of the content of the screen text buffer. Returns a Lua table with the content of the lines on a per line basis. The form value is result = {relative_linenumber = line}.
    Absolute line numbers are used.
    Parameters
    • from_line_number:

    First line number
    • to_line_number:

    End line number
    Example
    -- retrieve & echo the last line: 
    echo(getLines(getLineNumber()-1, getLineNumber())[1])
    -- find out which server and port you are connected to (as per Mudlet settings dialog):
    local t = getLines(0, getLineNumber())
    
    local server, port
    
    for i = 1, #t do
      local s, p = t[i]:match("looking up the IP address of server:(.-):(%d+)")
      if s then server, port = s, p break end
    end
    
    display(server)
    display(port)

    getLineNumber

    getLineNumber()
    Returns the absolute line number of the current user cursor. The cursor by default is on the current line the triggers are processing - which you can move around with moveCursor() and moveCursorEnd(). This function can come in handy in combination when using with moveCursor() and getLines().
    Example
    -- use getLines() in conjuction with getLineNumber() to check if the previous line has a certain word
    if getLines(getLineNumber()-1, getLineNumber())[1]:find("attacks") then echo("previous line had the word 'attacks' in it!\n") end

    getMainConsoleWidth

    getMainConsoleWidth()
    Returns a single number; the width of the main console (MuD output) in pixels.
    Parameters
    None
    Example
    -- Save width of the main console to a variable for future use.
    consoleWidth = getMainConsoleWidth()

    hasFocus

    hasFocus()
    Returns true or false depending if Mudlet's main window is currently in focus (ie, the user isn't focused on another window, like a browser). This can be useful for determining whenever your script should call for attention or not, for example.
    Parameters
    None
    Example
    if attacked and not hasFocus() then
      runaway()
    else
      fight()
    end

    getMainWindowSize

    getMainWindowSize()
    Returns two numbers, the width and height in pixels.
    Parameters
    None
    Example
    --this will get the size of your main mudlet window and save them 
    --into the variables mainHeight and mainWidth
    mainWidth, mainHeight = getMainWindowSize()

    getStopWatchTime

    getStopWatchTimer(watchID)
    Returns the time (milliseconds based) in form of 0.058 (= clock ran for 58 milliseconds before it was stopped). Please note that after the stopwatch is stopped, retrieving the time will not work - it's only valid while it is running.
    See also: createStopWatch()
    Returns a number
    Parameters
    • watchID

    The ID number of the watch.
    Example
    -- an example of showing the time left on the stopwatch
    teststopwatch = teststopwatch or createStopWatch()
    startStopWatch(teststopwatch)
    echo("Time on stopwatch: "..getStopWatchTime(teststopwatch))
    tempTimer(1, [[echo("Time on stopwatch: "..getStopWatchTime(teststopwatch))]])
    tempTimer(2, [[echo("Time on stopwatch: "..getStopWatchTime(teststopwatch))]])
    stopStopWatch(teststopwatch)

    handleWindowResizeEvent

    handleWindowResizeEvent()
    (depreciated) This function is depreciated and should not be used; it's only documented here for historical reference - use the sysWindowResizeEvent() event instead.

    The standard implementation of this function does nothing. However, this function gets called whenever the main window is being manually resized. You can overwrite this function in your own scripts to handle window resize events yourself and e. g. adjust the screen position and size of your mini console windows, labels or other relevant GUI elements in your scripts that depend on the size of the main Window. To override this function you can simply put a function with the same name in one of your scripts thus overwriting the original empty implementation of this

    Parameters
    None
    Example
    function handleWindowResizeEvent()
       -- determine the size of your screen
       WindowWidth=0;
       WindowHeight=0;
       WindowWidth, WindowHeight = getMainWindowSize();
    
       -- move mini console "sys" to the far right side of the screen whenever the screen gets resized
       moveWindow("sys",WindowWidth-300,0)
    end

    hasFocus

    hasFocus()
    Returns true or false depending on if the main Mudlet window is in focus. By focus, it means that the window is selected and you can type in the input line and etc. Not in focus means that the window isn’t selected, some other window is currently in focus.
    Parameters
    None
    Example

    Need example

    hecho

    hecho(window, text)
    Echoes text that can be easily formatted with colour tags in the hexadecimal format.
    See Also: decho(), cecho()
    Parameters
    • window:

    Optional - the window name to echo to - can either be none or "main" for the main window, or the miniconsoles name.
    • text:

    The text to display, with color changes made within the string using the format |cFRFGFB,BRBGBB where FR is the foreground red value, FG is the foreground green value, FB is the foreground blue value, BR is the background red value, etc., BRBGBB is optional. |r can be used within the string to reset the colors to default.
    Example
    hecho("|ca00040black!")

    hideToolBar

    hideToolBar(name)
    Hides the toolbar with the given name name and makes it disappear. If all toolbars of a tool bar area (top, left, right) are hidden, the entire tool bar area disappears automatically.
    Parameters
    • name:

    name of the button group to display
    Example
    hideToolBar("my offensive buttons")

    hideWindow

    hideWindow(name)
    This function hides a mini console label. To show it again, use showWindow().
    See also: createMiniConsole(), createLabel()
    Parameters
    None
    Example

    Need example

    insertLink

    insertLink([windowName], text, command, hint, [bool use_current_format or defaultLinkFormat])
    Inserts a piece of text as a clickable link at the current cursor position - similar to insertText().
    Parameters
    • text:

    text to display in the echo. Same as a normal echo().
    • command:

    lua code to do when the link is clicked.
    • hint:

    text for the tooltip to be displayed when the mouse is over the link.
    • window:

    if true, then the link will use the current selection style (colors, underline, etc). If missing or false, it will use the default link style - blue on black underlined text.
    Example

    Need example

    insertPopup

    insertPopup([windowName], text, {commands}, {hints}, [current or default format])
    Creates text with a left-clickable link, and a right-click menu for more options exactly where the cursor position is, similar to insertText(). The inserted text, upon being left-clicked, will do the first command in the list. Upon being right-clicked, it'll display a menu with all possible commands. The menu will be populated with hints, one for each line.
    Parameters
    • window:

    Optional - the window to echo to - use either main or omit for the main window, or the miniconsoles name otherwise.
    • name:

    the name of the console to operate on. If not using this in a miniConsole, use "main" as the name.
    • {lua code}:

    a table of lua code strings to do. ie,
    {[[send("hello")]], [[echo("hi!"]]}
    .
    • {hints}:

    a table of strings which will be shown on the popup and right-click menu. ie,
    {"send the hi command", "echo hi to yourself"}
    .
    • current or default format:

    a boolean value for using either the current formatting options (colour, underline, italic) or the link default (blue underline).
    Example
    -- Create some text as a clickable with a popup menu:
    insertPopup("activities to do", {[[send "sleep"]], [[send "sit"]], [[send "stand"]]}, {"sleep", "sit", "stand"})

    insertText

    insertText([optional windowName], text)
    Inserts text at cursor postion in window - unlike echo(), which inserts the text at the end of the last line in the buffer (typically the one being processed by the triggers). You can use moveCursor() to move the cursor into position first.
    insertHTML() also does the same thing as insertText, if you ever come across it.
    See also: cinsertText()
    Parameters
    • window:

    The window to insert the text to.
    • text:

    The text you will insert into the current cursor position.
    Example
    -- move the cursor to the end of the previous line and insert some text
    
    -- move to the previous line
    moveCursor(0, getLineNumber()-1)
    -- move the end the of the previous line
    moveCursor(#getCurrentLine(), getLineNumber())
    
    fg("dark_slate_gray")
    insertText(' <- that looks nice.')
    
    deselect()
    resetFormat()
    moveCursorEnd()

    isAnsiBgColor

    isAnsiBgColor(ansiBgColorCode)
    This function tests if the first character of the current selection has the background color specified by ansiBgColorCode.
    Parameters
    • ansiBgColorCode:

    A color code to test for, possible codes are:
    0 = default text color
    1 = light black
    2 = dark black
    3 = light red
    4 = dark red
    5 = light green
    6 = dark green
    7 = light yellow
    8 = dark yellow
    9 = light blue
    10 = dark blue
    11 = light magenta
    12 = dark magenta
    13 = light cyan
    14 = dark cyan
    15 = light white
    16 = dark white
    Example
    selectString( matches[1], 1 )
    if isAnsiBgColor( 5 ) then
        bg("red");
        resetFormat();
        echo("yes, the background of the text is light green")
    else
        echo( "no sorry, some other backgroundground color" )
    end

    Note: matches[1] holds the matched trigger pattern - even in substring, exact match, begin of line substring trigger patterns or even color triggers that do not know about the concept of capture groups. Consequently, you can always test if the text that has fired the trigger has a certain color and react accordingly. This function is faster than using getFgColor() and then handling the color comparison in Lua.

    isAnsiFgColor

    isAnsiFgColor(ansiFgColorCode)
    This function tests if the first character of the current selection has the foreground color specified by ansiFgColorCode.
    Parameters
    • ansiFgColorCode:

    A color code to test for, possible codes are:
    0 = default text color
    1 = light black
    2 = dark black
    3 = light red
    4 = dark red
    5 = light green
    6 = dark green
    7 = light yellow
    8 = dark yellow
    9 = light blue
    10 = dark blue
    11 = light magenta
    12 = dark magenta
    13 = light cyan
    14 = dark cyan
    15 = light white
    16 = dark white
    Example
    selectString( matches[1], 1 )
    if isAnsiFgColor( 5 ) then
        bg("red");
        resetFormat();
        echo("yes, the text is light green")
    else
        echo( "no sorry, some other foreground color" )
    end

    Note: matches[1] holds the matched trigger pattern - even in substring, exact match, begin of line substring trigger patterns or even color triggers that do not know about the concept of capture groups. Consequently, you can always test if the text that has fired the trigger has a certain color and react accordingly. This function is faster than using getFgColor() and then handling the color comparison in Lua.

    moveCursor

    moveCursor([optional windowName], x, y)
    Moves the user cursor of the window windowName, or the main window, to the absolute point (x,y). This function returns false if such a move is impossible e.g. the coordinates don’t exist. To determine the correct coordinates use getLineNumber(), getColumnNumber() and getLastLineNumber(). The trigger engine will always place the user cursor at the beginning of the current line before the script is run. If you omit the windowName argument, the main screen will be used.
    Returns true or false depending on if the cursor was moved to a valid position. Check this before doing further cursor operations - because things like deleteLine() might invalidate this.
    Parameters
    • windowName:

    The window you are going to move the cursor in.
    • x:

    The horizontal axis in the window - that is, the line number.
    • y:

    The vertical axis in the window - that is, the letter position within the line.
    Example
    -- move cursor to the start of the previous line and insert -<(
    -- the first 0 means we want the cursor right at the start of the line,
    -- and getLineNumber()-1 means we want the cursor on the current line# - 1 which
    -- equals to the previous line
    moveCursor(0, getLineNumber()-1)
    insertText("-<(")
    
    -- now we move the cursor at the end of the previous line. Because the 
    -- cursor is on the previous line already, we can use #getCurrentLine()
    -- to see how long it is. We also just do getLineNumber() because getLineNumber()
    -- returns the current line # the cursor is on
    moveCursor(#getCurrentLine(), getLineNumber())
    insertText(")>-")
    
    -- finally, reset it to the end where it was after our shenaningans - other scripts
    -- could expect the cursor to be at the end
    moveCursorEnd()
    -- a more complicated example showing how to work with Mudlet functions
    
    -- set up the small system message window in the top right corner
    -- determine the size of your screen
    local WindowWidth, WindowHeight = getMainWindowSize()
    
    -- define a mini console named "sys" and set its background color
    createMiniConsole("sys",WindowWidth-650,0,650,300)
    setBackgroundColor("sys",85,55,0,255)
    
    -- you *must* set the font size, otherwise mini windows will not work properly
    setMiniConsoleFontSize("sys", 12)
    -- wrap lines in window "sys" at 65 characters per line
    setWindowWrap("sys", 60)
    -- set default font colors and font style for window "sys"
    setTextFormat("sys",0,35,255,50,50,50,0,0,0)
    -- clear the window
    clearUserWindow("sys")
    
    moveCursorEnd("sys")
    setFgColor("sys", 10,10,0)
    setBgColor("sys", 0,0,255)
    echo("sys", "test1---line1\n<this line is to be deleted>\n<this line is to be deleted also>\n")
    echo("sys", "test1---line2\n")
    echo("sys", "test1---line3\n")
    setTextFormat("sys",158,0,255,255,0,255,0,0,0);
    --setFgColor("sys",255,0,0);
    echo("sys", "test1---line4\n")
    echo("sys", "test1---line5\n")
    moveCursor("sys", 1,1)
    
    -- deleting lines 2+3
    deleteLine("sys")
    deleteLine("sys")
    
    -- inserting a line at pos 5,2
    moveCursor("sys", 5,2)
    setFgColor("sys", 100,100,0)
    setBgColor("sys", 255,100,0)
    insertText("sys","############## line inserted at pos 5/2 ##############")
    
    -- inserting a line at pos 0,0
    moveCursor("sys", 0,0)
    selectCurrentLine("sys")
    setFgColor("sys", 255,155,255)
    setBold( "sys", true );
    setUnderline( "sys", true )
    setItalics( "sys", true )
    insertText("sys", "------- line inserted at: 0/0 -----\n")
    
    setBold( "sys", true )
    setUnderline( "sys", false )
    setItalics( "sys", false )
    setFgColor("sys", 255,100,0)
    setBgColor("sys", 155,155,0)
    echo("sys", "*** This is the end. ***\n")

    moveCursorEnd

    moveCursorEnd( windowName )
    Moves the cursor to the end of the buffer. "main" is the name of the main window, otherwise use the name of your user window.
    See Also: moveCursor()
    Returns true or false
    Parameters
    • windowName:

    The name of your user window.
    Example

    Need example

    moveGauge

    moveGauge(gaugeName, newX, newY)
    Moves a gauge created with createGauge to the new x,y coordinates. Remember the coordinates are relative to the top-left corner of the output window.
    Parameters
    • gaugeName:

    The name of your gauge
    • newX:

    The horizontal pixel location
    • newY:

    The vertical pixel location
    Example
    -- This would move the health bar gauge to the location 1200, 400
    moveGauge("healthBar", 1200, 400)

    moveWindow

    moveWindow( name, x, y )
    This function moves window name to the given x/y coordinate. The main screen cannot be moved. Instead you’ll have to set appropriate border values → preferences to move the main screen e.g. to make room for chat or information mini consoles, or other GUI elements. In the future moveWindow() will set the border values automatically if the name parameter is omitted.
    See Also: createMiniConsole(), createLabel(), handleWindowResizeEvent(), resizeWindow(), setBorderTop()
    Parameters
    • name:

    The name of your winow
    • newX:

    The horizontal pixel location
    • newY:

    The vertical pixel location

    openUserWindow

    openUserWindow(name)
    Opens a user dockable console window for user output e.g. statistics, chat etc. If a window of such a name already exists, nothing happens. You can move these windows, dock them, make them into notebook tabs or float them. Note that they do currently have a bug in a sense that they will inherit your main windows borders. The windows position cannot be adjusting via scripting yet at the moment, and the layout won't be remembered next time Mudlet is open.
    Parameters
    • name: The name of your window

    Examples
    openUserWindow("My floatig window")
    cecho("My floatig window", "<red>hello <blue>bob!")

    paste

    paste(windowName)
    Pastes the previously copied text including all format codes like color, font etc. at the current user cursor position. The copy() and paste() functions can be used to copy formated text from the main window to a user window without losing colors e. g. for chat windows, map windows etc.
    Parameters
    • windowName:

    The name of your window

    pasteUserWindow

    pasteUserWindow(windowName)
    Need description here
    Parameters
    • windowName:

    The name of your window

    prefix

    prefix(text)
    Prefixes text at the beginning of the current line when used in a trigger.
    Parameters
    • text:

    The information you want to prefix
    Example
    -- Prefix the hours, minutes and seconds onto our prompt even though Mudlet has a button for that
    prefix(os.date("%H:%M:%S "))

    replace

    replace([windowName,] newtext)
    Replaces the currently selected text with the new text. To select text, use selectString(), selectSection() or a similar function.

    Note: If you’d like to delete/gag the whole line, use deleteLine().

    Note: This won't preserve existing colours by default - however it's easy to make it, see example below.

    Parameters
    • windowName: optional name of window (a miniconsole)

    • with: the new text to display.

    Example
    -- replace word "troll" with "cute trolly"
    selectString("troll",1)
    replace("cute trolly")
    
    -- replace the whole line
    selectCurrentLine()
    replace("Out with the old, in with the new!")
    
    -- if you'd like to keep the original colouring instead of applying your own, you can do this:
    if selectString("There", 1) ~= -1 then
      setBgColor(getBgColor())
      setFgColor(getFgColor())
      replace("Here")
    end

    replaceAll

    replaceAll( what, with )
    Replaces all occurrences of what in the current line with with.
    Parameters
    • what: the text to replace

    • with: the new text to have in place

    Examples
    -- replace all occurrences of the word "south" in the line with "north"
    replaceAll("south", "north")
    -- replace all occurrences of the text that the variable "target" has
    replaceAll(target, "The Bad Guy")

    resizeWindow

    resizeWindow(name,width,height)
    Resizes a mini console or label
    See also: createMiniConsole(), createLabel(), handleWindowResizeEvent(), resizeWindow(), setBorderTop()

    selectCaptureGroup

    selectCaptureGroup(groupNumber)
    Selects the content of the capture group number in your Perl regular expression
    Example
    Perl Reqular expression e.g. "you have (\d+) Euro".
    --If you want to color the amount of money you have green you do: 
    
    selectCaptureGroup(1); 
    setFgColor(0,255,0)

    selectSection

    selectSection(from, how long)
    Selects the specified parts of the line starting from the left and extending to the right for however how long. The line starts from 0.
    Returns true if the selection was successful, and false if the line wasn't actually long enough or the selection couldn't be done in general.
    Example
    -- select and colour the first character in the line red
    if selectSection(0,1) then fg("red") end
    
    -- select and colour the second character green (start selecting from the first character, and select 1 character)
    if selectSection(1,1) then fg("green") end
    
    -- select and colour three character after the first two grey (start selecting from the 2nd character for 3 characters long)
    if selectSection(2,3) then fg("grey") end

    selectString

    selectString( text, number_of_match )
    Selects a substring from the line where the user cursor is currently positioned - allowing you to edit selected text (apply colour, make it be a link, copy to other windows or other things).

    You can move the user cursor with moveCursor(). When a new line arrives from the MUD, the user cursor is positioned at the beginning of the line. However, if one of your trigger scripts moves the cursor around you need to take care of the cursor position yourself and make sure that the cursor is in the correct line if you want to call one of the select functions. To deselect text, see deselect().

    Returns position in line or -1 on error (text not found in line)

    Note: To prevent selection of random data use the error return if not found like this:

    if selectString( "big monster", 1 ) > -1 then setFgColor( 255,0,0) end

    setBgColor

    setBgColor([windowName], r,g,b )
    Sets the current text background color in the main window unless windowName parameter given. If you have selected text prior to this call, the selection will be highlighted otherwise the current text background color will be changed. If you set a foreground or background color, the color will be used until you call resetFormat() on all further print commands.

    See also: cecho()

    Parameters
    • windowName:

    Optional parameter set the current text background color in windowname given.
    • r:

    The red component of the gauge color. Passed as an integer number from 0 to 255
    • g:

    The green component of the gauge color. Passed as an integer number from 0 to 255
    • b:

    The blue component of the gauge color. Passed as an integer number from 0 to 255
    Example
    --highlights the first occurrence of the string "Tom" in the current line with a red background color.
    selectString( "Tom", 1 )
    setBgColor( 255,0,0 )
    --prints "Hello" on red background and "You" on blue.
    setBgColor(255,0,0)
    echo("Hello")
    setBgColor(0,0,255)
    echo(" You!")
    resetFormat()

    setBold

    setBold(windowName, bool)
    Sets the current text font to bold (true) or non-bold (false) mode. If the windowName parameters omitted, the main screen will be used.

    setFgColor

    setFgColor([windowName],r, g, b)
    Sets the current text foreground color in the main window unless windowName parameter given.
    • windowName:

    Optional parameter set the current text background color in windowname given.
    • r:

    The red component of the gauge color. Passed as an integer number from 0 to 255
    • g:

    The green component of the gauge color. Passed as an integer number from 0 to 255
    • b:

    The blue component of the gauge color. Passed as an integer number from 0 to 255
    Example
    --highlights the first occurrence of the string "Tom" in the current line with a red foreground color.
    selectString( "Tom", 1 )
    setFgColor( 255,0,0 )

    setGauge

    setGauge(gaugeName, currentValue, maxValue, gaugeText)
    Use this function when you want to change the gauges look according to your values. Typical usage would be in a prompt with your current health or whatever value, and throw in some variables instead of the numbers.
    Example
    --Change the looks of the gauge named healthBar and make it 
    --fill to half of its capacity. The height is always remembered.
    setGauge("healthBar", 200, 400)
    --If you wish to change the text on your gauge, you’d do the following:
    setGauge("healthBar", 200, 400, "some text")

    setItalics

    setItalics(windowName, bool)
    Sets the current text font to italics/non-italics mode. If the windowName parameters omitted, the main screen will be used.

    setMiniConsoleFontSize

    setMiniConsoleFontSize(name, fontSize)

    Sets the font size of the mini console. see also: createMiniConsole(), createLabel()

    setTextFormat

    setTextFormat(windowName, r1, g1, b1, r2, g2, b2, bold, underline, italics)
    Sets current text format of window windowName: foreground color(r1,g1,b1), background color(r2,g2,b2), bold(1/0), underline(1/0), italics(1/0) A more convenient way to control the text format in a mini console is to use setFgColor( windowName, r,g,b ), setBold( windowName, true ), setItalics( windowName, true ), setUnderline( windowName, true ) etc. → createMiniConsole, setBold, setBgColor, setFgColor, setItalics, setUnderline
    Example
    --This script would create a mini text console and write with yellow foreground color and blue background color "This is a test".
    createMiniConsole( "con1", 0,0,300,100);
    setTextFormat("con1",0,0,255,255,255,0,1,1,1);
    echo("con1","This is a test")

    setUnderline

    setUnderline(windowName, bool)
    Sets the current text font to underline/non-underline mode. If the windowName parameters omitted, the main screen will be used.

    setWindowWrap

    setWindowWrap(windowName, wrapAt)
    sets at what position in the line the console or miniconsole will start word wrap

    showCaptureGroups

    showCaptureGroups()
    Lua debug function that highlights in random coolors all capture groups in your trigger regex on the screen. This is very handy if you make complex regex and want to see what really matches in the text. This function is defined in LuaGlobal.lua.
    Example
    Make a trigger with the regex (\w+) and call this function in a trigger. All words in the text will be highlighted in random colors.

    showMultimatches

    showMultimatches()
    Lua helper function to show you what the table multimatches[n][m] contains. This is very useful when debugging multiline triggers - just doing showMultimatches() in your script will make it give the info.

    showWindow

    showWindow(name)
    Shows user window name.

    replaceWildcard

    replaceWildcard(which, replacement)
    Replaces the given wildcard (as a number) with the given text. Equivalent to doing:
    selectString(matches[2], 1)
    replace("text")
    Parameters
    • which:

    Wildcard to replace.
    • replacement:

    Text to replace the wildcard with.
    Example
    replaceWildcard(2, "hello") -- on a perl regex trigger of ^You wave (goodbye)\.$, it will make it seem like you waved hello

    resetFormat

    resetFormat()
    Resets the colour/bold/italics formatting. Always use this function when done adjusting formatting, so make sure what you've set doesn't 'bleed' onto other triggers/aliases.
    Parameters
    None
    Example
    -- select and set the 'Tommy' to red in the line
    if selectString("Tommy", 1) ~= -1 then fg("red") end
    
    -- now reset the formatting, so our echo isn't red
    resetFormat()
    echo(" Hi Tommy!")
    
    -- another example: just highlighting some words
    for _, word in ipairs{"he", "she", "her", "their"} do
      if selectString(word, 1) ~= -1 then
        bg("blue")
      end
    end
    resetFormat()

    selectCurrentLine

    selectCurrentLine()
    Selects the content of the current line that the cursor at. By default, the cursor is at the start of the current line that the triggers are processing, but you can move it with the moveCursor() function. Note: This selects the whole line, including the linebreak - so it has a subtle difference from the slightly slower selectString(line, 1) selection method.
    See Also: selectString(), getCurrentLine()
    Parameters
    None
    Example
    -- color the whole line green!
    selectCurrentLine()
    fg("green")
    deselect()
    resetFormat()

    setBackgroundColor

    setBackgroundColor(labelName, red, green, blue, transparency)
    Sets rgb color values and the transparency for the given window. Colors are from 0 to 255 (0 being black), and transparency is from - to 255 (0 being completely transparent).

    Note: Transparency only works on labels, not miniConsoles for efficiency reasons.

    Parameters
    • labelName:

    The name of the label to change it's background color.
    • red:

    Amount of red to use, from 255 (full) to 0 (none).
    • green:

    Amount of green to use, from 255 (full) to 0 (none).
    • blue:

    Amount of red to use, from 255 (full) to 0 (none).
    • transparency:

    Amount of transparency to use, from 255 (fully opaque) to 0 (fully transparent).
    Example
    -- make a red label that's somewhat transparent
    setBackgroundColor("some label",255,0,0,200)

    setBackgroundImage

    setBackgroundImage(labelName, imageLocation)
    Loads an image file (png) as a background image for a label. This can be used to display clickable buttons in combination with setLabelClickCallback() and such.
    Note you can only do this for labels, not miniconsoles.
    Note you can also load images via setLabelStyleSheet().
    Parameters
    • labelName:

    The name of the label to change it's background color.
    • imageLocation:

    The full path to the image location. It's best to use [[ ]] instead of "" for it - because for Windows paths, backslashes need to be escaped.
    Example
    -- give the top border a nice look
    setBackgroundImage("top bar", [[/home/vadi/Games/Mudlet/games/top_bar.png]])

    setBorderBottom

    setBorderBottom(size)
    Sets the size of the bottom border of the main window in pixels. A border means that the MUD text won't go on it, so this gives you room to place your graphical elements there.
    See Also: setBorderColor()
    Parameters
    • size:

    Height of the border in pixels - with 0 indicating no border.
    Example
    setBorderLeft(100)

    setBorderColor

    setBorderColor(r,g,b)
    Sets the color of the main windows border that you can create either with setBorderTop(), setBorderBottom(), setBorderLeft(), setBorderRight(), or via the main window settings.
    See Also: setBorderTop(), setBorderBottom(), setBorderLeft(), setBorderRight()
    Parameters
    • r:

    Amount of red to use, from 0 to 255.
    • g:

    Amount of green to use, from 0 to 255.
    • b:

    Amount of blue to use, from 0 to 255.
    Example
    -- set the border to be completely blue
    setBorderColor(0, 0, 255)
    
    -- or red, using a name
    setBorderColor( unpack(color_table.red) )

    setBorderLeft

    setBorderLeft(size)
    Sets the size of the left border of the main window in pixels. A border means that the MUD text won't go on it, so this gives you room to place your graphical elements there.
    See Also: setBorderColor()
    Parameters
    • size:

    Width of the border in pixels - with 0 indicating no border.
    Example
    setBorderLeft(100)

    setBorderRight

    setBorderRight(size)
    Sets the size of the right border of the main window in pixels. A border means that the MUD text won't go on it, so this gives you room to place your graphical elements there.
    See Also: setBorderColor()
    Parameters
    • size:

    Width of the border in pixels - with 0 indicating no border.
    Example
    setBorderRight(100)

    setBorderTop

    setBorderTop(size)
    Sets the size of the top border of the main window in pixels. A border means that the MUD text won't go on it, so this gives you room to place your graphical elements there.
    See Also: setBorderColor()
    Parameters
    • size:

    Height of the border in pixels - with 0 indicating no border.
    Example
    setBorderTop(100)

    setLabelClickCallback

    setLabelClickCallback(labelName, luaFunctionName, optional any amount of arguments)
    Specifies a Lua function to be called if the user clicks on the label/image. This function can pass any number of string or integer number values as additional parameters. These parameters are then used in the callback - thus you can associate data with the label/button.
    Parameters
    • labelName:

    The name of the label to attach a callback function to.
    • luaFunctionName:

    The Lua function name to call, as a string - it must be registered as a global function, and not inside any namespaces (tables).
    • optional any amount of arguments:

    Y position of the miniconsole. Measured in pixels, with 0 being the very top. Passed as an integer number.
    Example
    function onClickGoNorth()
      echo("the north button was clicked!")
    end
    
    setLabelClickCallback( "compassNorthImage", "onClickGoNorth" )

    setLink

    setLink(command, tooltip)
    Turns the selected() text into a clickable link - upon being clicked, the link will do the command code. Tooltip is a string which will be displayed when the mouse is over the selected text.
    Parameters
    • command:

    command to do when the text is clicked
    • tooltip:

    tooltip to show when the mouse is over the text - explaining what would clicking do
    Example
    -- you can clickify a lot of things to save yourself some time - for example, you can change
    --  the line where you receive a message to be clickable to read it!
    -- prel regex trigger:
    -- ^You just received message #(\w+) from \w+\.$
    -- script:
    selectString(matches[2], 1)
    setUnderline(true) setLink([[send("msg read ]]..matches[2]..[[")]], "Read #"..matches[2])
    resetFormat()

    setLabelStyleSheet

    setLabelStyleSheet(label, markup)
    Applies Qt style formatting to a label via a special markup language.
    Parameters
    • label:

    The name of the label to be formatted (passed when calling createLabel).
    • markup:

    The string instructions, as specified by the Qt Style Sheet reference.
    References
    http://doc.qt.nokia.com/4.7/stylesheet-reference.html#list-of-properties
    Example
    -- This creates a label with a white background and a green border, with the text "test"
    -- inside.
    createLabel("test", 50, 50, 100, 100, 0)
    setLabelStyleSheet("test", [[
            background-color: white;
            border: 10px solid green;
            font-size: 12px;
            ]])
    echo("test", "test")
    
    -- This creates a label with a single image, that will tile or clip depending on the
    -- size of the label. To use this example, please supply your own image.
    createLabel("test5", 50, 353, 164, 55, 0)
    setLabelStyleSheet("test5", [[
            background-image: url(C:/Users/Administrator/.config/mudlet/profiles/Midkemia Online/Vyzor/MkO_logo.png);
            ]])
    
    -- This creates a label with a single image, that can be resized (such as during a
    -- sysWindowResizeEvent). To use this example, please supply your own image.
    createLabel("test9", 215, 353, 100, 100, 0)
    setLabelStyleSheet("test9", [[
            border-image: url(C:/Users/Administrator/.config/mudlet/profiles/Midkemia Online/Vyzor/MkO_logo.png);
            ]])

    setPopup

    setPopup(name, {lua code}, {hints})
    Turns the selected() text into a left-clickable link, and a right-click menu for more options. The selected text, upon being left-clicked, will do the first command in the list. Upon being right-clicked, it'll display a menu with all possible commands. The menu will be populated with hints, one for each line.
    Parameters
    • name:

    the name of the console to operate on. If not using this in a miniConsole, use "main" as the name.
    • {lua code}:

    a table of lua code strings to do. ie,
    {[[send("hello")]], [[echo("hi!"]]}
    • {hints}:

    a table of strings which will be shown on the popup and right-click menu. ie,
    {"send the hi command", "echo hi to yourself"}
    .
    Example
    -- In a `Raising your hand in greeting, you say "Hello!"` exact match trigger, 
    -- the following code will make left-clicking on `Hello` show you an echo, while right-clicking
    -- will show some commands you can do.
    
    selectString("Hello", 1)
    setPopup("main", {[[send("bye")]], [[echo("hi!")]]}, {"left-click or right-click and do first item to send bye", "click to echo hi"})

    showToolBar

    showToolBar(name)
    Makes a toolbar (a button group) appear on the screen.
    Parameters
    • name:

    name of the button group to display
    Example
    showToolBar("my offensive buttons")

    wrapLine

    wrapLine(windowName, lineNumber)
    wraps the line specified by lineNumber of mini console (window) windowName. This function will interpret \n characters, apply word wrap and display the new lines on the screen. This function may be necessary if you use deleteLine() and thus erase the entire current line in the buffer, but you want to do some further echo() calls after calling deleteLine(). You will then need to re-wrap the last line of the buffer to actually see what you have echoed and get your \n interpreted as newline characters properly. Using this function is no good programming practice and should be avoided. There are better ways of handling situations where you would call deleteLine() and echo afterwards e.g.:
    selectString(line,1)
    replace("")

    This will effectively have the same result as a call to deleteLine() but the buffer line will not be entirely removed. Consequently, further calls to echo() etc. sort of functions are possible without using wrapLine() unnecessarily.

    See Also: replace(), deleteLine()
    Parameters
    • windowName:

    The miniconsole or the main window (use main for the main window)
    • lineNumber:

    The line number which you'd like re-wrapped.
    Example
    -- re-wrap the last line in the main window
    wrapLine("main", getLineCount())
    mudlet-2.1/src/glwidget.cpp0000644000175000017500000025102512020507607015263 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2010-2011 by Heiko Koehn ( KoehnHeiko@googlemail.com ) * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include //#include #include //problem with git #include #include #include "glwidget.h" #include "Host.h" #include "dlgMapper.h" #ifndef GL_MULTISAMPLE #define GL_MULTISAMPLE 0x809D #endif #if QT_VERSION >= 0x040800 #include #endif bool ortho; bool selectionMode = false; bool mPanMode = false; float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0, mPanXStart=0, mPanYStart=0; float zmax, zmin; GLWidget::GLWidget(QWidget *parent) : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) { mpMap = 0; xDist=0.0; yDist=0.0; zDist=0.0; xRot=1.0; yRot=5.0; zRot=10.0; ortho=false;//true; xDist = 0; yDist = 0; zDist = -1 ; mScale = 1.0; zmax = 9999999.0; zmin = 9999999.0; mShowTopLevels = 9999999; mShowBottomLevels = 999999; setAttribute( Qt::WA_OpaquePaintEvent ); is2DView = false; mShiftMode = false; mAID = 0; mRID = 0; mOx = 0; mOy = 0; mOz = 0; } GLWidget::GLWidget(TMap * pM, QWidget *parent) : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) { mpHost = 0; mpMap = pM; is2DView = false; mShiftMode = false; mAID = 0; mRID = 0; mOx = 0; mOy = 0; mOz = 0; } GLWidget::~GLWidget() { } QSize GLWidget::minimumSizeHint() const { return QSize(50, 50); } QSize GLWidget::sizeHint() const { return QSize(400, 400); } static void qNormalizeAngle(int &angle) { angle /= 10; } void GLWidget::fullView() { mShowTopLevels = 9999999; mShowBottomLevels = 999999; updateGL(); } void GLWidget::shiftDown() { mShiftMode = true; mOy--; updateGL(); } void GLWidget::shiftUp() { mShiftMode = true; mOy++; updateGL(); } void GLWidget::shiftLeft() { mShiftMode = true; mOx--; updateGL(); } void GLWidget::shiftRight() { mShiftMode = true; mOx++; updateGL(); } void GLWidget::shiftZup() { mShiftMode = true; mOz++; updateGL(); } void GLWidget::shiftZdown() { mShiftMode = true; mOz--; updateGL(); } void GLWidget::showInfo() { mShowInfo = !mShowInfo; updateGL(); } void GLWidget::singleView() { mShowTopLevels = 0; mShowBottomLevels = 0; updateGL(); } void GLWidget::increaseTop() { mShowTopLevels += 1; updateGL(); } void GLWidget::reduceTop() { if( mShowTopLevels <= 0 ) mShowTopLevels = abs(zmax); if( abs(mShowTopLevels) > abs(zmax) ) mShowTopLevels = abs(zmax); mShowTopLevels--; updateGL(); } void GLWidget::increaseBottom() { mShowBottomLevels++; updateGL(); } void GLWidget::reduceBottom() { if( mShowBottomLevels <= 0 ) mShowBottomLevels = abs(zmin); if( abs(mShowBottomLevels) > abs(zmin) ) mShowBottomLevels = abs(zmin); mShowBottomLevels--; updateGL(); } void GLWidget::defaultView() { xRot=1.0; yRot=5.0; zRot=10.0; mScale = 1.0; is2DView = false; setVisible(!isVisible()); mpMap->mpMapper->mp2dMap->setVisible(!mpMap->mpMapper->mp2dMap->isVisible()); updateGL(); } void GLWidget::sideView() { xRot=7.0; yRot=-10.0; zRot=0.0; mScale = 1.0; is2DView = false; updateGL(); } void GLWidget::topView() { xRot=0.0; yRot=0.0; zRot=15.0; mScale = 1.0; is2DView = true; updateGL(); } void GLWidget::goRoom( const QString & s ) { } void GLWidget::setScale(int angle) { mScale = 150/((float)angle+300); resizeGL(width(),height()); updateGL(); return; } void GLWidget::setXRotation(int angle) { qNormalizeAngle(angle); xRot=angle; is2DView = false; updateGL(); return; } void GLWidget::setYRotation(int angle) { qNormalizeAngle(angle); yRot=angle; is2DView = false; updateGL(); return; } void GLWidget::setZRotation(int angle) { qNormalizeAngle(angle); zRot=angle; is2DView = false; updateGL(); return; } void GLWidget::setXDist(int angle) { xDist=angle; is2DView = false; updateGL(); return; } void GLWidget::setYDist(int angle) { yDist=angle; is2DView = false; updateGL(); return; } void GLWidget::setZDist(int angle) { zDist=angle; is2DView = false; updateGL(); return; } void GLWidget::initializeGL() { qglClearColor( Qt::black ); xRot = 1; yRot = 5; zRot = 10; glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glShadeModel( GL_SMOOTH ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearDepth(1.0); is2DView = false; } void GLWidget::showArea(QString name) { if( !mpMap ) return; QMapIterator it( mpMap->areaNamesMap ); while( it.hasNext() ) { it.next(); int areaID = it.key(); QString _n = it.value(); if( name == _n ) { mAID = areaID; mRID = mpMap->mRoomId;//FIXME: mShiftMode = true; mOx = 0; mOy = 0; mOz = 0; updateGL(); break; } } } void GLWidget::paintGL() { if( ! mpMap ) return; float px,py,pz; if( mRID != mpMap->mRoomId && mShiftMode ) mShiftMode = false; int ox, oy, oz; if( ! mShiftMode ) { mRID = mpMap->mRoomId; if( ! mpMap->rooms.contains( mRID ) ) { glClearDepth(1.0); glDepthFunc(GL_LESS); glClearColor (0.0,0.0,0.0,1.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderText(width()/3,height()/2,"no map or no valid position on map", QFont("Bitstream Vera Sans Mono", 30, QFont::Courier ) ); glLoadIdentity(); glFlush(); return; } mAID = mpMap->rooms[mRID]->area; ox = mpMap->rooms[mRID]->x; oy = mpMap->rooms[mRID]->y; oz = mpMap->rooms[mRID]->z; mOx = ox; mOy = oy; mOz = oz; } else { ox = mOx; oy = mOy; oz = mOz; } px = static_cast(ox);//mpMap->rooms[mpMap->mRoomId]->x); py = static_cast(oy);//mpMap->rooms[mpMap->mRoomId]->y); pz = static_cast(oz);//mpMap->rooms[mpMap->mRoomId]->z); if( ! mpMap->areas.contains(mAID) ) return; TArea * pArea = mpMap->areas[mAID];//mpMap->rooms[mpMap->mRoomId]->area]; if( ! pArea ) return; if( pArea->gridMode ) { xRot=0.0; yRot=0.0; zRot=15.0; } zmax = static_cast(pArea->max_z); zmin = static_cast(pArea->min_z); float zEbene; glEnable(GL_CULL_FACE); glClearDepth(1.0); glDepthFunc(GL_LESS); glClearColor (0.0,0.0,0.0,1.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); GLfloat diffuseLight[] = {0.507, 0.507, 0.507, 1.0}; GLfloat diffuseLight2[] = {0.501, 0.901, 0.501, 1.0}; GLfloat ambientLight[] = {0.403, 0.403, 0.403, 1.0}; GLfloat ambientLight2[] = {0.4501, 0.4501, 0.4501, 1.0}; if( !mpMap->rooms.contains(mRID) ) return; //GLfloat specularLight[] = {.01, .01, .01, 1.};//TODO: fuer ich-sphere GLfloat light0Pos[] = {5000.0, 4000.0, 1000.0, 0}; GLfloat light1Pos[] = {5000.0, 1000.0, 1000.0, 0}; glLightfv( GL_LIGHT0, GL_AMBIENT, ambientLight ); glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseLight ); glLightfv (GL_LIGHT0, GL_POSITION, light0Pos ); glLightfv( GL_LIGHT1, GL_AMBIENT, ambientLight2 ); glLightfv( GL_LIGHT1, GL_DIFFUSE, diffuseLight2 ); glLightfv (GL_LIGHT1, GL_POSITION, light1Pos ); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); glLightfv (GL_LIGHT0, GL_POSITION, light0Pos ); glLightfv (GL_LIGHT1, GL_POSITION, light1Pos ); glBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);//GL_ONE_MINUS_SRC_ALPHA); glLoadIdentity(); dehnung = 4.0; if( ! mpMap ) { return; } glDisable( GL_FOG ); glEnable(GL_BLEND); glEnable( GL_LIGHTING ); glDisable(GL_DEPTH_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LIGHT0); //glEnable(GL_LIGHT1); if( zRot <= 0 ) zEbene = zmax; else zEbene = zmin; glEnable (GL_LINE_SMOOTH); glEnable (GL_LINE_STIPPLE); glLineWidth(1.0); int quads=0; int verts=0; float ebenenColor2[][4] = { {0.9, 0.5, 0.0, 1.0}, {165.0/255.0, 102.0/255.0, 167.0/255.0, 1.0}, {170.0/255.0, 10.0/255.0, 127.0/255.0, 1.0}, {203.0/255.0, 135.0/255.0, 101.0/255.0, 1.0}, {154.0/255.0, 154.0/255.0, 115.0/255.0, 1.0}, {107.0/255.0, 154.0/255.0, 100.0/255.0, 1.0}, {154.0/255.0, 184.0/255.0, 111.0/255.0, 1.0}, {67.0/255.0, 154.0/255.0, 148.0/255.0, 1.0}, {154.0/255.0, 118.0/255.0, 151.0/255.0, 1.0}, {208.0/255.0, 213.0/255.0, 164.0/255.0, 1.0}, {213.0/255.0, 169.0/255.0, 158.0/255.0, 1.0}, {139.0/255.0, 209.0/255.0, 0, 1.0}, {163.0/255.0, 209.0/255.0, 202.0/255.0, 1.0}, {158.0/255.0, 156.0/255.0, 209.0/255.0, 1.0}, {209.0/255.0, 144.0/255.0, 162.0/255.0, 1.0}, {209.0/255.0, 183.0/255.0, 78.0/255.0, 1.0}, {111.0/255.0, 209.0/255.0, 88.0/255.0, 1.0}, {95.0/255.0, 120.0/255.0, 209.0/255.0, 1.0}, {31.0/255.0, 209.0/255.0, 126.0/255.0, 1.0}, {1.0, 170.0/255.0, 1.0, 1.0}, {158.0/255.0, 105.0/255.0, 158.0/255.0, 1.0}, {68.0/255.0, 189.0/255.0, 189.0/255.0, 1.0}, {0.1, 0.69, 0.49, 1.0}, {0.0, 0.15, 1.0, 1.0}, {0.12, 0.02, 0.20, 1.0}, {0.0, 0.3, 0.1, 1.0} }; float ebenenColor[][4] = { { 0.5, 0.6, 0.5, 0.2 }, {0.233, 0.498, 0.113, 0.2}, {0.666, 0.333, 0.498, 0.2}, {0.5, 0.333, 0.666, 0.2}, {0.69, 0.458, 0.0, 0.2}, {0.333, 0.0, 0.49, 0.2}, {133.0/255.0, 65.0/255.0, 98.0/255.0, 0.2}, {0.3, 0.3, 0.0, 0.2}, {0.6, 0.2, 0.6, 0.2}, {0.6, 0.6, 0.2, 0.2}, {0.4, 0.1, 0.4, 0.2}, {0.4, 0.4, 0.1, 0.2}, {0.3, 0.1, 0.3, 0.2}, {0.3, 0.3, 0.1, 0.2}, {0.2, 0.1, 0.2, 0.2}, {0.2, 0.2, 0.1, 0.2}, {0.24, 0.1, 0.5, 0.2}, {0.1, 0.1, 0.0, 0.2}, {0.54, 0.6, 0.2, 0.2}, {0.2, 0.2, 0.5, 0.2}, {0.6, 0.6, 0.2, 0.2}, {0.6, 0.4, 0.6, 0.2}, {0.4, 0.4, 0.1, 0.2}, {0.4, 0.2, 0.4, 0.2}, {0.2, 0.2, 0.0, 0.2}, {0.2, 0.1, 0.3, 0.2} }; while( true ) { if( zRot <= 0 ) { if( zEbene < zmin ) { break; } } else { if( zEbene > zmax ) { break; } } for( int i=0; irooms.size(); i++ ) { float rx = static_cast(mpMap->rooms[pArea->rooms[i]]->x); float ry = static_cast(mpMap->rooms[pArea->rooms[i]]->y); float rz = static_cast(mpMap->rooms[pArea->rooms[i]]->z); if( rz != zEbene ) continue; if( rz > pz ) if( abs(rz-pz) > mShowTopLevels ) continue; if( rz < pz ) if( abs(rz-pz) > mShowBottomLevels ) continue; QList exitList; exitList.push_back( mpMap->rooms[pArea->rooms[i]]->north ); exitList.push_back( mpMap->rooms[pArea->rooms[i]]->northwest ); exitList.push_back( mpMap->rooms[pArea->rooms[i]]->east ); exitList.push_back( mpMap->rooms[pArea->rooms[i]]->southeast ); exitList.push_back( mpMap->rooms[pArea->rooms[i]]->south ); exitList.push_back( mpMap->rooms[pArea->rooms[i]]->southwest ); exitList.push_back( mpMap->rooms[pArea->rooms[i]]->west ); exitList.push_back( mpMap->rooms[pArea->rooms[i]]->northwest ); exitList.push_back( mpMap->rooms[pArea->rooms[i]]->up ); exitList.push_back( mpMap->rooms[pArea->rooms[i]]->down ); int e = mpMap->rooms[pArea->rooms[i]]->z; int ef; ef = abs(e%26); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ebenenColor[ef]); glMateriali(GL_FRONT, GL_SHININESS, 1); glDisable(GL_DEPTH_TEST); if( rz <= pz ) { if( ( rz == pz ) && ( rx == px ) && ( ry == py ) ) { glDisable(GL_BLEND); glEnable( GL_LIGHTING ); float mc3[] = { 1.0f, 0.0f, 0.0f, 1.0f }; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc3); glMateriali(GL_FRONT, GL_SHININESS, 1); glColor4f(1.0, 0.0, 0.0, 1.0); } else { glDisable(GL_BLEND); glEnable( GL_LIGHTING ); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ebenenColor[ef]); glMateriali(GL_FRONT, GL_SHININESS, 1); glColor4f(0.3,0.3,0.3,1.0);/*ebenenColor[ef][0], ebenenColor[ef][1], ebenenColor[ef][2], ebenenColor[ef][3]);*/ } for( int k=0; krooms.contains( exitList[k] ) ) { continue; } if( mpMap->rooms[exitList[k]]->area != mAID )// mpMap->rooms[mRID]->area ) { areaExit = true; } else { areaExit = false; } float ex = static_cast(mpMap->rooms[exitList[k]]->x); float ey = static_cast(mpMap->rooms[exitList[k]]->y); float ez = static_cast(mpMap->rooms[exitList[k]]->z); QVector3D p1( ex, ey, ez ); QVector3D p2( rx, ry, rz ); glLoadIdentity(); gluLookAt(px*0.1+xRot, py*0.1+yRot, pz*0.1+zRot, px*0.1, py*0.1, pz*0.1,0.0,1.0,0.0); glScalef( 0.1, 0.1, 0.1); if( areaExit ) glLineWidth(1);//1/mScale+2); else glLineWidth(1);//1/mScale); if( exitList[k] == mRID || ( ( rz == pz ) && ( rx == px ) && ( ry == py ) ) ) { glDisable(GL_BLEND); glEnable( GL_LIGHTING ); float mc3[] = { 1.0f, 0.0f, 0.0f, 1.0f }; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc3); glMateriali(GL_FRONT, GL_SHININESS, 1); glColor4f(1.0, 0.0, 0.0, 1.0); } else { glDisable(GL_BLEND); glEnable( GL_LIGHTING ); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ebenenColor[ef]); glMateriali(GL_FRONT, GL_SHININESS, 1); glColor4f(0.3,0.3,0.3,1.0);//ebenenColor[ef][0], // ebenenColor[ef][1], // ebenenColor[ef][2], // ebenenColor[ef][3]); } glBegin(GL_LINES); if( ! areaExit ) { glVertex3f( p1.x(), p1.y(), p1.z() ); } else { if( mpMap->rooms[pArea->rooms[i]]->north == exitList[k] ) glVertex3f( p2.x(), p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->south == exitList[k] ) glVertex3f( p2.x(), p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->west == exitList[k] ) glVertex3f( p2.x()-1, p2.y(), p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->east == exitList[k] ) glVertex3f( p2.x()+1, p2.y(), p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->southwest == exitList[k] ) glVertex3f( p2.x()-1, p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->southeast == exitList[k] ) glVertex3f( p2.x()+1, p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->northeast == exitList[k] ) glVertex3f( p2.x()+1, p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->northwest == exitList[k] ) glVertex3f( p2.x()-1, p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->up == exitList[k] ) glVertex3f( p2.x(), p2.y(), p2.z()+1 ); else if( mpMap->rooms[pArea->rooms[i]]->down == exitList[k] ) glVertex3f( p2.x(), p2.y(), p2.z()-1 ); } glVertex3f( p2.x(), p2.y(), p2.z() ); glEnd(); verts++; if( areaExit ) { glDisable(GL_BLEND); glEnable( GL_LIGHTING ); glDisable(GL_LIGHT1); float mc4[] = { 85.0/255.0, 170.0/255.0, 0.0/255.0, 1.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc4); glMateriali(GL_FRONT, GL_SHININESS, 1); glColor4f(85.0/255.0, 170.0/255.0, 0.0/255.0, 1.0); glLoadIdentity(); gluLookAt(px*0.1+xRot, py*0.1+yRot, pz*0.1+zRot, px*0.1, py*0.1, pz*0.1,0.0,1.0,0.0); glScalef( 0.1, 0.1, 0.1); if( mpMap->rooms[pArea->rooms[i]]->north == exitList[k] ) glTranslatef( p2.x(), p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->south == exitList[k] ) glTranslatef( p2.x(), p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->west == exitList[k] ) glTranslatef( p2.x()-1, p2.y(), p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->east == exitList[k] ) glTranslatef( p2.x()+1, p2.y(), p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->southwest == exitList[k] ) glTranslatef( p2.x()-1, p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->southeast == exitList[k] ) glTranslatef( p2.x()+1, p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->northeast == exitList[k] ) glTranslatef( p2.x()+1, p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->northwest == exitList[k] ) glTranslatef( p2.x()-1, p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->up == exitList[k] ) glTranslatef( p2.x(), p2.y(), p2.z()+1 ); else if( mpMap->rooms[pArea->rooms[i]]->down == exitList[k] ) glTranslatef( p2.x(), p2.y(), p2.z()-1 ); float mc6[] = { 85.0/255.0, 170.0/255.0, 0.0/255.0, 0.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc6); glMateriali(GL_FRONT, GL_SHININESS, 96); glLoadName( exitList[k] ); quads++; glBegin( GL_QUADS ); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glEnd(); //drauf float mc3[] = { 0.2, 0.2, 0.6, 1.0 }; int env = mpMap->rooms[exitList[k]]->environment; if( mpMap->envColors.contains(env) ) env = mpMap->envColors[env]; else { if( ! mpMap->customEnvColors.contains(env)) { env = 1; } } switch( env ) { case 1: glColor4b(128,50,50,200); mc3[0]=128.0/255.0; mc3[1]=0.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 2: glColor4b(128,128,50, 200); mc3[0]=0.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 3: glColor4b(50,128,50,200); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 4: glColor4b(50,50,128,200); mc3[0]=0.0/255.0; mc3[1]=0.0/255.0; mc3[2]=128.0/255.0; mc3[3]=0.2; break; case 5: glColor4b(128,50,128,200); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 6: glColor4b(50,128,128,200); mc3[0]=0.0/255.0; mc3[1]=128.0/255.0; mc3[2]=128.0/255.0; mc3[3]=0.2; break; case 7: glColor4b(52,38,78,200); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=128.0/255.0; mc3[3]=0.2; break; case 8: glColor4b(65, 55, 35, 200); mc3[0]=55.0/255.0; mc3[1]=55.0/255.0; mc3[2]=55.0/255.0; mc3[3]=0.2; break; case 9: glColor4b(175,50,50,200); mc3[0]=255.0/255.0; mc3[1]=50.0/255.0; mc3[2]=50.0/255.0; mc3[3]=0.2; break; case 10: glColor4b(255,255,50,200); mc3[0]=50.0/255.0; mc3[1]=255.0/255.0; mc3[2]=50.0/255.0; mc3[3]=0.2; break; case 11: glColor4b(50,175,175,200); mc3[0]=255.0/255.0; mc3[1]=255.0/255.0; mc3[2]=50.0/255.0; mc3[3]=0.2; break; case 12: glColor4b(175,175,50,200); mc3[0]=50.0/255.0; mc3[1]=50.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; case 13: glColor4b(175,50,175,200); mc3[0]=255.0/255.0; mc3[1]=50.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; case 14: glColor4b(50,175,50,200); mc3[0]=50.0/255.0; mc3[1]=255.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; case 15: glColor4b(50,50,175,200); mc3[0]=255.0/255.0; mc3[1]=255.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; default: //user defined room color if( ! mpMap->customEnvColors.contains(env) ) break; QColor &_c = mpMap->customEnvColors[env]; glColor4b(_c.red(),_c.green(),_c.blue(),25); mc3[0]=_c.redF(); mc3[1]=_c.greenF(); mc3[2]=_c.blueF(); mc3[3]=0.2; } glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc3); glMateriali(GL_FRONT, GL_SHININESS, 1); glDisable(GL_DEPTH_TEST); glLoadIdentity(); gluLookAt(px*0.1+xRot, py*0.1+yRot, pz*0.1+zRot, px*0.1, py*0.1, pz*0.1,0.0,1.0,0.0); glScalef( 0.05, 0.05, 0.020); if( mpMap->rooms[pArea->rooms[i]]->north == exitList[k] ) glTranslatef( 2*p2.x(), 2*(p2.y()+1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->south == exitList[k] ) glTranslatef( 2*p2.x(), 2*(p2.y()-1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->west == exitList[k] ) glTranslatef( 2*(p2.x()-1), 2*p2.y(), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->east == exitList[k] ) glTranslatef( 2*(p2.x()+1), 2*p2.y(), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->southwest == exitList[k] ) glTranslatef( 2*(p2.x()-1), 2*(p2.y()-1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->southeast == exitList[k] ) glTranslatef( 2*(p2.x()+1), 2*(p2.y()-1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->northeast == exitList[k] ) glTranslatef( 2*(p2.x()+1), 2*(p2.y()+1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->northwest == exitList[k] ) glTranslatef( 2*(p2.x()-1), 2*(p2.y()+1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->up == exitList[k] ) glTranslatef( 2*p2.x(), 2*p2.y(), 5.0*(p2.z()+1+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->down == exitList[k] ) glTranslatef( 2*p2.x(), 2*p2.y(), 5.0*(p2.z()-1+0.25) ); glBegin( GL_QUADS ); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glEnd(); } } } else { for( int k=0; krooms.contains( exitList[k] ) ) { continue; } if( mpMap->rooms[exitList[k]]->area != mAID ) { areaExit = true; } else { areaExit = true; } float ex = static_cast(mpMap->rooms[exitList[k]]->x); float ey = static_cast(mpMap->rooms[exitList[k]]->y); float ez = static_cast(mpMap->rooms[exitList[k]]->z); QVector3D p1( ex, ey, ez ); QVector3D p2( rx, ry, rz ); glLoadIdentity(); gluLookAt(px*0.1+xRot, py*0.1+yRot, pz*0.1+zRot, px*0.1, py*0.1, pz*0.1,0.0,1.0,0.0); glScalef( 0.1, 0.1, 0.1); if( areaExit ) glLineWidth(1);//1/mScale+2); else glLineWidth(1);//1/mScale); if( exitList[k] == mRID || ( ( rz == pz ) && ( rx == px ) && ( ry == py ) ) ) { glDisable(GL_BLEND); glEnable( GL_LIGHTING ); float mc3[] = { 1.0f, 0.0f, 0.0f, 1.0f }; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mc3); glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 1); glColor4f(1.0, 0.0, 0.0, 1.0); } else { glEnable(GL_BLEND); glEnable( GL_LIGHTING ); glEnable(GL_LIGHT1); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ebenenColor2[ef]); glMateriali(GL_FRONT, GL_SHININESS, 1);//gut:36 glColor4f(0.3,0.3,0.3,1.0);/*ebenenColor2[ef][0], ebenenColor2[ef][1], ebenenColor2[ef][2], ebenenColor2[ef][3])*/; } glBegin(GL_LINES); if( ! areaExit ) { glVertex3f( p1.x(), p1.y(), p1.z() ); } else { if( mpMap->rooms[pArea->rooms[i]]->north == exitList[k] ) glVertex3f( p2.x(), p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->south == exitList[k] ) glVertex3f( p2.x(), p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->west == exitList[k] ) glVertex3f( p2.x()-1, p2.y(), p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->east == exitList[k] ) glVertex3f( p2.x()+1, p2.y(), p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->southwest == exitList[k] ) glVertex3f( p2.x()-1, p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->southeast == exitList[k] ) glVertex3f( p2.x()+1, p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->northeast == exitList[k] ) glVertex3f( p2.x()+1, p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->northwest == exitList[k] ) glVertex3f( p2.x()-1, p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->up == exitList[k] ) glVertex3f( p2.x(), p2.y(), p2.z()+1 ); else if( mpMap->rooms[pArea->rooms[i]]->down == exitList[k] ) glVertex3f( p2.x(), p2.y(), p2.z()-1 ); } glVertex3f( p2.x(), p2.y(), p2.z() ); glEnd(); verts++; if( areaExit ) { glDisable(GL_BLEND); glEnable( GL_LIGHTING ); glDisable(GL_LIGHT1); float mc4[] = { 85.0/255.0, 170.0/255.0, 0.0/255.0, 1.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc4); glMateriali(GL_FRONT, GL_SHININESS, 1); glColor4f(85.0/255.0, 170.0/255.0, 0.0/255.0, 1.0); glLoadIdentity(); gluLookAt(px*0.1+xRot, py*0.1+yRot, pz*0.1+zRot, px*0.1, py*0.1, pz*0.1,0.0,1.0,0.0); glScalef( 0.1, 0.1, 0.1); if( mpMap->rooms[pArea->rooms[i]]->north == exitList[k] ) glTranslatef( p2.x(), p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->south == exitList[k] ) glTranslatef( p2.x(), p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->west == exitList[k] ) glTranslatef( p2.x()-1, p2.y(), p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->east == exitList[k] ) glTranslatef( p2.x()+1, p2.y(), p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->southwest == exitList[k] ) glTranslatef( p2.x()-1, p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->southeast == exitList[k] ) glTranslatef( p2.x()+1, p2.y()-1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->northeast == exitList[k] ) glTranslatef( p2.x()+1, p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->northwest == exitList[k] ) glTranslatef( p2.x()-1, p2.y()+1, p2.z() ); else if( mpMap->rooms[pArea->rooms[i]]->up == exitList[k] ) glTranslatef( p2.x(), p2.y(), p2.z()+1 ); else if( mpMap->rooms[pArea->rooms[i]]->down == exitList[k] ) glTranslatef( p2.x(), p2.y(), p2.z()-1 ); glLoadName( exitList[k] ); quads++; glBegin( GL_QUADS ); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glEnd(); //drauf float mc3[] = { 0.2, 0.2, 0.6, 0.2 }; int env = mpMap->rooms[exitList[k]]->environment; if( mpMap->envColors.contains(env) ) env = mpMap->envColors[env]; else { if( ! mpMap->customEnvColors.contains(env)) { env = 1; } } switch( env ) { case 1: glColor4b(128,50,50,2); mc3[0]=128.0/255.0; mc3[1]=0.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 2: glColor4b(128,128,50, 2); mc3[0]=0.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 3: glColor4b(50,128,50,2); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 4: glColor4b(50,50,128,2); mc3[0]=0.0/255.0; mc3[1]=0.0/255.0; mc3[2]=128.0/255.0; mc3[3]=0.2; break; case 5: glColor4b(128,50,128,2); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 6: glColor4b(50,128,128,2); mc3[0]=0.0/255.0; mc3[1]=128.0/255.0; mc3[2]=128.0/255.0; mc3[3]=0.2; break; case 7: glColor4b(52,38,78,2); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=128.0/255.0; mc3[3]=0.2; break; case 8: glColor4b(65, 55, 35, 2); mc3[0]=55.0/255.0; mc3[1]=55.0/255.0; mc3[2]=55.0/255.0; mc3[3]=0.2; break; case 9: glColor4b(175,50,50,2); mc3[0]=255.0/255.0; mc3[1]=50.0/255.0; mc3[2]=50.0/255.0; mc3[3]=0.2; break; case 10: glColor4b(255,255,50,2); mc3[0]=50.0/255.0; mc3[1]=255.0/255.0; mc3[2]=50.0/255.0; mc3[3]=0.2; break; case 11: glColor4b(50,175,175,2); mc3[0]=255.0/255.0; mc3[1]=255.0/255.0; mc3[2]=50.0/255.0; mc3[3]=0.2; break; case 12: glColor4b(175,175,50,2); mc3[0]=50.0/255.0; mc3[1]=50.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; case 13: glColor4b(175,50,175,2); mc3[0]=255.0/255.0; mc3[1]=50.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; case 14: glColor4b(50,175,50,2); mc3[0]=50.0/255.0; mc3[1]=255.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; case 15: glColor4b(50,50,175,2); mc3[0]=255.0/255.0; mc3[1]=255.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; default: //user defined room color if( ! mpMap->customEnvColors.contains(env) ) break; QColor &_c = mpMap->customEnvColors[env]; glColor4b(_c.red(),_c.green(),_c.blue(),255); mc3[0]=_c.redF(); mc3[1]=_c.greenF(); mc3[2]=_c.blueF(); mc3[3]=0.2; } glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc3); glMateriali(GL_FRONT, GL_SHININESS, 36); glDisable(GL_DEPTH_TEST); glLoadIdentity(); gluLookAt(px*0.1+xRot, py*0.1+yRot, pz*0.1+zRot, px*0.1, py*0.1, pz*0.1,0.0,1.0,0.0); glScalef( 0.05, 0.05, 0.020); if( mpMap->rooms[pArea->rooms[i]]->north == exitList[k] ) glTranslatef( 2*p2.x(), 2*(p2.y()+1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->south == exitList[k] ) glTranslatef( 2*p2.x(), 2*(p2.y()-1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->west == exitList[k] ) glTranslatef( 2*(p2.x()-1), 2*p2.y(), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->east == exitList[k] ) glTranslatef( 2*(p2.x()+1), 2*p2.y(), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->southwest == exitList[k] ) glTranslatef( 2*(p2.x()-1), 2*(p2.y()-1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->southeast == exitList[k] ) glTranslatef( 2*(p2.x()+1), 2*(p2.y()-1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->northeast == exitList[k] ) glTranslatef( 2*(p2.x()+1), 2*(p2.y()+1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->northwest == exitList[k] ) glTranslatef( 2*(p2.x()-1), 2*(p2.y()+1), 5.0*(p2.z()+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->up == exitList[k] ) glTranslatef( 2*p2.x(), 2*p2.y(), 5.0*(p2.z()+1+0.25) ); else if( mpMap->rooms[pArea->rooms[i]]->down == exitList[k] ) glTranslatef( 2*p2.x(), 2*p2.y(), 5.0*(p2.z()-1+0.25) ); glBegin( GL_QUADS ); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glEnd(); } } glFlush(); } } if( zRot <= 0) zEbene -= 1.0; else zEbene += 1.0; } if( zRot <= 0 ) zEbene = zmax; else zEbene = zmin; quads = 0; zEbene = zmin; glDisable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glDisable(GL_LIGHT1); while( true ) { if( zEbene > zmax ) { break; } for( int i=0; irooms.size(); i++ ) { glDisable(GL_LIGHT1); float rx = static_cast(mpMap->rooms[pArea->rooms[i]]->x); float ry = static_cast(mpMap->rooms[pArea->rooms[i]]->y); float rz = static_cast(mpMap->rooms[pArea->rooms[i]]->z); if( rz != zEbene ) continue; if( rz > pz ) if( abs(rz-pz) > mShowTopLevels ) continue; if( rz < pz ) if( abs(rz-pz) > mShowBottomLevels ) continue; int e = mpMap->rooms[pArea->rooms[i]]->z; int ef = abs(e%26); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ebenenColor[ef]); glMateriali(GL_FRONT, GL_SHININESS, 36);//gut:96 if( ( rz == pz ) && ( rx == px ) && ( ry == py ) ) { glDisable(GL_BLEND); glEnable( GL_LIGHTING ); glDisable(GL_LIGHT1); float mc3[] = { 1.0f, 0.0f, 0.0f, 1.0f }; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc3); glMateriali(GL_FRONT, GL_SHININESS, 36); glColor4f(1.0, 0.0, 0.0, 1.0); } else if( pArea->rooms[i] == mTarget ) { glDisable(GL_BLEND); glEnable( GL_LIGHTING ); glDisable(GL_LIGHT1); float mc4[] = { 0.0, 1.0, 0.0, 1.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc4); glMateriali(GL_FRONT, GL_SHININESS, 36);//36 glColor4f(0.0, 1.0, 0.0, 1.0); } else if( rz <= pz ) { glDisable(GL_BLEND); glEnable( GL_LIGHTING ); glDisable(GL_LIGHT1); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ebenenColor2[ef]); glMateriali(GL_FRONT, GL_SHININESS, 36); glColor4f(ebenenColor[ef][0], ebenenColor[ef][1], ebenenColor[ef][2], ebenenColor[ef][3]); } else { glEnable(GL_BLEND); glEnable( GL_LIGHTING ); glEnable(GL_LIGHT1); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ebenenColor[ef]); glMateriali(GL_FRONT, GL_SHININESS, 36);//56);//gut:36 glColor4f(ebenenColor2[ef][0], ebenenColor2[ef][1], ebenenColor2[ef][2], ebenenColor2[ef][3]); glLoadIdentity(); gluLookAt(px*0.1+xRot, py*0.1+yRot, pz*0.1+zRot, px*0.1, py*0.1, pz*0.1,0.0,1.0,0.0); if( pArea->gridMode ) { glScalef( 0.2, 0.2, 0.1); glTranslatef( 0.5*rx, 0.5*ry, rz ); } else { glScalef( 0.1, 0.1, 0.1); glTranslatef( rx, ry, rz ); } glLoadName( pArea->rooms[i] ); quads++; glBegin( GL_QUADS ); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glEnd(); float mc3[] = { 0.2, 0.2, 0.6, 0.2 }; int env = mpMap->rooms[pArea->rooms[i]]->environment; if( mpMap->envColors.contains(env) ) env = mpMap->envColors[env]; else { if( ! mpMap->customEnvColors.contains(env)) { env = 1; } } switch( env ) { case 1: glColor4b(128,50,50,2); mc3[0]=128.0/255.0; mc3[1]=0.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 2: glColor4b(128,128,50, 2); mc3[0]=0.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 3: glColor4b(50,128,50,2); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 4: glColor4b(50,50,128,2); mc3[0]=0.0/255.0; mc3[1]=0.0/255.0; mc3[2]=128.0/255.0; mc3[3]=0.2; break; case 5: glColor4b(128,50,128,2); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=0.2; break; case 6: glColor4b(50,128,128,2); mc3[0]=0.0/255.0; mc3[1]=128.0/255.0; mc3[2]=128.0/255.0; mc3[3]=0.2; break; case 7: glColor4b(52,38,78,2); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=128.0/255.0; mc3[3]=0.2; break; case 8: glColor4b(65, 55, 35, 2); mc3[0]=55.0/255.0; mc3[1]=55.0/255.0; mc3[2]=55.0/255.0; mc3[3]=0.2; break; case 9: glColor4b(175,50,50,2); mc3[0]=255.0/255.0; mc3[1]=50.0/255.0; mc3[2]=50.0/255.0; mc3[3]=0.2; break; case 10: glColor4b(255,255,50,2); mc3[0]=50.0/255.0; mc3[1]=255.0/255.0; mc3[2]=50.0/255.0; mc3[3]=0.2; break; case 11: glColor4b(50,175,175,2); mc3[0]=255.0/255.0; mc3[1]=255.0/255.0; mc3[2]=50.0/255.0; mc3[3]=0.2; break; case 12: glColor4b(175,175,50,2); mc3[0]=50.0/255.0; mc3[1]=50.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; case 13: glColor4b(175,50,175,2); mc3[0]=255.0/255.0; mc3[1]=50.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; case 14: glColor4b(50,175,50,2); mc3[0]=50.0/255.0; mc3[1]=255.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; case 15: glColor4b(50,50,175,2); mc3[0]=255.0/255.0; mc3[1]=255.0/255.0; mc3[2]=255.0/255.0; mc3[3]=0.2; break; default: //user defined room color if( ! mpMap->customEnvColors.contains(env) ) break; QColor &_c = mpMap->customEnvColors[env]; glColor4b(_c.red(),_c.green(),_c.blue(),255); mc3[0]=_c.redF(); mc3[1]=_c.greenF(); mc3[2]=_c.blueF(); mc3[3]=0.2; } glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc3); glMateriali(GL_FRONT, GL_SHININESS, 96); glDisable(GL_DEPTH_TEST); glLoadIdentity(); gluLookAt(px*0.1+xRot, py*0.1+yRot, pz*0.1+zRot, px*0.1, py*0.1, pz*0.1,0.0,1.0,0.0); if( pArea->gridMode ) { if( ( rz == pz ) && ( rx == px ) && ( ry == py ) ) { glScalef( 0.1, 0.1, 0.020 ); glTranslatef( 0.1*rx, 0.1*ry, 5.0*(rz+0.25) ); } else { glScalef( 0.2, 0.2, 0.020); glTranslatef( 0.5*rx, 0.5*ry, 5.0*(rz+0.25) ); } } else { glScalef( 0.075, 0.075, 0.020); glTranslatef( 1.333333333*rx,1.333333333*ry,5.0*(rz+0.25) );//+0.4 } glBegin( GL_QUADS ); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glEnd(); continue; } float mc3[] = { 0.2f, 0.2f, 0.7f, 1.0f }; glLoadIdentity(); gluLookAt(px*0.1+xRot, py*0.1+yRot, pz*0.1+zRot, px*0.1, py*0.1, pz*0.1,0.0,1.0,0.0); if( pArea->gridMode ) { glScalef( 0.2, 0.2, 0.1 ); glTranslatef( 0.5*rx, 0.5*ry, rz ); } else { glScalef( 0.1, 0.1, 0.1); glTranslatef( rx, ry, rz ); } glLoadName( pArea->rooms[i] ); quads++; glBegin( GL_QUADS ); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glEnd(); int env = mpMap->rooms[pArea->rooms[i]]->environment; if( mpMap->envColors.contains(env) ) env = mpMap->envColors[env]; else { if( ! mpMap->customEnvColors.contains(env)) { env = 1; } } switch( env ) { case 1: glColor4b(128,50,50,255); mc3[0]=128.0/255.0; mc3[1]=0.0/255.0; mc3[2]=0.0/255.0; mc3[3]=255.0/255.0; break; case 2: glColor4b(128,128,50, 255); mc3[0]=0.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=255.0/255.0; break; case 3: glColor4b(50,128,50,255); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=255.0/255.0; break; case 4: glColor4b(50,50,128,255); mc3[0]=0.0/255.0; mc3[1]=0.0/255.0; mc3[2]=128.0/255.0; mc3[3]=255.0/255.0; break; case 5: glColor4b(128,50,128,255); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=0.0/255.0; mc3[3]=255.0/255.0; break; case 6: glColor4b(50,128,128,255); mc3[0]=0.0/255.0; mc3[1]=128.0/255.0; mc3[2]=128.0/255.0; mc3[3]=255.0/255.0; break; case 7: glColor4b(52,38,78,255); mc3[0]=128.0/255.0; mc3[1]=128.0/255.0; mc3[2]=128.0/255.0; mc3[3]=255.0/255.0; break; case 8: glColor4b(65, 55, 35, 255); mc3[0]=55.0/255.0; mc3[1]=55.0/255.0; mc3[2]=55.0/255.0; mc3[3]=255.0/255.0; break; case 9: glColor4b(175,50,50,255); mc3[0]=255.0/255.0; mc3[1]=50.0/255.0; mc3[2]=50.0/255.0; mc3[3]=255.0/255.0; break; case 10: glColor4b(255,255,50,255); mc3[0]=50.0/255.0; mc3[1]=255.0/255.0; mc3[2]=50.0/255.0; mc3[3]=255.0/255.0; break; case 11: glColor4b(50,175,175,255); mc3[0]=255.0/255.0; mc3[1]=255.0/255.0; mc3[2]=50.0/255.0; mc3[3]=255.0/255.0; break; case 12: glColor4b(175,175,50,255); mc3[0]=50.0/255.0; mc3[1]=50.0/255.0; mc3[2]=255.0/255.0; mc3[3]=255.0/255.0; break; case 13: glColor4b(175,50,175,255); mc3[0]=255.0/255.0; mc3[1]=50.0/255.0; mc3[2]=255.0/255.0; mc3[3]=255.0/255.0; break; case 14: glColor4b(50,175,50,255); mc3[0]=50.0/255.0; mc3[1]=255.0/255.0; mc3[2]=255.0/255.0; mc3[3]=255.0/255.0; break; case 15: glColor4b(50,50,175,255); mc3[0]=255.0/255.0; mc3[1]=255.0/255.0; mc3[2]=255.0/255.0; mc3[3]=255.0/255.0; break; default: //user defined room color if( ! mpMap->customEnvColors.contains(env) ) break; QColor &_c = mpMap->customEnvColors[env]; glColor4b(_c.red(),_c.green(),_c.blue(),255); mc3[0]=_c.redF(); mc3[1]=_c.greenF(); mc3[2]=_c.blueF(); mc3[3]=1.0; } glDisable(GL_DEPTH_TEST); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mc3); glMateriali(GL_FRONT, GL_SHININESS, 6); glLoadIdentity(); gluLookAt(px*0.1+xRot, py*0.1+yRot, pz*0.1+zRot, px*0.1, py*0.1, pz*0.1,0.0,1.0,0.0); if( pArea->gridMode ) { if( ( rz == pz ) && ( rx == px ) && ( ry == py ) ) { glScalef( 0.1, 0.1, 0.020 ); glTranslatef( rx, ry, 5.0*(rz+0.25) ); } else { glScalef( 0.2, 0.2, 0.020); glTranslatef( 0.5*rx, 0.5*ry, 5.0*(rz+0.25) ); } } else { if( is2DView ) { glScalef( 0.090, 0.090, 0.020); glTranslatef( 1.1111111*rx,1.1111111*ry,5.0*(rz+0.25) );//+0.4 } else { glScalef( 0.075, 0.075, 0.020); glTranslatef( 1.333333333*rx,1.333333333*ry,5.0*(rz+0.25) );//+0.4 } } glBegin( GL_QUADS ); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, 0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, -0.57735, -0.57735); glVertex3f(1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, -0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, -0.57735, 0.57735); glVertex3f(-1.0/dehnung, -1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, -0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, -0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, -1.0/dehnung); glNormal3f(-0.57735, 0.57735, 0.57735); glVertex3f(-1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glNormal3f(0.57735, 0.57735, 0.57735); glVertex3f(1.0/dehnung, 1.0/dehnung, 1.0/dehnung); glEnd(); glColor4b(128,128,128,255); glBegin( GL_TRIANGLES ); if( mpMap->rooms[pArea->rooms[i]]->down > -1 ) { glVertex3f( 0.0, -0.95/dehnung, 0.0); glVertex3f(0.95/dehnung, -0.25/dehnung, 0.0); glVertex3f( -0.95/dehnung, -0.25/dehnung, 0.0); } if( mpMap->rooms[pArea->rooms[i]]->up > -1 ) { glVertex3f( 0.0, 0.95/dehnung, 0.0); glVertex3f(-0.95/dehnung, 0.25/dehnung, 0.0); glVertex3f( 0.95/dehnung, 0.25/dehnung, 0.0); } glEnd(); // if( mpMap->rooms[pArea->rooms[i]]->out > -1 ) // { // glBegin( GL_LINE_LOOP ); // for( int angle=0; angle<360; angle += 1 ) // { // glVertex3f( (0.5 + sin((float)angle) * 0.25)/dehnung, ( cos((float)angle) * 0.25)/dehnung, 0.0); // } // glEnd(); // } // glTranslatef( -0.1, 0.0, 0.0 ); // if( mpMap->rooms[pArea->rooms[i]]->in > -1 ) // { // glBegin( GL_TRIANGLE_FAN ); // glVertex3f( 0.0, 0.0, 0.0); // for( int angle=0; angle<=360; angle += 5 ) // { // glVertex3f( (sin((float)angle)*0.25)/dehnung, (cos((float)angle)*0.25)/dehnung, 0.0); // } // glEnd(); // } } zEbene += 1.0; } // qDebug()<<"FINAL: mQuads.size()="<rooms.size()<<" quads="<buttons() & Qt::LeftButton) { int x = event->x(); int y = height()-event->y();//opengl ursprungspunkt liegt unten links GLuint buff[16] = {0}; GLint hits; GLint view[4]; glSelectBuffer( 16, buff ); glGetIntegerv( GL_VIEWPORT, view ); glRenderMode( GL_SELECT ); glInitNames(); glPushName( 0 ); glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); gluPickMatrix(x, y, 0.1, 0.1, view); gluPerspective( 60*mScale, (GLfloat)width() / (GLfloat)height(), 0.0001, 10000.0); glMatrixMode(GL_MODELVIEW); mQuads.clear(); mTarget=-22; selectionMode = true; paintGL(); selectionMode = false; glMatrixMode(GL_PROJECTION); glPopMatrix(); hits = glRenderMode(GL_RENDER); int i; for (i = 0; i < hits; i++) { mTarget = buff[i * 4 + 3]; //TODO: Mehrfachbelegungen // unsigned int minZ = buff[i * 4 + 1]; // unsigned int maxZ = buff[i * 4 + 2]; } glViewport( 0, 0, (GLint)width(), (GLint)height() ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 60*mScale, (GLfloat)width() / (GLfloat)height(), 0.0001, 10000.0); glMatrixMode(GL_MODELVIEW); updateGL(); if( mpMap->rooms.contains(mTarget) ) { mpMap->mTargetID = mTarget; if( mpMap->findPath( mpMap->mRoomId, mpMap->mTargetID) ) { mpMap->mpHost->startSpeedWalk(); } // else // { // QMessageBox msgBox; // msgBox.setText("Cannot find a path to this room using regular exits.#glWidget\n"); // msgBox.exec(); // } } else{ mPanMode = true; mPanXStart = x; mPanYStart = y; } // else // { // QMessageBox msgBox; // msgBox.setText("ERROR: Target room cannot be found in map db.\n"); // msgBox.exec(); // } } } void GLWidget::mouseMoveEvent( QMouseEvent * event ) { if (mPanMode) { int x = event->x(); int y = height()-event->y();//opengl ursprungspunkt liegt unten links if ((mPanXStart-x) > 1){ shiftRight(); mPanXStart = x; } else if ((mPanXStart-x) < -1){ shiftLeft(); mPanXStart = x; } if ((mPanYStart-y) > 1){ shiftUp(); mPanYStart = y; } else if ((mPanYStart-y) < -1){ shiftDown(); mPanYStart = y; } } } void GLWidget::mouseReleaseEvent( QMouseEvent * event ) { mPanMode = false; } void GLWidget::wheelEvent ( QWheelEvent * e ) { //int delta = e->delta() / 8 / 15; if( e->delta() < 0 ) { if( abs(mScale) < 0.3 ) mScale -= 0.01; else mScale -= 0.03; resizeGL(width(),height()); updateGL(); e->accept(); return; } if( e->delta() > 0 ) { if( abs(mScale) < 0.3 ) mScale += 0.01; else mScale += 0.03; resizeGL(width(),height()); updateGL(); e->accept(); return; } e->ignore(); return; } mudlet-2.1/src/AliasUnit.h0000644000175000017500000001164011647202526015016 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn (KoehnHeiko@googlemail.com) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _Alias_UNIT_H #define _Alias_UNIT_H #include "TAlias.h" #include #include #include #include #include class TAlias; class Host; class AliasUnit { friend class XMLexport; friend class XMLimport; public: AliasUnit( Host * pHost ) : mpHost(pHost), mMaxID(0) { initStats();} std::list getAliasRootNodeList() { return mAliasRootNodeList; } TAlias * getAlias( int id ); void compileAll(); TAlias * findAlias( QString & name ); bool enableAlias( QString & ); bool disableAlias( QString & ); bool killAlias( QString & name ); bool registerAlias( TAlias * pT ); void unregisterAlias( TAlias * pT ); void uninstall( QString ); void _uninstall( TAlias * pChild, QString packageName ); // bool serialize( QDataStream & ); // bool restore( QDataStream &, bool ); void reParentAlias( int childID, int oldParentID, int newParentID, int parentPosition = -1, int childPosition = -1 ); bool processDataStream( QString & ); void dump(); void setAliasStayOpen( QString, int ); void stopAllTriggers(); void reenableAllTriggers(); QString assembleReport(); std::list mCleanupList; qint64 getNewID(); QMultiMap mLookupTable; QMutex mAliasUnitLock; void markCleanup( TAlias * pT ); void doCleanup(); int statsAliasTotal; int statsTempAliass; int statsActiveAliass; int statsActiveAliassMax; int statsActiveAliassMin; int statsActiveAliassAverage; int statsTempAliassCreated; int statsTempAliassKilled; int statsAverageLineProcessingTime; int statsMaxLineProcessingTime; int statsMinLineProcessingTime; int statsRegexAliass; QList uninstallList; private: AliasUnit(){;} void initStats(); void _assembleReport( TAlias * ); TAlias * getAliasPrivate( int id ); void addAliasRootNode( TAlias * pT, int parentPosition = -1, int childPosition = -1, bool moveAlias = false ); void addAlias( TAlias * pT ); void removeAliasRootNode( TAlias * pT ); void removeAlias( TAlias *); Host * mpHost; QMap mAliasMap; std::list mAliasRootNodeList; qint64 mMaxID; bool mModuleMember; }; #endif mudlet-2.1/src/dlgIRC.cpp0000644000175000017500000002335011624306130014554 0ustar csmallcsmall /*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn - KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include //#define IRC_SHARED #include "dlgIRC.h" #include //#include "irc/include/ircsession.h" //#include #include "mudlet.h" dlgIRC::dlgIRC() { setupUi(this); session = new Irc::Session(this); irc->setOpenExternalLinks ( true ); setUnifiedTitleAndToolBarOnMac( true ); connect( irc, SIGNAL(anchorClicked(QUrl)), this, SLOT(anchorClicked(QUrl))); connect( session, SIGNAL(msgMessageReceived(const QString &, const QString &, const QString &)), this, SLOT(irc_gotMsg(QString, QString, QString))); connect( session, SIGNAL(msgNoticeReceived(const QString &, const QString &, const QString &)), this, SLOT(irc_gotMsg(QString, QString, QString))); connect( session, SIGNAL(msgUnknownMessageReceived(const QString &, const QStringList &)), this, SLOT(irc_gotMsg2(QString, QStringList))); connect( session, SIGNAL(msgNumericMessageReceived(const QString &, uint, const QStringList &)), this, SLOT(irc_gotMsg3(QString, uint, QStringList))); connect( lineEdit, SIGNAL(returnPressed()), this, SLOT(sendMsg())); connect( session, SIGNAL(msgJoined(const QString &, const QString &)), this, SLOT(slot_joined(QString, QString))); connect( session, SIGNAL(msgParted(const QString &, const QString &, const QString &)), this, SLOT(slot_parted(QString, QString, QString))); QStringList chans; chans << "#mudlet"; session->setAutoJoinChannels( chans ); QFile file( QDir::homePath()+"/.config/mudlet/irc_nick" ); file.open( QIODevice::ReadOnly ); QDataStream ifs( & file ); QString nick; ifs >> nick; file.close(); if( nick.isEmpty() ) { nick = tr("Mudlet%1").arg(QString::number(rand()%10000)); QFile file( QDir::homePath()+"/.config/mudlet/irc_nick" ); file.open( QIODevice::WriteOnly | QIODevice::Unbuffered ); QDataStream ofs( & file ); ofs << nick; file.close(); } session->setNick(nick); mNick = nick; session->setIdent("mudlet"); session->setRealName(mudlet::self()->version); session->connectToServer("irc.freenode.net", 6667); } void dlgIRC::sendMsg() { QString txt = lineEdit->text(); lineEdit->clear(); if( txt.startsWith("/nick ") ) { txt.replace("/nick ", "" ); session->setNick( txt ); mNick = txt; session->cmdNames("#mudlet"); return; } if( txt.startsWith( "/msg ") ) { if( txt.size() < 5 ) return; txt = txt.mid(5); int _i = txt.indexOf(" "); if( _i == -1 || _i < 1 || txt.size()<_i+2 ) return; QString r = txt.mid(0, _i); QString m = txt.mid( _i+1 ); session->cmdMessage( r, m ); qDebug()<<"r="<cmdMessage("#mudlet", txt); session->cmdNames( "#mudlet" ); } #include #include void dlgIRC::irc_gotMsg( QString a, QString b, QString c ) { qDebug()<<"a<"< b<"<"<<" c<"<"; HostManager::self()->postIrcMessage( a, b, c ); c.replace("<","<"); c.replace(">",">"); const QString _t = QTime::currentTime().toString(); QRegExp rx("(http://[^ ]*)"); QStringList list; int pos = 0; while( (pos = rx.indexIn(c, pos)) != -1) { QString _l = ""); c.insert(pos,_l); pos += (rx.matchedLength()*2)+9; c.insert(pos,"< /a>"); pos += 5; } const QString msg = c; const QString n = a; QString t; if( b == a ) t = tr("[%1] msg from %2: %3").arg(_t).arg(n).arg(msg); else if( a == mNick ) t = tr("[%1] %2: %3").arg(_t).arg(n).arg(msg); else t = tr("[%1] %2: %3").arg(_t).arg(n).arg(msg); QString hi = QString("%1").arg(mNick); t.replace(mNick, hi); QTextCursor cur = irc->textCursor(); cur.movePosition(QTextCursor::End); cur.insertBlock(); cur.insertHtml(t); irc->verticalScrollBar()->triggerAction(QScrollBar::SliderToMaximum); } void dlgIRC::irc_gotMsg2( QString a, QStringList c ) { QString m = c.join(" "); m.replace("<","<"); m.replace(">",">"); const QString _t = QTime::currentTime().toString(); QRegExp rx("(http://[^ ]*)"); QStringList list; int pos = 0; while( (pos = rx.indexIn(m, pos)) != -1) { QString _l = ""); m.insert(pos,_l); pos += (rx.matchedLength()*2)+9; m.insert(pos,"< /a>"); pos += 5; } const QString msg = m; const QString n = a; QString t; if( msg.contains( mNick ) ) t = tr("[%1] %2: %3").arg(_t).arg(n).arg(msg); else t = tr("[%1] %2: %3").arg(_t).arg(n).arg(msg); //QString t = tr("[%1] %2: %3").arg(_t).arg(n).arg(msg); QTextCursor cur = irc->textCursor(); cur.movePosition(QTextCursor::End); cur.insertBlock(); cur.insertHtml(t); irc->verticalScrollBar()->triggerAction(QScrollBar::SliderToMaximum); } void dlgIRC::irc_gotMsg3( QString a, uint code, QStringList c ) { qDebug()<<"code="<",">"); const QString _t = QTime::currentTime().toString(); QRegExp rx("(http://[^ ]*)"); QStringList list; int pos = 0; while( (pos = rx.indexIn(m, pos)) != -1) { QString _l = ""); m.insert(pos,_l); pos += (rx.matchedLength()*2)+9; m.insert(pos,"< /a>"); pos += 5; } const QString msg = m; const QString n = a; QString t = tr("
    INFO: supported commands: /nick and /msg
    CHANNEL TOPIC:: %1").arg(msg); QTextCursor cur = irc->textCursor(); cur.movePosition(QTextCursor::End); cur.insertBlock(); t.replace(mNick, ""); cur.insertHtml(t); } else if( code == 353 && c.size()>=3 ) { QString nicks = c[3]; QStringList nList = nicks.split(" "); nickList->clear(); for( int i=0; iaddItem( nList[i]); } } else if( code == 433 ) { QString m = c.join(" "); if( m.contains( "name is already in use" ) ) { mNick.append("_"); session->setNick( mNick ); irc_gotMsg( "", "", "You have changed your nick." ); } } else if( code = 366 ) return; else { irc_gotMsg2("", c.replaceInStrings(mNick, "") ); } irc->verticalScrollBar()->triggerAction(QScrollBar::SliderToMaximum); } void dlgIRC::slot_joined(QString nick, QString chan ) { const QString _t = QTime::currentTime().toString(); QString t = tr("[%1] %2 has joined the channel.").arg(_t).arg(nick); QTextCursor cur = irc->textCursor(); cur.movePosition(QTextCursor::End); cur.insertBlock(); cur.insertHtml(t); irc->verticalScrollBar()->triggerAction(QScrollBar::SliderToMaximum); nickList->addItem( nick ); } void dlgIRC::slot_parted(QString nick, QString chan, QString msg ) { const QString _t = QTime::currentTime().toString(); QString t = tr("[%1] %2 has left the channel.").arg(_t).arg(nick); QTextCursor cur = irc->textCursor(); cur.movePosition(QTextCursor::End); cur.insertBlock(); cur.insertHtml(t); irc->verticalScrollBar()->triggerAction(QScrollBar::SliderToMaximum); nickList->clear(); session->cmdNames( "#mudlet" ); } void dlgIRC::anchorClicked(const QUrl& link) { QDesktopServices::openUrl(link); } mudlet-2.1/src/TTreeWidgetItem.cpp0000644000175000017500000000645711513237311016470 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "Host.h" #include "HostManager.h" #include "TTreeWidgetItem.h" TTreeWidgetItem::TTreeWidgetItem( TTreeWidgetItem * parent, const QStringList & strings, int type ) : QTreeWidgetItem( (QTreeWidgetItem*)parent, strings, type ) { } TTreeWidgetItem::TTreeWidgetItem( int type ) : QTreeWidgetItem( type ) { } TTreeWidgetItem::TTreeWidgetItem( const QStringList & strings, int type ) : QTreeWidgetItem( strings, type ) { } TTreeWidgetItem::TTreeWidgetItem( TTreeWidget * parent, int type ) : QTreeWidgetItem( (QTreeWidgetItem*)parent, type ) { } TTreeWidgetItem::TTreeWidgetItem( TTreeWidget * parent, const QStringList & strings, int type ) : QTreeWidgetItem( (QTreeWidgetItem*)parent, strings, type ) { } TTreeWidgetItem::TTreeWidgetItem( TTreeWidget * parent, TTreeWidgetItem * preceding, int type ) : QTreeWidgetItem( (QTreeWidgetItem*)parent, (QTreeWidgetItem*)preceding, type ) { } TTreeWidgetItem::TTreeWidgetItem( TTreeWidgetItem * parent, int type ) : QTreeWidgetItem( (QTreeWidgetItem*)parent, type ) { } TTreeWidgetItem::TTreeWidgetItem( TTreeWidgetItem * parent, TTreeWidgetItem * preceding, int type ) : QTreeWidgetItem( (QTreeWidgetItem*)parent, (QTreeWidgetItem*)preceding, type ) { } TTreeWidgetItem::TTreeWidgetItem( const TTreeWidgetItem & other ) : QTreeWidgetItem( other ) { } void TTreeWidgetItem::removeChild( QTreeWidgetItem * child ) { QTreeWidgetItem::removeChild( child ); } void TTreeWidgetItem::addChildren( const QList & children ) { QTreeWidgetItem::addChildren( children ); } void TTreeWidgetItem::addChildren( const QList & children ) { //QTreeWidgetItem::addChildren( children ); } TTreeWidgetItem * TTreeWidgetItem::takeChild ( int index ) { return static_cast(QTreeWidgetItem::takeChild( index )); } void TTreeWidgetItem::addChild( QTreeWidgetItem * child ) { QTreeWidgetItem::addChild( child ); } mudlet-2.1/src/TKey.h0000644000175000017500000001042112070466512013773 0ustar csmallcsmall#ifndef _TKEY_H_ #define _TKEY_H_ /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "Tree.h" #include #include "Host.h" #include class TLuaInterpreter; class TKey : public Tree { friend class XMLexport; friend class XMLimport; public: virtual ~TKey(); TKey( TKey * parent, Host * pHost ); TKey( QString name, Host * pHost ); TKey& clone(const TKey& ); void compileAll(); QString getName() { return mName; } void setName( QString name ) { mName = name; } int getKeyCode() { return mKeyCode; } void setKeyCode( int code ) { mKeyCode = code; } int getKeyModifiers() { return mKeyModifier; } void setKeyModifiers( int code ) { mKeyModifier = code; } void enableKey( QString & name ); void disableKey( QString & name ); void compile(); bool compileScript(); void execute(); QString getScript() { return mScript; } bool setScript( QString & script ); void setCommand( QString command ) { mCommand = command; } QString getCommand() { return mCommand; } bool isFolder() { return mIsFolder; } void setIsFolder( bool b ) { mIsFolder = b; } bool match( int, int ); bool registerKey(); //bool serialize( QDataStream & ); //bool restore( QDataStream & fs, bool ); bool isClone( TKey & ) const; bool exportItem; private: TKey(){}; QString mName; QString mCommand; /*Qt::NoModifier 0x00000000 No modifier key is pressed. Qt::ShiftModifier 0x02000000 A Shift key on the keyboard is pressed. Qt::ControlModifier 0x04000000 A Ctrl key on the keyboard is pressed. Qt::AltModifier 0x08000000 An Alt key on the keyboard is pressed. Qt::MetaModifier 0x10000000 A Meta key on the keyboard is pressed. Qt::KeypadModifier 0x20000000 A keypad button is pressed. */ int mKeyCode; int mKeyModifier; QString mRegexCode; QRegExp mRegex; QString mScript; QString mFuncName; bool mIsFolder; Host * mpHost; bool mNeedsToBeCompiled; bool mModuleMember; bool mModuleMasterFolder; }; #endif mudlet-2.1/src/CMakeLists.txt0000755000175000017500000001452011624306130015506 0ustar csmallcsmallproject (mudlet) CMAKE_MINIMUM_REQUIRED (VERSION 2.6) SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake ${CMAKE_MODULE_PATH}) SET(QT_MIN_VERSION "4.4.0") # we need at least version 4.4 of Qt now SET(QT_USE_QTNETWORK 1) SET(QT_USE_QOPENGL 1) SET(QT_USE_PHONON 1) SET(QT_USE_OPENGL 1) SET(CMAKE_CONFIGURATION_TYPES "Release" "Debug") SET(mudlet_RCCS mudlet_alpha.qrc) SET( mudlet_SRCS TConsole.cpp ctelnet.cpp main.cpp Host.cpp HostManager.cpp HostPool.cpp dlgConnectionProfiles.cpp dlgTriggerEditor.cpp TTrigger.cpp TriggerUnit.cpp TLuaInterpreter.cpp dlgTriggersMainArea.cpp dlgOptionsAreaTriggers.cpp dlgOptionsAreaTimers.cpp dlgOptionsAreaScripts.cpp TCommandLine.cpp TTreeWidget.cpp TTreeWidgetItem.cpp TTimer.cpp TScript.cpp TAlias.cpp dlgTimersMainArea.cpp dlgSystemMessageArea.cpp dlgSourceEditorArea.cpp TimerUnit.cpp ScriptUnit.cpp AliasUnit.cpp dlgScriptsMainArea.cpp dlgAliasMainArea.cpp dlgOptionsAreaAlias.cpp dlgSearchArea.cpp TAction.cpp ActionUnit.cpp dlgActionMainArea.cpp dlgOptionsAreaAction.cpp EAction.cpp dlgAboutDialog.cpp TDebug.cpp dlgKeysMainArea.cpp TKey.cpp KeyUnit.cpp dlgProfilePreferences.cpp TTextEdit.cpp XMLexport.cpp XMLimport.cpp FontManager.cpp TFlipButton.cpp TToolBar.cpp TLabel.cpp TEasyButtonBar.cpp TForkedProcess.cpp dlgColorTrigger.cpp dlgTriggerPatternEdit.cpp TSplitter.cpp TSplitterHandle.cpp mudlet.cpp dlgNotepad.cpp THighlighter.cpp dlgComposer.cpp TArea.cpp glwidget.cpp dlgMapper.cpp TRoom.cpp TMap.cpp TBuffer.cpp T2DMap.cpp dlgRoomExits.cpp lua_yajl.c dlgIrc.cpp ) SET(mudlet_UIS ui/connection_profiles.ui ui/main_window.ui ui/trigger_editor.ui ui/options_area_triggers.ui ui/options_area_timers.ui ui/options_area_aliases.ui ui/options_area_scripts.ui ui/triggers_main_area.ui ui/scripts_main_area.ui ui/aliases_main_area.ui ui/system_message_area.ui ui/source_editor_area.ui ui/extended_search_area.ui ui/actions_main_area.ui ui/options_area_actions.ui ui/timers_main_area.ui ui/about_dialog.ui ui/keybindings_main_area.ui ui/color_trigger.ui ui/notes_editor.ui ui/trigger_pattern_edit.ui ui/composer.ui ui/mapper.ui ui/profile_preferences.ui ui/mapper_room_color.ui ui/room_exits.ui ui/lacking_mapper_script.ui ) SET(mudlet_MOC_HDRS mudlet.h TTimer.h EAction.h TConsole.h ctelnet.h Host.h TMap.h TAStar.h HostManager.h HostPool.h dlgConnectionProfiles.h dlgTriggerEditor.h TTrigger.h TLuaInterpreter.h dlgTriggers_main_area.h dlgOptionsAreaTriggers.h dlgTriggerPatternEdit.h TCommandLine.h TTreeWidget.h TTreeWidgetItem.h TScript.h TAlias.h dlgTimersMainArea.h dlgSourceEditorArea.h dlgSystemMessageArea.h TimerUnit.h ScriptUnit.h AliasUnit.h dlgScriptsMainArea.h dlgAliasMainArea.h dlgOptionsAreaAlias.h dlgOptionsAreaScripts.h dlgOptionsAreaTimers.h dlgSearchArea.h TAction.h ActionUnit.h dlgActionMainArea.h dlgOptionsAreaAction.h dlgAboutDialog.h TMatchState.h TEvent.h TDebug.h dlgKeysMainArea.h TKey.h KeyUnit.h dlgProfilePreferences.h TTextEdit.h TFlipButton.h TToolBar.h TBuffer.h TriggerUnit.h TLabel.h TEasyButtonBar.h TForkedProcess.h dlgColorTrigger.h TSplitter.h TSplitterHandle.h dlgNotepad.h THighlighter.h dlgComposer.h TRoom.h TArea.h TMap.h glwidget.h dlgMapper.h Tree.h T2DMap.h dlgRoomExits.h dlgIrc.h ) FIND_PACKAGE(Qt4 REQUIRED) #FIND_PACKAGE(Lua51 REQUIRED) #FIND_PACKAGE(ZLIB REQUIRED) #FIND_PACKAGE(PCRE REQUIRED) INCLUDE(../MudletCPack.cmake) # Use CPack INCLUDE(${QT_USE_FILE}) INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${mudlet_BINARY_DIR} "C:\\mudlet_package_MSVC\\pcre-8.0-lib\\include" "C:\\mudlet_package_MSVC\\Lua_src\\include" "C:\\mudlet_package_MSVC\\zlib-1.2.5" "c:\\mudlet_package_MSVC\\boost_1_45_0" "c:\\mudlet_package_MSVC\\pcre-8.0-lib\\include" "C:\\mudlet_package_MSVC\\hunspell-1.3.1\\src" "C:\\mudlet_package_MSVC\\lloyd-yajl-f4b2b1a\\yajl-2.0.1\\include" "C:\\mudlet_package_MSVC\\libircclient-qt-0.5.0\\include" ) IF(CMAKE_COMPILER_IS_GNUCXX) ADD_DEFINITIONS(${CMAKE_CXX_FLAGS} "-Wno-deprecated -DUNICODE -D_UNICODE") ENDIF(CMAKE_COMPILER_IS_GNUCXX) QT4_AUTOMOC(${mudlet_SRCS}) QT4_WRAP_UI(mudlet_UIS_H ${mudlet_UIS}) QT4_WRAP_CPP(mudlet_MOC_SRCS ${mudlet_MOC_HDRS}) QT4_ADD_RESOURCES(mudlet_RCC_SRCS ${mudlet_RCCS}) add_executable(mudlet WIN32 ${mudlet_SRCS} ${mudlet_UIS_H} ${mudlet_MOC_SRCS} ${mudlet_RCC_SRCS}) TARGET_LINK_LIBRARIES( mudlet c:\\Qt_VC\\4.7.3\\lib\\qtmain.lib C:\\Qt_VC\\4.7.3\\lib\\QtOpenGL4.lib C:\\Qt_VC\\4.7.3\\lib\\QtCore4.lib C:\\Qt_VC\\4.7.3\\lib\\QtGui4.lib C:\\Qt_VC\\4.7.3\\lib\\QtNetwork4.lib C:\\Qt_VC\\4.7.3\\lib\\QtUiTools.lib C:\\Qt_VC\\4.7.3\\lib\\phonon4.lib c:\\mudlet_package_MSVC\\zlib_125\\zlibwapi.lib C:\\mudlet_package_MSVC\\Lua_src\\lib\\lua51.lib C:\\mudlet_package_MSVC\\pcre-8.12\\Release\\pcre.lib C:\\mudlet_package_MSVC\\hunspell-1.3.1\\src\\win_api\\Release_dll\\libhunspell\\libhunspell.lib "C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\Lib\\OpenGL32.Lib" "C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\Lib\\GlU32.Lib" "C:\\Users\\heiko\\Desktop\\lloyd-yajl-f4b2b1a\\yajl-2.0.1\\lib\\Release\\yajl.lib" "C:\\mudlet_package_MSVC\\libircclient-qt-0.5.0\\lib\\ircclient-qt.lib" ) install( PROGRAMS mudlet DESTINATION "/usr/local/bin" ) install( FILES LuaGlobal.lua mudlet_documentation.html fonts/ttf-bitstream-vera-1.10/COPYRIGHT.TXT fonts/ttf-bitstream-vera-1.10/local.conf fonts/ttf-bitstream-vera-1.10/README.TXT fonts/ttf-bitstream-vera-1.10/RELEASENOTES.TXT fonts/ttf-bitstream-vera-1.10/VeraBd.ttf fonts/ttf-bitstream-vera-1.10/VeraBI.ttf fonts/ttf-bitstream-vera-1.10/VeraIt.ttf fonts/ttf-bitstream-vera-1.10/VeraMoBd.ttf fonts/ttf-bitstream-vera-1.10/VeraMoBI.ttf fonts/ttf-bitstream-vera-1.10/VeraMoIt.ttf fonts/ttf-bitstream-vera-1.10/VeraMono.ttf fonts/ttf-bitstream-vera-1.10/VeraSeBd.ttf fonts/ttf-bitstream-vera-1.10/VeraSe.ttf fonts/ttf-bitstream-vera-1.10/Vera.ttf DESTINATION "/usr/local/share/mudlet" ) mudlet-2.1/src/dlgSystemMessageArea.h0000644000175000017500000000327711513237311017175 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DLG_system_message_area_H #define DLG_system_message_area_H #include "ui_system_message_area.h" #include class dlgSystemMessageArea : public QWidget , public Ui::systemMessageArea { Q_OBJECT public: dlgSystemMessageArea(QWidget*); signals: public slots: }; #endif mudlet-2.1/src/TFlipButton.cpp0000644000175000017500000000526211513237311015665 0ustar csmallcsmall #include #include "TFlipButton.h" #include #include TFlipButton::TFlipButton( TToolBar * parent, TAction * pTAction, int id, Host * pHost ) : QPushButton( 0 ) , mpTAction( pTAction ) , mID( id ) , mpHost( pHost ) { init(); } TFlipButton::TFlipButton( TEasyButtonBar * parent, TAction * pTAction, int id, Host * pHost ) : QPushButton( 0 ) , mpTAction( pTAction ) , mID( id ) , mpHost( pHost ) { init(); } void TFlipButton::init() { mOrientation = Qt::Horizontal; mMirrored = false; } Qt::Orientation TFlipButton::orientation() const { return mOrientation; } void TFlipButton::setOrientation( Qt::Orientation orientation ) { mOrientation = orientation; switch( orientation ) { case Qt::Horizontal: setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ); break; case Qt::Vertical: setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ); break; } } bool TFlipButton::mirrored() const { return mMirrored; } void TFlipButton::setMirrored( bool mirrored ) { mMirrored = mirrored; } QSize TFlipButton::sizeHint() const { QSize size = QPushButton::sizeHint(); if( mOrientation == Qt::Vertical ) { size.transpose(); } return size; } QSize TFlipButton::minimumSizeHint() const { QSize size = QPushButton::minimumSizeHint(); if( mOrientation == Qt::Vertical ) { size.transpose(); } return size; } void TFlipButton::paintEvent( QPaintEvent * event ) { Q_UNUSED( event ); QStylePainter p( this ); switch( mOrientation ) { case Qt::Horizontal: if( mMirrored ) { p.rotate( 180 ); p.translate( -width(), -height() ); } break; case Qt::Vertical: if( mMirrored ) { p.rotate( -90 ); p.translate( -height(), 0 ); } else { p.rotate( 90 ); p.translate( 0, -width() ); } break; } p.drawControl( QStyle::CE_PushButton, getStyleOption() ); } QStyleOptionButton TFlipButton::getStyleOption() const { QStyleOptionButton opt; opt.initFrom( this ); if( mOrientation == Qt::Vertical ) { QSize size = opt.rect.size(); size.transpose(); opt.rect.setSize(size); } opt.features = QStyleOptionButton::None; if( menu() ) opt.features |= QStyleOptionButton::HasMenu; if( isDown() || ( menu() && menu()->isVisible() ) ) opt.state |= QStyle::State_Sunken; if( isChecked() ) opt.state |= QStyle::State_On; opt.text = text(); opt.icon = icon(); opt.iconSize = iconSize(); return opt; } mudlet-2.1/src/THighlighter.cpp0000644000175000017500000001116512020507607016036 0ustar csmallcsmall#include "THighlighter.h" #include THighlighter::THighlighter( QTextDocument *parent ) : QSyntaxHighlighter( parent ) { //isString = false; HighlightingRule rule; keywordFormat.setForeground( Qt::darkBlue ); keywordFormat.setFontWeight( QFont::Bold ); QStringList keywordPatterns; keywordPatterns << "\\btrue\\b" << "\\bfalse\\b" << "\\bnil\\b" << "\\bnot\\b" << "\\band\\b" << "\\bor\\b" << "\\bfunction\\b" << "\\blocal\\b" << "\\end\\b" << "\\bwhile\\b" << "\\bdo\\b" << "\\bif\\b" << "\\bthen\\b" << "\\belse\\b" << "\\bwhile\\b" << "\\brepeat\\b" << "\\bfor\\b" << "\\bpairs\\b" << "\\bipairs\\b" << "\\bin\\b" << "\\buntil\\b" << "\\bbreak\\b" << "\\breturn\\b" << "\\belseif\\b"; foreach( QString pattern, keywordPatterns ) { rule.pattern = QRegExp( pattern ); rule.format = keywordFormat; highlightingRules.append( rule ); } classFormat.setFontWeight( QFont::Bold ); classFormat.setForeground( Qt::darkMagenta ); rule.pattern = QRegExp( "\\bQ[A-Za-z]+\\b" ); rule.format = classFormat; highlightingRules.append( rule ); functionFormat.setFontItalic( false ); functionFormat.setFontWeight( QFont::Bold ); functionFormat.setForeground( Qt::black ); rule.pattern = QRegExp( "\\b[A-Za-z0-9_]+(?=\\()" ); rule.format = functionFormat; highlightingRules.append( rule ); quotationFormat.setForeground( Qt::darkGreen ); rule.pattern = QRegExp( "\"[^\"]*\"" ); rule.format = quotationFormat; highlightingRules.append( rule ); rule.pattern = QRegExp( "\\[\\[[^\\]\\]]*\\]\\]" ); rule.format = quotationFormat; highlightingRules.append( rule ); singleLineCommentFormat.setForeground( Qt::darkGreen ); rule.pattern = QRegExp( "--[^\n]*" );//\\[\\]]*" ); rule.format = singleLineCommentFormat; highlightingRules.append( rule ); multiLineCommentFormat.setForeground( Qt::darkGreen ); stringStart = QRegExp( "\\[\\[" ); stringEnd = QRegExp( "\\]\\]" ); commentStartExpression = QRegExp( "\\[\\[" ); commentEndExpression = QRegExp( "\\]\\]" ); //highlightingRules.append( rule ); searchFormat.setForeground( QColor(0,0,0) ); searchFormat.setBackground( QColor(255,255,0) ); mSearchPattern = "MudletTheMUDClient"; searchFormat.setForeground( QColor(0,0,0) ); searchFormat.setBackground( QColor(255,255,0) ); rule.pattern = QRegExp( mSearchPattern ); rule.format = searchFormat; highlightingRules.append( rule ); } void THighlighter::setSearchPattern( QString p ) { HighlightingRule rule; mSearchPattern = QRegExp::escape( p ); searchFormat.setForeground( QColor(0,0,0) ); searchFormat.setBackground( QColor(255,255,0) ); rule.pattern = QRegExp( mSearchPattern ); rule.pattern.setCaseSensitivity(Qt::CaseInsensitive); rule.format = searchFormat; highlightingRules.last() = rule; } void THighlighter::highlightBlock( const QString & text ) { if( text.size() < 1 ) return; foreach( HighlightingRule rule, highlightingRules ) { QRegExp expression( rule.pattern ); int index = text.indexOf( expression ); while( index >= 0 ) { int length = expression.matchedLength(); setFormat( index, length, rule.format ); index = text.indexOf( expression, index + length ); } } setCurrentBlockState( 0 ); int startIndex = 0; if( previousBlockState() != 1 ) { startIndex = text.indexOf( commentStartExpression ); } while( startIndex >= 0 ) { int endIndex = text.indexOf( commentEndExpression, startIndex ); int commentLength; if( endIndex == -1 ) { setCurrentBlockState( 1 ); commentLength = text.length() - startIndex; } else { commentLength = endIndex - startIndex + 2; } setFormat( startIndex, commentLength, multiLineCommentFormat ); startIndex = text.indexOf( commentStartExpression, startIndex + commentLength ); } QRegExp expression( highlightingRules.last().pattern ); int index = text.indexOf( mSearchPattern, 0, Qt::CaseInsensitive );//expression ); while( index >= 0 ) { int length = mSearchPattern.length();//expression.matchedLength(); setFormat( index, length, highlightingRules.last().format ); //index = text.indexOf( expression, index + length ); index = text.indexOf( mSearchPattern, index + length, Qt::CaseInsensitive ); } } mudlet-2.1/src/dlgTriggerEditor.h0000644000175000017500000003254612070466512016374 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DLGTRIGGEREDITOR_H #define DLGTRIGGEREDITOR_H #include #include "ui_trigger_editor.h" #include #include #include #include #include #include #include "TTrigger.h" #include "TAction.h" //#include //#include #include "dlgTriggersMainArea.h" #include "dlgTimersMainArea.h" #include "dlgSystemMessageArea.h" #include "dlgSourceEditorArea.h" #include "dlgOptionsAreaTriggers.h" #include "dlgSearchArea.h" #include "TTreeWidget.h" #include "TKey.h" //#include "TConsole.h" class dlgTimersMainArea; class dlgSystemMessageArea; class dlgSourceEditorArea; class dlgTriggersMainArea; class dlgActionMainArea; class dlgOptionsAreaTriggers; class dlgSearchArea; class dlgAliasMainArea; class dlgScriptsMainArea; class dlgOptionsAreaAlias; class dlgOptionsAreaScripts; class dlgOptionsAreaTimers; class dlgOptionsAreaAction; class dlgKeysMainArea; class dlgTriggerPatternEdit; class TKey; class TConsole; class dlgTriggerEditor : public QMainWindow , private Ui::trigger_editor { Q_OBJECT public: dlgTriggerEditor( Host * ); void fillout_form(); void closeEvent(QCloseEvent *event); void showError( QString ); void showWarning( QString ); void showInfo( QString ); void focusInEvent( QFocusEvent * ); void focusOutEvent( QFocusEvent * ); void enterEvent( QEvent * pE ); void children_icon_triggers( QTreeWidgetItem * pWidgetItemParent ); void children_icon_alias( QTreeWidgetItem * pWidgetItemParent ); void children_icon_key( QTreeWidgetItem * pWidgetItemParent ); void doCleanReset(); QToolBar * toolBar; QToolBar * toolBar2; bool mNeedUpdateData; TConsole * mpErrorConsole; signals: void signal_establish_connection( QString profile_name ); void accept(); void update(); public slots: void slot_viewErrorsAction(); void slot_cursorPositionChanged(); void slot_set_pattern_type_color( int ); void slot_soundTrigger(); void slot_colorizeTriggerSetBgColor(); void slot_colorizeTriggerSetFgColor(); void slot_itemClicked( QTreeWidgetItem * pItem, int column ); void slot_choseButtonColor(); void slot_export(); void slot_import(); void slot_viewStatsAction(); void slot_debug_mode(); void slot_saveTriggerAfterEdit(); void slot_saveTimerAfterEdit(); void slot_saveScriptAfterEdit(); void slot_saveAliasAfterEdit(); void slot_saveActionAfterEdit(); void slot_saveKeyAfterEdit(); void slot_show_timers(); void slot_show_triggers(); void slot_show_scripts(); void slot_show_aliases(); void slot_show_actions(); void slot_show_keys(); void slot_trigger_clicked( QTreeWidgetItem *pItem, int column ); void slot_timer_clicked( QTreeWidgetItem *pItem, int column ); void slot_scripts_clicked( QTreeWidgetItem *pItem, int column ); void slot_alias_clicked( QTreeWidgetItem *pItem, int column ); void slot_action_clicked( QTreeWidgetItem * pItem, int column ); void slot_key_clicked( QTreeWidgetItem *pItem, int column ); void slot_update(); void slot_deleteProfile(); void slot_connection_dlg_finnished(); void slot_add_new(); void slot_add_new_folder(); void slot_addTrigger(); void slot_addTriggerGroup(); void slot_addTimer(); void recursiveSearchTriggers( TTrigger * pTriggerParent, const QString & ); void recursiveSearchAlias( TAlias * pTriggerParent, const QString & s ); void recursiveSearchScripts( TScript * pTriggerParent, const QString & s ); void recursiveSearchActions( TAction * pTriggerParent, const QString & s ); void recursiveSearchTimers( TTimer * pTriggerParent, const QString & s ); void recursiveSearchKeys( TKey * pTriggerParent, const QString & s ); void slot_addTimerGroup(); void slot_addAlias(); void slot_addAliasGroup(); void slot_addScript(); void slot_addScriptGroup(); void slot_addAction(); void slot_addActionGroup(); void slot_addKey(); void slot_addKeyGroup(); void slot_toggle_active(); void slot_trigger_toggle_active(); void slot_action_toggle_active(); void slot_timer_toggle_active(); void slot_alias_toggle_active(); void slot_script_toggle_active(); void slot_key_toggle_active(); void slot_search_triggers( const QString s ); void slot_item_clicked_search_list(QTreeWidgetItem*, int); void slot_switchToExpertMonde(); void slot_delete_item(); void slot_deleteTrigger(); void slot_deleteTimer(); void slot_deleteAlias(); void slot_deleteScript(); void slot_deleteAction(); void slot_deleteKey(); void slot_save_edit(); void slot_chose_action_icon(); //void slot_trigger_main_area_edit_regex(QListWidgetItem*); //void slot_trigger_main_area_add_regex(); void slot_show_search_area(); //void slot_trigger_main_area_delete_regex(); void slot_script_main_area_delete_handler(); void slot_script_main_area_add_handler(); void slot_script_main_area_edit_handler(QListWidgetItem*); void slot_grab_key(); bool event( QEvent * event ); void grab_key_callback( int key, int modifier ); void slot_profileSaveAction(); void slot_profileSaveAsAction(); void setTBIconSize( int ); void slot_color_trigger_fg(); void slot_color_trigger_bg(); private: void saveOpenChanges(); void saveTrigger(); void saveAlias(); void saveTimer(); void saveKey(); void saveScript(); void saveAction(); void readSettings(); void writeSettings(); void addScript( bool ); void addAlias( bool ); void addTimer( bool isFolder ); void addTrigger( bool isFolder ); void addAction( bool isFolder ); void addKey( bool ); void expand_child_triggers( TTrigger * pTriggerParent, QTreeWidgetItem * pItem ); void expand_child_timers( TTimer * pTimerParent, QTreeWidgetItem * pWidgetItemParent ); void expand_child_scripts( TScript * pTriggerParent, QTreeWidgetItem * pWidgetItemParent ); void expand_child_alias( TAlias *, QTreeWidgetItem * ); void expand_child_action( TAction *, QTreeWidgetItem * ); void expand_child_key( TKey * pTriggerParent, QTreeWidgetItem * pWidgetItemParent ); void exportTrigger( QFile & ); void exportTimer( QFile & ); void exportAlias( QFile & ); void exportAction( QFile & ); void exportScript( QFile & ); void exportKey( QFile & ); QTreeWidgetItem * mCurrentAlias; QTreeWidgetItem * mCurrentTrigger; QTreeWidgetItem * mCurrentTimer; QTreeWidgetItem * mCurrentAction; QTreeWidgetItem * mCurrentScript; QTreeWidgetItem * mCurrentKey; QTreeWidgetItem * mpAliasBaseItem; QTreeWidgetItem * mpTriggerBaseItem; QTreeWidgetItem * mpScriptsBaseItem; QTreeWidgetItem * mpTimerBaseItem; QTreeWidgetItem * mpActionBaseItem; QTreeWidgetItem * mpKeyBaseItem; QTreeWidgetItem * mpCurrentActionItem; QTreeWidgetItem * mpCurrentKeyItem; QTreeWidgetItem * mpCurrentTimerItem; QTreeWidgetItem * mpCurrentScriptItem; QTreeWidgetItem * mpCurrentTriggerItem; QTreeWidgetItem * mpCurrentAliasItem; QLineEdit * mpCursorPositionIndicator; int mCurrentView; static const int cmTriggerView; static const int cmTimerView; static const int cmAliasView; static const int cmScriptView; static const int cmActionView; static const int cmKeysView; QScrollArea * mpScrollArea; QWidget * HpatternList; dlgTriggersMainArea * mpTriggersMainArea; dlgTimersMainArea * mpTimersMainArea; dlgSystemMessageArea * mpSystemMessageArea; dlgSourceEditorArea * mpSourceEditorArea; dlgOptionsAreaTriggers * mpOptionsAreaTriggers; //dlgSearchArea * mpSearchArea; //QTreeWidget * mpSearchArea; dlgAliasMainArea * mpAliasMainArea; dlgActionMainArea * mpActionsMainArea; dlgScriptsMainArea * mpScriptsMainArea; dlgKeysMainArea * mpKeysMainArea; dlgOptionsAreaScripts * mpOptionsAreaScripts; dlgOptionsAreaAction * mpOptionsAreaActions; dlgOptionsAreaAlias * mpOptionsAreaAlias; dlgOptionsAreaTimers * mpOptionsAreaTimers; //bool mIsTriggerMainAreaEditRegex; //QListWidgetItem * mpTriggerMainAreaEditRegexItem; bool mIsScriptsMainAreaEditHandler; QListWidgetItem * mpScriptsMainAreaEditHandlerItem; bool mIsGrabKey; //QsciDocument mDocument; Host * mpHost; QList mTriggerPatternEdit; }; #endif mudlet-2.1/src/dlgProfilePreferences.cpp0000644000175000017500000017257512070466512017746 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include "dlgProfilePreferences.h" #include #include #include #include "Host.h" #include "mudlet.h" #include "TTextEdit.h" dlgProfilePreferences::dlgProfilePreferences( QWidget * pF, Host * pH ) : QDialog( pF ) , mFontSize( 10 ) , mpHost( pH ) { // init generated dialog setupUi(this); mFORCE_MXP_NEGOTIATION_OFF->setChecked(mpHost->mFORCE_MXP_NEGOTIATION_OFF); mMapperUseAntiAlias->setChecked(mpHost->mMapperUseAntiAlias); acceptServerGUI->setChecked(mpHost->mAcceptServerGUI); QString nick = tr("Mudlet%1").arg(QString::number(rand()%10000)); QFile file( QDir::homePath()+"/.config/mudlet/irc_nick" ); file.open( QIODevice::ReadOnly ); QDataStream ifs( & file ); ifs >> nick; file.close(); if( nick.isEmpty() ) nick = tr("Mudlet%1").arg(QString::number(rand()%10000)); ircNick->setText( nick ); dictList->setSelectionMode( QAbstractItemView::SingleSelection ); enableSpellCheck->setChecked( pH->mEnableSpellCheck ); #ifdef Q_OS_LINUX QDir dir( "/usr/share/hunspell/" ); #else QDir dir( "./" ); #endif QStringList entries = dir.entryList( QDir::Files, QDir::Time ); QRegExp rex("\\.dic$"); entries = entries.filter( rex ); for( int i=0; iaddItem( item ); if( entries[i] == mpHost->mSpellDic ) { item->setSelected( true ); } } if( pH->mUrl.toLower().contains("achaea.com") || pH->mUrl.toLower().contains("aetolia.com") || pH->mUrl.toLower().contains("imperian.com") || pH->mUrl.toLower().contains("midkemiaonline.com") || pH->mUrl.toLower().contains("lusternia.com") ) { downloadMapOptions->setVisible( true ); connect(buttonDownloadMap, SIGNAL(clicked()), this, SLOT(downloadMap())); } else downloadMapOptions->setVisible( false ); connect(closeButton, SIGNAL(pressed()), this, SLOT(slot_save_and_exit())); connect(pushButton_black, SIGNAL(clicked()), this, SLOT(setColorBlack())); QPalette palette; QString styleSheet; QColor color; color = mpHost->mCommandLineFgColor; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_command_line_foreground_color->setStyleSheet( styleSheet ); connect(pushButton_command_line_foreground_color, SIGNAL(clicked()), this, SLOT(setCommandLineFgColor())); color = mpHost->mCommandLineBgColor; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_command_line_background_color->setStyleSheet( styleSheet ); connect(pushButton_command_line_background_color, SIGNAL(clicked()), this, SLOT(setCommandLineBgColor())); color = mpHost->mBlack; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_black->setStyleSheet( styleSheet ); connect(pushButton_Lblack, SIGNAL(clicked()), this, SLOT(setColorLightBlack())); color = mpHost->mLightBlack; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblack->setStyleSheet( styleSheet ); connect(pushButton_green, SIGNAL(clicked()), this, SLOT(setColorGreen())); color = mpHost->mGreen; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_green->setStyleSheet( styleSheet ); connect(pushButton_Lgreen, SIGNAL(clicked()), this, SLOT(setColorLightGreen())); color = mpHost->mLightGreen; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lgreen->setStyleSheet( styleSheet ); connect(pushButton_red, SIGNAL(clicked()), this, SLOT(setColorRed())); color = mpHost->mRed; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_red->setStyleSheet( styleSheet ); connect(pushButton_Lred, SIGNAL(clicked()), this, SLOT(setColorLightRed())); color = mpHost->mLightRed; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lred->setStyleSheet( styleSheet ); connect(pushButton_blue, SIGNAL(clicked()), this, SLOT(setColorBlue())); color = mpHost->mBlue; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_blue->setStyleSheet( styleSheet ); connect(pushButton_Lblue, SIGNAL(clicked()), this, SLOT(setColorLightBlue())); color = mpHost->mLightBlue; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblue->setStyleSheet( styleSheet ); connect(pushButton_yellow, SIGNAL(clicked()), this, SLOT(setColorYellow())); color = mpHost->mYellow; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_yellow->setStyleSheet( styleSheet ); connect(pushButton_Lyellow, SIGNAL(clicked()), this, SLOT(setColorLightYellow())); color = mpHost->mLightYellow; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lyellow->setStyleSheet( styleSheet ); connect(pushButton_cyan, SIGNAL(clicked()), this, SLOT(setColorCyan())); color = mpHost->mCyan; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_cyan->setStyleSheet( styleSheet ); connect(pushButton_Lcyan, SIGNAL(clicked()), this, SLOT(setColorLightCyan())); color = mpHost->mLightCyan; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lcyan->setStyleSheet( styleSheet ); connect(pushButton_magenta, SIGNAL(clicked()), this, SLOT(setColorMagenta())); color = mpHost->mMagenta; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_magenta->setStyleSheet( styleSheet ); connect(pushButton_Lmagenta, SIGNAL(clicked()), this, SLOT(setColorLightMagenta())); color = mpHost->mLightMagenta; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lmagenta->setStyleSheet( styleSheet ); connect(pushButton_white, SIGNAL(clicked()), this, SLOT(setColorWhite())); color = mpHost->mWhite; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_white->setStyleSheet( styleSheet ); connect(pushButton_Lwhite, SIGNAL(clicked()), this, SLOT(setColorLightWhite())); color = mpHost->mLightWhite; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lwhite->setStyleSheet( styleSheet ); connect(pushButton_foreground_color, SIGNAL(clicked()), this, SLOT(setFgColor())); color = mpHost->mFgColor; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_foreground_color->setStyleSheet( styleSheet ); connect(pushButton_background_color, SIGNAL(clicked()), this, SLOT(setBgColor())); color = mpHost->mBgColor; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_background_color->setStyleSheet( styleSheet ); connect(pushButton_command_foreground_color, SIGNAL(clicked()), this, SLOT(setCommandFgColor())); color = mpHost->mCommandFgColor; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_command_foreground_color->setStyleSheet( styleSheet ); connect(pushButton_command_background_color, SIGNAL(clicked()), this, SLOT(setCommandBgColor())); color = mpHost->mCommandBgColor; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_command_background_color->setStyleSheet( styleSheet ); connect(reset_colors_button, SIGNAL(clicked()), this, SLOT(resetColors())); connect(fontComboBox, SIGNAL( currentFontChanged( const QFont & ) ), this, SLOT(setDisplayFont())); QStringList sizeList; for( int i=1; i<40; i++ ) sizeList << QString::number(i); fontSize->insertItems( 1, sizeList ); connect(fontSize, SIGNAL(currentIndexChanged(int)), this, SLOT(setFontSize())); //connect(pushButton_command_line_font, SIGNAL(clicked()), this, SLOT(setCommandLineFont())); connect(pushButtonBorderColor, SIGNAL(clicked()), this, SLOT(setBorderColor())); connect(pushButtonBorderImage, SIGNAL(clicked()), this, SLOT(setBorderImage())); color = mpHost->mBlack_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_black_2->setStyleSheet( styleSheet ); connect(pushButton_black_2, SIGNAL(clicked()), this, SLOT(setColorBlack2())); connect(pushButton_Lblack_2, SIGNAL(clicked()), this, SLOT(setColorLightBlack2())); color = mpHost->mLightBlack_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblack_2->setStyleSheet( styleSheet ); connect(pushButton_green_2, SIGNAL(clicked()), this, SLOT(setColorGreen2())); color = mpHost->mGreen_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_green_2->setStyleSheet( styleSheet ); connect(pushButton_Lgreen_2, SIGNAL(clicked()), this, SLOT(setColorLightGreen2())); color = mpHost->mLightGreen_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lgreen_2->setStyleSheet( styleSheet ); connect(pushButton_red_2, SIGNAL(clicked()), this, SLOT(setColorRed2())); color = mpHost->mRed_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_red_2->setStyleSheet( styleSheet ); connect(pushButton_Lred_2, SIGNAL(clicked()), this, SLOT(setColorLightRed2())); color = mpHost->mLightRed_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lred_2->setStyleSheet( styleSheet ); connect(pushButton_blue_2, SIGNAL(clicked()), this, SLOT(setColorBlue2())); color = mpHost->mBlue_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_blue_2->setStyleSheet( styleSheet ); connect(pushButton_Lblue_2, SIGNAL(clicked()), this, SLOT(setColorLightBlue2())); color = mpHost->mLightBlue_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblue_2->setStyleSheet( styleSheet ); connect(pushButton_yellow_2, SIGNAL(clicked()), this, SLOT(setColorYellow2())); color = mpHost->mYellow_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_yellow_2->setStyleSheet( styleSheet ); connect(pushButton_Lyellow_2, SIGNAL(clicked()), this, SLOT(setColorLightYellow2())); color = mpHost->mLightYellow_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lyellow_2->setStyleSheet( styleSheet ); connect(pushButton_cyan_2, SIGNAL(clicked()), this, SLOT(setColorCyan2())); color = mpHost->mCyan_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_cyan_2->setStyleSheet( styleSheet ); connect(pushButton_Lcyan_2, SIGNAL(clicked()), this, SLOT(setColorLightCyan2())); color = mpHost->mLightCyan_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lcyan_2->setStyleSheet( styleSheet ); connect(pushButton_magenta_2, SIGNAL(clicked()), this, SLOT(setColorMagenta2())); color = mpHost->mMagenta_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_magenta_2->setStyleSheet( styleSheet ); connect(pushButton_Lmagenta_2, SIGNAL(clicked()), this, SLOT(setColorLightMagenta2())); color = mpHost->mLightMagenta_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lmagenta_2->setStyleSheet( styleSheet ); connect(pushButton_white_2, SIGNAL(clicked()), this, SLOT(setColorWhite2())); color = mpHost->mWhite_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_white_2->setStyleSheet( styleSheet ); connect(pushButton_Lwhite_2, SIGNAL(clicked()), this, SLOT(setColorLightWhite2())); color = mpHost->mLightWhite_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lwhite_2->setStyleSheet( styleSheet ); connect(pushButton_foreground_color_2, SIGNAL(clicked()), this, SLOT(setFgColor2())); color = mpHost->mFgColor_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_foreground_color_2->setStyleSheet( styleSheet ); connect(pushButton_background_color_2, SIGNAL(clicked()), this, SLOT(setBgColor2())); color = mpHost->mBgColor_2; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_background_color_2->setStyleSheet( styleSheet ); // the GMCP warning is hidden by default and is only enabled when the value is toggled need_reconnect_for_gmcp->hide(); connect(mEnableGMCP, SIGNAL(clicked()), need_reconnect_for_gmcp, SLOT(show())); // same with special connection warnings need_reconnect_for_specialoption->hide(); connect(mFORCE_MCCP_OFF, SIGNAL(clicked()), need_reconnect_for_specialoption, SLOT(show())); connect(mFORCE_GA_OFF, SIGNAL(clicked()), need_reconnect_for_specialoption, SLOT(show())); Host * pHost = mpHost; if( pHost ) { mFontSize = pHost->mDisplayFont.pointSize(); fontComboBox->setCurrentFont( pHost->mDisplayFont ); if( mFontSize < 0 ) { mFontSize = 10; } if( mFontSize <= 40 ) fontSize->setCurrentIndex( mFontSize ); setColors(); wrap_at_spinBox->setValue(pHost->mWrapAt); indent_wrapped_spinBox->setValue(pHost->mWrapIndentCount); show_sent_text_checkbox->setChecked(pHost->mPrintCommand); auto_clear_input_line_checkbox->setChecked(pHost->mAutoClearCommandLineAfterSend); command_separator_lineedit->setText( pHost->mCommandSeparator); //disable_auto_completion_checkbox->setChecked(pHost->mDisableAutoCompletion); checkBox_USE_IRE_DRIVER_BUGFIX->setChecked( pHost->mUSE_IRE_DRIVER_BUGFIX ); //this option is changed into a forced option for GA enabled drivers as triggers wont run on prompt lines otherwise //checkBox_LF_ON_GA->setChecked( pHost->mLF_ON_GA ); checkBox_mUSE_FORCE_LF_AFTER_PROMPT->setChecked( pHost->mUSE_FORCE_LF_AFTER_PROMPT ); USE_UNIX_EOL->setChecked( pHost->mUSE_UNIX_EOL ); QFile file_use_smallscreen( QDir::homePath()+"/.config/mudlet/mudlet_option_use_smallscreen" ); if( file_use_smallscreen.exists() ) checkBox_USE_SMALL_SCREEN->setChecked( true ); else checkBox_USE_SMALL_SCREEN->setChecked( false ); topBorderHeight->setValue(pHost->mBorderTopHeight); bottomBorderHeight->setValue(pHost->mBorderBottomHeight); leftBorderWidth->setValue(pHost->mBorderLeftWidth); qDebug()<<"loading: left border width:"<mBorderLeftWidth; rightBorderWidth->setValue(pHost->mBorderRightWidth); MainIconSize->setValue(mudlet::self()->mMainIconSize); TEFolderIconSize->setValue(mudlet::self()->mTEFolderIconSize); showMenuBar->setChecked( mudlet::self()->mShowMenuBar ); if( ! showMenuBar->isChecked() ) showToolbar->setChecked( true ); else showToolbar->setChecked( mudlet::self()->mShowToolbar ); mRawStreamDump->setChecked( pHost->mRawStreamDump ); commandLineMinimumHeight->setValue( pHost->commandLineMinimumHeight ); mNoAntiAlias->setChecked( ! pHost->mNoAntiAlias ); mFORCE_MCCP_OFF->setChecked( pHost->mFORCE_NO_COMPRESSION ); mFORCE_GA_OFF->setChecked( pHost->mFORCE_GA_OFF ); mAlertOnNewData->setChecked( pHost->mAlertOnNewData ); //mMXPMode->setCurrentIndex( pHost->mMXPMode ); //encoding->setCurrentIndex( pHost->mEncoding ); mFORCE_SAVE_ON_EXIT->setChecked( pHost->mFORCE_SAVE_ON_EXIT ); mEnableGMCP->setChecked( pHost->mEnableGMCP ); // load profiles into mappers "copy map to profile" combobox // this feature should worm seamlessly both for online and offline profiles QStringList mProfileList = QDir(QDir::homePath()+"/.config/mudlet/profiles").entryList(QDir::Dirs, QDir::Time); // sort by profile "hotness" for( int i=0; iaddItem( mProfileList[i] ); } connect(copy_map_profile, SIGNAL(clicked()), this, SLOT(copyMap())); // label to show on sucessful map file action map_file_action->hide(); connect(load_map_button, SIGNAL(clicked()), this, SLOT(loadMap())); connect(save_map_button, SIGNAL(clicked()), this, SLOT(saveMap())); } } void dlgProfilePreferences::setColors() { Host * pHost = mpHost; if( ! pHost ) return; QString styleSheet; QPalette palette; QColor color; color = pHost->mFgColor; palette.setColor( QPalette::Button, color ); pushButton_foreground_color->setPalette( palette ); color = mpHost->mFgColor; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_foreground_color->setStyleSheet( styleSheet ); color = pHost->mBgColor; palette.setColor( QPalette::Button, color ); pushButton_background_color->setPalette( palette ); color = mpHost->mBgColor; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_background_color->setStyleSheet( styleSheet ); color = pHost->mBlack; palette.setColor( QPalette::Button, color ); pushButton_black->setPalette( palette ); color = mpHost->mBlack; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_black->setStyleSheet( styleSheet ); color = pHost->mLightBlack; palette.setColor( QPalette::Button, color ); pushButton_Lblack->setPalette( palette ); color = mpHost->mLightBlack; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblack->setStyleSheet( styleSheet ); color = pHost->mRed; palette.setColor( QPalette::Button, color ); pushButton_red->setPalette( palette ); color = mpHost->mRed; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_red->setStyleSheet( styleSheet ); color = pHost->mLightRed; palette.setColor( QPalette::Button, color ); pushButton_Lred->setPalette( palette ); color = mpHost->mLightRed; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lred->setStyleSheet( styleSheet ); color = pHost->mGreen; palette.setColor( QPalette::Button, color ); pushButton_green->setPalette( palette ); color = mpHost->mGreen; palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_green->setStyleSheet( styleSheet ); color = pHost->mLightGreen; palette.setColor( QPalette::Button, color ); pushButton_Lgreen->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lgreen->setStyleSheet( styleSheet ); color = pHost->mBlue; palette.setColor( QPalette::Button, color ); pushButton_blue->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_blue->setStyleSheet( styleSheet ); color = pHost->mLightBlue; palette.setColor( QPalette::Button, color ); pushButton_Lblue->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblue->setStyleSheet( styleSheet ); color = pHost->mYellow; palette.setColor( QPalette::Button, color ); pushButton_yellow->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_yellow->setStyleSheet( styleSheet ); color = pHost->mLightYellow; palette.setColor( QPalette::Button, color ); pushButton_Lyellow->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lyellow->setStyleSheet( styleSheet ); color = pHost->mCyan; palette.setColor( QPalette::Button, color ); pushButton_cyan->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_cyan->setStyleSheet( styleSheet ); color = pHost->mLightCyan; palette.setColor( QPalette::Button, color ); pushButton_Lcyan->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lcyan->setStyleSheet( styleSheet ); color = pHost->mMagenta; palette.setColor( QPalette::Button, color ); pushButton_magenta->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_magenta->setStyleSheet( styleSheet ); color = pHost->mLightMagenta; palette.setColor( QPalette::Button, color ); pushButton_Lmagenta->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lmagenta->setStyleSheet( styleSheet ); color = pHost->mWhite; palette.setColor( QPalette::Button, color ); pushButton_white->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_white->setStyleSheet( styleSheet ); color = pHost->mLightWhite; palette.setColor( QPalette::Button, color ); pushButton_Lwhite->setPalette( palette ); palette.setColor( QPalette::Button, color ); styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lwhite->setStyleSheet( styleSheet ); } void dlgProfilePreferences::resetColors() { Host * pHost = mpHost; if( ! pHost ) return; pHost->mFgColor = QColor(255,255,255); pHost->mBgColor = QColor( 0, 0, 0); pHost->mBlack = QColor( 0, 0, 0); pHost->mLightBlack = QColor(128,128,128); pHost->mRed = QColor(128, 0, 0); pHost->mLightRed = QColor(255, 0, 0); pHost->mGreen = QColor( 0,179, 0); pHost->mLightGreen = QColor( 0,255 ,0); pHost->mBlue = QColor( 0, 0,128); pHost->mLightBlue = QColor( 0, 0,255); pHost->mYellow = QColor(128,128, 0); pHost->mLightYellow = QColor(255,255, 0); pHost->mCyan = QColor( 0,128,128); pHost->mLightCyan = QColor( 0,255,255); pHost->mMagenta = QColor(128, 0,128); pHost->mLightMagenta = QColor(255, 0,255); pHost->mWhite = QColor(192,192,192); pHost->mLightWhite = QColor(255,255,255); setColors(); if( mudlet::self()->mConsoleMap.contains( pHost ) ) { mudlet::self()->mConsoleMap[pHost]->changeColors(); } } void dlgProfilePreferences::setFgColor() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mFgColor, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_foreground_color->setPalette( palette ); pHost->mFgColor = color; if( mudlet::self()->mConsoleMap.contains( pHost ) ) mudlet::self()->mConsoleMap[pHost]->changeColors(); color = mpHost->mFgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_foreground_color->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setBgColor() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mBgColor, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_background_color->setPalette( palette ); pHost->mBgColor = color; if( mudlet::self()->mConsoleMap.contains( pHost ) ) mudlet::self()->mConsoleMap[pHost]->changeColors(); color = mpHost->mBgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_background_color->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setCommandFgColor() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mCommandFgColor, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_command_foreground_color->setPalette( palette ); pHost->mCommandFgColor = color; if( mudlet::self()->mConsoleMap.contains( pHost ) ) mudlet::self()->mConsoleMap[pHost]->changeColors(); color = mpHost->mCommandFgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_command_foreground_color->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setCommandLineFgColor() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mCommandLineFgColor, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_command_line_foreground_color->setPalette( palette ); pHost->mCommandLineFgColor = color; if( mudlet::self()->mConsoleMap.contains( pHost ) ) mudlet::self()->mConsoleMap[pHost]->changeColors(); color = mpHost->mCommandLineFgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_command_line_foreground_color->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setCommandLineBgColor() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mCommandLineBgColor, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_command_line_background_color->setPalette( palette ); pHost->mCommandLineBgColor = color; if( mudlet::self()->mConsoleMap.contains( pHost ) ) mudlet::self()->mConsoleMap[pHost]->changeColors(); color = mpHost->mCommandLineBgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_command_line_background_color->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setCommandBgColor() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mCommandBgColor, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_command_background_color->setPalette( palette ); pHost->mCommandBgColor = color; if( mudlet::self()->mConsoleMap.contains( pHost ) ) mudlet::self()->mConsoleMap[pHost]->changeColors(); color = mpHost->mCommandBgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_command_background_color->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setFontSize() { mFontSize = fontSize->currentIndex(); setDisplayFont(); } void dlgProfilePreferences::setDisplayFont() { Host * pHost = mpHost; if( ! pHost ) return; QFont font = fontComboBox->currentFont(); font.setPointSize( mFontSize ); pHost->mDisplayFont = font; if( mudlet::self()->mConsoleMap.contains( pHost ) ) { mudlet::self()->mConsoleMap[pHost]->changeColors(); } } void dlgProfilePreferences::setCommandLineFont() { Host * pHost = mpHost; if( ! pHost ) return; bool ok; QFont font = QFontDialog::getFont( &ok, pHost->mCommandLineFont, this ); pHost->mCommandLineFont = font; if( mudlet::self()->mConsoleMap.contains( pHost ) ) { mudlet::self()->mConsoleMap[pHost]->changeColors(); } } void dlgProfilePreferences::setColorBlack() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mBlack, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_black->setPalette( palette ); pHost->mBlack = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_black->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightBlack() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightBlack, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lblack->setPalette( palette ); pHost->mLightBlack = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblack->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorRed() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mRed, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_red->setPalette( palette ); pHost->mRed = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_red->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightRed() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightRed, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lred->setPalette( palette ); pHost->mLightRed = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lred->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorGreen() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mGreen, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_green->setPalette( palette ); pHost->mGreen = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_green->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightGreen() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightGreen, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lgreen->setPalette( palette ); pHost->mLightGreen = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lgreen->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorBlue() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mBlue, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_blue->setPalette( palette ); pHost->mBlue = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_blue->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightBlue() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightBlue, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lblue->setPalette( palette ); pHost->mLightBlue = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblue->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorYellow() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mYellow, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_yellow->setPalette( palette ); pHost->mYellow = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_yellow->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightYellow() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightYellow, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lyellow->setPalette( palette ); pHost->mLightYellow = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lyellow->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorCyan() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mCyan, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_cyan->setPalette( palette ); pHost->mCyan = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_cyan->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightCyan() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightCyan, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lcyan->setPalette( palette ); pHost->mLightCyan = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lcyan->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorMagenta() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mMagenta, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_magenta->setPalette( palette ); pHost->mMagenta = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_magenta->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightMagenta() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightMagenta, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lmagenta->setPalette( palette ); pHost->mLightMagenta = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lmagenta->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorWhite() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mWhite, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_white->setPalette( palette ); pHost->mWhite = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_white->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightWhite() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightWhite, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lwhite->setPalette( palette ); pHost->mLightWhite = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lwhite->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setFgColor2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mFgColor_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_foreground_color_2->setPalette( palette ); pHost->mFgColor_2 = color; color = mpHost->mFgColor_2; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_foreground_color_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setBgColor2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mBgColor_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_background_color_2->setPalette( palette ); pHost->mBgColor_2 = color; color = mpHost->mBgColor_2; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_background_color_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorBlack2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mBlack_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_black_2->setPalette( palette ); pHost->mBlack_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_black_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightBlack2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightBlack_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lblack_2->setPalette( palette ); pHost->mLightBlack_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblack_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorRed2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mRed_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_red_2->setPalette( palette ); pHost->mRed_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_red_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightRed2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightRed_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lred_2->setPalette( palette ); pHost->mLightRed_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lred_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorGreen2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mGreen_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_green_2->setPalette( palette ); pHost->mGreen_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_green_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightGreen2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightGreen_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lgreen_2->setPalette( palette ); pHost->mLightGreen_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lgreen_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorBlue2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mBlue_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_blue_2->setPalette( palette ); pHost->mBlue_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_blue_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightBlue2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightBlue_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lblue_2->setPalette( palette ); pHost->mLightBlue_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lblue_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorYellow2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mYellow_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_yellow_2->setPalette( palette ); pHost->mYellow_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_yellow_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightYellow2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightYellow_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lyellow_2->setPalette( palette ); pHost->mLightYellow_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lyellow_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorCyan2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mCyan_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_cyan_2->setPalette( palette ); pHost->mCyan_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_cyan_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightCyan2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightCyan_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lcyan_2->setPalette( palette ); pHost->mLightCyan_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lcyan_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorMagenta2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mMagenta_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_magenta_2->setPalette( palette ); pHost->mMagenta_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_magenta_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightMagenta2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightMagenta_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lmagenta_2->setPalette( palette ); pHost->mLightMagenta_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lmagenta_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorWhite2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mWhite_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_white_2->setPalette( palette ); pHost->mWhite_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_white_2->setStyleSheet( styleSheet ); } } void dlgProfilePreferences::setColorLightWhite2() { Host * pHost = mpHost; if( ! pHost ) return; QColor color = QColorDialog::getColor( pHost->mLightWhite_2, this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); pushButton_Lwhite_2->setPalette( palette ); pHost->mLightWhite_2 = color; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); pushButton_Lwhite_2->setStyleSheet( styleSheet ); } } #include "dlgMapper.h" void dlgProfilePreferences::downloadMap() { if( ! mpHost->mpMap->mpMapper ) mudlet::self()->slot_mapper(); mpHost->mpMap->mpMapper->downloadMap(); } #include void dlgProfilePreferences::loadMap() { Host * pHost = mpHost; if( ! pHost ) return; QString fileName = QFileDialog::getOpenFileName(this, tr("Load Mudlet map"), QDir::homePath(), "Mudlet map (*.dat);;Any file (*)"); if( fileName.isEmpty() ) return; map_file_action->show(); map_file_action->setText("Loading map..."); if ( mpHost->mpConsole->loadMap(fileName) ) { map_file_action->setText("Loaded map from "+fileName); QTimer::singleShot(10*1000, this, SLOT(hideActionLabel())); } else { map_file_action->setText("Couldn't load map from "+fileName); QTimer::singleShot(10*1000, this, SLOT(hideActionLabel())); } if( mpHost->mpMap ) if( mpHost->mpMap->mpMapper ) mpHost->mpMap->mpMapper->updateAreaComboBox(); } void dlgProfilePreferences::saveMap() { Host * pHost = mpHost; if( ! pHost ) return; QString fileName = QFileDialog::getSaveFileName(this, tr("Save Mudlet map"), QDir::homePath(), "Mudlet map (*.dat)"); if( fileName.isEmpty() ) return; if ( ! fileName.endsWith(".dat", Qt::CaseInsensitive) ) fileName.append(".dat"); map_file_action->show(); map_file_action->setText("Saving map..."); if ( mpHost->mpConsole->saveMap(fileName) ) { map_file_action->setText("Saved map to "+fileName); QTimer::singleShot(10*1000, this, SLOT(hideActionLabel())); } else { map_file_action->setText("Couldn't save map to "+fileName); QTimer::singleShot(10*1000, this, SLOT(hideActionLabel())); } } void dlgProfilePreferences::hideActionLabel() { map_file_action->hide(); } void dlgProfilePreferences::copyMap() { Host * pHost = mpHost; if( ! pHost ) return; QString toProfile = mapper_profiles_combobox->itemText(mapper_profiles_combobox->currentIndex()); // at first, save our current map map_file_action->show(); map_file_action->setText("Copying map..."); if ( ! mpHost->mpConsole->saveMap("") ) { map_file_action->setText("Couldn't copy the map - saving it failed."); QTimer::singleShot(10*1000, this, SLOT(hideActionLabel())); return; } // then copy over into the profiles map folder, so it is loaded first when map is open - this covers the offline case QDir dir_map; QString directory_map = QDir::homePath()+"/.config/mudlet/profiles/"+toProfile+"/map"; if( ! dir_map.exists( directory_map ) ) { dir_map.mkpath( directory_map ); } // work out which map is latest QFile latestMap; QString toMapFolder(QDir::homePath()+"/.config/mudlet/profiles/"+pHost->getName()+"/map"); QStringList mProfileList = QDir(toMapFolder).entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Time); for( int i=0; isetText("Couldn't copy the map - failed to work out which map file did we just save the map as."); QTimer::singleShot(10*1000, this, SLOT(hideActionLabel())); return; } QFileInfo lm(latestMap.fileName()); if ( !latestMap.copy(directory_map+"/"+lm.fileName()) ) { map_file_action->setText("Couldn't copy the map - couldn't copy the offline map file over."); QTimer::singleShot(10*1000, this, SLOT(hideActionLabel())); return; } map_file_action->setText("Map copied successfully."); // don't mention offline here, would be a bit confusing // then force that profile to reload it's latest map - this covers the online case QMap activeSessions = mudlet::self()->mConsoleMap; QMapIterator it2(activeSessions); while (it2.hasNext()){ it2.next(); Host * host = it2.key(); if (host->mHostName != toProfile) continue; if ( host->mpConsole->loadMap(directory_map+"/"+lm.fileName()) ) { map_file_action->setText("Map copied and reloaded on "+toProfile+"."); QTimer::singleShot(10*1000, this, SLOT(hideActionLabel())); } else { map_file_action->setText("Map copied, but couldn't be reloaded on "+toProfile+"."); QTimer::singleShot(10*1000, this, SLOT(hideActionLabel())); } return; } } #include "dlgIRC.h" void dlgProfilePreferences::slot_save_and_exit() { Host * pHost = mpHost; if( ! pHost ) return; if( dictList->currentItem() ) pHost->mSpellDic = dictList->currentItem()->text(); pHost->mEnableSpellCheck = enableSpellCheck->isChecked(); pHost->mWrapAt = wrap_at_spinBox->value(); pHost->mWrapIndentCount = indent_wrapped_spinBox->value(); pHost->mPrintCommand = show_sent_text_checkbox->isChecked(); pHost->mAutoClearCommandLineAfterSend = auto_clear_input_line_checkbox->isChecked(); pHost->mCommandSeparator = command_separator_lineedit->text(); pHost->mAcceptServerGUI = acceptServerGUI->isChecked(); //pHost->mDisableAutoCompletion = disable_auto_completion_checkbox->isChecked(); pHost->mUSE_IRE_DRIVER_BUGFIX = checkBox_USE_IRE_DRIVER_BUGFIX->isChecked(); pHost->set_USE_IRE_DRIVER_BUGFIX( checkBox_USE_IRE_DRIVER_BUGFIX->isChecked() ); //pHost->set_LF_ON_GA( checkBox_LF_ON_GA->isChecked() ); pHost->mUSE_FORCE_LF_AFTER_PROMPT = checkBox_mUSE_FORCE_LF_AFTER_PROMPT->isChecked(); pHost->mUSE_UNIX_EOL = USE_UNIX_EOL->isChecked(); pHost->mFORCE_NO_COMPRESSION = mFORCE_MCCP_OFF->isChecked(); pHost->mFORCE_GA_OFF = mFORCE_GA_OFF->isChecked(); pHost->mFORCE_SAVE_ON_EXIT = mFORCE_SAVE_ON_EXIT->isChecked(); pHost->mEnableGMCP = mEnableGMCP->isChecked(); pHost->mMapperUseAntiAlias = mMapperUseAntiAlias->isChecked(); if( pHost->mpMap ) if( pHost->mpMap->mpMapper ) pHost->mpMap->mpMapper->mp2dMap->mMapperUseAntiAlias = mMapperUseAntiAlias->isChecked(); pHost->mBorderTopHeight = topBorderHeight->value(); pHost->mBorderBottomHeight = bottomBorderHeight->value(); pHost->mBorderLeftWidth = leftBorderWidth->value(); pHost->mBorderRightWidth = rightBorderWidth->value(); qDebug()<<"Left border width:"<mBorderLeftWidth<<" right:"<mBorderRightWidth; pHost->commandLineMinimumHeight = commandLineMinimumHeight->value(); //pHost->mMXPMode = mMXPMode->currentIndex(); //pHost->mEncoding = encoding->currentIndex(); pHost->mFORCE_MXP_NEGOTIATION_OFF = mFORCE_MXP_NEGOTIATION_OFF->isChecked(); mudlet::self()->mMainIconSize = MainIconSize->value(); mudlet::self()->mTEFolderIconSize = TEFolderIconSize->value(); mudlet::self()->setIcoSize(MainIconSize->value()); pHost->mpEditorDialog->setTBIconSize( 0 ); mudlet::self()->mShowMenuBar = showMenuBar->isChecked(); if( showMenuBar->isChecked() ) mudlet::self()->menuBar()->show(); else mudlet::self()->menuBar()->hide(); mudlet::self()->mShowToolbar = showToolbar->isChecked(); if( showToolbar->isChecked() ) mudlet::self()->mpMainToolBar->show(); else mudlet::self()->mpMainToolBar->hide(); pHost->mRawStreamDump = mRawStreamDump->isChecked(); pHost->mNoAntiAlias = !mNoAntiAlias->isChecked(); pHost->mAlertOnNewData = mAlertOnNewData->isChecked(); pHost->mpConsole->changeColors(); //pHost->mIRCNick = ircNick->text(); QString old_nick = mudlet::self()->mIrcNick; QString new_nick = ircNick->text(); if( new_nick.isEmpty() ) new_nick = tr("Mudlet%1").arg(QString::number(rand()%10000)); QFile file( QDir::homePath()+"/.config/mudlet/irc_nick" ); file.open( QIODevice::WriteOnly | QIODevice::Unbuffered ); QDataStream ofs( & file ); ofs << new_nick; file.close(); if( mudlet::self()->mpIRC ) mudlet::self()->mpIRC->session->setNick( new_nick ); if( checkBox_USE_SMALL_SCREEN->isChecked() ) { QFile file_use_smallscreen( QDir::homePath()+"/.config/mudlet/mudlet_option_use_smallscreen" ); file_use_smallscreen.open( QIODevice::WriteOnly | QIODevice::Text ); QTextStream out(&file_use_smallscreen); file_use_smallscreen.close(); } else { QFile file_use_smallscreen( QDir::homePath()+"/.config/mudlet/mudlet_option_use_smallscreen" ); file_use_smallscreen.remove(); } pHost->mpConsole->console->updateScreenView(); pHost->mpConsole->console->forceUpdate(); pHost->mpConsole->refresh(); int x = pHost->mpConsole->width(); int y = pHost->mpConsole->height(); QSize s = QSize(x,y); QResizeEvent event(s, s); QApplication::sendEvent( pHost->mpConsole, &event); qDebug()<<"after console refresh: Left border width:"<mBorderLeftWidth<<" right:"<mBorderRightWidth; close(); } mudlet-2.1/src/dlgTriggersMainArea.h0000644000175000017500000000331511513237311016770 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DLG_TRIGGERsmainarea_H #define DLG_TRIGGERsmainarea_H #include "ui_triggers_main_area.h" #include #include "TTrigger.h" class dlgTriggersMainArea : public QWidget , public Ui::trigger_main_area { Q_OBJECT public: dlgTriggersMainArea(QWidget*); signals: public slots: }; #endif mudlet-2.1/src/XMLexport.cpp0000644000175000017500000007413212070466512015365 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn ( KoehnHeiko@googlemail.com ) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "XMLexport.h" using namespace std; XMLexport::XMLexport( Host * pH ) : mpHost( pH ) , mType( "Host" ) { setAutoFormatting(true); } XMLexport::XMLexport( Host * pT, bool b ) : mpHost( pT ) , mType( "GenericPackage" ) { setAutoFormatting(true); } XMLexport::XMLexport( TTrigger * pT ) : mpTrigger( pT ) , mType( "Trigger" ) { setAutoFormatting(true); } XMLexport::XMLexport( TTimer * pT ) : mpTimer( pT ) , mType( "Timer" ) { setAutoFormatting(true); } XMLexport::XMLexport( TAlias * pT ) : mpAlias( pT ) , mType( "Alias" ) { setAutoFormatting(true); } XMLexport::XMLexport( TAction * pT ) : mpAction( pT ) , mType( "Action" ) { setAutoFormatting(true); } XMLexport::XMLexport( TScript * pT ) : mpScript( pT ) , mType( "Script" ) { setAutoFormatting(true); } XMLexport::XMLexport( TKey * pT ) : mpKey( pT ) , mType( "Key" ) { setAutoFormatting(true); } bool XMLexport::writeModuleXML( QIODevice * device, QString moduleName){ setDevice(device); qDebug()<"); writeStartElement( "MudletPackage" ); writeAttribute("version", "1.0"); qDebug()<<"starting writeModule routine"; writeStartElement( "TriggerPackage" ); Host * pT = mpHost; bool ret = true; int nodesWritten = 0; //we go a level down for all these functions so as to not infinitely nest the module typedef list::const_iterator ItTriggerUnit; for( ItTriggerUnit it1 = pT->mTriggerUnit.mTriggerRootNodeList.begin(); it1 != pT->mTriggerUnit.mTriggerRootNodeList.end(); it1++) { TTrigger * pChildTrigger = *it1; if( ! pChildTrigger || pChildTrigger->mPackageName != moduleName) continue; if( ! pChildTrigger->isTempTrigger() && pChildTrigger->mModuleMember) { ret = writeTrigger( pChildTrigger ); nodesWritten+=1; } } if (!nodesWritten) writeEndElement(); //end trigger package tag nodesWritten=0; writeStartElement("TimerPackage"); typedef list::const_iterator ItTimerUnit; for( ItTimerUnit it2 = pT->mTimerUnit.mTimerRootNodeList.begin(); it2 != pT->mTimerUnit.mTimerRootNodeList.end(); it2++) { TTimer * pChildTimer = *it2; if( ! pChildTimer || pChildTimer->mPackageName != moduleName) continue; if( ! pChildTimer->isTempTimer() && pChildTimer->mModuleMember) { ret = writeTimer( pChildTimer ); nodesWritten+=1; } } if (!nodesWritten) writeEndElement(); //end trigger package tag nodesWritten=0; writeStartElement("AliasPackage"); typedef list::const_iterator ItAliasUnit; for( ItAliasUnit it3 = pT->mAliasUnit.mAliasRootNodeList.begin(); it3 != pT->mAliasUnit.mAliasRootNodeList.end(); it3++) { TAlias * pChildAlias = *it3; if( ! pChildAlias || pChildAlias->mPackageName != moduleName) continue; if( ! pChildAlias->isTempAlias() && pChildAlias->mModuleMember) { ret = writeAlias( pChildAlias ); nodesWritten+=1; } } if (!nodesWritten) writeEndElement(); //end trigger package tag nodesWritten=0; writeStartElement("ActionPackage"); typedef list::const_iterator ItActionUnit; for( ItActionUnit it4 = pT->mActionUnit.mActionRootNodeList.begin(); it4 != pT->mActionUnit.mActionRootNodeList.end(); it4++) { TAction * pChildAction = *it4; if( ! pChildAction || pChildAction->mPackageName != moduleName) continue; if (pChildAction->mModuleMember){ ret = writeAction( pChildAction ); nodesWritten+=1; } } if (!nodesWritten) writeEndElement(); //end trigger package tag nodesWritten=0; writeStartElement("ScriptPackage"); typedef list::const_iterator ItScriptUnit; for( ItScriptUnit it5 = pT->mScriptUnit.mScriptRootNodeList.begin(); it5 != pT->mScriptUnit.mScriptRootNodeList.end(); it5++) { TScript * pChildScript = *it5; if( ! pChildScript || pChildScript->mPackageName != moduleName) continue; if (pChildScript->mModuleMember){ ret = writeScript( pChildScript ); nodesWritten+=1; } } if (!nodesWritten) writeEndElement(); //end trigger package tag nodesWritten=0; writeStartElement("KeyPackage"); typedef list::const_iterator ItKeyUnit; for( ItKeyUnit it6 = pT->mKeyUnit.mKeyRootNodeList.begin(); it6 != pT->mKeyUnit.mKeyRootNodeList.end(); it6++) { TKey * pChildKey = *it6; if( ! pChildKey || pChildKey->mPackageName != moduleName) continue; if (pChildKey->mModuleMember){ ret = writeKey( pChildKey ); nodesWritten+=1; } } if (!nodesWritten) writeEndElement(); //end trigger package tag nodesWritten=0; writeStartElement("HelpPackage"); if (mpHost->moduleHelp.contains(moduleName) && mpHost->moduleHelp[moduleName].contains("helpURL")) writeTextElement( "helpURL", mpHost->moduleHelp[moduleName]["helpURL"]); else writeTextElement( "helpURL", ""); writeEndElement(); //end trigger package tag writeEndElement();//end hostpackage writeEndElement();//MudletPackage writeEndDocument(); return true; } bool XMLexport::exportHost( QIODevice * device ) { setDevice(device); writeStartDocument(); writeDTD(""); writeStartElement( "MudletPackage" ); writeAttribute("version", "1.0"); writeStartElement( "HostPackage" ); writeHost( mpHost ); writeEndElement(); writeEndElement();//MudletPackage writeEndDocument(); return true; } bool XMLexport::writeHost( Host * pT ) { writeStartElement( "Host" ); writeAttribute( "autoClearCommandLineAfterSend", pT->mAutoClearCommandLineAfterSend ? "yes" : "no" ); writeAttribute( "disableAutoCompletion", pT->mDisableAutoCompletion ? "yes" : "no" ); writeAttribute( "printCommand", pT->mPrintCommand ? "yes" : "no" ); writeAttribute( "USE_IRE_DRIVER_BUGFIX", pT->mUSE_IRE_DRIVER_BUGFIX ? "yes" : "no" ); writeAttribute( "mUSE_FORCE_LF_AFTER_PROMPT", pT->mUSE_FORCE_LF_AFTER_PROMPT ? "yes" : "no" ); writeAttribute( "mUSE_UNIX_EOL", pT->mUSE_UNIX_EOL ? "yes" : "no" ); writeAttribute( "mNoAntiAlias", pT->mNoAntiAlias ? "yes" : "no" ); writeAttribute( "mRawStreamDump", pT->mRawStreamDump ? "yes" : "no" ); writeAttribute( "mAlertOnNewData", pT->mAlertOnNewData ? "yes" : "no" ); writeAttribute( "mFORCE_NO_COMPRESSION", pT->mFORCE_NO_COMPRESSION ? "yes" : "no" ); writeAttribute( "mFORCE_GA_OFF", pT->mFORCE_GA_OFF ? "yes" : "no" ); writeAttribute( "mFORCE_SAVE_ON_EXIT", pT->mFORCE_SAVE_ON_EXIT ? "yes" : "no" ); writeAttribute( "mEnableGMCP", pT->mEnableGMCP ? "yes" : "no" ); writeAttribute( "mMapStrongHighlight", pT->mMapStrongHighlight ? "yes" : "no" ); writeAttribute( "mLogStatus", pT->mLogStatus ? "yes" : "no" ); writeAttribute( "mEnableSpellCheck", pT->mEnableSpellCheck ? "yes" : "no" ); writeAttribute( "mShowInfo", pT->mShowInfo ? "yes" : "no" ); writeAttribute( "mAcceptServerGUI", pT->mAcceptServerGUI ? "yes" : "no" ); writeAttribute( "mMapperUseAntiAlias", pT->mMapperUseAntiAlias ? "yes" : "no" ); writeAttribute( "mFORCE_MXP_NEGOTIATION_OFF", pT->mFORCE_MXP_NEGOTIATION_OFF ? "yes" : "no" ); writeAttribute( "mRoomSize", QString::number(pT->mRoomSize)); writeAttribute( "mLineSize", QString::number(pT->mLineSize)); writeAttribute( "mBubbleMode", pT->mBubbleMode ? "yes" : "no"); writeAttribute( "mShowRoomIDs", pT->mShowRoomID ? "yes" : "no"); writeAttribute( "mShowPanel", pT->mShowPanel ? "yes" : "no"); writeAttribute( "mHaveMapperScript", pT->mHaveMapperScript ? "yes" : "no"); writeTextElement( "name", pT->mHostName ); //writeTextElement( "login", pT->mLogin ); //writeTextElement( "pass", pT->mPass ); writeStartElement( "mInstalledPackages" ); for( int i=0; imInstalledPackages.size(); i++ ) { writeTextElement( "string", pT->mInstalledPackages[i] ); } writeEndElement(); if (pT->mInstalledModules.size()){ qDebug()<<"installed module being done"; writeStartElement( "mInstalledModules" ); QMapIterator it(pT->mInstalledModules); pT->modulesToWrite.clear(); while( it.hasNext() ) { it.next(); writeTextElement("key", it.key()); QStringList entry = it.value(); qDebug()<<"XMLexport"<modulesToWrite[it.key()] = entry; } writeTextElement("priority", QString::number(pT->mModulePriorities[it.key()])); } writeEndElement(); } writeTextElement( "url", pT->mUrl ); writeTextElement( "serverPackageName", pT->mServerGUI_Package_name ); writeTextElement( "serverPackageVersion", QString::number(pT->mServerGUI_Package_version ) ); writeTextElement( "port", QString::number(pT->mPort) ); writeTextElement( "borderTopHeight", QString::number(pT->mBorderTopHeight) ); writeTextElement( "borderBottomHeight", QString::number(pT->mBorderBottomHeight) ); writeTextElement( "borderLeftWidth", QString::number(pT->mBorderLeftWidth) ); writeTextElement( "borderRightWidth", QString::number(pT->mBorderRightWidth) ); writeTextElement( "wrapAt", QString::number(pT->mWrapAt) ); writeTextElement( "wrapIndentCount", QString::number(pT->mWrapIndentCount) ); writeTextElement( "commandSeperator", pT->mCommandSeperator ); writeTextElement( "mFgColor", pT->mFgColor.name() ); writeTextElement( "mBgColor", pT->mBgColor.name() ); writeTextElement( "mCommandFgColor", pT->mCommandFgColor.name() ); writeTextElement( "mCommandBgColor", pT->mCommandBgColor.name() ); writeTextElement( "mCommandLineFgColor", pT->mCommandLineFgColor.name() ); writeTextElement( "mCommandLineBgColor", pT->mCommandLineBgColor.name() ); writeTextElement( "mBlack", pT->mBlack.name() ); writeTextElement( "mLightBlack", pT->mLightBlack.name() ); writeTextElement( "mRed", pT->mRed.name() ); writeTextElement( "mLightRed", pT->mLightRed.name() ); writeTextElement( "mBlue", pT->mBlue.name() ); writeTextElement( "mLightBlue", pT->mLightBlue.name() ); writeTextElement( "mGreen", pT->mGreen.name() ); writeTextElement( "mLightGreen", pT->mLightGreen.name() ); writeTextElement( "mYellow", pT->mYellow.name() ); writeTextElement( "mLightYellow", pT->mLightYellow.name() ); writeTextElement( "mCyan", pT->mCyan.name() ); writeTextElement( "mLightCyan", pT->mLightCyan.name() ); writeTextElement( "mMagenta", pT->mMagenta.name() ); writeTextElement( "mLightMagenta", pT->mLightMagenta.name() ); writeTextElement( "mWhite", pT->mWhite.name() ); writeTextElement( "mLightWhite", pT->mLightWhite.name() ); writeTextElement( "mDisplayFont", pT->mDisplayFont.toString() ); writeTextElement( "mCommandLineFont", pT->mCommandLineFont.toString() ); writeTextElement( "mCommandSeparator", pT->mCommandSeparator ); writeTextElement( "commandLineMinimumHeight", QString::number(pT->commandLineMinimumHeight) ); writeTextElement( "mFgColor2", pT->mFgColor_2.name() ); writeTextElement( "mBgColor2", pT->mBgColor_2.name() ); writeTextElement( "mBlack2", pT->mBlack_2.name() ); writeTextElement( "mLightBlack2", pT->mLightBlack_2.name() ); writeTextElement( "mRed2", pT->mRed_2.name() ); writeTextElement( "mLightRed2", pT->mLightRed_2.name() ); writeTextElement( "mBlue2", pT->mBlue_2.name() ); writeTextElement( "mLightBlue2", pT->mLightBlue_2.name() ); writeTextElement( "mGreen2", pT->mGreen_2.name() ); writeTextElement( "mLightGreen2", pT->mLightGreen_2.name() ); writeTextElement( "mYellow2", pT->mYellow_2.name() ); writeTextElement( "mLightYellow2", pT->mLightYellow_2.name() ); writeTextElement( "mCyan2", pT->mCyan_2.name() ); writeTextElement( "mLightCyan2", pT->mLightCyan_2.name() ); writeTextElement( "mMagenta2", pT->mMagenta_2.name() ); writeTextElement( "mLightMagenta2", pT->mLightMagenta_2.name() ); writeTextElement( "mWhite2", pT->mWhite_2.name() ); writeTextElement( "mLightWhite2", pT->mLightWhite_2.name() ); writeTextElement( "mSpellDic", pT->mSpellDic ); writeTextElement( "mLineSize", QString::number(pT->mLineSize) ); writeTextElement( "mRoomSize", QString::number(pT->mRoomSize) ); writeEndElement(); // end Host tag writeEndElement(); // end HostPackage tag writeStartElement( "TriggerPackage" ); bool ret = true; typedef list::const_iterator ItTriggerUnit; for( ItTriggerUnit it1 = pT->mTriggerUnit.mTriggerRootNodeList.begin(); it1 != pT->mTriggerUnit.mTriggerRootNodeList.end(); it1++) { TTrigger * pChildTrigger = *it1; if( ! pChildTrigger || pChildTrigger->mModuleMember) continue; if( ! pChildTrigger->isTempTrigger()) { ret = writeTrigger( pChildTrigger ); } } writeEndElement(); //end trigger package tag writeStartElement("TimerPackage"); typedef list::const_iterator ItTimerUnit; for( ItTimerUnit it2 = pT->mTimerUnit.mTimerRootNodeList.begin(); it2 != pT->mTimerUnit.mTimerRootNodeList.end(); it2++) { TTimer * pChildTimer = *it2; if (pChildTimer->mModuleMember) continue; if( ! pChildTimer->isTempTimer()) { ret = writeTimer( pChildTimer ); } } writeEndElement(); writeStartElement("AliasPackage"); typedef list::const_iterator ItAliasUnit; for( ItAliasUnit it3 = pT->mAliasUnit.mAliasRootNodeList.begin(); it3 != pT->mAliasUnit.mAliasRootNodeList.end(); it3++) { TAlias * pChildAlias = *it3; if (pChildAlias->mModuleMember) continue; if( ! pChildAlias->isTempAlias()) { ret = writeAlias( pChildAlias ); } } writeEndElement(); writeStartElement("ActionPackage"); typedef list::const_iterator ItActionUnit; for( ItActionUnit it4 = pT->mActionUnit.mActionRootNodeList.begin(); it4 != pT->mActionUnit.mActionRootNodeList.end(); it4++) { TAction * pChildAction = *it4; if (pChildAction->mModuleMember) continue; ret = writeAction( pChildAction ); } writeEndElement(); writeStartElement("ScriptPackage"); typedef list::const_iterator ItScriptUnit; for( ItScriptUnit it5 = pT->mScriptUnit.mScriptRootNodeList.begin(); it5 != pT->mScriptUnit.mScriptRootNodeList.end(); it5++) { TScript * pChildScript = *it5; if (pChildScript->mModuleMember) continue; ret = writeScript( pChildScript ); } writeEndElement(); writeStartElement("KeyPackage"); typedef list::const_iterator ItKeyUnit; for( ItKeyUnit it6 = pT->mKeyUnit.mKeyRootNodeList.begin(); it6 != pT->mKeyUnit.mKeyRootNodeList.end(); it6++) { TKey * pChildKey = *it6; if (pChildKey->mModuleMember) continue; ret = writeKey( pChildKey ); } writeEndElement(); return ret; } bool XMLexport::exportGenericPackage( QIODevice * device ) { setDevice(device); writeStartDocument(); writeDTD(""); writeStartElement( "MudletPackage" ); writeAttribute("version", "1.0"); writeGenericPackage( mpHost ); writeEndElement();//MudletPackage writeEndDocument(); return true; } bool XMLexport::writeGenericPackage( Host * pT ) { writeStartElement( "TriggerPackage" ); bool ret = true; typedef list::const_iterator ItTriggerUnit; for( ItTriggerUnit it1 = pT->mTriggerUnit.mTriggerRootNodeList.begin(); it1 != pT->mTriggerUnit.mTriggerRootNodeList.end(); it1++) { TTrigger * pChildTrigger = *it1; if( ! pChildTrigger ) continue; if( ! pChildTrigger->isTempTrigger()) { ret = writeTrigger( pChildTrigger ); } } writeEndElement(); //end trigger package tag writeStartElement("TimerPackage"); typedef list::const_iterator ItTimerUnit; for( ItTimerUnit it2 = pT->mTimerUnit.mTimerRootNodeList.begin(); it2 != pT->mTimerUnit.mTimerRootNodeList.end(); it2++) { TTimer * pChildTimer = *it2; if( ! pChildTimer->isTempTimer()) { ret = writeTimer( pChildTimer ); } } writeEndElement(); writeStartElement("AliasPackage"); typedef list::const_iterator ItAliasUnit; for( ItAliasUnit it3 = pT->mAliasUnit.mAliasRootNodeList.begin(); it3 != pT->mAliasUnit.mAliasRootNodeList.end(); it3++) { TAlias * pChildAlias = *it3; if( ! pChildAlias->isTempAlias()) { ret = writeAlias( pChildAlias ); } } writeEndElement(); writeStartElement("ActionPackage"); typedef list::const_iterator ItActionUnit; for( ItActionUnit it4 = pT->mActionUnit.mActionRootNodeList.begin(); it4 != pT->mActionUnit.mActionRootNodeList.end(); it4++) { TAction * pChildAction = *it4; ret = writeAction( pChildAction ); } writeEndElement(); writeStartElement("ScriptPackage"); typedef list::const_iterator ItScriptUnit; for( ItScriptUnit it5 = pT->mScriptUnit.mScriptRootNodeList.begin(); it5 != pT->mScriptUnit.mScriptRootNodeList.end(); it5++) { TScript * pChildScript = *it5; ret = writeScript( pChildScript ); } writeEndElement(); writeStartElement("KeyPackage"); typedef list::const_iterator ItKeyUnit; for( ItKeyUnit it6 = pT->mKeyUnit.mKeyRootNodeList.begin(); it6 != pT->mKeyUnit.mKeyRootNodeList.end(); it6++) { TKey * pChildKey = *it6; ret = writeKey( pChildKey ); } writeEndElement(); return ret; } bool XMLexport::exportTrigger( QIODevice * device ) { setDevice(device); writeStartDocument(); writeDTD(""); writeStartElement( "MudletPackage" ); writeAttribute("version", "1.0"); writeStartElement( "TriggerPackage" ); writeTrigger( mpTrigger ); writeEndElement();//TriggerPackage writeEndElement();//MudletPackage writeEndDocument(); return true; } bool XMLexport::writeTrigger( TTrigger * pT ) { if (!pT->mModuleMasterFolder && pT->exportItem){ //qDebug()<<"trigger written"<mModuleMember; QString tag; if( pT->mIsFolder ) { tag = "TriggerGroup"; } else { tag = "Trigger"; } writeStartElement( tag ); writeAttribute( "isActive", pT->shouldBeActive() ? "yes" : "no" ); writeAttribute( "isFolder", pT->mIsFolder ? "yes" : "no" ); writeAttribute( "isTempTrigger", pT->mIsTempTrigger ? "yes" : "no" ); writeAttribute( "isMultiline", pT->mIsMultiline ? "yes" : "no" ); writeAttribute( "isPerlSlashGOption", pT->mPerlSlashGOption ? "yes" : "no" ); writeAttribute( "isColorizerTrigger", pT->mIsColorizerTrigger ? "yes" : "no" ); writeAttribute( "isFilterTrigger", pT->mFilterTrigger ? "yes" : "no" ); writeAttribute( "isSoundTrigger", pT->mSoundTrigger ? "yes" : "no" ); writeAttribute( "isColorTrigger", pT->mColorTrigger ? "yes" : "no" ); writeAttribute( "isColorTriggerFg", pT->mColorTriggerFg ? "yes" : "no" ); writeAttribute( "isColorTriggerBg", pT->mColorTriggerBg ? "yes" : "no" ); writeTextElement( "name", pT->mName ); writeTextElement( "script", pT->mScript ); writeTextElement( "triggerType", QString::number( pT->mTriggerType ) ); writeTextElement( "conditonLineDelta", QString::number( pT->mConditionLineDelta ) ); writeTextElement( "mStayOpen", QString::number( pT->mStayOpen ) ); writeTextElement( "mCommand", pT->mCommand ); writeTextElement( "packageName", pT->mPackageName ); writeTextElement( "mFgColor", pT->mFgColor.name() ); writeTextElement( "mBgColor", pT->mBgColor.name() ); writeTextElement( "mSoundFile", pT->mSoundFile ); writeTextElement( "colorTriggerFgColor", pT->mColorTriggerFgColor.name() ); writeTextElement( "colorTriggerBgColor", pT->mColorTriggerBgColor.name() ); writeStartElement( "regexCodeList" ); for( int i=0; imRegexCodeList.size(); i++ ) { writeTextElement( "string", pT->mRegexCodeList[i] ); } writeEndElement(); writeStartElement( "regexCodePropertyList" ); for( int i=0; imRegexCodePropertyList.size(); i++ ) { writeTextElement( "integer", QString::number( pT->mRegexCodePropertyList[i] ) ); } writeEndElement(); } typedef list::const_iterator I; for( I it = pT->mpMyChildrenList->begin(); it != pT->mpMyChildrenList->end(); it++) { TTrigger * pChild = *it; // if (pChild->mModuleMember) continue; writeTrigger( pChild ); } if (pT->exportItem) writeEndElement(); return true; } bool XMLexport::exportAlias( QIODevice * device ) { setDevice(device); writeStartDocument(); writeDTD(""); writeStartElement( "MudletPackage" ); writeAttribute("version", "1.0"); writeStartElement( "AliasPackage" ); writeAlias( mpAlias ); writeEndElement(); writeEndElement();//MudletPackage writeEndDocument(); return true; } bool XMLexport::writeAlias( TAlias * pT ) { if (!pT->mModuleMasterFolder && pT->exportItem){ QString tag; if( pT->mIsFolder ) { tag = "AliasGroup"; } else { tag = "Alias"; } writeStartElement( tag ); writeAttribute( "isActive", pT->shouldBeActive() ? "yes" : "no" ); writeAttribute( "isFolder", pT->mIsFolder ? "yes" : "no" ); writeTextElement( "name", pT->mName ); writeTextElement( "script", pT->mScript ); writeTextElement( "command", pT->mCommand ); writeTextElement( "packageName", pT->mPackageName ); writeTextElement( "regex", pT->mRegexCode ); } typedef list::const_iterator I; for( I it = pT->mpMyChildrenList->begin(); it != pT->mpMyChildrenList->end(); it++) { TAlias * pChild = *it; writeAlias( pChild ); } if (pT->exportItem) writeEndElement(); return true; } bool XMLexport::exportAction( QIODevice * device ) { setDevice(device); writeStartDocument(); writeDTD(""); writeStartElement( "MudletPackage" ); writeAttribute("version", "1.0"); writeStartElement( "ActionPackage" ); writeAction( mpAction ); writeEndElement(); writeEndElement();//MudletPackage writeEndDocument(); return true; } bool XMLexport::writeAction( TAction * pT ) { if (!pT->mModuleMasterFolder && pT->exportItem){ QString tag; if( pT->mIsFolder ) { tag = "ActionGroup"; } else { tag = "Action"; } writeStartElement( tag ); writeAttribute( "isActive", pT->shouldBeActive() ? "yes" : "no" ); writeAttribute( "isFolder", pT->mIsFolder ? "yes" : "no" ); writeAttribute( "isPushButton", pT->mIsPushDownButton ? "yes" : "no" ); writeAttribute( "isFlatButton", pT->mButtonFlat ? "yes" : "no" ); writeAttribute( "useCustomLayout", pT->mUseCustomLayout ? "yes" : "no" ); writeTextElement( "name", pT->mName ); writeTextElement( "packageName", pT->mPackageName ); writeTextElement( "script", pT->mScript ); writeTextElement( "css", pT->css ); writeTextElement( "commandButtonUp", pT->mCommandButtonUp ); writeTextElement( "commandButtonDown", pT->mCommandButtonDown ); writeTextElement( "icon", pT->mIcon ); writeTextElement( "orientation", QString::number(pT->mOrientation) ); writeTextElement( "location", QString::number(pT->mLocation) ); writeTextElement( "posX", QString::number(pT->mPosX) ); writeTextElement( "posY", QString::number(pT->mPosY) ); writeTextElement( "mButtonState", QString::number(pT->mButtonState) ); writeTextElement( "sizeX", QString::number(pT->mSizeX) ); writeTextElement( "sizeY", QString::number(pT->mSizeY) ); writeTextElement( "buttonColumn", QString::number(pT->mButtonColumns) ); writeTextElement( "buttonRotation", QString::number(pT->mButtonRotation) ); writeTextElement( "buttonColor", pT->mButtonColor.name() ); } typedef list::const_iterator I; for( I it = pT->mpMyChildrenList->begin(); it != pT->mpMyChildrenList->end(); it++) { TAction * pChild = *it; writeAction( pChild ); } if (pT->exportItem) writeEndElement(); return true; } bool XMLexport::exportTimer( QIODevice * device ) { setDevice(device); writeStartDocument(); writeDTD(""); writeStartElement( "MudletPackage" ); writeAttribute("version", "1.0"); writeStartElement( "TimerPackage" ); writeTimer( mpTimer ); writeEndElement(); writeEndElement();//MudletPackage writeEndDocument(); return true; } bool XMLexport::writeTimer( TTimer * pT ) { if (!pT->mModuleMasterFolder && pT->exportItem){ QString tag; if( pT->mIsFolder ) { tag = "TimerGroup"; } else { tag = "Timer"; } writeStartElement( tag ); writeAttribute( "isActive", pT->shouldBeActive() ? "yes" : "no" ); writeAttribute( "isFolder", pT->mIsFolder ? "yes" : "no" ); writeAttribute( "isTempTimer", pT->mIsTempTimer ? "yes" : "no" ); writeAttribute( "isOffsetTimer", pT->isOffsetTimer() ? "yes" : "no" ); writeTextElement( "name", pT->mName ); writeTextElement( "script", pT->mScript ); writeTextElement( "command", pT->mCommand ); writeTextElement( "packageName", pT->mPackageName ); writeTextElement( "time", pT->mTime.toString( "hh:mm:ss.zzz" ) ); } typedef list::const_iterator I; for( I it = pT->mpMyChildrenList->begin(); it != pT->mpMyChildrenList->end(); it++) { TTimer * pChild = *it; writeTimer( pChild ); } if (pT->exportItem) writeEndElement(); return true; } bool XMLexport::exportScript( QIODevice * device ) { setDevice(device); writeStartDocument(); writeDTD(""); writeStartElement( "MudletPackage" ); writeAttribute("version", "1.0"); writeStartElement( "ScriptPackage" ); writeScript( mpScript ); writeEndElement(); writeEndElement();//MudletPackage writeEndDocument(); return true; } bool XMLexport::writeScript( TScript * pT ) { if (!pT->mModuleMasterFolder && pT->exportItem){ QString tag; if( pT->mIsFolder ) { tag = "ScriptGroup"; } else { tag = "Script"; } writeStartElement( tag ); writeAttribute( "isActive", pT->shouldBeActive() ? "yes" : "no" ); writeAttribute( "isFolder", pT->mIsFolder ? "yes" : "no" ); writeTextElement( "name", pT->mName ); writeTextElement( "packageName", pT->mPackageName ); writeTextElement( "script", pT->mScript ); writeStartElement( "eventHandlerList" ); for( int i=0; imEventHandlerList.size(); i++ ) { writeTextElement( "string", pT->mEventHandlerList[i] ); } writeEndElement(); } typedef list::const_iterator I; for( I it = pT->mpMyChildrenList->begin(); it != pT->mpMyChildrenList->end(); it++) { TScript * pChild = *it; writeScript( pChild ); } if (pT->exportItem) writeEndElement(); return true; } bool XMLexport::exportKey( QIODevice * device ) { setDevice(device); writeStartDocument(); writeDTD(""); writeStartElement( "MudletPackage" ); writeAttribute("version", "1.0"); writeStartElement( "KeyPackage" ); writeKey( mpKey ); writeEndElement(); writeEndElement();//MudletPackage writeEndDocument(); return true; } bool XMLexport::writeKey( TKey * pT ) { if (!pT->mModuleMasterFolder && pT->exportItem){ QString tag; if( pT->mIsFolder ) { tag = "KeyGroup"; } else { tag = "Key"; } writeStartElement( tag ); writeAttribute( "isActive", pT->shouldBeActive() ? "yes" : "no" ); writeAttribute( "isFolder", pT->mIsFolder ? "yes" : "no" ); writeTextElement( "name", pT->mName ); writeTextElement( "packageName", pT->mPackageName ); writeTextElement( "script", pT->mScript ); writeTextElement( "command", pT->mCommand ); writeTextElement( "keyCode", QString::number( pT->mKeyCode ) ); writeTextElement( "keyModifier", QString::number( pT->mKeyModifier ) ); } typedef list::const_iterator I; for( I it = pT->mpMyChildrenList->begin(); it != pT->mpMyChildrenList->end(); it++) { TKey * pChild = *it; writeKey( pChild ); } if (pT->exportItem) writeEndElement(); return true; } mudlet-2.1/src/mudlet.h0000644000175000017500000003154212070466513014421 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef MUDLET_H #define MUDLET_H #include #include //#include "ui_console.h" #include "TConsole.h" #include "mudlet.h" #include "ctelnet.h" #include "HostManager.h" #include #include #include "Host.h" #include #include "TConsole.h" #include "ui_main_window.h" //#ifdef Q_OS_LINUX // #include //#else // #include //#endif //Debian BSD patch: #ifdef Q_OS_WIN32 #include #else #include #endif class QAction; class QMenu; class QTextEdit; class EAction; class TConsole; class TLabel; class dlgIRC; class mudlet : public QMainWindow, public Ui::MainWindow { Q_OBJECT public: mudlet(); ~mudlet(); static mudlet * self(); void addSubWindow(TConsole* p); void printSystemMessage( Host * pH, QString & s ); void print( Host *, QString & ); void addConsoleForNewHost( Host * pH ); void disableToolbarButtons(); void enableToolbarButtons(); Host * getActiveHost(); void registerTimer( TTimer *, QTimer * ); void unregisterTimer( QTimer * ); bool openWindow( Host *, QString & ); bool createMiniConsole( Host *, QString &, int, int, int, int ); bool createLabel( Host *, QString &, int, int, int, int, bool ); bool echoWindow( Host *, QString &, QString & ); bool echoLink( Host * pHost, QString & name, QString & text, QStringList &, QStringList &, bool customFormat=false ); void insertLink( Host *, QString &, QString, QStringList &, QStringList &, bool customFormat=false ); bool appendBuffer( Host *, QString & ); bool createBuffer( Host *, QString & ); bool showWindow( Host *, QString & ); bool hideWindow( Host *, QString & ); bool paste( Host *, QString & ); bool closeWindow( Host *, QString & ); bool resizeWindow( Host *, QString &, int, int ); bool clearWindow( Host *, QString & ); bool pasteWindow( Host * pHost, QString & name ); bool setBackgroundColor( Host *, QString & name, int r, int g, int b, int alpha ); bool setBackgroundImage( Host *, QString & name, QString & path ); bool setTextFormat( Host *, QString & name, int, int, int, int, int, int, bool, bool, bool ); bool setLabelClickCallback( Host *, QString &, QString &, TEvent * ); bool setLabelOnEnter( Host *, QString &, QString &, TEvent * ); bool setLabelOnLeave( Host *, QString &, QString &, TEvent * ); bool moveWindow( Host *, QString & name, int, int ); void deleteLine( Host *, QString & name ); void insertText( Host *, QString & name, QString ); void replace( Host *, QString & name, QString ); int selectString( Host *, QString & name, QString what, int ); int selectSection( Host *, QString & name, int, int ); void setBold( Host *, QString & name, bool ); void setLink( Host * pHost, QString & name, QString & linkText, QStringList & linkFunction, QStringList & ); void setItalics( Host *, QString & name, bool ); void setUnderline( Host *, QString & name, bool ); void setFgColor( Host *, QString & name, int, int, int ); void setBgColor( Host *, QString & name, int, int, int ); bool userWindowLineWrap( Host * pHost, QString & name, bool on ); QString readProfileData( QString profile, QString item ); bool setWindowWrap( Host * pHost, QString & name, int & wrap ); bool setWindowWrapIndent( Host * pHost, QString & name, int & wrap ); bool copy( Host * pHost, QString & name ); bool moveCursorEnd( Host *, QString & ); bool moveCursor( Host *, QString &, int, int ); int getLastLineNumber( Host *, QString & ); void readSettings(); void writeSettings(); void showUnzipProgress( QString txt ); bool openWebPage(QString path); void processEventLoopHack(); static TConsole * mpDebugConsole; static QMainWindow * mpDebugArea; static bool debugMode; QMap mConsoleMap; QMap > mHostConsoleMap; QMap > mHostLabelMap; QIcon * testicon; bool mShowMenuBar; bool mShowToolbar; bool isGoingDown() { return mIsGoingDown; } int mMainIconSize; int mTEFolderIconSize; void setIcoSize( int s ); void replayStart(); bool setConsoleBufferSize( Host * pHost, QString & name, int x1, int y1 ); void replayOver(); void showEvent( QShowEvent * event ); void hideEvent( QHideEvent * event ); bool resetFormat( Host *, QString & name ); bool mWindowMinimized; //QString readProfileData( QString profile, QString item ); void doAutoLogin( QString & ); void deselect( Host * pHost, QString & name ); void playSound( QString s ); QTime mReplayTime; int mReplaySpeed; QToolBar * mpMainToolBar; QMap mTimerMap; dlgIRC * mpIRC; QString version; Host * mpCurrentActiveHost; bool mAutolog; QString mIrcNick; Phonon::MediaObject * mpMusicBox1; Phonon::MediaObject * mpMusicBox2; Phonon::MediaObject * mpMusicBox3; Phonon::MediaObject * mpMusicBox4; QTabBar * mpTabBar; QStringList packagesToInstallList; public slots: void processEventLoopHack_timerRun(); void slot_mapper(); void slot_replayTimeChanged(); void slot_replaySpeedUp(); void slot_replaySpeedDown(); void toggleFullScreenView(); void slot_userToolBar_orientation_changed(Qt::Orientation); void slot_show_about_dialog(); void slot_show_help_dialog_video(); void slot_show_help_dialog_forum(); void slot_show_help_dialog_irc(); void slot_show_help_dialog_download(); void slot_open_mappingscripts_page(); void slot_module_clicked(QTableWidgetItem*); void slot_module_changed(QTableWidgetItem*); void slot_multi_view(); void slot_stopAllTriggers(); void slot_userToolBar_hovered( QAction* pA ); void slot_connection_dlg_finnished( QString profile, int historyVersion ); void slot_timer_fires(); void slot_send_login(); void slot_send_pass(); void slot_replay(); void slot_disconnect(); void slot_notes(); void slot_reconnect(); void slot_close_profile_requested(int); void startAutoLogin(); void slot_irc(); void slot_uninstall_package(); void slot_install_package(); void slot_package_manager(); void slot_package_exporter(); void slot_uninstall_module(); void slot_install_module(); void slot_module_manager(); void layoutModules(); void slot_help_module(); protected: void closeEvent(QCloseEvent *event); private slots: void slot_close_profile(); void slot_tab_changed( int ); void show_help_dialog(); void connectToServer(); void show_trigger_dialog(); void show_alias_dialog(); void show_script_dialog(); void show_timer_dialog(); void show_action_dialog(); void show_key_dialog(); void show_options_dialog(); private: void goingDown() { mIsGoingDown = true; } QMap mTabMap; //QTabBar * mpTabBar; QWidget * mainPane; Host * mpDefaultHost; QQueue tempLoginQueue; QQueue tempPassQueue; QQueue tempHostQueue; static mudlet * _self; QMap dockWindowMap; //QMap dockWindowConsoleMap; //QMap> mLabelMap; QMap mUserToolbarMap; QMenu * restoreBar; bool mIsGoingDown; QAction * actionReplaySpeedDown; QAction * actionReplaySpeedUp; QAction * actionReconnect; void check_for_mappingscript(); QListWidget * packageList; QPushButton * uninstallButton; QPushButton * installButton; QTableWidget * moduleTable; QPushButton * moduleUninstallButton; QPushButton * moduleInstallButton; QPushButton * moduleHelpButton; }; class TConsoleMonitor : public QObject { Q_OBJECT protected: bool eventFilter(QObject *obj, QEvent *event); }; #endif mudlet-2.1/src/TArea.h0000644000175000017500000000544412020507606014117 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn (KoehnHeiko@googlemail.com) * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TAREA_H #define TAREA_H #include #include #include #include #include #include #include class TMap; class TArea { public: TArea( TMap * ); void calcSpan(); void fast_calcSpan(int); void fast_ausgaengeBestimmen(int); QList getCollisionNodes(); QList getRoomsByPosition( int x, int y, int z ); QMap > > koordinatenSystem(); void ausgaengeBestimmen(); QMultiMap > exits; // rooms that border on this area: key=in_area room id, pair.first=out_of_area room id pair.second=direction QList rooms; // rooms of this area QVector3D pos; // pos auf der map und 0 punkt des area internen koordinatensystems QVector3D span; int min_x; int min_y; int min_z; int max_x; int max_y; int max_z; QMap xminEbene; QMap xmaxEbene; QMap yminEbene; QMap ymaxEbene; QMap zminEbene; QMap zmaxEbene; QList ebenen; TMap * mpMap; bool gridMode; bool isZone; int zoneAreaRef; //QMap labelMap; }; // - gezeichnet werden erstmal die areas // unter berücksichtigung der an die area angrenzenden edges // - der span der area ist unterschiedlich #endif // TAREA_H mudlet-2.1/src/dlgPackageExporter.h0000644000175000017500000000276412070466512016705 0ustar csmallcsmall#ifndef DLGPACKAGEEXPORTER_H #define DLGPACKAGEEXPORTER_H #include #include "Host.h" namespace Ui { class dlgPackageExporter; } class dlgPackageExporter : public QDialog { Q_OBJECT public: explicit dlgPackageExporter(QWidget *parent = 0); explicit dlgPackageExporter(QWidget *parent, Host*); ~dlgPackageExporter(); void recurseTree(QTreeWidgetItem *, QList&); void listTriggers(); void recurseTriggers(TTrigger*, QTreeWidgetItem*); void listAliases(); void recurseAliases(TAlias*, QTreeWidgetItem*); void listScripts(); void recurseScripts(TScript*, QTreeWidgetItem*); void listKeys(); void recurseKeys(TKey*, QTreeWidgetItem*); void listActions(); void recurseActions(TAction*, QTreeWidgetItem*); void listTimers(); void recurseTimers(TTimer*, QTreeWidgetItem*); QMap triggerMap; QMap aliasMap; QMap scriptMap; QMap keyMap; QMap actionMap; QMap timerMap; private: Ui::dlgPackageExporter *ui; Host* mpHost; QTreeWidget * treeWidget; QPushButton *exportButton; QPushButton *closeButton; QString filePath; QString tempDir; QString packageName; QString zip; public slots: void slot_addFiles(); void slot_browse_button(); void slot_export_package(); }; #endif // DLGPACKAGEEXPORTER_H mudlet-2.1/src/T2DMap.h0000644000175000017500000001220112070466512014144 0ustar csmallcsmall /*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn - KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef T2DMAP_H #define T2DMAP_H #include #include #include class T2DMap : public QWidget { Q_OBJECT public: T2DMap(); explicit T2DMap( QWidget *parent = 0); void paintMap(); void setMapZoom( int zoom ); QColor getColor( int id ); QColor _getColor( int id ); void init(); void exportAreaImage( int ); void paintEvent( QPaintEvent * ); void mousePressEvent(QMouseEvent * ); void mouseDoubleClickEvent ( QMouseEvent * event ); bool event(QEvent * event ); void wheelEvent ( QWheelEvent * ); void mouseMoveEvent( QMouseEvent * event ); void mouseReleaseEvent(QMouseEvent * e ); int getTopLeftSelection(); void setRoomSize( double ); void setExitSize( double ); void createLabel( QRectF labelRect ); TMap * mpMap; Host * mpHost; int xzoom; int yzoom; int _rx; int _ry; QPoint mPHighlight; bool mPick; int mTarget; //int mRoomSelection; bool mStartSpeedWalk; QMap mAreaExitList; QMap mUserActions; //string list: 0 is event name, 1 is menu it is under if it is QMap mUserMenus; //unique name, List:parent name ("" if null), display name QPoint mMoveTarget; bool mRoomBeingMoved; QPoint mPHighlightMove; float mTX; float mTY; int mChosenRoomColor; float xspan; float yspan; bool mMultiSelection; QRectF mMultiRect; bool mPopupMenu; QList mMultiSelectionList; QPoint mOldMousePos; bool mNewMoveAction; QRectF mMapInfoRect; int mFontHeight; bool mShowRoomID; QMap mPixMap; // QMap mGridPix; int gzoom; double rSize; double eSize; int mRID; int mAID; int mOx; int mOy; int mOz; bool mShiftMode; bool mShowInfo; QComboBox * arealist_combobox; QDialog * mpCustomLinesDialog; int mCustomLinesRoomFrom; int mCustomLinesRoomTo; QString mCustomLinesRoomExit; QComboBox * mpCurrentLineStyle; QPushButton * mpCurrentLineColor; QColor mCurrentLineColor; QCheckBox * mpCurrentLineArrow; bool mShowGrid; QPointF mLastMouseClick; bool mBubbleMode; bool mMapperUseAntiAlias; bool mLabelHilite; bool mMoveLabel; int mCustomLineSelectedRoom; QString mCustomLineSelectedExit; int mCustomLineSelectedPoint; QTreeWidget mMultiSelectionListWidget; bool mSizeLabel; bool gridMapSizeChange; bool isCenterViewCall; QString mHelpMsg; signals: public slots: void slot_roomSelectionChanged(); void slot_deleteCustomExitLine(); void slot_moveLabel(); void slot_deleteLabel(); void slot_editLabel(); void slot_setPlayerLocation(); void slot_createLabel(); void slot_customLineColor(); void shiftZup(); void shiftZdown(); void switchArea(QString); void toggleShiftMode(); void shiftUp(); void shiftDown(); void shiftLeft(); void shiftRight(); void slot_setCharacter(); void slot_setImage(); void slot_movePosition(); void slot_defineNewColor(); void slot_selectRoomColor(QListWidgetItem * pI ); void slot_moveRoom(); void slot_deleteRoom(); void slot_changeColor(); void slot_spread(); void slot_shrink(); void slot_setExits(); void slot_setUserData(); void slot_lockRoom(); void slot_setRoomWeight(); void slot_setArea(); void slot_setCustomLine(); void slot_setCustomLine2(); void slot_userAction(QString); void slot_setCustomLine2B(QTreeWidgetItem*, int); }; #endif // T2DMAP_H mudlet-2.1/src/TConsole.cpp0000644000175000017500000026226212076170616015217 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn (KoehnHeiko@googlemail.com) * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "TConsole.h" #include "mudlet.h" #include #include "TCommandLine.h" #include //#include #include #include #include #include //#include #include #include #include #include #include #include #include #include "TDebug.h" #include "TTextEdit.h" #include #include "XMLexport.h" #include #include "TLabel.h" #include "TSplitter.h" #include "TSplitterHandle.h" #include #include "dlgNotepad.h" #include #include "dlgMapper.h" using namespace std; const QString TConsole::cmLuaLineVariable("line"); TConsole::TConsole( Host * pH, bool isDebugConsole, QWidget * parent ) : QWidget( parent ) , mpHost( pH ) , buffer( pH ) , emergencyStop( new QToolButton ) , layerCommandLine( 0 ) , mBgColor( QColor( 255, 255, 255 ) ) , mClipboard( mpHost ) , mCommandBgColor( QColor( 0, 0, 0 ) ) , mCommandFgColor( QColor( 213, 195, 0 ) ) , mConsoleName( "main" ) , mDisplayFont( QFont("Bitstream Vera Sans Mono", 10, QFont::Courier ) )//mDisplayFont( QFont("Monospace", 10, QFont::Courier ) ) , mFgColor( QColor( 0, 0, 0 ) ) , mIndentCount( 0 ) , mIsDebugConsole( isDebugConsole ) , mLogFileName(QString("")) , mLogToLogFile( false ) , mMainFrameBottomHeight( 0 ) , mMainFrameLeftWidth( 0 ) , mMainFrameRightWidth( 0 ) , mMainFrameTopHeight( 0 ) , mOldX( 0 ) , mOldY( 0 ) , mpBaseVFrame( new QWidget( this ) ) , mpTopToolBar( new QWidget( mpBaseVFrame ) ) , mpBaseHFrame( new QWidget( mpBaseVFrame ) ) , mpLeftToolBar( new QWidget( mpBaseHFrame ) ) , mpMainFrame( new QWidget( mpBaseHFrame ) ) , mpRightToolBar( new QWidget( mpBaseHFrame ) ) , mpMainDisplay( new QWidget( mpMainFrame ) ) , mpMapper( 0 ) , mpScrollBar( new QScrollBar ) , mRecordReplay( false ) , mSystemMessageBgColor( mBgColor ) , mSystemMessageFgColor( QColor( 255,0,0 ) ) , mTriggerEngineMode( false ) , mUserConsole( false ) , mWindowIsHidden( false ) , mWrapAt( 100 ) , networkLatency( new QLineEdit ) , mLastBufferLogLine( 0 ) , mUserAgreedToCloseConsole( false ) , mpBufferSearchBox( new QLineEdit ) , mpBufferSearchUp( new QToolButton ) , mpBufferSearchDown( new QToolButton ) , mCurrentSearchResult( 0 ) , mSearchQuery("") { //mDisplayFont.setWordSpacing( 0 ); // mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, 0 ); QShortcut * ps = new QShortcut(this); ps->setKey(Qt::CTRL + Qt::Key_W); ps->setContext(Qt::WidgetShortcut); if( mIsDebugConsole ) { setWindowTitle("Debug Console"); mWrapAt = 50; mIsSubConsole = false; mStandardFormat.bgR = mBgColor.red(); mStandardFormat.bgG = mBgColor.green(); mStandardFormat.bgB = mBgColor.blue(); mStandardFormat.fgR = mFgColor.red(); mStandardFormat.fgG = mFgColor.green(); mStandardFormat.fgB = mFgColor.blue(); mStandardFormat.bold = false; mStandardFormat.italics = false; mStandardFormat.underline = false; } else { setWindowTitle("keine Debug Console"); if( parent ) { mIsSubConsole = true; mpHost->mpConsole->mSubConsoleList.append( this ); mMainFrameTopHeight = 0; mMainFrameBottomHeight = 0; mMainFrameLeftWidth = 0; mMainFrameRightWidth = 0; } else { mIsSubConsole = false; mMainFrameTopHeight = mpHost->mBorderTopHeight; mMainFrameBottomHeight = mpHost->mBorderBottomHeight; mMainFrameLeftWidth = mpHost->mBorderLeftWidth; mMainFrameRightWidth = mpHost->mBorderRightWidth; mCommandBgColor = mpHost->mCommandBgColor; mCommandFgColor = mpHost->mCommandFgColor; } mStandardFormat.bgR = mpHost->mBgColor.red(); mStandardFormat.bgG = mpHost->mBgColor.green(); mStandardFormat.bgB = mpHost->mBgColor.blue(); mStandardFormat.fgR = mpHost->mFgColor.red(); mStandardFormat.fgG = mpHost->mFgColor.green(); mStandardFormat.fgB = mpHost->mFgColor.blue(); mStandardFormat.bold = false; mStandardFormat.italics = false; mStandardFormat.underline = false; } setContentsMargins(0,0,0,0); if( mpHost ) profile_name = mpHost->getName(); else profile_name = "debug console"; mFormatSystemMessage.bgR = mBgColor.red(); mFormatSystemMessage.bgG = mBgColor.green(); mFormatSystemMessage.bgB = mBgColor.blue(); mFormatSystemMessage.fgR = 255; mFormatSystemMessage.fgG = 0; mFormatSystemMessage.fgB = 0; setAttribute( Qt::WA_DeleteOnClose ); setAttribute( Qt::WA_OpaquePaintEvent );//was disabled mWaitingForHighColorCode = false; mHighColorModeForeground = false; mHighColorModeBackground = false; mIsHighColorMode = false; QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding); QSizePolicy sizePolicy3( QSizePolicy::Expanding, QSizePolicy::Expanding); QSizePolicy sizePolicy2( QSizePolicy::Expanding, QSizePolicy::Fixed); QSizePolicy sizePolicy4( QSizePolicy::Fixed, QSizePolicy::Expanding); QSizePolicy sizePolicy5( QSizePolicy::Fixed, QSizePolicy::Fixed); QPalette mainPalette; mainPalette.setColor( QPalette::Text, QColor(0,0,0) ); mainPalette.setColor( QPalette::Highlight, QColor(55,55,255) ); mainPalette.setColor( QPalette::Window, QColor(0,0,0,255) ); QPalette splitterPalette; splitterPalette = mainPalette; splitterPalette.setColor( QPalette::Button, QColor(0,0,255,255) ); splitterPalette.setColor( QPalette::Window, QColor(0,255,0));//,255) ); splitterPalette.setColor( QPalette::Base, QColor(255,0,0,255) ); splitterPalette.setColor( QPalette::Window, QColor(255,255,255) ); //setPalette( mainPalette ); //QVBoxLayout * layoutFrame = new QVBoxLayout( mainFrame ); QPalette framePalette; framePalette.setColor( QPalette::Text, QColor(0,0,0) ); framePalette.setColor( QPalette::Highlight, QColor(55,55,255) ); framePalette.setColor( QPalette::Window, QColor(0,0,0,255) ); mpMainFrame->setPalette( framePalette ); mpMainFrame->setAutoFillBackground(true); mpMainFrame->setContentsMargins(0,0,0,0); QVBoxLayout * centralLayout = new QVBoxLayout; setLayout( centralLayout ); QVBoxLayout * baseVFrameLayout = new QVBoxLayout; mpBaseVFrame->setLayout( baseVFrameLayout ); baseVFrameLayout->setMargin( 0 ); baseVFrameLayout->setSpacing( 0 ); centralLayout->addWidget( mpBaseVFrame ); QHBoxLayout * baseHFrameLayout = new QHBoxLayout; mpBaseHFrame->setLayout( baseHFrameLayout ); baseHFrameLayout->setMargin( 0 ); baseHFrameLayout->setSpacing( 0 ); layout()->setSpacing( 0 ); layout()->setMargin( 0 ); setContentsMargins( 0, 0, 0, 0 ); QHBoxLayout * topBarLayout = new QHBoxLayout; mpTopToolBar->setLayout( topBarLayout ); mpTopToolBar->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); mpTopToolBar->setContentsMargins(0,0,0,0); mpTopToolBar->setAutoFillBackground(true); QPalette topbarPalette; topbarPalette.setColor( QPalette::Text, QColor(255,255,255) ); topbarPalette.setColor( QPalette::Highlight, QColor(55,55,255) ); topbarPalette.setColor( QPalette::Window, QColor(0,255,0,255) ); topbarPalette.setColor( QPalette::Base, QColor(0,255,0,255) ); //mpTopToolBar->setPalette(topbarPalette); topBarLayout->setMargin( 0 ); topBarLayout->setSpacing(0); QVBoxLayout * leftBarLayout = new QVBoxLayout; mpLeftToolBar->setLayout( leftBarLayout ); mpLeftToolBar->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding)); mpLeftToolBar->setAutoFillBackground(true); leftBarLayout->setMargin( 0 ); leftBarLayout->setSpacing(0); mpLeftToolBar->setContentsMargins(0,0,0,0); QVBoxLayout * rightBarLayout = new QVBoxLayout; mpRightToolBar->setLayout( rightBarLayout ); mpRightToolBar->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding)); mpRightToolBar->setAutoFillBackground(true); rightBarLayout->setMargin( 0 ); rightBarLayout->setSpacing(0); mpRightToolBar->setContentsMargins(0,0,0,0); mpBaseVFrame->setContentsMargins(0,0,0,0); baseVFrameLayout->setSpacing(0); baseVFrameLayout->setMargin( 0 ); mpTopToolBar->setContentsMargins(0,0,0,0); baseVFrameLayout->addWidget( mpTopToolBar ); baseVFrameLayout->addWidget( mpBaseHFrame ); baseHFrameLayout->addWidget( mpLeftToolBar ); QWidget * mpCorePane = new QWidget( mpBaseHFrame ); QVBoxLayout * coreSpreadLayout = new QVBoxLayout; mpCorePane->setLayout( coreSpreadLayout ); mpCorePane->setContentsMargins(0,0,0,0); coreSpreadLayout->setMargin(0); coreSpreadLayout->setSpacing(0); coreSpreadLayout->addWidget( mpMainFrame ); mpCorePane->setSizePolicy( sizePolicy ); baseHFrameLayout->addWidget( mpCorePane ); baseHFrameLayout->addWidget( mpRightToolBar ); mpTopToolBar->setContentsMargins(0,0,0,0); mpBaseHFrame->setAutoFillBackground(true); baseHFrameLayout->setSpacing(0); baseHFrameLayout->setMargin(0); setContentsMargins(0,0,0,0); mpBaseHFrame->setContentsMargins(0,0,0,0); centralLayout->setSpacing(0); centralLayout->setContentsMargins(0,0,0,0); centralLayout->setMargin(0); mpMainDisplay->move( mMainFrameLeftWidth, mMainFrameTopHeight ); mpMainFrame->show(); mpMainDisplay->show(); mpMainFrame->setContentsMargins(0,0,0,0); mpMainDisplay->setContentsMargins(0,0,0,0); QVBoxLayout * layout = new QVBoxLayout; mpMainDisplay->setLayout(layout); layout->setContentsMargins(0,0,0,0); layout->setSpacing(0); mpBaseVFrame->setSizePolicy(sizePolicy); mpBaseHFrame->setSizePolicy(sizePolicy); mpBaseVFrame->setFocusPolicy(Qt::NoFocus); mpBaseHFrame->setFocusPolicy(Qt::NoFocus); baseVFrameLayout->setMargin(0); baseHFrameLayout->setMargin(0); centralLayout->setMargin(0); mpCommandLine = new TCommandLine( pH, this, mpMainDisplay ); mpCommandLine->setContentsMargins(0,0,0,0); mpCommandLine->setSizePolicy( sizePolicy ); mpCommandLine->setFocusPolicy( Qt::StrongFocus ); layer = new QWidget( mpMainDisplay ); layer->setContentsMargins(0,0,0,0); layer->setContentsMargins( 0, 0, 0, 0 );//neu rc1 layer->setSizePolicy( sizePolicy ); layer->setFocusPolicy( Qt::NoFocus ); QHBoxLayout * layoutLayer = new QHBoxLayout; layer->setLayout( layoutLayer ); layoutLayer->setMargin( 0 );//neu rc1 layoutLayer->setSpacing( 0 );//neu rc1 layoutLayer->setMargin( 0 );//neu rc1 QSizePolicy sizePolicyLayer(QSizePolicy::Expanding, QSizePolicy::Expanding); mpScrollBar->setFixedWidth( 15 ); splitter = new TSplitter( Qt::Vertical ); splitter->setContentsMargins(0,0,0,0); splitter->setSizePolicy( sizePolicy ); splitter->setOrientation( Qt::Vertical ); splitter->setHandleWidth( 3 ); splitter->setPalette( splitterPalette ); splitter->setParent( layer ); setFocusProxy( mpCommandLine ); console = new TTextEdit( this, splitter, &buffer, mpHost, isDebugConsole, false ); console->setContentsMargins(0,0,0,0); console->setSizePolicy( sizePolicy3 ); console->setFocusPolicy( Qt::NoFocus ); console2 = new TTextEdit( this, splitter, &buffer, mpHost, isDebugConsole, true ); console2->setContentsMargins(0,0,0,0); console2->setSizePolicy( sizePolicy3 ); console2->setFocusPolicy( Qt::NoFocus ); splitter->addWidget( console ); splitter->addWidget( console2 ); splitter->setCollapsible( 1, false ); splitter->setCollapsible( 0, false ); splitter->setStretchFactor(0,6); splitter->setStretchFactor(1,1); layoutLayer->addWidget( splitter ); layoutLayer->addWidget( mpScrollBar ); layoutLayer->setContentsMargins(0,0,0,0); layoutLayer->setSpacing( 1 );// nicht naeher dran, da es sonst performance probleme geben koennte beim display layerCommandLine = new QWidget;//( mpMainFrame );//layer ); layerCommandLine->setContentsMargins(0,0,0,0); layerCommandLine->setSizePolicy( sizePolicy2 ); layerCommandLine->setMaximumHeight(31); layerCommandLine->setMinimumHeight(31); QHBoxLayout * layoutLayer2 = new QHBoxLayout( layerCommandLine ); layoutLayer2->setMargin(0); layoutLayer2->setSpacing(0); QWidget * buttonMainLayer = new QWidget;//( layerCommandLine ); buttonMainLayer->setSizePolicy(sizePolicy); buttonMainLayer->setContentsMargins(0,0,0,0); QVBoxLayout * layoutButtonMainLayer = new QVBoxLayout( buttonMainLayer ); layoutButtonMainLayer->setMargin(0); layoutButtonMainLayer->setContentsMargins(0,0,0,0); layoutButtonMainLayer->setSpacing(0); /*buttonMainLayer->setMinimumHeight(31); buttonMainLayer->setMaximumHeight(31);*/ QWidget * buttonLayer = new QWidget; QGridLayout * layoutButtonLayer = new QGridLayout( buttonLayer ); layoutButtonLayer->setMargin(0); layoutButtonLayer->setSpacing(0); QWidget * buttonLayerSpacer = new QWidget(buttonLayer); buttonLayerSpacer->setSizePolicy( sizePolicy4 ); layoutButtonMainLayer->addWidget( buttonLayerSpacer ); layoutButtonMainLayer->addWidget( buttonLayer ); QToolButton * timeStampButton = new QToolButton; timeStampButton->setCheckable( true ); timeStampButton->setMinimumSize(QSize(30,30)); timeStampButton->setMaximumSize(QSize(30,30)); timeStampButton->setSizePolicy( sizePolicy5 ); timeStampButton->setFocusPolicy( Qt::NoFocus ); timeStampButton->setToolTip("Show Time Stamps"); QIcon icon(":/icons/dialog-information.png"); timeStampButton->setIcon( icon ); connect( timeStampButton, SIGNAL(pressed()), console, SLOT(slot_toggleTimeStamps())); QToolButton * replayButton = new QToolButton; replayButton->setCheckable( true ); replayButton->setMinimumSize(QSize(30,30)); replayButton->setMaximumSize(QSize(30,30)); replayButton->setSizePolicy( sizePolicy5 ); replayButton->setFocusPolicy( Qt::NoFocus ); replayButton->setToolTip("record a replay"); QIcon icon4(":/icons/media-tape.png"); replayButton->setIcon( icon4 ); connect( replayButton, SIGNAL(pressed()), this, SLOT(slot_toggleReplayRecording())); logButton = new QToolButton; logButton->setMinimumSize(QSize(30, 30)); logButton->setMaximumSize(QSize(30, 30)); logButton->setCheckable( true ); logButton->setSizePolicy( sizePolicy5 ); logButton->setFocusPolicy( Qt::NoFocus ); logButton->setToolTip("start logging MUD output to log file"); QIcon icon3(":/icons/folder-downloads.png"); logButton->setIcon( icon3 ); connect( logButton, SIGNAL(pressed()), this, SLOT(slot_toggleLogging())); networkLatency->setReadOnly( true ); networkLatency->setSizePolicy( sizePolicy4 ); networkLatency->setFocusPolicy( Qt::NoFocus ); networkLatency->setToolTip("N: is the latency of the MUD server and network (aka ping, in seconds),
    S: is the system processing time - how long your triggers took to process the last line(s)"); networkLatency->setMaximumSize( 120, 30 ); networkLatency->setMinimumSize( 120, 30 ); networkLatency->setAutoFillBackground( true ); networkLatency->setContentsMargins(0,0,0,0); QPalette basePalette; basePalette.setColor( QPalette::Text, QColor(0,0,0) ); basePalette.setColor( QPalette::Base, QColor(255, 255, 255) ); networkLatency->setPalette( basePalette ); networkLatency->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter ); QFont latencyFont = QFont("Bitstream Vera Sans Mono", 10, QFont::Courier); int width; int maxWidth = 120; width = QFontMetrics( latencyFont ).boundingRect(QString("N:0.000 S:0.000")).width(); if( width < maxWidth ) { networkLatency->setFont( latencyFont ); } else { QFont latencyFont2 = QFont("Bitstream Vera Sans Mono", 9, QFont::Courier); width = QFontMetrics( latencyFont2 ).boundingRect(QString("N:0.000 S:0.000")).width(); if( width < maxWidth ) { networkLatency->setFont( latencyFont2 ); } else { QFont latencyFont3 = QFont("Bitstream Vera Sans Mono", 8, QFont::Courier); width = QFontMetrics( latencyFont3 ).boundingRect(QString("N:0.000 S:0.000")).width(); networkLatency->setFont( latencyFont3 ); } } QIcon icon2(":/icons/edit-bomb.png"); emergencyStop->setMinimumSize(QSize(30,30)); emergencyStop->setMaximumSize(QSize(30,30)); emergencyStop->setIcon( icon2 ); emergencyStop->setSizePolicy( sizePolicy4 ); emergencyStop->setFocusPolicy( Qt::NoFocus ); emergencyStop->setCheckable( true ); emergencyStop->setToolTip("Emergency Stop. Stop All Timers and Triggers"); connect( emergencyStop, SIGNAL(clicked(bool)), this, SLOT(slot_stop_all_triggers( bool ))); mpBufferSearchBox->setMinimumSize(QSize(100,30)); mpBufferSearchBox->setMaximumSize(QSize(150,30)); mpBufferSearchBox->setSizePolicy( sizePolicy5 ); mpBufferSearchBox->setFont(mpHost->mCommandLineFont); mpBufferSearchBox->setFocusPolicy( Qt::ClickFocus ); #if QT_VERSION >= 0x040700 mpBufferSearchBox->setPlaceholderText("Search ..."); #endif QPalette __pal; __pal.setColor(QPalette::Text, mpHost->mCommandLineFgColor );//QColor(0,0,192)); __pal.setColor(QPalette::Highlight,QColor(0,0,192)); __pal.setColor(QPalette::HighlightedText, QColor(255,255,255)); __pal.setColor(QPalette::Base,mpHost->mCommandLineBgColor);//QColor(255,255,225)); __pal.setColor(QPalette::Window, mpHost->mCommandLineBgColor); mpBufferSearchBox->setPalette( __pal ); mpBufferSearchBox->setToolTip("Search buffer"); connect( mpBufferSearchBox, SIGNAL(returnPressed()), this, SLOT(slot_searchBufferUp())); mpBufferSearchUp->setMinimumSize(QSize(30,30)); mpBufferSearchUp->setMaximumSize(QSize(30,30)); mpBufferSearchUp->setSizePolicy( sizePolicy5 ); mpBufferSearchUp->setFocusPolicy( Qt::NoFocus ); mpBufferSearchUp->setToolTip("next result"); mpBufferSearchUp->setFocusPolicy( Qt::NoFocus ); QIcon icon34(":/icons/export.png"); mpBufferSearchUp->setIcon( icon34 ); connect( mpBufferSearchUp, SIGNAL(clicked()), this, SLOT(slot_searchBufferUp())); mpBufferSearchDown->setMinimumSize(QSize(30,30)); mpBufferSearchDown->setMaximumSize(QSize(30,30)); mpBufferSearchDown->setSizePolicy( sizePolicy5 ); mpBufferSearchDown->setFocusPolicy( Qt::NoFocus ); mpBufferSearchDown->setToolTip("next result"); mpBufferSearchDown->setFocusPolicy( Qt::NoFocus ); QIcon icon35(":/icons/import.png"); mpBufferSearchDown->setIcon( icon35 ); connect( mpBufferSearchDown, SIGNAL(clicked()), this, SLOT(slot_searchBufferDown())); layoutLayer2->addWidget( mpCommandLine ); layoutLayer2->addWidget( buttonMainLayer ); layoutButtonLayer->addWidget( mpBufferSearchBox,0, 0, 0, 4 ); layoutButtonLayer->addWidget( mpBufferSearchUp, 0, 5 ); layoutButtonLayer->addWidget( mpBufferSearchDown, 0, 6 ); layoutButtonLayer->addWidget( timeStampButton, 0, 7 ); layoutButtonLayer->addWidget( replayButton, 0, 8 ); layoutButtonLayer->addWidget( logButton, 0, 9 ); layoutButtonLayer->addWidget( emergencyStop, 0, 10 ); layoutButtonLayer->addWidget( networkLatency, 0, 11 ); layoutLayer2->setContentsMargins(0,0,0,0); layout->addWidget( layer ); networkLatency->setFrame( false ); //QPalette whitePalette; //whitePalette.setColor( QPalette::Window, baseColor);//,255) ); layerCommandLine->setPalette( basePalette ); layerCommandLine->setAutoFillBackground( true ); centralLayout->addWidget( layerCommandLine ); QList sizeList; sizeList << 6 << 2; splitter->setSizes( sizeList ); console->show(); console2->show(); console2->hide(); if( mIsDebugConsole ) mpCommandLine->hide(); isUserScrollBack = false; connect( mpScrollBar, SIGNAL(valueChanged(int)), console, SLOT(slot_scrollBarMoved(int))); if( mIsSubConsole ) { mpScrollBar->hide(); console2->hide(); layerCommandLine->hide(); mpMainFrame->move(0,0); mpMainDisplay->move(0,0); } if( mIsDebugConsole ) { layerCommandLine->hide(); } mpBaseVFrame->setContentsMargins(0,0,0,0); mpBaseHFrame->setContentsMargins(0,0,0,0); mpBaseVFrame->layout()->setMargin(0); mpBaseVFrame->layout()->setSpacing(0); mpBaseHFrame->layout()->setMargin(0); mpBaseHFrame->layout()->setSpacing(0); setAttribute( Qt::WA_OpaquePaintEvent );//was disabled buttonLayerSpacer->setMinimumHeight(0); buttonLayerSpacer->setMinimumWidth(100); buttonLayer->setMaximumHeight(31); //buttonLayer->setMaximumWidth(31); buttonLayer->setMinimumWidth(400); buttonLayer->setMaximumWidth(400); buttonMainLayer->setMinimumWidth(400); buttonMainLayer->setMaximumWidth(400); setFocusPolicy(Qt::ClickFocus); setFocusProxy(mpCommandLine); console->setFocusPolicy(Qt::ClickFocus); console->setFocusProxy(mpCommandLine); console2->setFocusPolicy(Qt::ClickFocus); console2->setFocusProxy(mpCommandLine); buttonLayerSpacer->setAutoFillBackground( true ); buttonLayerSpacer->setPalette( __pal ); buttonMainLayer->setAutoFillBackground( true ); buttonMainLayer->setPalette( __pal ); buttonLayer->setAutoFillBackground( true ); buttonLayer->setPalette( __pal ); layerCommandLine->setPalette( __pal ); changeColors(); } void TConsole::setLabelStyleSheet( std::string & buf, std::string & sh ) { std::string key = buf; QString sheet = sh.c_str(); if( mLabelMap.find( key ) != mLabelMap.end() ) { QLabel * pC = mLabelMap[key]; if( ! pC ) return; pC->setStyleSheet( sheet ); return; } } void TConsole::resizeEvent( QResizeEvent * event ) { if( ! mIsDebugConsole && ! mIsSubConsole ) { mMainFrameTopHeight = mpHost->mBorderTopHeight; mMainFrameBottomHeight = mpHost->mBorderBottomHeight; mMainFrameLeftWidth = mpHost->mBorderLeftWidth; mMainFrameRightWidth = mpHost->mBorderRightWidth; } int x = event->size().width(); int y = event->size().height(); if( ! mIsSubConsole && ! mIsDebugConsole ) { mpMainFrame->resize(x,y); mpBaseVFrame->resize(x, y); mpBaseHFrame->resize(x, y); x = x-mpLeftToolBar->width()-mpRightToolBar->width(); y = y-mpTopToolBar->height(); mpMainDisplay->resize( x - mMainFrameLeftWidth - mMainFrameRightWidth, y - mMainFrameTopHeight - mMainFrameBottomHeight - mpCommandLine->height() ); } else { mpMainFrame->resize( x, y ); mpMainDisplay->resize( x,y);//x - mMainFrameLeftWidth - mMainFrameRightWidth, y - mMainFrameTopHeight - mMainFrameBottomHeight ); } mpMainDisplay->move( mMainFrameLeftWidth, mMainFrameTopHeight ); if( mIsSubConsole || mIsDebugConsole ) { layerCommandLine->hide(); mpCommandLine->hide(); } else { //layerCommandLine->move(0,mpMainFrame->height()-layerCommandLine->height()); layerCommandLine->move(0, mpBaseVFrame->height()-layerCommandLine->height()); } QWidget::resizeEvent( event ); if( ! mIsDebugConsole && ! mIsSubConsole ) { TLuaInterpreter * pLua = mpHost->getLuaInterpreter(); QString func = "handleWindowResizeEvent"; QString n = "WindowResizeEvent"; pLua->call( func, n ); TEvent me; me.mArgumentList.append( "sysWindowResizeEvent" ); me.mArgumentList.append( QString::number(x - mMainFrameLeftWidth - mMainFrameRightWidth) ); me.mArgumentList.append( QString::number(y - mMainFrameTopHeight - mMainFrameBottomHeight - mpCommandLine->height()) ); me.mArgumentList.append( mConsoleName ); me.mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); me.mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); me.mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); me.mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); mpHost->raiseEvent( &me ); } } void TConsole::refresh() { if( ! mIsDebugConsole ) { mMainFrameTopHeight = mpHost->mBorderTopHeight; mMainFrameBottomHeight = mpHost->mBorderBottomHeight; mMainFrameLeftWidth = mpHost->mBorderLeftWidth; mMainFrameRightWidth = mpHost->mBorderRightWidth; } int x = width(); int y = height(); mpBaseVFrame->resize( x, y ); mpBaseHFrame->resize( x, y ); x = mpBaseVFrame->width(); if( !mpLeftToolBar->isHidden() ) x -= mpLeftToolBar->width(); if( !mpRightToolBar->isHidden() ) x -= mpRightToolBar->width(); y = mpBaseVFrame->height(); if( !mpTopToolBar->isHidden() ) y -= mpTopToolBar->height(); mpMainDisplay->resize( x - mMainFrameLeftWidth - mMainFrameRightWidth, y - mMainFrameTopHeight - mMainFrameBottomHeight - mpCommandLine->height() ); mpMainDisplay->move( mMainFrameLeftWidth, mMainFrameTopHeight ); x = width(); y = height(); QSize s = QSize(x,y); QResizeEvent event(s, s); QApplication::sendEvent( this, &event); } void TConsole::closeEvent( QCloseEvent *event ) { if( mIsDebugConsole ) { if( ! mudlet::self()->isGoingDown() ) { hide(); mudlet::mpDebugArea->setVisible(false); mudlet::debugMode = false; event->ignore(); return; } else { event->accept(); return; } } if( mUserConsole ) { if( ! mudlet::self()->isGoingDown() ) { hide(); event->ignore(); return; } else { event->accept(); return; } } if( profile_name != "default_host" ) { TEvent conCloseEvent; conCloseEvent.mArgumentList.append( "sysExitEvent" ); conCloseEvent.mArgumentTypeList.append(ARGUMENT_TYPE_STRING); mpHost->raiseEvent( & conCloseEvent ); if( mpHost->mFORCE_SAVE_ON_EXIT ) { QString directory_xml = QDir::homePath()+"/.config/mudlet/profiles/"+profile_name+"/current"; QString filename_xml = directory_xml + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss")+".xml"; QDir dir_xml; if( ! dir_xml.exists( directory_xml ) ) { dir_xml.mkpath( directory_xml ); } QFile file_xml( filename_xml ); if( file_xml.open( QIODevice::WriteOnly ) ) { mpHost->modulesToWrite.clear(); XMLexport writer( mpHost ); writer.exportHost( & file_xml ); file_xml.close(); mpHost->saveModules(0); } if( mpHost->mpMap->rooms.size() > 0 ) { QDir dir_map; QString directory_map = QDir::homePath()+"/.config/mudlet/profiles/"+profile_name+"/map"; QString filename_map = directory_map + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss")+"map.dat"; if( ! dir_map.exists( directory_map ) ) { dir_map.mkpath( directory_map ); } QFile file_map( filename_map ); if ( file_map.open( QIODevice::WriteOnly ) ) { QDataStream out( & file_map ); mpHost->mpMap->serialize( out ); file_map.close(); } } event->accept(); return; } } if( profile_name != "default_host" && ! mUserAgreedToCloseConsole ) { ASK: int choice = QMessageBox::question( this, "Exiting Session: Question", "Do you want to save the profile "+profile_name, QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel ); if( choice == QMessageBox::Cancel ) { event->setAccepted(false); event->ignore(); return; } if( choice == QMessageBox::Yes ) { QString directory_xml = QDir::homePath()+"/.config/mudlet/profiles/"+profile_name+"/current"; QString filename_xml = directory_xml + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss")+".xml"; QDir dir_xml; if( ! dir_xml.exists( directory_xml ) ) { dir_xml.mkpath( directory_xml ); } QFile file_xml( filename_xml ); if( file_xml.open( QIODevice::WriteOnly ) ) { /*XMLexport writer( mpHost ); writer.exportHost( & file_xml ); file_xml.close();*/ mpHost->modulesToWrite.clear(); XMLexport writer( mpHost ); writer.exportHost( & file_xml ); file_xml.close(); mpHost->saveModules(0); if( mpHost->mpMap->rooms.size() > 0 ) { QDir dir_map; QString directory_map = QDir::homePath()+"/.config/mudlet/profiles/"+profile_name+"/map"; QString filename_map = directory_map + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss")+"map.dat"; if( ! dir_map.exists( directory_map ) ) { dir_map.mkpath( directory_map ); } QFile file_map( filename_map ); if ( file_map.open( QIODevice::WriteOnly ) ) { QDataStream out( & file_map ); mpHost->mpMap->serialize( out ); file_map.close(); } } event->accept(); return; } else { QMessageBox::critical( this, "ERROR: Not closing profile.", "Failed to save "+profile_name+" to location "+filename_xml+" because of the following error: "+file_xml.errorString() ); goto ASK; } } else if( choice == QMessageBox::No ) { event->accept(); return; } else { if( ! mudlet::self()->isGoingDown() ) { QMessageBox::warning( this, "Aborting exit","Session exit aborted on user request." ); event->ignore(); return; } else { event->accept(); return; } } } } int TConsole::getButtonState() { return mButtonState; } void TConsole::slot_toggleLogging() { if( mIsDebugConsole ) return; mLogToLogFile = ! mLogToLogFile; //mpHost->mLogStatus = mLogToLogFile; if( mLogToLogFile ) { QFile file( QDir::homePath()+"/.config/mudlet/autolog" ); file.open( QIODevice::WriteOnly | QIODevice::Text ); QTextStream out(&file); file.close(); } else { QFile file( QDir::homePath()+"/.config/mudlet/autolog" ); file.remove(); } if( mLogToLogFile ) { mLastBufferLogLine = buffer.size(); QString directoryLogFile = QDir::homePath()+"/.config/mudlet/profiles/"+profile_name+"/log"; QString mLogFileName = directoryLogFile + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss"); if( mpHost->mRawStreamDump ) { mLogFileName.append(".html"); } else mLogFileName.append(".txt"); QDir dirLogFile; if( ! dirLogFile.exists( directoryLogFile ) ) { dirLogFile.mkpath( directoryLogFile ); } mLogFile.setFileName( mLogFileName ); mLogFile.open( QIODevice::WriteOnly ); mLogStream.setDevice( &mLogFile ); if( mpHost->mRawStreamDump ) mLogStream << ""; QString message = QString("Logging has started. Log file is ") + mLogFile.fileName() + "\n"; printSystemMessage( message ); } else { if( mpHost->mRawStreamDump ) mLogStream << "
"; mLogFile.close(); QString message = QString("Logging has been stopped. Log file is ") + mLogFile.fileName() + "\n"; printSystemMessage( message ); } } void TConsole::slot_toggleReplayRecording() { if( mIsDebugConsole ) return; mRecordReplay = ! mRecordReplay; if( mRecordReplay ) { QString directoryLogFile = QDir::homePath()+"/.config/mudlet/profiles/"+profile_name+"/log"; QString mLogFileName = directoryLogFile + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss"); mLogFileName.append(".dat"); QDir dirLogFile; if( ! dirLogFile.exists( directoryLogFile ) ) { dirLogFile.mkpath( directoryLogFile ); } mReplayFile.setFileName( mLogFileName ); mReplayFile.open( QIODevice::WriteOnly ); mReplayStream.setDevice( &mReplayFile ); mpHost->mTelnet.recordReplay(); QString message = QString("Replay recording has started. File: ") + mReplayFile.fileName() + "\n"; printSystemMessage( message ); } else { mReplayFile.close(); QString message = QString("Replay recording has been stopped. File: ") + mLogFile.fileName() + "\n"; printSystemMessage( message ); } } void TConsole::changeColors() { mDisplayFont.setFixedPitch(true); if( mIsDebugConsole ) { mDisplayFont.setStyleStrategy( (QFont::StyleStrategy)(QFont::NoAntialias | QFont::PreferQuality) ); mDisplayFont.setFixedPitch(true); console->setFont( mDisplayFont ); console2->setFont( mDisplayFont ); QPalette palette; palette.setColor( QPalette::Text, mFgColor ); palette.setColor( QPalette::Highlight, QColor(55,55,255) ); palette.setColor( QPalette::Base, QColor(0,0,0) ); console->setPalette( palette ); console2->setPalette( palette ); } else if( mIsSubConsole ) { mDisplayFont.setStyleStrategy( (QFont::StyleStrategy)(QFont::NoAntialias | QFont::PreferQuality ) ); #if defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && QT_VERSION >= 0x040800) QPixmap pixmap = QPixmap( 2000, 600 ); QPainter p(&pixmap); mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, 0 ); p.setFont(mDisplayFont); const QRectF r = QRectF(0,0,2000, 600); QRectF r2; const QString t = "123"; p.drawText(r,1,t,&r2); int mFontHeight = QFontMetrics( mDisplayFont ).height(); int mFontWidth = QFontMetrics( mDisplayFont ).width( QChar('W') ); qreal letterSpacing = (qreal)((qreal)mFontWidth-(qreal)(r2.width()/t.size())); console->mLetterSpacing = letterSpacing; console2->mLetterSpacing = letterSpacing; mpHost->mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, letterSpacing ); mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, console->mLetterSpacing ); #endif mDisplayFont.setFixedPitch(true); console->setFont( mDisplayFont ); console2->setFont( mDisplayFont ); QPalette palette; palette.setColor( QPalette::Text, mFgColor ); palette.setColor( QPalette::Highlight, QColor(55,55,255) ); palette.setColor( QPalette::Base, mBgColor ); setPalette( palette ); layer->setPalette( palette ); console->setPalette( palette ); console2->setPalette( palette ); } else { QPalette pal; pal.setColor(QPalette::Text, mpHost->mCommandLineFgColor );//QColor(0,0,192)); pal.setColor(QPalette::Highlight,QColor(0,0,192)); pal.setColor(QPalette::HighlightedText, QColor(255,255,255)); pal.setColor(QPalette::Base,mpHost->mCommandLineBgColor);//QColor(255,255,225)); mpCommandLine->setPalette( pal ); mpCommandLine->mRegularPalette = pal; if( mpHost->mNoAntiAlias ) mpHost->mDisplayFont.setStyleStrategy( QFont::NoAntialias ); else mpHost->mDisplayFont.setStyleStrategy( (QFont::StyleStrategy)( QFont::PreferAntialias | QFont::PreferQuality ) ); mpHost->mDisplayFont.setFixedPitch(true); mDisplayFont.setFixedPitch(true); #if defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && QT_VERSION >= 0x040800) QPixmap pixmap = QPixmap( 2000, 600 ); QPainter p(&pixmap); QFont _font = mpHost->mDisplayFont; _font.setLetterSpacing(QFont::AbsoluteSpacing, 0); p.setFont(_font); const QRectF r = QRectF(0,0,2000, 600); QRectF r2; const QString t = "123"; p.drawText(r,1,t,&r2); int mFontHeight = QFontMetrics( mpHost->mDisplayFont ).height(); int mFontWidth = QFontMetrics( mpHost->mDisplayFont ).width( QChar('W') ); qreal letterSpacing = (qreal)((qreal)mFontWidth-(qreal)(r2.width()/t.size())); console->mLetterSpacing = letterSpacing; console2->mLetterSpacing = letterSpacing; mpHost->mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, letterSpacing ); mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, console->mLetterSpacing ); #endif console->setFont( mpHost->mDisplayFont ); console2->setFont( mpHost->mDisplayFont ); QPalette palette; palette.setColor( QPalette::Text, mpHost->mFgColor ); palette.setColor( QPalette::Highlight, QColor(55,55,255) ); palette.setColor( QPalette::Base, mpHost->mBgColor ); setPalette( palette ); layer->setPalette( palette ); console->setPalette( palette ); console2->setPalette( palette ); mCommandFgColor = mpHost->mCommandFgColor; mCommandBgColor = mpHost->mCommandBgColor; mpCommandLine->setFont(mpHost->mDisplayFont); } QPalette palette; palette.setColor( QPalette::Button, QColor(0,0,255) ); palette.setColor( QPalette::Window, QColor(0,255,0) ); palette.setColor( QPalette::Base, QColor(255,0,0) ); if( ! mIsSubConsole ) { console->mWrapAt = mWrapAt; console2->mWrapAt = mWrapAt; splitter->setPalette( palette ); } buffer.updateColors(); if( ! mIsDebugConsole && ! mIsSubConsole ) { buffer.mWrapAt = mpHost->mWrapAt; buffer.mWrapIndent = mpHost->mWrapIndentCount; } } void TConsole::setConsoleBgColor( int r, int g, int b ) { mBgColor = QColor(r,g,b); console->setConsoleBgColor( r, g, b ); changeColors(); } void TConsole::setConsoleFgColor( int r, int g, int b ) { mFgColor = QColor(r,g,b); console->setConsoleFgColor( r, g, b ); changeColors(); } /*std::string TConsole::getCurrentTime() { time_t t; time(&t); tm lt; ostringstream s; s.str(""); struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); localtime_r( &t, < ); s << "["<mTelnet.loadReplay( fileName ); } void TConsole::printOnDisplay( std::string & incomingSocketData ) { //buffer.messen(); QString prompt ="";//FIXME mProcessingTime.restart(); mTriggerEngineMode = true; buffer.translateToPlainText( incomingSocketData ); mTriggerEngineMode = false; if( mLogToLogFile ) { if( ! mIsDebugConsole ) { if( mpHost->mRawStreamDump ) { if( buffer.size() > mLastBufferLogLine + 1 ) { if( buffer.size() < mLastBufferLogLine) { mLastBufferLogLine -= buffer.mBatchDeleteSize; if( mLastBufferLogLine < 0 ) { mLastBufferLogLine = 0; } } for( int i=mLastBufferLogLine+1; imTelnet.mGA_Driver ) { networkLatency->setText( QString("N:%1 S:%2").arg(mpHost->mTelnet.networkLatency,0,'f',3) .arg(processT/1000,0,'f',3)); } else { networkLatency->setText( QString(" S:%1").arg(processT/1000,0,'f',3)); } } void TConsole::runTriggers( int line ) { mDeletedLines = 0; mUserCursor.setY( line ); mIsPromptLine = buffer.promptBuffer.at( line ); mEngineCursor = line; mUserCursor.setX( 0 ); mCurrentLine = buffer.line( line ); mpHost->getLuaInterpreter()->set_lua_string( cmLuaLineVariable, mCurrentLine ); mCurrentLine.append('\n'); if( mLogToLogFile ) { if( ! mIsDebugConsole ) { if( ! mpHost->mRawStreamDump ) { mCurrentLine.replace(QChar(255), '\n'); mLogStream << mCurrentLine; } } } if( mudlet::debugMode ) { TDebug(QColor(Qt::darkGreen),QColor(Qt::black)) << "new line arrived:">>0; TDebug(QColor(Qt::lightGray),QColor(Qt::black)) << mCurrentLine<<"\n">>0; } mpHost->incomingStreamProcessor( mCurrentLine, line ); mIsPromptLine = false; //FIXME: neu schreiben: wenn lines oberhalb der aktuellen zeile gelöscht wurden->redraw clean slice // ansonsten einfach löschen } void TConsole::finalize() { console->showNewLines(); console2->showNewLines(); } QString TConsole::assemble_html_font_specs() { QString s; s = ""; return s; } void TConsole::logger_set_text_properties( QString tags ) { switch( tags.toInt() ) { case 0: m_LoggerfontSpecs.reset(); break; case 1: m_LoggerfontSpecs.bold = true; break; case 2: m_LoggerfontSpecs.bold = false; break; case 3: m_LoggerfontSpecs.italics = true; break; case 4: m_LoggerfontSpecs.underline = true; case 5: break; //FIXME support blinking case 6: break; //FIXME support fast blinking case 7: break; //FIXME support inverse case 9: break; //FIXME support strikethrough case 22: m_LoggerfontSpecs.bold = false; break; case 23: m_LoggerfontSpecs.italics = false; break; case 24: m_LoggerfontSpecs.underline = false; break; case 27: break; //FIXME inverse off case 29: break; //FIXME case 30: m_LoggerfontSpecs.fgColor = mpHost->mBlack; m_LoggerfontSpecs.fgColorLight = mpHost->mLightBlack; m_LoggerfontSpecs.fg_color_change(); break; case 31: m_LoggerfontSpecs.fgColor = mpHost->mRed; m_LoggerfontSpecs.fgColorLight = mpHost->mLightRed; m_LoggerfontSpecs.fg_color_change(); break; case 32: m_LoggerfontSpecs.fgColor = mpHost->mGreen; m_LoggerfontSpecs.fgColorLight = mpHost->mLightGreen; m_LoggerfontSpecs.fg_color_change(); break; case 33: m_LoggerfontSpecs.fgColor = mpHost->mYellow; m_LoggerfontSpecs.fgColorLight = mpHost->mLightYellow; m_LoggerfontSpecs.fg_color_change(); break; case 34: m_LoggerfontSpecs.fgColor = mpHost->mBlue; m_LoggerfontSpecs.fgColorLight = mpHost->mLightBlue; m_LoggerfontSpecs.fg_color_change(); break; case 35: m_LoggerfontSpecs.fgColor = mpHost->mMagenta; m_LoggerfontSpecs.fgColorLight = mpHost->mLightMagenta; m_LoggerfontSpecs.fg_color_change(); break; case 36: m_LoggerfontSpecs.fgColor = mpHost->mCyan; m_LoggerfontSpecs.fgColorLight = mpHost->mLightCyan; m_LoggerfontSpecs.fg_color_change(); break; case 37: m_LoggerfontSpecs.fgColor = mpHost->mWhite; m_LoggerfontSpecs.fgColorLight = mpHost->mLightWhite; m_LoggerfontSpecs.fg_color_change(); break; case 39: m_LoggerfontSpecs.bgColor = mpHost->mBgColor;//mWhite m_LoggerfontSpecs.bg_color_change(); break; case 40: m_LoggerfontSpecs.bgColor = mpHost->mBlack; m_LoggerfontSpecs.bg_color_change(); break; case 41: m_LoggerfontSpecs.bgColor = mpHost->mRed; m_LoggerfontSpecs.bg_color_change(); break; case 42: m_LoggerfontSpecs.bgColor = mpHost->mGreen; m_LoggerfontSpecs.bg_color_change(); break; case 43: m_LoggerfontSpecs.bgColor = mpHost->mYellow; m_LoggerfontSpecs.bg_color_change(); break; case 44: m_LoggerfontSpecs.bgColor = mpHost->mBlue; m_LoggerfontSpecs.bg_color_change(); break; case 45: m_LoggerfontSpecs.bgColor = mpHost->mMagenta; m_LoggerfontSpecs.bg_color_change(); break; case 46: m_LoggerfontSpecs.bgColor = mpHost->mCyan; m_LoggerfontSpecs.bg_color_change(); break; case 47: m_LoggerfontSpecs.bgColor = mpHost->mWhite; m_LoggerfontSpecs.bg_color_change(); break; }; } QString TConsole::logger_translate( QString & s ) { /* ANSI color codes: sequence = "ESCAPE + [ code_1; ... ; code_n m" ----------------------------------------- 0 reset 1 intensity bold on 2 intensity faint 3 italics on 4 underline on 5 blink slow 6 blink fast 7 inverse on 9 strikethrough 22 intensity normal (not bold, not faint) 23 italics off 24 underline off 27 inverse off 28 strikethrough off 30 fg black 31 fg red 32 fg green 33 fg yellow 34 fg blue 35 fg magenta 36 fg cyan 37 fg white 39 bg default white 40 bg black 41 bg red 42 bg green 43 bg yellow 44 bg blue 45 bg magenta 46 bg cyan 47 bg white 49 bg black */ //s.replace(QChar('\\'), "\\\\"); s.replace(QChar('\n'), "
"); s.replace(QChar('\t'), " "); int sequence_begin = 0; int sequence_end = 0; QString sequence; while( (sequence_begin = s.indexOf(QString("\033["),0) ) != -1 ) { sequence_end = s.indexOf(QChar('m'),sequence_begin); int sequence_length = abs(sequence_begin - sequence_end )+1; if( sequence_end != -1 ) { sequence = s.mid(sequence_begin+2,sequence_length-3); // weil 3 elemente ausgelassen werden QStringList textPropertyList; if( sequence.indexOf(QChar(';'),0) ) { textPropertyList = sequence.split(QChar(';'),QString::SkipEmptyParts); } else { textPropertyList << sequence; } for( int i=0; iscrollDown( lines ); if( console->isTailMode() ) { console2->mCursorY = buffer.lineBuffer.size();//getLastLineNumber(); console2->hide(); console->mCursorY = buffer.lineBuffer.size();//getLastLineNumber(); console->mIsTailMode = true; console->updateScreenView(); console->forceUpdate(); } } void TConsole::scrollUp( int lines ) { console2->mIsTailMode = true; console2->mCursorY = buffer.size();//getLastLineNumber(); console2->show(); console2->updateScreenView(); console2->forceUpdate(); console->scrollUp( lines ); } void TConsole::deselect() { P_begin.setX( 0 ); P_begin.setY( 0 ); P_end.setX( 0 ); P_end.setY( 0 ); } void TConsole::showEvent( QShowEvent * event ) { if( ! mIsDebugConsole && ! mIsSubConsole ) { if( mpHost ) { mpHost->mTelnet.mAlertOnNewData = false; } } QWidget::showEvent( event );//FIXME-refac: might cause problems } void TConsole::hideEvent( QHideEvent * event ) { if( ! mIsDebugConsole && ! mIsSubConsole ) { if( mpHost ) { if( mudlet::self()->mWindowMinimized ) { if( mpHost->mAlertOnNewData ) { mpHost->mTelnet.mAlertOnNewData = true; } } } } QWidget::hideEvent( event );//FIXME-refac: might cause problems } void TConsole::reset() { deselect(); mFormatCurrent.bgR = mStandardFormat.bgR; mFormatCurrent.bgG = mStandardFormat.bgG; mFormatCurrent.bgB = mStandardFormat.bgB; mFormatCurrent.fgR = mStandardFormat.fgR; mFormatCurrent.fgG = mStandardFormat.fgG; mFormatCurrent.fgB = mStandardFormat.fgB; mFormatCurrent.bold = false; mFormatCurrent.italics = false; mFormatCurrent.underline = false; } void TConsole::insertLink( QString text, QStringList & func, QStringList & hint, QPoint P, bool customFormat ) { int x = P.x(); int y = P.y(); int o = 0;//FIXME: das ist ein fehler bei mehrzeiliger selection int r = text.size(); QPoint P2 = P; P2.setX( x+r ); if( mTriggerEngineMode ) { if( hasSelection() ) { if( r < o ) { int a = -1*(o-r); mpHost->getLuaInterpreter()->adjustCaptureGroups( x, a ); } if( r > o ) { int a = r-o; mpHost->getLuaInterpreter()->adjustCaptureGroups( x, a ); } } else { mpHost->getLuaInterpreter()->adjustCaptureGroups( x, r ); } if( y < mEngineCursor ) { if( customFormat ) buffer.insertInLine( P, text, mFormatCurrent ); else { TChar _f = TChar(0,0,255,mBgColor.red(), mBgColor.green(), mBgColor.blue(), false, false, true ); buffer.insertInLine( P, text, _f ); } buffer.applyLink( P, P2, text, func, hint ); console->needUpdate( mUserCursor.y(), mUserCursor.y()+1 ); } else if( y >= mEngineCursor ) { if( customFormat ) buffer.insertInLine( P, text, mFormatCurrent ); else { TChar _f = TChar(0,0,255,mBgColor.red(), mBgColor.green(), mBgColor.blue(), false, false, true ); buffer.insertInLine( P, text, _f ); } buffer.applyLink( P, P2, text, func, hint ); } return; } else { if( ( buffer.buffer.size() == 0 && buffer.buffer[0].size() == 0 ) || mUserCursor == buffer.getEndPos() ) { if( customFormat ) buffer.addLink( mTriggerEngineMode, text, func, hint, mFormatCurrent ); else { TChar _f = TChar(0,0,255,mBgColor.red(), mBgColor.green(), mBgColor.blue(), false, false, true ); buffer.addLink( mTriggerEngineMode, text, func, hint, _f ); } /*buffer.append( text, 0, text.size(), mFormatCurrent.fgR, mFormatCurrent.fgG, mFormatCurrent.fgB, mFormatCurrent.bgR, mFormatCurrent.bgG, mFormatCurrent.bgB, mFormatCurrent.bold, mFormatCurrent.italics, mFormatCurrent.underline );*/ console->showNewLines(); console2->showNewLines(); } else { if( customFormat ) buffer.insertInLine( mUserCursor, text, mFormatCurrent ); else { TChar _f = TChar(0,0,255,mBgColor.red(), mBgColor.green(), mBgColor.blue(), false, false, true ); buffer.insertInLine( mUserCursor, text, _f ); } buffer.applyLink( P, P2, text, func, hint ); if( text.indexOf("\n") != -1 ) { int y_tmp = mUserCursor.y(); int down = buffer.wrapLine( mUserCursor.y(),mpHost->mScreenWidth, mpHost->mWrapIndentCount, mFormatCurrent ); console->needUpdate( y_tmp, y_tmp+down+1 ); int y_neu = y_tmp+down; int x_adjust = text.lastIndexOf("\n"); int x_neu = 0; if( x_adjust != -1 ) { x_neu = text.size()-x_adjust-1 > 0 ? text.size()-x_adjust-1 : 0; } moveCursor( x_neu, y_neu ); } else { console->needUpdate( mUserCursor.y(),mUserCursor.y()+1 ); moveCursor( mUserCursor.x()+text.size(), mUserCursor.y() ); } } } } void TConsole::insertText( QString text, QPoint P ) { int x = P.x(); int y = P.y(); int o = 0;//FIXME: das ist ein fehler bei mehrzeiliger selection int r = text.size(); if( mTriggerEngineMode ) { if( hasSelection() ) { if( r < o ) { int a = -1*(o-r); mpHost->getLuaInterpreter()->adjustCaptureGroups( x, a ); } if( r > o ) { int a = r-o; mpHost->getLuaInterpreter()->adjustCaptureGroups( x, a ); } } else { mpHost->getLuaInterpreter()->adjustCaptureGroups( x, r ); } if( y < mEngineCursor ) { buffer.insertInLine( P, text, mFormatCurrent ); console->needUpdate( mUserCursor.y(), mUserCursor.y()+1 ); } else if( y >= mEngineCursor ) { buffer.insertInLine( P, text, mFormatCurrent ); } return; } else { if( ( buffer.buffer.size() == 0 && buffer.buffer[0].size() == 0 ) || mUserCursor == buffer.getEndPos() ) { buffer.append( text, 0, text.size(), mFormatCurrent.fgR, mFormatCurrent.fgG, mFormatCurrent.fgB, mFormatCurrent.bgR, mFormatCurrent.bgG, mFormatCurrent.bgB, mFormatCurrent.bold, mFormatCurrent.italics, mFormatCurrent.underline ); console->showNewLines(); console2->showNewLines(); } else { buffer.insertInLine( mUserCursor, text, mFormatCurrent ); if( text.indexOf("\n") != -1 ) { int y_tmp = mUserCursor.y(); int down = buffer.wrapLine( mUserCursor.y(),mpHost->mScreenWidth, mpHost->mWrapIndentCount, mFormatCurrent ); console->needUpdate( y_tmp, y_tmp+down+1 ); int y_neu = y_tmp+down; int x_adjust = text.lastIndexOf("\n"); int x_neu = 0; if( x_adjust != -1 ) { x_neu = text.size()-x_adjust-1 > 0 ? text.size()-x_adjust-1 : 0; } moveCursor( x_neu, y_neu ); } else { console->needUpdate( mUserCursor.y(),mUserCursor.y()+1 ); moveCursor( mUserCursor.x()+text.size(), mUserCursor.y() ); } } } } void TConsole::replace( QString text ) { int x = P_begin.x(); int o = P_end.x() - P_begin.x(); int r = text.size(); if( mTriggerEngineMode ) { if( hasSelection() ) { if( r < o ) { int a = -1*(o-r); mpHost->getLuaInterpreter()->adjustCaptureGroups( x, a ); } if( r > o ) { int a = r-o; mpHost->getLuaInterpreter()->adjustCaptureGroups( x, a ); } } else { mpHost->getLuaInterpreter()->adjustCaptureGroups( x, r ); } } buffer.replaceInLine( P_begin, P_end, text, mFormatCurrent ); } void TConsole::skipLine() { if( deleteLine( mUserCursor.y() ) ) { mDeletedLines++; } } bool TConsole::saveMap(QString location) { QDir dir_map; QString filename_map; QString directory_map = QDir::homePath()+"/.config/mudlet/profiles/"+profile_name+"/map"; if (location == "") filename_map = directory_map + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss")+"map.dat"; else filename_map = location; if( ! dir_map.exists( directory_map ) ) { dir_map.mkpath( directory_map ); } QFile file_map( filename_map ); if ( file_map.open( QIODevice::WriteOnly ) ) { QDataStream out( & file_map ); mpHost->mpMap->serialize( out ); file_map.close(); } else return false; return true; } bool TConsole::loadMap(QString location) { if( !mpHost ) return false; if( !mpHost->mpMap || !mpHost->mpMap->mpMapper ) { mudlet::self()->slot_mapper(); } if( !mpHost->mpMap || !mpHost->mpMap->mpMapper ) return false; if ( mpHost->mpMap->restore(location) ) { mpHost->mpMap->init( mpHost ); mpHost->mpMap->mpMapper->mp2dMap->init(); mpHost->mpMap->mpMapper->show(); if( mpHost->mpMap ) if( mpHost->mpMap->mpMapper ) mpHost->mpMap->mpMapper->updateAreaComboBox(); // previous selections stay, so we need to clear it //mpHost->mpMap->mpMapper->mp2dMap->deselect(); return true; } return false; } bool TConsole::deleteLine( int y ) { return buffer.deleteLine( y ); } bool TConsole::hasSelection() { if( P_begin != P_end ) return true; else return false; } void TConsole::insertText( QString msg ) { insertText( msg, mUserCursor ); } void TConsole::insertLink( QString text, QStringList & func, QStringList & hint, bool customFormat ) { insertLink( text, func, hint, mUserCursor, customFormat ); } void TConsole::insertHTML( QString text ) { insertText( text ); } int TConsole::getLineNumber() { return mUserCursor.y(); } int TConsole::getColumnNumber() { return mUserCursor.x(); } int TConsole::getLineCount() { return buffer.getLastLineNumber(); } QStringList TConsole::getLines( int from, int to ) { QStringList ret; int delta = abs( from - to ); for( int i=0; iselectCurrentLine(); return; } else { return; } }*/ void TConsole::selectCurrentLine( std::string & buf ) { std::string key = buf; if( buf == "main" ) { selectCurrentLine(); } if( mSubConsoleMap.find( key ) != mSubConsoleMap.end() ) { TConsole * pC = mSubConsoleMap[key]; if( ! pC ) return; pC->selectCurrentLine(); } else { return; } } std::list TConsole::_getFgColor() { std::list result; int x = P_begin.x(); int y = P_begin.y(); if( y < 0 ) return result; if( x < 0 ) return result; if( y >= static_cast(buffer.buffer.size()) ) return result; if( static_cast(buffer.buffer[y].size())-1 >= x ) { result.push_back( buffer.buffer[y][x].fgR ); result.push_back( buffer.buffer[y][x].fgG ); result.push_back( buffer.buffer[y][x].fgB ); } return result; } std::list TConsole::_getBgColor() { std::list result; int x = P_begin.x(); int y = P_begin.y(); if( y < 0 ) return result; if( x < 0 ) return result; if( y >= static_cast(buffer.buffer.size()) ) return result; if( static_cast(buffer.buffer[y].size())-1 >= x ) { result.push_back( buffer.buffer[y][x].bgR ); result.push_back( buffer.buffer[y][x].bgG ); result.push_back( buffer.buffer[y][x].bgB ); } return result; } std::list TConsole::getFgColor( std::string & buf ) { std::list result; std::string key = buf; if( buf == "main" ) { return _getFgColor(); } if( mSubConsoleMap.find( key ) != mSubConsoleMap.end() ) { TConsole * pC = mSubConsoleMap[key]; if( ! pC ) return result; return pC->_getFgColor(); } else { return result; } } std::list TConsole::getBgColor( std::string & buf ) { std::list result; std::string key = buf; if( buf == "main" ) { return _getBgColor(); } if( mSubConsoleMap.find( key ) != mSubConsoleMap.end() ) { TConsole * pC = mSubConsoleMap[key]; if( ! pC ) return result; return pC->_getBgColor(); } else { return result; } } void TConsole::luaWrapLine( std::string & buf, int line ) { std::string key = buf; if( buf == "main" ) { _luaWrapLine( line ); return; } if( mSubConsoleMap.find( key ) != mSubConsoleMap.end() ) { TConsole * pC = mSubConsoleMap[key]; if( ! pC ) return; pC->_luaWrapLine( line ); return; } } void TConsole::_luaWrapLine( int line ) { if( !mpHost ) return; TChar ch(mpHost); buffer.wrapLine( line, mWrapAt, mIndentCount, ch ); } bool TConsole::setMiniConsoleFontSize( std::string & buf, int size ) { std::string key = buf; if( mSubConsoleMap.find( key ) != mSubConsoleMap.end() ) { TConsole * pC = mSubConsoleMap[key]; if( ! pC ) return false; pC->console->mDisplayFont = QFont("Bitstream Vera Sans Mono", size, QFont::Courier); pC->console->updateScreenView(); pC->console->forceUpdate(); pC->console2->mDisplayFont = QFont("Bitstream Vera Sans Mono", size, QFont::Courier); pC->console2->updateScreenView(); pC->console2->forceUpdate(); return true; } return false; } QString TConsole::getCurrentLine() { return buffer.line( mUserCursor.y() ); } QString TConsole::getCurrentLine( std::string & buf ) { std::string key = buf; if( buf == "main" ) { return getCurrentLine(); } if( mSubConsoleMap.find( key ) != mSubConsoleMap.end() ) { TConsole * pC = mSubConsoleMap[key]; if( ! pC ) return false; return pC->getCurrentLine(); } else { return QString("ERROR: mini console does not exist"); } } int TConsole::getLastLineNumber() { return buffer.getLastLineNumber(); } void TConsole::moveCursorEnd() { int y = buffer.getLastLineNumber(); int x = buffer.line( y ).size()-1; x = x >= 0 ? x : 0; moveCursor( x, y ); } bool TConsole::moveCursor( int x, int y ) { QPoint P( x, y ); if( buffer.moveCursor( P ) ) { mUserCursor.setX( x ); mUserCursor.setY( y ); return true; } else { return false; } } void TConsole::setUserWindow() { mUserConsole = true; } int TConsole::select( QString text, int numOfMatch ) { if( mUserCursor.y()<0 ) return -1; if( mUserCursor.y()>=buffer.size() ) return -1; if( mudlet::debugMode ) {TDebug(QColor(Qt::darkMagenta), QColor(Qt::black)) << "\nline under current user cursor: ">>0; TDebug(QColor(Qt::red),QColor(Qt::black))<>0; TDebug(QColor(Qt::gray),QColor(Qt::black)) << buffer.line( mUserCursor.y() ) << "\n" >> 0;} int begin = -1; for( int i=0;i> 0;} return begin; } bool TConsole::selectSection( int from, int to ) { if( mudlet::debugMode ) { if( mudlet::debugMode ) {TDebug(QColor(Qt::darkMagenta),QColor(Qt::black)) <<"\nselectSection("<> 0;} } if( from < 0 ) { return false; } if( mUserCursor.y() >= static_cast(buffer.buffer.size()) ) { return false; } int s = buffer.buffer[mUserCursor.y()].size(); if( from > s || from + to > s ) { return false; } P_begin.setX( from ); P_begin.setY( mUserCursor.y() ); P_end.setX( from + to ); P_end.setY( mUserCursor.y() ); if( mudlet::debugMode ){ TDebug(QColor(Qt::darkMagenta),QColor(Qt::black))<<"P_begin("<> 0;} return true; } void TConsole::setLink( QString & linkText, QStringList & linkFunction, QStringList & linkHint ) { buffer.applyLink( P_begin, P_end, linkText, linkFunction, linkHint ); } void TConsole::setBold( bool b ) { mFormatCurrent.bold = b; buffer.applyBold( P_begin, P_end, b ); } void TConsole::setItalics( bool b ) { mFormatCurrent.italics = b; buffer.applyItalics( P_begin, P_end, b ); } void TConsole::setUnderline( bool b ) { mFormatCurrent.underline = b; buffer.applyUnderline( P_begin, P_end, b ); } void TConsole::setFgColor( int r, int g, int b ) { mFormatCurrent.fgR = r; mFormatCurrent.fgG = g; mFormatCurrent.fgB = b; buffer.applyFgColor( P_begin, P_end, r,g,b ); } void TConsole::setBgColor( int r, int g, int b ) { mFormatCurrent.bgR = r; mFormatCurrent.bgG = g; mFormatCurrent.bgB = b; buffer.applyBgColor( P_begin, P_end, r,g,b ); } void TConsole::printCommand( QString & msg ) { if( mTriggerEngineMode ) { msg.append("\n"); int lineBeforeNewContent = buffer.getLastLineNumber(); if( lineBeforeNewContent >= 0 ) { if( buffer.lineBuffer[lineBeforeNewContent].right(1) != "\n" ) { msg.prepend("\n"); } } buffer.appendLine( msg, 0, msg.size()-1, mCommandFgColor.red(), mCommandFgColor.green(), mCommandFgColor.blue(), mCommandBgColor.red(), mCommandBgColor.green(), mCommandBgColor.blue(), false, false, false ); } else { int lineBeforeNewContent = buffer.size()-2; if( lineBeforeNewContent >= 0 ) { int promptEnd = buffer.buffer[lineBeforeNewContent].size(); if( promptEnd < 0 ) { promptEnd = 0; } if( buffer.promptBuffer[lineBeforeNewContent] == true ) { QPoint P( promptEnd, lineBeforeNewContent ); TChar format; format.fgR = mCommandFgColor.red(); format.fgG = mCommandFgColor.green(); format.fgB = mCommandFgColor.blue(); format.bgR = mCommandBgColor.red(); format.bgG = mCommandBgColor.green(); format.bgB = mCommandBgColor.blue(); buffer.insertInLine( P, msg, format ); int down = buffer.wrapLine( lineBeforeNewContent, mpHost->mScreenWidth, mpHost->mWrapIndentCount, mFormatCurrent ); console->needUpdate( lineBeforeNewContent, lineBeforeNewContent+1+down ); console2->needUpdate( lineBeforeNewContent, lineBeforeNewContent+1+down ); buffer.promptBuffer[lineBeforeNewContent] = false; return; } } msg.append("\n"); print( msg, mCommandFgColor.red(), mCommandFgColor.green(), mCommandFgColor.blue(), mCommandBgColor.red(), mCommandBgColor.green(), mCommandBgColor.blue() ); } } void TConsole::echoLink( QString & text, QStringList & func, QStringList & hint, bool customFormat ) { if( customFormat ) buffer.addLink( mTriggerEngineMode, text, func, hint, mFormatCurrent ); else { if( ! mIsSubConsole && ! mIsDebugConsole ) { TChar f = TChar(0, 0, 255, mpHost->mBgColor.red(), mpHost->mBgColor.green(), mpHost->mBgColor.blue(), false, false, true); buffer.addLink( mTriggerEngineMode, text, func, hint, f ); } else { TChar f = TChar(0, 0, 255, mBgColor.red(), mBgColor.green(), mBgColor.blue(), false, false, true); buffer.addLink( mTriggerEngineMode, text, func, hint, f ); } } } void TConsole::echo( QString & msg ) { if( mTriggerEngineMode ) { buffer.appendLine( msg, 0, msg.size()-1, mFormatCurrent.fgR, mFormatCurrent.fgG, mFormatCurrent.fgB, mFormatCurrent.bgR, mFormatCurrent.bgG, mFormatCurrent.bgB, mFormatCurrent.bold, mFormatCurrent.italics, mFormatCurrent.underline ); } else { print( msg ); } } void TConsole::print( const char * txt ) { QString msg = txt; buffer.append( msg, 0, msg.size(), mFormatCurrent.fgR, mFormatCurrent.fgG, mFormatCurrent.fgB, mFormatCurrent.bgR, mFormatCurrent.bgG, mFormatCurrent.bgB, mFormatCurrent.bold, mFormatCurrent.italics, mFormatCurrent.underline ); console->showNewLines(); console2->showNewLines(); } void TConsole::printDebug( QColor & c, QColor & d, QString & msg ) { buffer.append( msg, 0, msg.size(), c.red(), c.green(), c.blue(), d.red(), d.green(), d.blue(), false, false, false ); console->showNewLines(); console2->showNewLines(); } TConsole * TConsole::createBuffer( QString & name ) { std::string key = name.toLatin1().data(); if( mSubConsoleMap.find( key ) == mSubConsoleMap.end() ) { TConsole * pC = new TConsole( mpHost, false ); mSubConsoleMap[key] = pC; pC->setWindowTitle(name); pC->setContentsMargins(0,0,0,0); pC->hide(); pC->layerCommandLine->hide(); //pC->mpScrollBar->hide(); pC->setUserWindow(); return pC; } else { return 0; } } void TConsole::resetMainConsole() { std::map::const_iterator it; it = mSubConsoleMap.begin(); for( ; it != mSubConsoleMap.end(); it++ ) { QMap & dockWindowConsoleMap = mudlet::self()->mHostConsoleMap[mpHost]; QString n = it->first.c_str(); dockWindowConsoleMap.remove( n ); (*it->second).close(); } std::map::const_iterator it2; for( it2 = mLabelMap.begin(); it2 != mLabelMap.end(); it2++ ) { QMap & dockWindowConsoleMap = mudlet::self()->mHostLabelMap[mpHost]; QString n = it2->first.c_str(); dockWindowConsoleMap.remove( n ); (*it2->second).close(); } mSubConsoleMap.clear(); mLabelMap.clear(); } TConsole * TConsole::createMiniConsole( QString & name, int x, int y, int width, int height ) { std::string key = name.toLatin1().data(); if( mSubConsoleMap.find( key ) == mSubConsoleMap.end() ) { TConsole * pC = new TConsole(mpHost, false, mpMainFrame ); if( ! pC ) { return 0; } mSubConsoleMap[key] = pC; pC->setFocusPolicy( Qt::NoFocus ); pC->setUserWindow(); pC->console->setIsMiniConsole(); pC->console2->setIsMiniConsole(); pC->resize( width, height ); pC->mOldX = x; pC->mOldY = y; pC->setContentsMargins(0,0,0,0); pC->move( x, y ); std::string _n = name.toStdString(); pC->setMiniConsoleFontSize( _n, 12 ); pC->show(); return pC; } else { return 0; } } TLabel * TConsole::createLabel( QString & name, int x, int y, int width, int height, bool fillBackground ) { std::string key = name.toLatin1().data(); if( mLabelMap.find( key ) == mLabelMap.end() ) { TLabel * pC = new TLabel( mpMainFrame ); mLabelMap[key] = pC; pC->setAutoFillBackground( fillBackground ); pC->resize( width, height ); pC->setContentsMargins(0,0,0,0); pC->move( x, y ); pC->show(); return pC; } else { return 0; } } void TConsole::createMapper( int x, int y, int width, int height ) { if( ! mpMapper ) { mpMapper = new dlgMapper( mpMainFrame, mpHost, mpHost->mpMap ); mpHost->mpMap->mpM = mpMapper->glWidget; mpHost->mpMap->mpHost = mpHost; mpHost->mpMap->mpMapper = mpMapper; mpMapper->mpHost = mpHost; mpHost->mpMap->restore(""); mpHost->mpMap->init( mpHost ); TEvent mapOpenEvent; mapOpenEvent.mArgumentList.append( "mapOpenEvent" ); mapOpenEvent.mArgumentTypeList.append(ARGUMENT_TYPE_STRING); mpHost->raiseEvent( & mapOpenEvent ); } mpMapper->resize( width, height ); mpMapper->move( x, y ); //mpMapper->mp2dMap->init(); mpMapper->mp2dMap->gridMapSizeChange = true; //mapper size has changed, but only init grid map when necessary mpMapper->show(); } bool TConsole::createButton( QString & name, int x, int y, int width, int height, bool fillBackground ) { std::string key = name.toLatin1().data(); if( mLabelMap.find( key ) == mLabelMap.end() ) { TLabel * pC = new TLabel( mpMainFrame ); mLabelMap[key] = pC; pC->setAutoFillBackground( fillBackground ); pC->resize( width, height ); pC->setContentsMargins(0,0,0,0); pC->move( x, y ); pC->show(); return true; } else return false; } bool TConsole::setBackgroundImage( QString & name, QString & path ) { std::string key = name.toLatin1().data(); if( mLabelMap.find( key ) != mLabelMap.end() ) { QPixmap bgPixmap( path ); mLabelMap[key]->setPixmap( bgPixmap ); return true; } else return false; } bool TConsole::setBackgroundColor( QString & name, int r, int g, int b, int alpha ) { std::string key = name.toLatin1().data(); if( mSubConsoleMap.find( key ) != mSubConsoleMap.end() ) { QPalette mainPalette; mainPalette.setColor( QPalette::Window, QColor(r, g, b, alpha) ); mSubConsoleMap[key]->setPalette( mainPalette ); mSubConsoleMap[key]->console->mBgColor = QColor( r,g,b,alpha); mSubConsoleMap[key]->console2->mBgColor = QColor( r,g,b,alpha); return true; } else if( mLabelMap.find( key ) != mLabelMap.end() ) { QPalette mainPalette; mainPalette.setColor( QPalette::Window, QColor(r, g, b, alpha) ); mLabelMap[key]->setPalette( mainPalette ); return true; } else return false; } bool TConsole::showWindow( QString & name ) { std::string key = name.toLatin1().data(); if( mSubConsoleMap.find( key ) != mSubConsoleMap.end() ) { mSubConsoleMap[key]->console->updateScreenView(); mSubConsoleMap[key]->console->forceUpdate(); mSubConsoleMap[key]->show(); mSubConsoleMap[key]->console2->updateScreenView(); mSubConsoleMap[key]->console2->forceUpdate(); //mSubConsoleMap[key]->move(mSubConsoleMap[key]->mOldX, mSubConsoleMap[key]->mOldY); return true; } else if( mLabelMap.find( key ) != mLabelMap.end() ) { mLabelMap[key]->show(); return true; } else return false; } bool TConsole::hideWindow( QString & name ) { std::string key = name.toLatin1().data(); if( mSubConsoleMap.find( key ) != mSubConsoleMap.end() ) { //mSubConsoleMap[key]->move(9999,9999); mSubConsoleMap[key]->hide(); return true; } else if( mLabelMap.find( key ) != mLabelMap.end() ) { mLabelMap[key]->hide(); return true; } else return false; } bool TConsole::printWindow( QString & name, QString & text ) { std::string key = name.toLatin1().data(); if( mSubConsoleMap.find( key ) != mSubConsoleMap.end() ) { mSubConsoleMap[key]->print( text ); return true; } else if( mLabelMap.find( key ) != mLabelMap.end() ) { mLabelMap[key]->setText( text ); return true; } else return false; } void TConsole::print( QString & msg ) { buffer.append( msg, 0, msg.size(), mFormatCurrent.fgR, mFormatCurrent.fgG, mFormatCurrent.fgB, mFormatCurrent.bgR, mFormatCurrent.bgG, mFormatCurrent.bgB, mFormatCurrent.bold, mFormatCurrent.italics, mFormatCurrent.underline ); console->showNewLines(); console2->showNewLines(); } void TConsole::print( QString & msg, int fgColorR, int fgColorG, int fgColorB, int bgColorR, int bgColorG, int bgColorB ) { buffer.append( msg, 0, msg.size(), fgColorR, fgColorG, fgColorB, bgColorR, bgColorG, bgColorB, false, false, false ); console->showNewLines(); console2->showNewLines(); } void TConsole::printSystemMessage( QString & msg ) { assert( mpHost ); QColor bgColor; QColor fgColor; if( mIsDebugConsole ) { bgColor = mBgColor; fgColor = mFgColor; } else { bgColor = mpHost->mBgColor; } //int lineBeforeNewContent = buffer.getLastLineNumber(); QString txt = QString("System Message: ")+msg; buffer.append( txt, 0, txt.size(), mSystemMessageFgColor.red(), mSystemMessageFgColor.green(), mSystemMessageFgColor.blue(), mSystemMessageBgColor.red(), mSystemMessageBgColor.green(), mSystemMessageBgColor.blue(), false, false, false ); console->showNewLines(); console2->showNewLines(); } void TConsole::echoUserWindow( QString & msg ) { print( msg ); } void TConsole::copy() { mpHost->mpConsole->mClipboard = buffer.copy( P_begin, P_end ); } void TConsole::cut() { mClipboard = buffer.cut( P_begin, P_end ); } void TConsole::paste() { if( buffer.size()-1 > mUserCursor.y() ) { buffer.paste( mUserCursor, mClipboard ); console->needUpdate( mUserCursor.y(), mUserCursor.y() ); } else { buffer.appendBuffer( mClipboard ); } console->showNewLines(); console2->showNewLines(); } void TConsole::pasteWindow( TBuffer bufferSlice ) { mClipboard = bufferSlice; paste(); } void TConsole::appendBuffer() { buffer.appendBuffer( mClipboard ); console->showNewLines(); console2->showNewLines(); } void TConsole::appendBuffer( TBuffer bufferSlice ) { buffer.appendBuffer( bufferSlice ); console->showNewLines(); console2->showNewLines(); } void TConsole::slot_stop_all_triggers( bool b ) { if( b ) { mpHost->stopAllTriggers(); QIcon icon2(":/icons/red-bomb.png"); emergencyStop->setIcon( icon2 ); } else { mpHost->reenableAllTriggers(); QIcon icon2(":/icons/edit-bomb.png"); emergencyStop->setIcon( icon2 ); } } void TConsole::showStatistics() { QStringList header; header << "\n" << "+--------------------------------------------------------------+\n" << "| system statistics |\n" << "+--------------------------------------------------------------+\n"; QString h = header.join(""); QString msg = h; print( msg, 150, 120, 0, 0, 0, 0 ); QString script = "setFgColor(190,150,0); setUnderline(true);echo([[\n\nGMCP events:\n]]);setUnderline(false);setFgColor(150,120,0);display( gmcp );"; mpHost->mLuaInterpreter.compileAndExecuteScript( script ); script = "setFgColor(190,150,0); setUnderline(true);echo([[\n\nATCP events:\n]]);setUnderline(false);setFgColor(150,120,0); display( atcp );"; mpHost->mLuaInterpreter.compileAndExecuteScript( script ); script = "setFgColor(190,150,0); setUnderline(true);echo([[\n\nchannel102 events:\n]]);setUnderline(false);setFgColor(150,120,0);display( channel102 );"; mpHost->mLuaInterpreter.compileAndExecuteScript( script ); script = "setFgColor(190,150,0); setUnderline(true); echo([[\n\nTrigger Report:\n\n]]); setBold(false);setUnderline(false);setFgColor(150,120,0)"; mpHost->mLuaInterpreter.compileAndExecuteScript( script ); QString r1 = mpHost->getTriggerUnit()->assembleReport(); msg = r1; print( msg, 150, 120, 0, 0, 0, 0 ); script = "setFgColor(190,150,0); setUnderline(true);echo([[\n\nTimer Report:\n\n]]);setBold(false);setUnderline(false);setFgColor(150,120,0)"; mpHost->mLuaInterpreter.compileAndExecuteScript( script ); QString r2 = mpHost->getTimerUnit()->assembleReport(); QString footer = QString("\n+--------------------------------------------------------------+\n" ); msg = r2; print( msg, 150, 120, 0, 0, 0, 0 ); mpHost->mpConsole->print( footer, 150, 120, 0, 0, 0, 0 ); script = "resetFormat();"; mpHost->mLuaInterpreter.compileAndExecuteScript( script ); mpHost->mpConsole->raise(); } void TConsole::slot_searchBufferUp() { QString _txt = mpBufferSearchBox->text(); if( _txt != mSearchQuery ) { mSearchQuery = _txt; mCurrentSearchResult = buffer.lineBuffer.size(); } if( buffer.lineBuffer.size() < 1 ) return; bool _found = false; for( int i=mCurrentSearchResult-1; i >= 0; i-- ) { int begin = -1; do { begin = buffer.lineBuffer[i].indexOf(mSearchQuery, begin+1 ); if( begin > -1 ) { int length = mSearchQuery.size(); moveCursor( 0, i ); selectSection( begin, length ); setBgColor( 255, 255, 0 ); setFgColor( 0, 0, 0 ); deselect(); reset(); _found = true; } } while( begin > -1 ); if( _found ) { scrollUp( buffer.mCursorY-i-3 ); console->forceUpdate(); mCurrentSearchResult = i; return; } } print("No search results, sorry!\n"); } void TConsole::slot_searchBufferDown() { QString _txt = mpBufferSearchBox->text(); if( _txt != mSearchQuery ) { mSearchQuery = _txt; mCurrentSearchResult = buffer.lineBuffer.size(); } if( buffer.lineBuffer.size() < 1 ) return; if( mCurrentSearchResult >= buffer.lineBuffer.size() ) return; bool _found = false; for( int i=mCurrentSearchResult+1; i < buffer.lineBuffer.size(); i++ ) { int begin = -1; do { begin = buffer.lineBuffer[i].indexOf(mSearchQuery, begin+1 ); if( begin > -1 ) { int length = mSearchQuery.size(); moveCursor( 0, i ); selectSection( begin, length ); setBgColor( 255, 255, 0 ); setFgColor( 0, 0, 0 ); deselect(); reset(); _found = true; } } while( begin > -1 ); if( _found ) { scrollUp( buffer.mCursorY-i-3 ); console->forceUpdate(); mCurrentSearchResult = i; return; } } print("No search results, sorry!\n"); } QSize TConsole::getMainWindowSize() const { QSize consoleSize = size(); int toolbarWidth = mpLeftToolBar->width() + mpRightToolBar->width(); int toolbarHeight = mpTopToolBar->height(); int commandLineHeight = mpCommandLine->height(); QSize mainWindowSize( consoleSize.width()-toolbarWidth, consoleSize.height()-(commandLineHeight+toolbarHeight)); return mainWindowSize; } mudlet-2.1/src/irc/0000755000175000017500000000000011513237311013517 5ustar csmallcsmallmudlet-2.1/src/irc/README0000644000175000017500000000024511513237311014400 0ustar csmallcsmallWebsite: http://bitbucket.org/jpnurmi/libircclient-qt Bug tracker: http://bitbucket.org/jpnurmi/libircclient-qt/issues IRC channel: #communi on irc.freenode.net mudlet-2.1/src/irc/libircclient-qt-config.prf0000644000175000017500000000002411513237311020554 0ustar csmallcsmallDEFINES+=IRC_SHARED mudlet-2.1/src/irc/CHANGELOG0000644000175000017500000000442711513237311014740 0ustar csmallcsmall0.5.0 ----- - Irc::Session API additions: - addBuffer() and buffers() for buffer management - welcomed() signal, emitted when 001 is received - Added IRC capability support - Implemented IDENTIFY-MSG capability - Fixed "icu.pri: Unescaped backslashes are deprecated" - Remove buffer upon parting a channel - Fixed Session::raw()'s check of written bytes - Fixed #3 An incorrect buffer is created when StripNicks is off and EchoMessages - Improved building on Mac - Make a difference between frameworks and standard dylibs (depending on Qt's installation style) - Set INSTALL_NAME correctly 0.4.1 ----- - Added support for static builds (qmake -config static) - Fixed qmake project messages output only once - Fixed MOC_DIR in release mode - Added default MacPorts paths for ICU - Fixed notices and messages from "real host" vs. "connected host" to get directed to the same buffer - Fixed CTCP requests not to create a new buffer 0.4.0 ----- - Introduced Irc::Buffer - the concept of server/channel/query specific buffers - Deprecated buffer-specific functionality in Irc::Session - Fixed tabs not to cause underlined text - Added a version number to the library - Added Irc::Rfc::toString() - Fixed euIRC connection problems 0.3.2 ----- - Fixed problems with "unknown" messages - Fixed Irc::Session::connectSlotsByName() not to try to establish a connection when the parameter types don't match - Code improvements 0.3.1 ----- - Fixed compilation on Mac - Fixed Irc::Session::connected() and disconnected() to be emitted correctly - Fixed Irc::Session::connectSlotsByName() not to establish multiple connections when a slot exists multiple times (reimplemented) - Made Irc::Session::cmdMessage(), cmdNotice() and cmdCtcpAction() to emit own messages, notices and actions. This simplifies client implementation - Started working on auto tests and added code coverage support - Added a workaround for older Qt versions that don't have the QT_FORWARD_DECLARE_CLASS() macro defined 0.3.0 ----- - Added SSL support - Quality & compatibility - no_keywords - QT_NO_CAST_FROM_ASCII - QT_NO_CAST_TO_ASCII - Bug fixes & code improvements 0.2.0 ----- - The first fully Qt-based version 0.1.1 ----- - Added support for optional encoding detection with ICU 0.1.0 ----- - The first internal release mudlet-2.1/src/irc/libircclient-qt.prf0000644000175000017500000000034011513237311017312 0ustar csmallcsmall###################################################################### # LibIrcClient-Qt ###################################################################### include(libircclient-qt-config.prf) qtAddLibrary(ircclient-qt) mudlet-2.1/src/irc/AUTHORS0000644000175000017500000000010111513237311014557 0ustar csmallcsmallJ-P Nurmi Sjors Gielen mudlet-2.1/src/irc/include/0000755000175000017500000000000011624306130015141 5ustar csmallcsmallmudlet-2.1/src/irc/include/IrcGlobal0000644000175000017500000000003011513237311016714 0ustar csmallcsmall#include mudlet-2.1/src/irc/include/ircsession.h0000644000175000017500000002532411624306130017501 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #ifndef IRC_SESSION_H #define IRC_SESSION_H //#include #include "ircglobal.h" #include QT_FORWARD_DECLARE_CLASS(QAbstractSocket) QT_FORWARD_DECLARE_CLASS(QStringList) namespace Irc { class Buffer; class SessionPrivate; class IRC_EXPORT Session : public QObject { Q_OBJECT Q_PROPERTY(QStringList autoJoinChannels READ autoJoinChannels WRITE setAutoJoinChannels) Q_PROPERTY(int autoReconnectDelay READ autoReconnectDelay WRITE setAutoReconnectDelay) Q_PROPERTY(QByteArray encoding READ encoding WRITE setEncoding) Q_PROPERTY(QString host READ host WRITE setHost) Q_PROPERTY(QString ident READ ident WRITE setIdent) Q_PROPERTY(QString nick READ nick WRITE setNick) Q_PROPERTY(Options options READ options WRITE setOptions) Q_PROPERTY(QString password READ password WRITE setPassword) Q_PROPERTY(quint16 port READ port WRITE setPort) Q_PROPERTY(QString realName READ realName WRITE setRealName) Q_PROPERTY(QStringList supportedCapabilities READ supportedCapabilities) Q_PROPERTY(QStringList enabledCapabilities READ enabledCapabilities) Q_FLAGS(Options) Q_ENUMS(Option) public: Session(QObject* parent = 0); ~Session(); QStringList autoJoinChannels() const; void addAutoJoinChannel(const QString& channel); void removeAutoJoinChannel(const QString& channel); void setAutoJoinChannels(const QStringList& channels); int autoReconnectDelay() const; void setAutoReconnectDelay(int seconds); QByteArray encoding() const; void setEncoding(const QByteArray& encoding); QString ident() const; void setIdent(const QString& ident); QString nick() const; void setNick(const QString& nick); QString password() const; void setPassword(const QString& password); QString realName() const; void setRealName(const QString& realName); QString host() const; void setHost(const QString& host); quint16 port() const; void setPort(quint16 port); enum Option { NoOptions = 0x0, StripNicks = 0x1, EchoMessages = 0x2 }; Q_DECLARE_FLAGS(Options, Option) Options options() const; void setOptions(Options options); QAbstractSocket* socket() const; void setSocket(QAbstractSocket* socket); QList buffers() const; Buffer* buffer(const QString& receiver = QString()) const; Buffer* addBuffer(const QString& receiver); Buffer* defaultBuffer() const; void setDefaultBuffer(Buffer* buffer); QStringList supportedCapabilities() const; QStringList enabledCapabilities() const; bool capabilityEnabled(const QString& name) const; public Q_SLOTS: void connectToServer(const QString& hostName = QString(), quint16 port = 6667); void reconnectToServer(); void disconnectFromServer(); bool raw(const QString& message); bool motd(); bool join(const QString& channel, const QString& key = QString()); bool part(const QString& channel, const QString& reason = QString()); bool quit(const QString& reason = QString()); bool names(const QString& channel); bool list(const QString& channel = QString()); bool whois(const QString& nick); bool whowas(const QString& nick); bool mode(const QString& target, const QString& mode = QString()); bool topic(const QString& channel, const QString& topic = QString()); bool invite(const QString& nick, const QString& channel); bool kick(const QString& nick, const QString& channel, const QString& reason = QString()); bool message(const QString& receiver, const QString& message); bool notice(const QString& receiver, const QString& notice); bool ctcpAction(const QString& receiver, const QString& action); bool ctcpRequest(const QString& nick, const QString& request); bool ctcpReply(const QString& nick, const QString& reply); void requestCapabilities(const QStringList& capabilities); void clearCapabilities(); #ifndef IRC_NO_DEPRECATED // TODO: for backwards compatibility, to be removed in 1.0 Q_DECL_DEPRECATED bool sendRaw(const QString& message); Q_DECL_DEPRECATED bool cmdJoin(const QString& channel, const QString& key = QString()); Q_DECL_DEPRECATED bool cmdPart(const QString& channel, const QString& reason = QString()); Q_DECL_DEPRECATED bool cmdQuit(const QString& reason = QString()); Q_DECL_DEPRECATED bool cmdNames(const QString& channel); Q_DECL_DEPRECATED bool cmdList(const QString& channel = QString()); Q_DECL_DEPRECATED bool cmdWhois(const QString& nick); Q_DECL_DEPRECATED bool cmdMode(const QString& target, const QString& mode = QString()); Q_DECL_DEPRECATED bool cmdTopic(const QString& channel, const QString& topic = QString()); Q_DECL_DEPRECATED bool cmdInvite(const QString& nick, const QString& channel); Q_DECL_DEPRECATED bool cmdKick(const QString& nick, const QString& channel, const QString& reason = QString()); Q_DECL_DEPRECATED bool cmdMessage(const QString& receiver, const QString& message); Q_DECL_DEPRECATED bool cmdNotice(const QString& receiver, const QString& notice); Q_DECL_DEPRECATED bool cmdCtcpAction(const QString& receiver, const QString& action); Q_DECL_DEPRECATED bool cmdCtcpRequest(const QString& nick, const QString& request); Q_DECL_DEPRECATED bool cmdCtcpReply(const QString& nick, const QString& reply); #endif // IRC_NO_DEPRECATED Q_SIGNALS: void connected(); void welcomed(); void reconnecting(); void disconnected(); void bufferAdded(Irc::Buffer* buffer); void bufferRemoved(Irc::Buffer* buffer); void capabilitiesListed(const QStringList& capabilities); void capabilitiesAcked(const QStringList& capabilities); void capabilitiesNotAcked(const QStringList& capabilities); #ifndef IRC_NO_DEPRECATED // TODO: for backwards compatibility, to be removed in 1.0 Q_DECL_DEPRECATED void msgJoined(const QString& origin, const QString& channel); Q_DECL_DEPRECATED void msgParted(const QString& origin, const QString& channel, const QString& message); Q_DECL_DEPRECATED void msgQuit(const QString& origin, const QString& message); Q_DECL_DEPRECATED void msgNickChanged(const QString& origin, const QString& nick); Q_DECL_DEPRECATED void msgModeChanged(const QString& origin, const QString& receiver, const QString& mode, const QString& args); Q_DECL_DEPRECATED void msgTopicChanged(const QString& origin, const QString& channel, const QString& topic); Q_DECL_DEPRECATED void msgInvited(const QString& origin, const QString& receiver, const QString& channel); Q_DECL_DEPRECATED void msgKicked(const QString& origin, const QString& channel, const QString& nick, const QString& message); Q_DECL_DEPRECATED void msgMessageReceived(const QString& origin, const QString& receiver, const QString& message); Q_DECL_DEPRECATED void msgNoticeReceived(const QString& origin, const QString& receiver, const QString& notice); Q_DECL_DEPRECATED void msgCtcpRequestReceived(const QString& origin, const QString& request); Q_DECL_DEPRECATED void msgCtcpReplyReceived(const QString& origin, const QString& reply); Q_DECL_DEPRECATED void msgCtcpActionReceived(const QString& origin, const QString& receiver, const QString& action); Q_DECL_DEPRECATED void msgNumericMessageReceived(const QString& origin, uint code, const QStringList& params); Q_DECL_DEPRECATED void msgUnknownMessageReceived(const QString& origin, const QStringList& params); #endif // IRC_NO_DEPRECATED protected: virtual Buffer* createBuffer(const QString& receiver); private: SessionPrivate* const d_ptr; Q_DECLARE_PRIVATE(Session) Q_DISABLE_COPY(Session) Q_PRIVATE_SLOT(d_func(), void _q_connected()) Q_PRIVATE_SLOT(d_func(), void _q_disconnected()) Q_PRIVATE_SLOT(d_func(), void _q_reconnect()) Q_PRIVATE_SLOT(d_func(), void _q_error()) Q_PRIVATE_SLOT(d_func(), void _q_state(QAbstractSocket::SocketState)) Q_PRIVATE_SLOT(d_func(), void _q_readData()) #ifndef IRC_NO_DEPRECATED // TODO: for backwards compatibility, to be removed in 1.0 Q_PRIVATE_SLOT(d_func(), void _q_joined(const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_parted(const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_quit(const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_nickChanged(const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_modeChanged(const QString&, const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_topicChanged(const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_invited(const QString&, const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_kicked(const QString&, const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_messageReceived(const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_noticeReceived(const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_ctcpRequestReceived(const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_ctcpReplyReceived(const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_ctcpActionReceived(const QString&, const QString&)); Q_PRIVATE_SLOT(d_func(), void _q_numericMessageReceived(const QString&, uint code, const QStringList&)); Q_PRIVATE_SLOT(d_func(), void _q_unknownMessageReceived(const QString&, const QStringList&)); #endif // IRC_NO_DEPRECATED friend class Buffer; friend class BufferPrivate; }; } #ifndef QT_NO_DEBUG_STREAM IRC_EXPORT QDebug operator<<(QDebug debug, const Irc::Session* session); #endif // QT_NO_DEBUG_STREAM Q_DECLARE_OPERATORS_FOR_FLAGS(Irc::Session::Options) #endif // IRC_SESSION_H mudlet-2.1/src/irc/include/ircutil.h0000644000175000017500000000167311513237311016775 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #ifndef IRC_UTIL_H #define IRC_UTIL_H #include namespace Irc { class IRC_EXPORT Util { public: static QString nickFromTarget(const QString& target); static QString hostFromTarget(const QString& target); static QString messageToHtml(const QString& message); static QString colorNameFromCode(int code); }; } #endif // IRC_UTIL_H mudlet-2.1/src/irc/include/Irc0000644000175000017500000000002211513237311015574 0ustar csmallcsmall#include mudlet-2.1/src/irc/include/ircbuffer.h0000644000175000017500000000750611513237311017272 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #ifndef IRC_BUFFER_H #define IRC_BUFFER_H #include #include #include namespace Irc { class Session; class BufferPrivate; class IRC_EXPORT Buffer : public QObject { Q_OBJECT Q_PROPERTY(QString receiver READ receiver) Q_PROPERTY(QString topic READ topic) Q_PROPERTY(QStringList names READ names) Q_FLAGS(MessageFlags) Q_ENUMS(MessageFlag) public: ~Buffer(); Session* session() const; QString receiver() const; QString topic() const; QStringList names() const; QString modes(const QString& name) const; QString visualMode(const QString& name) const; enum MessageFlag { NoFlags = 0x0, IdentifiedFlag = 0x1, EchoFlag = 0x2, }; Q_DECLARE_FLAGS(MessageFlags, MessageFlag) public Q_SLOTS: bool message(const QString& message); bool notice(const QString& notice); bool ctcpAction(const QString& action); Q_SIGNALS: void receiverChanged(const QString& receiver); void motdReceived(const QString& motd); void joined(const QString& origin); void parted(const QString& origin, const QString& message); void quit(const QString& origin, const QString& message); void nickChanged(const QString& origin, const QString& nick); void modeChanged(const QString& origin, const QString& mode, const QString& args); void topicChanged(const QString& origin, const QString& topic); void invited(const QString& origin, const QString& receiver, const QString& channel); void kicked(const QString& origin, const QString& nick, const QString& message); void messageReceived(const QString& origin, const QString& message, Irc::Buffer::MessageFlags flags = Irc::Buffer::NoFlags); void noticeReceived(const QString& origin, const QString& notice, Irc::Buffer::MessageFlags flags = Irc::Buffer::NoFlags); void ctcpRequestReceived(const QString& origin, const QString& request, Irc::Buffer::MessageFlags flags = Irc::Buffer::NoFlags); void ctcpReplyReceived(const QString& origin, const QString& reply, Irc::Buffer::MessageFlags flags = Irc::Buffer::NoFlags); void ctcpActionReceived(const QString& origin, const QString& action, Irc::Buffer::MessageFlags flags = Irc::Buffer::NoFlags); void numericMessageReceived(const QString& origin, uint code, const QStringList& params); void unknownMessageReceived(const QString& origin, const QStringList& params); protected: Buffer(const QString& receiver, Session* parent = 0); Buffer(BufferPrivate& dd, const QString& receiver, Session* parent = 0); BufferPrivate* const d_ptr; private: Q_DECLARE_PRIVATE(Buffer) Q_DISABLE_COPY(Buffer) friend class SessionPrivate; friend class Session; }; } #ifndef QT_NO_DEBUG_STREAM IRC_EXPORT QDebug operator<<(QDebug debug, const Irc::Buffer* buffer); #endif // QT_NO_DEBUG_STREAM Q_DECLARE_OPERATORS_FOR_FLAGS(Irc::Buffer::MessageFlags) #endif // IRC_BUFFER_H mudlet-2.1/src/irc/include/ircsession_p.h0000644000175000017500000000757311513237311020027 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #ifndef IRC_SESSION_P_H #define IRC_SESSION_P_H #include #include #include #include #include #include "ircbuffer.h" namespace Irc { class SessionPrivate { Q_DECLARE_PUBLIC(Session) public: SessionPrivate(); void init(Session* session); void _q_connected(); void _q_disconnected(); void _q_reconnect(); void _q_error(); void _q_state(QAbstractSocket::SocketState state); void _q_readData(); QString readString(const QByteArray& data) const; void readLines(const QByteArray& delimiter); void processLine(const QByteArray& line); Irc::Buffer::MessageFlags getMessageFlags(QString& message) const; bool isConnected() const; QString resolveTarget(const QString& sender, const QString& receiver) const; Buffer* createBuffer(const QString& receiver); void removeBuffer(Buffer* buffer); Session* q_ptr; QByteArray buffer; Session::Options options; QAbstractSocket* socket; QString ident; QString password; QString nick; QString realName; QString host; quint16 port; QString motd; QStringList channels; QByteArray encoding; int delay; QTimer timer; Buffer* defaultBuffer; QHash buffers; bool welcomed; // Capabilities supported by the server QStringList capabilities; // Capabilities enabled for this connection QStringList enabledCapabilities; // Capabilities to request only when connecting QStringList wantedCapabilities; // Temporary building list of capabilities in transmission QStringList tempCapabilities; // Whether the server has CAP implemented bool capabilitiesSupported; #ifndef IRC_NO_DEPRECATED // TODO: for backwards compatibility, to be removed in 1.0 void emitCompatSignal(const char* signal, const QVariantList& params); void _q_joined(const QString& origin); void _q_parted(const QString& origin, const QString& message); void _q_quit(const QString& origin, const QString& message); void _q_nickChanged(const QString& origin, const QString& nick); void _q_modeChanged(const QString& origin, const QString& mode, const QString& args); void _q_topicChanged(const QString& origin, const QString& topic); void _q_invited(const QString& origin, const QString& receiver, const QString& channel); void _q_kicked(const QString& origin, const QString& nick, const QString& message); void _q_messageReceived(const QString& origin, const QString& message); void _q_noticeReceived(const QString& origin, const QString& notice); void _q_ctcpRequestReceived(const QString& origin, const QString& request); void _q_ctcpReplyReceived(const QString& origin, const QString& reply); void _q_ctcpActionReceived(const QString& origin, const QString& action); void _q_numericMessageReceived(const QString& origin, uint code, const QStringList& params); void _q_unknownMessageReceived(const QString& origin, const QStringList& params); #endif // IRC_NO_DEPRECATED }; } #endif // IRC_BUFFER_P_H mudlet-2.1/src/irc/include/ircbuffer_p.h0000644000175000017500000000215611513237311017605 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #ifndef IRC_BUFFER_P_H #define IRC_BUFFER_P_H #include namespace Irc { class Buffer; class BufferPrivate { Q_DECLARE_PUBLIC(Buffer) public: BufferPrivate(); void addName(QString name); void removeName(const QString& name); void setReceiver(const QString& rec, bool replace = true); void updateMode(const QString& name, const QString& mode); Buffer* q_ptr; QString receiver; QString topic; QHash names; }; } #endif // IRC_BUFFER_P_H mudlet-2.1/src/irc/include/IrcSession0000644000175000017500000000003111513237311017140 0ustar csmallcsmall#include mudlet-2.1/src/irc/include/ircglobal.h0000644000175000017500000000374711513237311017264 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #ifndef IRC_GLOBAL_H #define IRC_GLOBAL_H #include /*! \file ircglobal.h */ #define IRC_STATIC #if defined(IRC_SHARED) # if defined(BUILD_IRC) # define IRC_EXPORT Q_DECL_EXPORT # else # define IRC_EXPORT Q_DECL_IMPORT # endif #elif defined(IRC_STATIC) # define IRC_EXPORT #else # error Installation problem: either IRC_SHARED or IRC_STATIC must be defined! #endif /*! \def IRC_VERSION This macro expands a numeric value of the form 0xMMNNPP (MM = major, NN = minor, PP = patch) that specifies LibIrcClient-Qt's version number. For example, if you compile your application against LibIrcClient-Qt 1.2.3, the IRC_VERSION macro will expand to 0x010203. You can use IRC_VERSION to use the latest LibIrcClient-Qt features where available. For example: \code #if IRC_VERSION >= 0x000300 session->setSocket(new QSslSocket(session)); session->connectToServer(host, port); #endif \endcode \sa IRC_VERSION_STR and Irc::version(). */ #define IRC_VERSION 0x000500 /*! \def IRC_VERSION_STR This macro expands to a string that specifies LibIrcClient-Qt's version number (for example, "1.2.3"). This is the version against which the application is compiled. \sa Irc::version() and IRC_VERSION. */ #define IRC_VERSION_STR "0.5.0" #ifndef QT_FORWARD_DECLARE_CLASS # define QT_FORWARD_DECLARE_CLASS(name) class name; #endif // QT_FORWARD_DECLARE_CLASS #endif // IRC_GLOBAL_H mudlet-2.1/src/irc/include/irc.h0000644000175000017500000001520711513237311016075 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #ifndef IRC_H #define IRC_H #include #include namespace Irc { IRC_EXPORT const char* version(); class IRC_EXPORT Rfc { Q_GADGET Q_ENUMS(Numeric) public: static const char* toString(uint code); enum Numeric { RPL_WELCOME = 001, RPL_YOURHOST = 002, RPL_CREATED = 003, RPL_MYINFO = 004, RPL_BOUNCE = 005, RPL_USERHOST = 302, RPL_ISON = 303, RPL_AWAY = 301, RPL_UNAWAY = 305, RPL_NOWAWAY = 306, RPL_WHOISUSER = 311, RPL_WHOISSERVER = 312, RPL_WHOISOPERATOR = 313, RPL_WHOISIDLE = 317, RPL_ENDOFWHOIS = 318, RPL_WHOISCHANNELS = 319, RPL_WHOWASUSER = 314, RPL_ENDOFWHOWAS = 369, RPL_LIST = 322, RPL_LISTEND = 323, RPL_UNIQOPIS = 325, RPL_CHANNELMODEIS = 324, RPL_CHANNELURL = 328, RPL_CHANNELCREATED = 329, RPL_NOTOPIC = 331, RPL_TOPIC = 332, RPL_TOPICSET = 333, RPL_INVITING = 341, RPL_SUMMONING = 342, RPL_INVITELIST = 346, RPL_ENDOFINVITELIST = 347, RPL_EXCEPTLIST = 348, RPL_ENDOFEXCEPTLIST = 349, RPL_VERSION = 351, RPL_WHOREPLY = 352, RPL_ENDOFWHO = 315, RPL_NAMREPLY = 353, RPL_ENDOFNAMES = 366, RPL_LINKS = 364, RPL_ENDOFLINKS = 365, RPL_BANLIST = 367, RPL_ENDOFBANLIST = 368, RPL_INFO = 371, RPL_ENDOFINFO = 374, RPL_MOTDSTART = 375, RPL_MOTD = 372, RPL_ENDOFMOTD = 376, RPL_YOUREOPER = 381, RPL_REHASHING = 382, RPL_YOURESERVICE = 383, RPL_TIME = 391, RPL_USERSSTART = 392, RPL_USERS = 393, RPL_ENDOFUSERS = 394, RPL_NOUSERS = 395, RPL_TRACELINK = 200, RPL_TRACECONNECTING = 201, RPL_TRACEHANDSHAKE = 202, RPL_TRACEUNKNOWN = 203, RPL_TRACEOPERATOR = 204, RPL_TRACEUSER = 205, RPL_TRACESERVER = 206, RPL_TRACESERVICE = 207, RPL_TRACENEWTYPE = 208, RPL_TRACECLASS = 209, RPL_TRACELOG = 261, RPL_TRACEEND = 262, RPL_STATSLINKINFO = 211, RPL_STATSCOMMANDS = 212, RPL_ENDOFSTATS = 219, RPL_STATSUPTIME = 242, RPL_STATSOLINE = 243, RPL_UMODEIS = 221, RPL_SERVLIST = 234, RPL_SERVLISTEND = 235, RPL_LUSERCLIENT = 251, RPL_LUSEROP = 252, RPL_LUSERUNKNOWN = 253, RPL_LUSERCHANNELS = 254, RPL_LUSERME = 255, RPL_ADMINME = 256, RPL_ADMINLOC1 = 257, RPL_ADMINLOC2 = 258, RPL_ADMINEMAIL = 259, RPL_TRYAGAIN = 263, ERR_NOSUCHNICK = 401, ERR_NOSUCHSERVER = 402, ERR_NOSUCHCHANNEL = 403, ERR_CANNOTSENDTOCHAN = 404, ERR_TOOMANYCHANNELS = 405, ERR_WASNOSUCHNICK = 406, ERR_TOOMANYTARGETS = 407, ERR_NOSUCHSERVICE = 408, ERR_NOORIGIN = 409, ERR_NORECIPIENT = 411, ERR_NOTEXTTOSEND = 412, ERR_NOTOPLEVEL = 413, ERR_WILDTOPLEVEL = 414, ERR_BADMASK = 415, ERR_UNKNOWNCOMMAND = 421, ERR_NOMOTD = 422, ERR_NOADMININFO = 423, ERR_FILEERROR = 424, ERR_NONICKNAMEGIVEN = 431, ERR_ERRONEUSNICKNAME = 432, ERR_NICKNAMEINUSE = 433, ERR_NICKCOLLISION = 436, ERR_UNAVAILRESOURCE = 437, ERR_USERNOTINCHANNEL = 441, ERR_NOTONCHANNEL = 442, ERR_USERONCHANNEL = 443, ERR_NOLOGIN = 444, ERR_SUMMONDISABLED = 445, ERR_USERSDISABLED = 446, ERR_NOTREGISTERED = 451, ERR_NEEDMOREPARAMS = 461, ERR_ALREADYREGISTRED = 462, ERR_NOPERMFORHOST = 463, ERR_PASSWDMISMATCH = 464, ERR_YOUREBANNEDCREEP = 465, ERR_YOUWILLBEBANNED = 466, ERR_KEYSET = 467, ERR_CHANNELISFULL = 471, ERR_UNKNOWNMODE = 472, ERR_INVITEONLYCHAN = 473, ERR_BANNEDFROMCHAN = 474, ERR_BADCHANNELKEY = 475, ERR_BADCHANMASK = 476, ERR_NOCHANMODES = 477, ERR_BANLISTFULL = 478, ERR_NOPRIVILEGES = 481, ERR_CHANOPRIVSNEEDED = 482, ERR_CANTKILLSERVER = 483, ERR_RESTRICTED = 484, ERR_UNIQOPPRIVSNEEDED = 485, ERR_NOOPERHOST = 491, ERR_UMODEUNKNOWNFLAG = 501, ERR_USERSDONTMATCH = 502 }; }; } #endif // IRC_H mudlet-2.1/src/irc/include/IrcBuffer0000644000175000017500000000003011513237311016725 0ustar csmallcsmall#include mudlet-2.1/src/irc/include/IrcUtil0000644000175000017500000000002611513237311016436 0ustar csmallcsmall#include mudlet-2.1/src/irc/examples/0000755000175000017500000000000011513237311015335 5ustar csmallcsmallmudlet-2.1/src/irc/examples/shared/0000755000175000017500000000000011513237311016603 5ustar csmallcsmallmudlet-2.1/src/irc/examples/shared/shared.pri0000644000175000017500000000051311513237311020564 0ustar csmallcsmall###################################################################### # LibIrcClient-Qt ###################################################################### QT = core network CONFIG += console no_keywords CONFIG += libircclient-qt INCLUDEPATH += ../shared DEPENDPATH += ../shared HEADERS += session.h SOURCES += session.cpp mudlet-2.1/src/irc/examples/shared/session.h0000644000175000017500000000451111513237311020440 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * This example is free, and not covered by LGPL license. There is no * restriction applied to their modification, redistribution, using and so on. * You can study them, modify them, use them in your own program - either * completely or partially. By using it you may give me some credits in your * program, but you don't have to. */ #ifndef SESSION_H #define SESSION_H #include #include class MyIrcSession : public Irc::Session { Q_OBJECT public: MyIrcSession(QObject* parent = 0); protected Q_SLOTS: void on_connected(); void on_disconnected(); void on_bufferAdded(Irc::Buffer* buffer); void on_bufferRemoved(Irc::Buffer* buffer); protected: virtual Irc::Buffer* createBuffer(const QString& receiver); }; class MyIrcBuffer : public Irc::Buffer { Q_OBJECT public: MyIrcBuffer(const QString& receiver, Irc::Session* parent); protected Q_SLOTS: void on_receiverChanged(const QString& receiver); void on_joined(const QString& origin); void on_parted(const QString& origin, const QString& message); void on_quit(const QString& origin, const QString& message); void on_nickChanged(const QString& origin, const QString& nick); void on_modeChanged(const QString& origin, const QString& mode, const QString& args); void on_topicChanged(const QString& origin, const QString& topic); void on_invited(const QString& origin, const QString& receiver, const QString& channel); void on_kicked(const QString& origin, const QString& nick, const QString& message); void on_messageReceived(const QString& origin, const QString& message, Irc::Buffer::MessageFlags flags); void on_noticeReceived(const QString& origin, const QString& notice, Irc::Buffer::MessageFlags flags); void on_ctcpRequestReceived(const QString& origin, const QString& request, Irc::Buffer::MessageFlags flags); void on_ctcpReplyReceived(const QString& origin, const QString& reply, Irc::Buffer::MessageFlags flags); void on_ctcpActionReceived(const QString& origin, const QString& action, Irc::Buffer::MessageFlags flags); void on_numericMessageReceived(const QString& origin, uint code, const QStringList& params); void on_unknownMessageReceived(const QString& origin, const QStringList& params); }; #endif // SESSION_H mudlet-2.1/src/irc/examples/shared/session.cpp0000644000175000017500000001425011513237311020774 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * This example is free, and not covered by LGPL license. There is no * restriction applied to their modification, redistribution, using and so on. * You can study them, modify them, use them in your own program - either * completely or partially. By using it you may give me some credits in your * program, but you don't have to. */ #include "session.h" #include MyIrcSession::MyIrcSession(QObject* parent) : Irc::Session(parent) { } void MyIrcSession::on_connected() { qDebug() << "connected:"; } void MyIrcSession::on_disconnected() { qDebug() << "disconnected:"; } void MyIrcSession::on_bufferAdded(Irc::Buffer* buffer) { qDebug() << "buffer added:" << buffer->receiver(); } void MyIrcSession::on_bufferRemoved(Irc::Buffer* buffer) { qDebug() << "buffer removed:" << buffer->receiver(); } Irc::Buffer* MyIrcSession::createBuffer(const QString& receiver) { return new MyIrcBuffer(receiver, this); } MyIrcBuffer::MyIrcBuffer(const QString& receiver, Irc::Session* parent) : Irc::Buffer(receiver, parent) { connect(this, SIGNAL(receiverChanged(QString)), SLOT(on_receiverChanged(QString))); connect(this, SIGNAL(joined(QString)), SLOT(on_joined(QString))); connect(this, SIGNAL(parted(QString, QString)), SLOT(on_parted(QString, QString))); connect(this, SIGNAL(quit(QString, QString)), SLOT(on_quit(QString, QString))); connect(this, SIGNAL(nickChanged(QString, QString)), SLOT(on_nickChanged(QString, QString))); connect(this, SIGNAL(modeChanged(QString, QString, QString)), SLOT(on_modeChanged(QString, QString, QString))); connect(this, SIGNAL(topicChanged(QString, QString)), SLOT(on_topicChanged(QString, QString))); connect(this, SIGNAL(invited(QString, QString, QString)), SLOT(on_invited(QString, QString, QString))); connect(this, SIGNAL(kicked(QString, QString, QString)), SLOT(on_kicked(QString, QString, QString))); connect(this, SIGNAL(messageReceived(QString, QString, Irc::Buffer::MessageFlags)), SLOT(on_messageReceived(QString, QString, Irc::Buffer::MessageFlags))); connect(this, SIGNAL(noticeReceived(QString, QString, Irc::Buffer::MessageFlags)), SLOT(on_noticeReceived(QString, QString, Irc::Buffer::MessageFlags))); connect(this, SIGNAL(ctcpRequestReceived(QString, QString, Irc::Buffer::MessageFlags)), SLOT(on_ctcpRequestReceived(QString, QString, Irc::Buffer::MessageFlags))); connect(this, SIGNAL(ctcpReplyReceived(QString, QString, Irc::Buffer::MessageFlags)), SLOT(on_ctcpReplyReceived(QString, QString, Irc::Buffer::MessageFlags))); connect(this, SIGNAL(ctcpActionReceived(QString, QString, Irc::Buffer::MessageFlags)), SLOT(on_ctcpActionReceived(QString, QString, Irc::Buffer::MessageFlags))); connect(this, SIGNAL(numericMessageReceived(QString, uint, QStringList)), SLOT(on_numericMessageReceived(QString, uint, QStringList))); connect(this, SIGNAL(unknownMessageReceived(QString, QStringList)), SLOT(on_unknownMessageReceived(QString, QStringList))); } void MyIrcBuffer::on_receiverChanged(const QString& receiver) { qDebug() << "receiver changed:" << receiver; } void MyIrcBuffer::on_joined(const QString& origin) { qDebug() << "joined:" << receiver() << origin; } void MyIrcBuffer::on_parted(const QString& origin, const QString& message) { qDebug() << "parted:" << receiver() << origin << message; } void MyIrcBuffer::on_quit(const QString& origin, const QString& message) { qDebug() << "quit:" << receiver() << origin << message; } void MyIrcBuffer::on_nickChanged(const QString& origin, const QString& nick) { qDebug() << "nick changed:" << receiver() << origin << nick; } void MyIrcBuffer::on_modeChanged(const QString& origin, const QString& mode, const QString& args) { qDebug() << "mode changed:" << receiver() << origin << mode << args; } void MyIrcBuffer::on_topicChanged(const QString& origin, const QString& topic) { qDebug() << "topic changed:" << receiver() << origin << topic; } void MyIrcBuffer::on_invited(const QString& origin, const QString& receiver, const QString& channel) { qDebug() << "invited:" << Irc::Buffer::receiver() << origin << receiver << channel; } void MyIrcBuffer::on_kicked(const QString& origin, const QString& nick, const QString& message) { qDebug() << "kicked:" << receiver() << origin << nick << message; } void MyIrcBuffer::on_messageReceived(const QString& origin, const QString& message, Irc::Buffer::MessageFlags flags) { qDebug() << "message received:" << receiver() << origin << message << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); } void MyIrcBuffer::on_noticeReceived(const QString& origin, const QString& notice, Irc::Buffer::MessageFlags flags) { qDebug() << "notice received:" << receiver() << origin << notice << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); } void MyIrcBuffer::on_ctcpRequestReceived(const QString& origin, const QString& request, Irc::Buffer::MessageFlags flags) { qDebug() << "ctcp request received:" << receiver() << origin << request << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); } void MyIrcBuffer::on_ctcpReplyReceived(const QString& origin, const QString& reply, Irc::Buffer::MessageFlags flags) { qDebug() << "ctcp reply received:" << receiver() << origin << reply << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); } void MyIrcBuffer::on_ctcpActionReceived(const QString& origin, const QString& action, Irc::Buffer::MessageFlags flags) { qDebug() << "ctcp action received:" << receiver() << origin << action << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)"); } void MyIrcBuffer::on_numericMessageReceived(const QString& origin, uint code, const QStringList& params) { qDebug() << "numeric message received:" << receiver() << origin << code << params; } void MyIrcBuffer::on_unknownMessageReceived(const QString& origin, const QStringList& params) { qDebug() << "unknown message received:" << receiver() << origin << params; } mudlet-2.1/src/irc/examples/examples.pro0000644000175000017500000000033211513237311017673 0ustar csmallcsmall###################################################################### # LibIrcClient-Qt ###################################################################### TEMPLATE = subdirs SUBDIRS += compattest irctest ssltest mudlet-2.1/src/irc/examples/irctest/0000755000175000017500000000000011513237311017012 5ustar csmallcsmallmudlet-2.1/src/irc/examples/irctest/main.cpp0000644000175000017500000000161511513237311020445 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * This example is free, and not covered by LGPL license. There is no * restriction applied to their modification, redistribution, using and so on. * You can study them, modify them, use them in your own program - either * completely or partially. By using it you may give me some credits in your * program, but you don't have to. */ #include #include "session.h" int main (int argc, char* argv[]) { QCoreApplication app(argc, argv); if (argc < 4) { qDebug("Usage: %s ", argv[0]); return 1; } QStringList channels; for (int i = 3; i < argc; ++i) { channels.append(argv[i]); } MyIrcSession session; session.setNick(argv[2]); session.setAutoJoinChannels(channels); session.connectToServer(argv[1], 6667); return app.exec(); } mudlet-2.1/src/irc/examples/irctest/irctest.pro0000644000175000017500000000042611513237311021213 0ustar csmallcsmall###################################################################### # LibIrcClient-Qt ###################################################################### TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += main.cpp include(../shared/shared.pri) mudlet-2.1/src/irc/examples/ssltest/0000755000175000017500000000000011513237311017036 5ustar csmallcsmallmudlet-2.1/src/irc/examples/ssltest/ssltest.pro0000644000175000017500000000042611513237311021263 0ustar csmallcsmall###################################################################### # LibIrcClient-Qt ###################################################################### TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += main.cpp include(../shared/shared.pri) mudlet-2.1/src/irc/examples/ssltest/main.cpp0000644000175000017500000000215211513237311020466 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * This example is free, and not covered by LGPL license. There is no * restriction applied to their modification, redistribution, using and so on. * You can study them, modify them, use them in your own program - either * completely or partially. By using it you may give me some credits in your * program, but you don't have to. */ #include #include #include "session.h" int main (int argc, char* argv[]) { QCoreApplication app(argc, argv); if (argc < 5) { qDebug("Usage: %s ", argv[0]); return 1; } QStringList channels; for (int i = 4; i < argc; ++i) { channels.append(argv[i]); } MyIrcSession session; session.setNick(argv[3]); session.setAutoJoinChannels(channels); QSslSocket* socket = new QSslSocket(&session); socket->ignoreSslErrors(); socket->setPeerVerifyMode(QSslSocket::VerifyNone); session.setSocket(socket); session.connectToServer(argv[1], QString(argv[2]).toInt()); return app.exec(); } mudlet-2.1/src/irc/examples/compattest/0000755000175000017500000000000011513237311017520 5ustar csmallcsmallmudlet-2.1/src/irc/examples/compattest/main.cpp0000644000175000017500000000163411513237311021154 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * This example is free, and not covered by LGPL license. There is no * restriction applied to their modification, redistribution, using and so on. * You can study them, modify them, use them in your own program - either * completely or partially. By using it you may give me some credits in your * program, but you don't have to. * * $Id$ */ #include #include "session.h" int main (int argc, char* argv[]) { QCoreApplication app(argc, argv); if (argc < 4) { qDebug("Usage: %s ", argv[0]); return 1; } QStringList channels; for (int i = 3; i < argc; ++i) { channels.append(argv[i]); } CompatIrcSession session; session.setNick(argv[2]); session.setAutoJoinChannels(channels); session.connectToServer(argv[1], 6667); return app.exec(); } mudlet-2.1/src/irc/examples/compattest/session.h0000644000175000017500000000403411513237311021355 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * This example is free, and not covered by LGPL license. There is no * restriction applied to their modification, redistribution, using and so on. * You can study them, modify them, use them in your own program - either * completely or partially. By using it you may give me some credits in your * program, but you don't have to. * * $Id$ */ #ifndef SESSION_H #define SESSION_H #include class CompatIrcSession : public Irc::Session { Q_OBJECT public: CompatIrcSession(QObject* parent = 0); protected Q_SLOTS: void on_connected(); void on_disconnected(); void on_msgJoined(const QString& origin, const QString& channel); void on_msgParted(const QString& origin, const QString& channel, const QString& message); void on_msgQuit(const QString& origin, const QString& message); void on_msgNickChanged(const QString& origin, const QString& nick); void on_msgModeChanged(const QString& origin, const QString& receiver, const QString& mode, const QString& args); void on_msgTopicChanged(const QString& origin, const QString& channel, const QString& topic); void on_msgInvited(const QString& origin, const QString& receiver, const QString& channel); void on_msgKicked(const QString& origin, const QString& channel, const QString& nick, const QString& message); void on_msgMessageReceived(const QString& origin, const QString& receiver, const QString& message); void on_msgNoticeReceived(const QString& origin, const QString& receiver, const QString& notice); void on_msgCtcpRequestReceived(const QString& origin, const QString& request); void on_msgCtcpReplyReceived(const QString& origin, const QString& reply); void on_msgCtcpActionReceived(const QString& origin, const QString& receiver, const QString& action); void on_msgNumericMessageReceived(const QString& origin, uint code, const QStringList& params); void on_msgUnknownMessageReceived(const QString& origin, const QStringList& params); }; #endif // SESSION_H mudlet-2.1/src/irc/examples/compattest/compattest.pro0000644000175000017500000000054411513237311022430 0ustar csmallcsmall###################################################################### # LibIrcClient-Qt ###################################################################### TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . QT = core network CONFIG += console no_keywords CONFIG += libircclient-qt # Input HEADERS += session.h SOURCES += session.cpp main.cpp mudlet-2.1/src/irc/examples/compattest/session.cpp0000644000175000017500000001200411513237311021704 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * This example is free, and not covered by LGPL license. There is no * restriction applied to their modification, redistribution, using and so on. * You can study them, modify them, use them in your own program - either * completely or partially. By using it you may give me some credits in your * program, but you don't have to. * * $Id$ */ #include "session.h" #include CompatIrcSession::CompatIrcSession(QObject* parent) : Irc::Session(parent) { connect(this, SIGNAL(connected()), SLOT(on_connected())); connect(this, SIGNAL(disconnected()), SLOT(on_disconnected())); connect(this, SIGNAL(msgJoined(QString, QString)), SLOT(on_msgJoined(QString, QString))); connect(this, SIGNAL(msgParted(QString, QString, QString)), SLOT(on_msgParted(QString, QString, QString))); connect(this, SIGNAL(msgQuit(QString, QString)), SLOT(on_msgQuit(QString, QString))); connect(this, SIGNAL(msgNickChanged(QString, QString)), SLOT(on_msgNickChanged(QString, QString))); connect(this, SIGNAL(msgModeChanged(QString, QString, QString, QString)), SLOT(on_msgModeChanged(QString, QString, QString, QString))); connect(this, SIGNAL(msgTopicChanged(QString, QString, QString)), SLOT(on_msgTopicChanged(QString, QString, QString))); connect(this, SIGNAL(msgInvited(QString, QString, QString)), SLOT(on_msgInvited(QString, QString, QString))); connect(this, SIGNAL(msgKicked(QString, QString, QString, QString)), SLOT(on_msgKicked(QString, QString, QString, QString))); connect(this, SIGNAL(msgMessageReceived(QString, QString, QString)), SLOT(on_msgMessageReceived(QString, QString, QString))); connect(this, SIGNAL(msgNoticeReceived(QString, QString, QString)), SLOT(on_msgNoticeReceived(QString, QString, QString))); connect(this, SIGNAL(msgCtcpRequestReceived(QString, QString)), SLOT(on_msgCtcpRequestReceived(QString, QString))); connect(this, SIGNAL(msgCtcpReplyReceived(QString, QString)), SLOT(on_msgCtcpReplyReceived(QString, QString))); connect(this, SIGNAL(msgCtcpActionReceived(QString, QString, QString)), SLOT(on_msgCtcpActionReceived(QString, QString, QString))); connect(this, SIGNAL(msgNumericMessageReceived(QString, uint, QStringList)), SLOT(on_msgNumericMessageReceived(QString, uint, QStringList))); connect(this, SIGNAL(msgUnknownMessageReceived(QString, QStringList)), SLOT(on_msgUnknownMessageReceived(QString, QStringList))); } void CompatIrcSession::on_connected() { qDebug() << "connected:"; } void CompatIrcSession::on_disconnected() { qDebug() << "disconnected:"; } void CompatIrcSession::on_msgJoined(const QString& origin, const QString& channel) { qDebug() << "join:" << origin << channel; } void CompatIrcSession::on_msgParted(const QString& origin, const QString& channel, const QString& message) { qDebug() << "part:" << origin << channel << message; } void CompatIrcSession::on_msgQuit(const QString& origin, const QString& message) { qDebug() << "quit:" << origin << message; } void CompatIrcSession::on_msgNickChanged(const QString& origin, const QString& nick) { qDebug() << "nick:" << origin << nick; } void CompatIrcSession::on_msgModeChanged(const QString& origin, const QString& receiver, const QString& mode, const QString& args) { qDebug() << "mode:" << origin << receiver << mode << args; } void CompatIrcSession::on_msgTopicChanged(const QString& origin, const QString& channel, const QString& topic) { qDebug() << "topic:" << origin << channel << topic; } void CompatIrcSession::on_msgInvited(const QString& origin, const QString& receiver, const QString& channel) { qDebug() << "invite:" << origin << receiver << channel; } void CompatIrcSession::on_msgKicked(const QString& origin, const QString& channel, const QString& nick, const QString& message) { qDebug() << "kick:" << origin << channel << nick << message; } void CompatIrcSession::on_msgMessageReceived(const QString& origin, const QString& receiver, const QString& message) { qDebug() << "message:" << origin << receiver << message; } void CompatIrcSession::on_msgNoticeReceived(const QString& origin, const QString& receiver, const QString& notice) { qDebug() << "notice:" << origin << receiver << notice; } void CompatIrcSession::on_msgCtcpRequestReceived(const QString& origin, const QString& request) { qDebug() << "ctcp request:" << origin << request; } void CompatIrcSession::on_msgCtcpReplyReceived(const QString& origin, const QString& reply) { qDebug() << "ctcp reply:" << origin << reply; } void CompatIrcSession::on_msgCtcpActionReceived(const QString& origin, const QString& receiver, const QString& action) { qDebug() << "ctcp action:" << origin << receiver << action; } void CompatIrcSession::on_msgNumericMessageReceived(const QString& origin, uint code, const QStringList& params) { qDebug() << "numeric:" << origin << code << params; } void CompatIrcSession::on_msgUnknownMessageReceived(const QString& origin, const QStringList& params) { qDebug() << "unknown:" << origin << params; } mudlet-2.1/src/irc/doc/0000755000175000017500000000000011513237311014264 5ustar csmallcsmallmudlet-2.1/src/irc/doc/ircbuffer_8h_source.html0000644000175000017500000003156011513237311021105 0ustar csmallcsmall LibIrcClient-Qt: include/ircbuffer.h Source File

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/index.html0000644000175000017500000000375111513237311016267 0ustar csmallcsmall LibIrcClient-Qt: LibIrcClient-Qt - a cross-platform C++ IRC library

LibIrcClient-Qt - a cross-platform C++ IRC library

0.5.0

Introduction

LibIrcClient-Qt is a cross-platform IRC client library written with Qt 4.

Installation

To compile LibIrcClient-Qt, do the standard mantra:

    # qmake -config (debug|release)
    # make
    # sudo make install

Usage

Add the following line to your qmake .pro file:

    CONFIG += libircclient-qt

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x62.html0000644000175000017500000001010011513237311017731 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- b -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x6d.html0000644000175000017500000001476311513237311020036 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- m -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x76.html0000644000175000017500000000713711513237311017756 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- v -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/classIrc_1_1Util-members.html0000644000175000017500000000501311513237311021642 0ustar csmallcsmall LibIrcClient-Qt: Member List

Irc::Util Member List

This is the complete list of members for Irc::Util, including all inherited members.
colorNameFromCode(int code)Irc::Util [static]
hostFromTarget(const QString &target)Irc::Util [static]
messageToHtml(const QString &message)Irc::Util [static]
nickFromTarget(const QString &target)Irc::Util [static]

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x72.html0000644000175000017500000004137211513237311017751 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- r -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/ircbuffer__p_8h_source.html0000644000175000017500000001100611513237311021554 0ustar csmallcsmall LibIrcClient-Qt: include/ircbuffer_p.h Source File
Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/deprecated.html0000644000175000017500000003222611513237311017257 0ustar csmallcsmall LibIrcClient-Qt: Deprecated List

Deprecated List

Member Irc::Session::cmdCtcpAction (const QString &receiver, const QString &action)
Use Irc::Session::ctcpAction()

Member Irc::Session::cmdCtcpReply (const QString &nick, const QString &reply)
Use Irc::Session::ctcpReply()

Member Irc::Session::cmdCtcpRequest (const QString &nick, const QString &request)
Use Irc::Session::ctcpRequest()

Member Irc::Session::cmdInvite (const QString &nick, const QString &channel)
Use Irc::Session::invite()

Member Irc::Session::cmdJoin (const QString &channel, const QString &key=QString())
Use Irc::Session::join()

Member Irc::Session::cmdKick (const QString &nick, const QString &channel, const QString &reason=QString())
Use Irc::Session::kick()

Member Irc::Session::cmdList (const QString &channel=QString())
Use Irc::Session::list()

Member Irc::Session::cmdMessage (const QString &receiver, const QString &message)
Use Irc::Session::message()

Member Irc::Session::cmdMode (const QString &target, const QString &mode=QString())
Use Irc::Session::mode()

Member Irc::Session::cmdNames (const QString &channel)
Use Irc::Session::names()

Member Irc::Session::cmdNotice (const QString &receiver, const QString &notice)
Use Irc::Session::notice()

Member Irc::Session::cmdPart (const QString &channel, const QString &reason=QString())
Use Irc::Session::part()

Member Irc::Session::cmdQuit (const QString &reason=QString())
Use Irc::Session::quit()

Member Irc::Session::cmdTopic (const QString &channel, const QString &topic=QString())
Use Irc::Session::topic()

Member Irc::Session::cmdWhois (const QString &nick)
Use Irc::Session::whois()

Member Irc::Session::msgCtcpActionReceived (const QString &origin, const QString &receiver, const QString &action)
Use Irc::Buffer::ctcpActionReceived(const QString& origin, const QString& action)

Member Irc::Session::msgCtcpReplyReceived (const QString &origin, const QString &reply)
Use Irc::Buffer::ctcpReplyReceived(const QString& origin, const QString& reply)

Member Irc::Session::msgCtcpRequestReceived (const QString &origin, const QString &request)
Use Irc::Buffer::ctcpRequestReceived(const QString& origin, const QString& request)

Member Irc::Session::msgInvited (const QString &origin, const QString &receiver, const QString &channel)
Use Irc::Buffer::invited(const QString& origin, const QString& receiver, const QString& channel)

Member Irc::Session::msgJoined (const QString &origin, const QString &channel)
Use Irc::Buffer::joined(const QString& origin)

Member Irc::Session::msgKicked (const QString &origin, const QString &channel, const QString &nick, const QString &message)
Use Irc::Buffer::kicked(const QString& origin, const QString& nick, const QString& message)

Member Irc::Session::msgMessageReceived (const QString &origin, const QString &receiver, const QString &message)
Use Irc::Buffer::messageReceived(const QString& origin, const QString& message)

Member Irc::Session::msgModeChanged (const QString &origin, const QString &receiver, const QString &mode, const QString &args)
Use Irc::Buffer::modeChanged(const QString& origin, const QString& mode, const QString& args)

Member Irc::Session::msgNickChanged (const QString &origin, const QString &nick)
Use Irc::Buffer::nickChanged(const QString& origin, const QString& nick)

Member Irc::Session::msgNoticeReceived (const QString &origin, const QString &receiver, const QString &notice)
Use Irc::Buffer::noticeReceived(const QString& origin, const QString& notice)

Member Irc::Session::msgNumericMessageReceived (const QString &origin, uint code, const QStringList &params)
Use Irc::Buffer::numericMessageReceived(const QString& origin, uint code, const QStringList& params)

Member Irc::Session::msgParted (const QString &origin, const QString &channel, const QString &message)
Use Irc::Buffer::parted(const QString& origin, const QString& message)

Member Irc::Session::msgQuit (const QString &origin, const QString &message)
Use Irc::Buffer::quit(const QString& origin, const QString& message)

Member Irc::Session::msgTopicChanged (const QString &origin, const QString &channel, const QString &topic)
Use Irc::Buffer::topicChanged(const QString& origin, const QString& topic)

Member Irc::Session::msgUnknownMessageReceived (const QString &origin, const QStringList &params)
Use Irc::Buffer::unknownMessageReceived(const QString& origin, const QStringList& params)

Member Irc::Session::sendRaw (const QString &message)
Use Irc::Session::raw()

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/classIrc_1_1Buffer.html0000644000175000017500000011551511513237311020517 0ustar csmallcsmall LibIrcClient-Qt: Irc::Buffer Class Reference

Irc::Buffer Class Reference

The Irc::Buffer class provides an IRC buffer. More...

#include <ircbuffer.h>

List of all members.

Public Types

enum  MessageFlag { NoFlags = 0x0, IdentifiedFlag = 0x1, EchoFlag = 0x2 }

Public Slots

bool message (const QString &message)
bool notice (const QString &notice)
bool ctcpAction (const QString &action)

Signals

void receiverChanged (const QString &receiver)
void motdReceived (const QString &motd)
void joined (const QString &origin)
void parted (const QString &origin, const QString &message)
void quit (const QString &origin, const QString &message)
void nickChanged (const QString &origin, const QString &nick)
void modeChanged (const QString &origin, const QString &mode, const QString &args)
void topicChanged (const QString &origin, const QString &topic)
void invited (const QString &origin, const QString &receiver, const QString &channel)
void kicked (const QString &origin, const QString &nick, const QString &message)
void messageReceived (const QString &origin, const QString &message, Irc::Buffer::MessageFlags flags=Irc::Buffer::NoFlags)
void noticeReceived (const QString &origin, const QString &notice, Irc::Buffer::MessageFlags flags=Irc::Buffer::NoFlags)
void ctcpRequestReceived (const QString &origin, const QString &request, Irc::Buffer::MessageFlags flags=Irc::Buffer::NoFlags)
void ctcpReplyReceived (const QString &origin, const QString &reply, Irc::Buffer::MessageFlags flags=Irc::Buffer::NoFlags)
void ctcpActionReceived (const QString &origin, const QString &action, Irc::Buffer::MessageFlags flags=Irc::Buffer::NoFlags)
void numericMessageReceived (const QString &origin, uint code, const QStringList &params)
void unknownMessageReceived (const QString &origin, const QStringList &params)

Public Member Functions

 ~Buffer ()
Sessionsession () const
QString receiver () const
QString topic () const
QStringList names () const
QString modes (const QString &name) const
QString visualMode (const QString &name) const

Protected Member Functions

 Buffer (const QString &receiver, Session *parent=0)

Detailed Description

The Irc::Buffer class acts as a buffer for a single receiver. Receivers can be:

  • the server
  • channels
  • queries.

Server/channel/query specific messages are delivered to the corresponding buffer.

Note:
Buffers are not intended to be instantiated directly, but via the virtual factory method Irc::Session::createBuffer().

Member Enumeration Documentation

This enum describes available message flags.

Enumerator:
NoFlags 

No flags for the message.

IdentifiedFlag 

Message was sent from an identified nick.

EchoFlag 

Message echoed back from library.


Constructor & Destructor Documentation

Irc::Buffer::~Buffer (  ) 

Destructs the IRC buffer.

Irc::Buffer::Buffer ( const QString &  receiver,
Session parent = 0 
) [protected]

Constructs a new IRC buffer with receiver and parent.

See also:
Session::createBuffer()

Member Function Documentation

bool Irc::Buffer::ctcpAction ( const QString &  action  )  [slot]

This convenience function sends a CTCP action to the buffers' receiver.

See also:
Session::ctcpAction()
void Irc::Buffer::ctcpActionReceived ( const QString &  origin,
const QString &  action,
Irc::Buffer::MessageFlags  flags = Irc::Buffer::NoFlags 
) [signal]

This signal is emitted when origin has sent a CTCP action.

void Irc::Buffer::ctcpReplyReceived ( const QString &  origin,
const QString &  reply,
Irc::Buffer::MessageFlags  flags = Irc::Buffer::NoFlags 
) [signal]

This signal is emitted when origin has sent a CTCP reply.

void Irc::Buffer::ctcpRequestReceived ( const QString &  origin,
const QString &  request,
Irc::Buffer::MessageFlags  flags = Irc::Buffer::NoFlags 
) [signal]

This signal is emitted when origin has sent a CTCP request.

void Irc::Buffer::invited ( const QString &  origin,
const QString &  receiver,
const QString &  channel 
) [signal]

This signal is emitted when origin has invited receiver to channel.

void Irc::Buffer::joined ( const QString &  origin  )  [signal]

This signal is emitted when origin has joined.

void Irc::Buffer::kicked ( const QString &  origin,
const QString &  nick,
const QString &  message 
) [signal]

This signal is emitted when origin has kicked nick with message.

bool Irc::Buffer::message ( const QString &  message  )  [slot]

This convenience function sends a message to the buffer's receiver.

See also:
Session::message()
void Irc::Buffer::messageReceived ( const QString &  origin,
const QString &  message,
Irc::Buffer::MessageFlags  flags = Irc::Buffer::NoFlags 
) [signal]

This signal is emitted when origin has sent message.

void Irc::Buffer::modeChanged ( const QString &  origin,
const QString &  mode,
const QString &  args 
) [signal]

This signal is emitted when origin has changed mode with args.

QString Irc::Buffer::modes ( const QString &  name  )  const

Returns the modes of name.

void Irc::Buffer::motdReceived ( const QString &  motd  )  [signal]

This signal is emitted when message of the day motd has been received.

QStringList Irc::Buffer::names (  )  const

Returns the names.

void Irc::Buffer::nickChanged ( const QString &  origin,
const QString &  nick 
) [signal]

This signal is emitted when origin has changed nick.

bool Irc::Buffer::notice ( const QString &  notice  )  [slot]

This convenience function sends a notice to the buffer's receiver.

See also:
Session::notice()
void Irc::Buffer::noticeReceived ( const QString &  origin,
const QString &  notice,
Irc::Buffer::MessageFlags  flags = Irc::Buffer::NoFlags 
) [signal]

This signal is emitted when origin has sent notice.

void Irc::Buffer::numericMessageReceived ( const QString &  origin,
uint  code,
const QStringList &  params 
) [signal]

This signal is emitted when origin has sent a numeric message with code and params.

void Irc::Buffer::parted ( const QString &  origin,
const QString &  message 
) [signal]

This signal is emitted when origin has parted with message.

void Irc::Buffer::quit ( const QString &  origin,
const QString &  message 
) [signal]

This signal is emitted when origin has quit with message.

QString Irc::Buffer::receiver (  )  const

Returns the receiver.

void Irc::Buffer::receiverChanged ( const QString &  receiver  )  [signal]

This signal is emitted whenever receiver has changed.

Session * Irc::Buffer::session (  )  const

Returns the session.

QString Irc::Buffer::topic (  )  const

Returns the topic.

void Irc::Buffer::topicChanged ( const QString &  origin,
const QString &  topic 
) [signal]

This signal is emitted when origin has changed topic.

void Irc::Buffer::unknownMessageReceived ( const QString &  origin,
const QStringList &  params 
) [signal]

This signal is emitted when origin has sent an unknown message with params.

QString Irc::Buffer::visualMode ( const QString &  name  )  const

Returns the visual mode of name.


The documentation for this class was generated from the following files:

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions.html0000644000175000017500000000774411513237311017176 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- a -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/globals_defs.html0000644000175000017500000000345511513237311017605 0ustar csmallcsmall LibIrcClient-Qt: Class Members
 

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x64.html0000644000175000017500000000754411513237311017755 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- d -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x73.html0000644000175000017500000001324711513237311017752 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- s -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/classes.html0000644000175000017500000000604611513237311016615 0ustar csmallcsmall LibIrcClient-Qt: Alphabetical List

Class Index

B | R | S | U
  B  
  R  
  S  
  U  
Util (Irc)   
Buffer (Irc)   Rfc (Irc)   Session (Irc)   
B | R | S | U

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/ircglobal_8h.html0000644000175000017500000001053511513237311017513 0ustar csmallcsmall LibIrcClient-Qt: include/ircglobal.h File Reference

include/ircglobal.h File Reference

#include <QtGlobal>

Go to the source code of this file.

Defines

#define IRC_VERSION   0x000500
#define IRC_VERSION_STR   "0.5.0"

Detailed Description


Define Documentation

#define IRC_VERSION   0x000500

This macro expands a numeric value of the form 0xMMNNPP (MM = major, NN = minor, PP = patch) that specifies LibIrcClient-Qt's version number. For example, if you compile your application against LibIrcClient-Qt 1.2.3, the IRC_VERSION macro will expand to 0x010203.

You can use IRC_VERSION to use the latest LibIrcClient-Qt features where available. For example:

#if IRC_VERSION >= 0x000300
    session->setSocket(new QSslSocket(session));
    session->connectToServer(host, port);
#endif
See also:
IRC_VERSION_STR and Irc::version().
#define IRC_VERSION_STR   "0.5.0"

This macro expands to a string that specifies LibIrcClient-Qt's version number (for example, "1.2.3"). This is the version against which the application is compiled.

See also:
Irc::version() and IRC_VERSION.

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/tab_l.gif0000644000175000017500000000130211513237311016030 0ustar csmallcsmallGIF89a ,薴ŝɯͻ, ,@P`H$!%CqVe2XJ(Ġ+3 2$ kv-u*"}|}|~q(" $f 'l(&&$r & !){rƲεҽͼиP?Bm A%V܈!k/Đ;^$Ɩ#Mf)f͇(WLK҄ I)L:eD Cx*4 Uh %A^NKbeXkx!2t !5t]$%X.i[]YfEkg`:zҞ;}jaaM׸c瞽vۺ8ȋ'?9積G_>yu_ߞ]zw߭Ǿm浏G~თ/>٫|W}v;mudlet-2.1/src/irc/doc/ircsession_8h_source.html0000644000175000017500000007260111513237311021320 0ustar csmallcsmall LibIrcClient-Qt: include/ircsession.h Source File
Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/ircutil_8h_source.html0000644000175000017500000001040511513237311020604 0ustar csmallcsmall LibIrcClient-Qt: include/ircutil.h Source File
Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/globals.html0000644000175000017500000000356511513237311016606 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented file members with links to the documentation:

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x74.html0000644000175000017500000000764711513237311017762 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- t -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x6a.html0000644000175000017500000000731711513237311020030 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- j -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x7e.html0000644000175000017500000000732711513237311020036 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- ~ -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x77.html0000644000175000017500000000751211513237311017754 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- w -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x68.html0000644000175000017500000000732311513237311017754 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- h -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/doxygen.png0000644000175000017500000000240111513237311016444 0ustar csmallcsmallPNG  IHDRd-ok>gAMAOX2tEXtSoftwareAdobe ImageReadyqe<]PLTEǾ"&ﶻޠ{ԍ눙נED9hg]_X<@:#mhU1tRNSvIDATxbC: d#h` @X",***LK.], X@t b @BD6%""  % B:Hf@ RPy"K`\PbC(!II!h(!Cąl!0[X\J\$TM(>a$S @ Ш@R.$LJBRAG1 (FPhhT%!`&q%u P    CT$B|Wl!B`R$( @A%%@,(%$RPmB U`1IYB  99\1 yCCCf"[N'=TGȒl8^K5<SRɤ%@@  b1qAXH&BR y nP4A j>  t!+(.WQA2MU܂ `1%`19F< 3cZ`e!\ D+. 83!lYYA -6EJV @XXX 4 @86`RdB4I " "@xrʌHA`f ȰC"XV0C b@2H ȓ p)!( 04)(%R $Tʀbb,s@7 Ѱ?f֗\PIx!I"Ȉ3 QYt^^gv- }>WJOAV`$&#88\FF SFJ$ƀƊ 4 - Hf ?5 k1d, ."FˀI"4Hgx|fm)))9. aMD& X@t b @%DK.], X@t b @d`ɽSOIENDB`mudlet-2.1/src/irc/doc/functions_eval.html0000644000175000017500000005657511513237311020213 0ustar csmallcsmall LibIrcClient-Qt: Class Members - Enumerator
 

- e -

- i -

- n -

- r -

- s -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/files.html0000644000175000017500000000467511513237311016270 0ustar csmallcsmall LibIrcClient-Qt: File Index

File List

Here is a list of all documented files with brief descriptions:
include/irc.h [code]
include/ircbuffer.h [code]
include/ircbuffer_p.h [code]
include/ircglobal.h [code]
include/ircsession.h [code]
include/ircsession_p.h [code]
include/ircutil.h [code]

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x6c.html0000644000175000017500000000713311513237311020026 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- l -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x70.html0000644000175000017500000000767311513237311017755 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- p -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/pages.html0000644000175000017500000000247311513237311016257 0ustar csmallcsmall LibIrcClient-Qt: Page Index

Related Pages

Here is a list of all related documentation pages:

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/tabs.css0000644000175000017500000000346411513237311015736 0ustar csmallcsmall/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ DIV.tabs { float : left; width : 100%; background : url("tab_b.gif") repeat-x bottom; margin-bottom : 4px; } DIV.tabs UL { margin : 0px; padding-left : 10px; list-style : none; } DIV.tabs LI, DIV.tabs FORM { display : inline; margin : 0px; padding : 0px; } DIV.tabs FORM { float : right; } DIV.tabs A { float : left; background : url("tab_r.gif") no-repeat right top; border-bottom : 1px solid #84B0C7; font-size : 80%; font-weight : bold; text-decoration : none; } DIV.tabs A:hover { background-position: 100% -150px; } DIV.tabs A:link, DIV.tabs A:visited, DIV.tabs A:active, DIV.tabs A:hover { color: #1A419D; } DIV.tabs SPAN { float : left; display : block; background : url("tab_l.gif") no-repeat left top; padding : 5px 9px; white-space : nowrap; } DIV.tabs #MSearchBox { float : right; display : inline; font-size : 1em; } DIV.tabs TD { font-size : 80%; font-weight : bold; text-decoration : none; } /* Commented Backslash Hack hides rule from IE5-Mac \*/ DIV.tabs SPAN {float : none;} /* End IE5-Mac hack */ DIV.tabs A:hover SPAN { background-position: 0% -150px; } DIV.tabs LI.current A { background-position: 100% -150px; border-width : 0px; } DIV.tabs LI.current SPAN { background-position: 0% -150px; padding-bottom : 6px; } DIV.navpath { background : none; border : none; border-bottom : 1px solid #84B0C7; text-align : center; margin : 2px; padding : 2px; } mudlet-2.1/src/irc/doc/irc_8h_source.html0000644000175000017500000007532111513237311017716 0ustar csmallcsmall LibIrcClient-Qt: include/irc.h Source File
Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/classIrc_1_1Session-members.html0000644000175000017500000006727011513237311022365 0ustar csmallcsmall LibIrcClient-Qt: Member List

Irc::Session Member List

This is the complete list of members for Irc::Session, including all inherited members.
addAutoJoinChannel(const QString &channel)Irc::Session
addBuffer(const QString &receiver)Irc::Session
autoJoinChannels() const Irc::Session
autoReconnectDelay() const Irc::Session
buffer(const QString &receiver=QString()) const Irc::Session
bufferAdded(Irc::Buffer *buffer)Irc::Session [signal]
bufferRemoved(Irc::Buffer *buffer)Irc::Session [signal]
buffers() const Irc::Session
capabilitiesAcked(const QStringList &capabilities)Irc::Session [signal]
capabilitiesListed(const QStringList &capabilities)Irc::Session [signal]
capabilitiesNotAcked(const QStringList &capabilities)Irc::Session [signal]
capabilityEnabled(const QString &name) const Irc::Session
clearCapabilities()Irc::Session [slot]
cmdCtcpAction(const QString &receiver, const QString &action)Irc::Session [slot]
cmdCtcpReply(const QString &nick, const QString &reply)Irc::Session [slot]
cmdCtcpRequest(const QString &nick, const QString &request)Irc::Session [slot]
cmdInvite(const QString &nick, const QString &channel)Irc::Session [slot]
cmdJoin(const QString &channel, const QString &key=QString())Irc::Session [slot]
cmdKick(const QString &nick, const QString &channel, const QString &reason=QString())Irc::Session [slot]
cmdList(const QString &channel=QString())Irc::Session [slot]
cmdMessage(const QString &receiver, const QString &message)Irc::Session [slot]
cmdMode(const QString &target, const QString &mode=QString())Irc::Session [slot]
cmdNames(const QString &channel)Irc::Session [slot]
cmdNotice(const QString &receiver, const QString &notice)Irc::Session [slot]
cmdPart(const QString &channel, const QString &reason=QString())Irc::Session [slot]
cmdQuit(const QString &reason=QString())Irc::Session [slot]
cmdTopic(const QString &channel, const QString &topic=QString())Irc::Session [slot]
cmdWhois(const QString &nick)Irc::Session [slot]
connected()Irc::Session [signal]
connectToServer(const QString &hostName=QString(), quint16 port=6667)Irc::Session [slot]
createBuffer(const QString &receiver)Irc::Session [protected, virtual]
ctcpAction(const QString &receiver, const QString &action)Irc::Session [slot]
ctcpReply(const QString &nick, const QString &reply)Irc::Session [slot]
ctcpRequest(const QString &nick, const QString &request)Irc::Session [slot]
defaultBuffer() const Irc::Session
disconnected()Irc::Session [signal]
disconnectFromServer()Irc::Session [slot]
EchoMessages enum valueIrc::Session
enabledCapabilities() const Irc::Session
encoding() const Irc::Session
host() const Irc::Session
ident() const Irc::Session
invite(const QString &nick, const QString &channel)Irc::Session [slot]
join(const QString &channel, const QString &key=QString())Irc::Session [slot]
kick(const QString &nick, const QString &channel, const QString &reason=QString())Irc::Session [slot]
list(const QString &channel=QString())Irc::Session [slot]
message(const QString &receiver, const QString &message)Irc::Session [slot]
mode(const QString &target, const QString &mode=QString())Irc::Session [slot]
motd()Irc::Session [slot]
msgCtcpActionReceived(const QString &origin, const QString &receiver, const QString &action)Irc::Session [signal]
msgCtcpReplyReceived(const QString &origin, const QString &reply)Irc::Session [signal]
msgCtcpRequestReceived(const QString &origin, const QString &request)Irc::Session [signal]
msgInvited(const QString &origin, const QString &receiver, const QString &channel)Irc::Session [signal]
msgJoined(const QString &origin, const QString &channel)Irc::Session [signal]
msgKicked(const QString &origin, const QString &channel, const QString &nick, const QString &message)Irc::Session [signal]
msgMessageReceived(const QString &origin, const QString &receiver, const QString &message)Irc::Session [signal]
msgModeChanged(const QString &origin, const QString &receiver, const QString &mode, const QString &args)Irc::Session [signal]
msgNickChanged(const QString &origin, const QString &nick)Irc::Session [signal]
msgNoticeReceived(const QString &origin, const QString &receiver, const QString &notice)Irc::Session [signal]
msgNumericMessageReceived(const QString &origin, uint code, const QStringList &params)Irc::Session [signal]
msgParted(const QString &origin, const QString &channel, const QString &message)Irc::Session [signal]
msgQuit(const QString &origin, const QString &message)Irc::Session [signal]
msgTopicChanged(const QString &origin, const QString &channel, const QString &topic)Irc::Session [signal]
msgUnknownMessageReceived(const QString &origin, const QStringList &params)Irc::Session [signal]
names(const QString &channel)Irc::Session [slot]
nick() const Irc::Session
NoOptions enum valueIrc::Session
notice(const QString &receiver, const QString &notice)Irc::Session [slot]
Option enum nameIrc::Session
options() const Irc::Session
part(const QString &channel, const QString &reason=QString())Irc::Session [slot]
password() const Irc::Session
port() const Irc::Session
quit(const QString &reason=QString())Irc::Session [slot]
raw(const QString &message)Irc::Session [slot]
realName() const Irc::Session
reconnecting()Irc::Session [signal]
reconnectToServer()Irc::Session [slot]
removeAutoJoinChannel(const QString &channel)Irc::Session
requestCapabilities(const QStringList &capabilities)Irc::Session [slot]
sendRaw(const QString &message)Irc::Session [slot]
Session(QObject *parent=0)Irc::Session
setAutoJoinChannels(const QStringList &channels)Irc::Session
setAutoReconnectDelay(int seconds)Irc::Session
setDefaultBuffer(Buffer *buffer)Irc::Session
setEncoding(const QByteArray &encoding)Irc::Session
setHost(const QString &host)Irc::Session
setIdent(const QString &ident)Irc::Session
setNick(const QString &nick)Irc::Session
setOptions(Options options)Irc::Session
setPassword(const QString &password)Irc::Session
setPort(quint16 port)Irc::Session
setRealName(const QString &realName)Irc::Session
setSocket(QAbstractSocket *socket)Irc::Session
socket() const Irc::Session
StripNicks enum valueIrc::Session
supportedCapabilities() const Irc::Session
topic(const QString &channel, const QString &topic=QString())Irc::Session [slot]
welcomed()Irc::Session [signal]
whois(const QString &nick)Irc::Session [slot]
whowas(const QString &nick)Irc::Session [slot]
~Session()Irc::Session

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/classIrc_1_1Buffer-members.html0000644000175000017500000002404611513237311022145 0ustar csmallcsmall LibIrcClient-Qt: Member List

Irc::Buffer Member List

This is the complete list of members for Irc::Buffer, including all inherited members.
Buffer(const QString &receiver, Session *parent=0)Irc::Buffer [protected]
ctcpAction(const QString &action)Irc::Buffer [slot]
ctcpActionReceived(const QString &origin, const QString &action, Irc::Buffer::MessageFlags flags=Irc::Buffer::NoFlags)Irc::Buffer [signal]
ctcpReplyReceived(const QString &origin, const QString &reply, Irc::Buffer::MessageFlags flags=Irc::Buffer::NoFlags)Irc::Buffer [signal]
ctcpRequestReceived(const QString &origin, const QString &request, Irc::Buffer::MessageFlags flags=Irc::Buffer::NoFlags)Irc::Buffer [signal]
EchoFlag enum valueIrc::Buffer
IdentifiedFlag enum valueIrc::Buffer
invited(const QString &origin, const QString &receiver, const QString &channel)Irc::Buffer [signal]
joined(const QString &origin)Irc::Buffer [signal]
kicked(const QString &origin, const QString &nick, const QString &message)Irc::Buffer [signal]
message(const QString &message)Irc::Buffer [slot]
MessageFlag enum nameIrc::Buffer
messageReceived(const QString &origin, const QString &message, Irc::Buffer::MessageFlags flags=Irc::Buffer::NoFlags)Irc::Buffer [signal]
modeChanged(const QString &origin, const QString &mode, const QString &args)Irc::Buffer [signal]
modes(const QString &name) const Irc::Buffer
motdReceived(const QString &motd)Irc::Buffer [signal]
names() const Irc::Buffer
nickChanged(const QString &origin, const QString &nick)Irc::Buffer [signal]
NoFlags enum valueIrc::Buffer
notice(const QString &notice)Irc::Buffer [slot]
noticeReceived(const QString &origin, const QString &notice, Irc::Buffer::MessageFlags flags=Irc::Buffer::NoFlags)Irc::Buffer [signal]
numericMessageReceived(const QString &origin, uint code, const QStringList &params)Irc::Buffer [signal]
parted(const QString &origin, const QString &message)Irc::Buffer [signal]
quit(const QString &origin, const QString &message)Irc::Buffer [signal]
receiver() const Irc::Buffer
receiverChanged(const QString &receiver)Irc::Buffer [signal]
session() const Irc::Buffer
topic() const Irc::Buffer
topicChanged(const QString &origin, const QString &topic)Irc::Buffer [signal]
unknownMessageReceived(const QString &origin, const QStringList &params)Irc::Buffer [signal]
visualMode(const QString &name) const Irc::Buffer
~Buffer()Irc::Buffer

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/namespacemembers.html0000644000175000017500000000346311513237311020467 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented namespace members with links to the namespaces they belong to:
  • version() : Irc

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/annotated.html0000644000175000017500000000516211513237311017133 0ustar csmallcsmall LibIrcClient-Qt: Class List

Class List

Here are the classes, structs, unions and interfaces with brief descriptions:
Irc::BufferThe Irc::Buffer class provides an IRC buffer
Irc::RfcThe Irc::Rfc class enumerates command responses and error replies
Irc::SessionThe Irc::Session class provides an IRC session
Irc::UtilThe Irc::Util class provides IRC related utility functions

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/tab_r.gif0000644000175000017500000000503111513237311016041 0ustar csmallcsmallGIF89a,薴ŝɯͻ,,@pH,Ȥrl:ШtJZجv h d@L"F:򑐌$9 (8&Nz (GFB^!˨)WVl)1 w̥.wY0Ib|Hpf:e pJ}Ȧ6nz 80%"8v~ @JЂMBІ:D'ZPKF ּ&16юz HGJRb L5Җ0LgJӚ#(e>Ӟ@ PJԢHMRԦ:PTJժ&5;%Uծz` XJVCjYֶp\Uxͫ^׾i)$Mb:v, ಘͬf7z hGKҚMjWֺ*$SPͭnwm +Mr:E?9Zͮv9" xKbLz^A|ͯ0/LN(; n0'LaJ0{/{ؘG|(SCr. v1wc6@LdHNd/PLeOXp|+s2L_153M5t3_:wsgʹπp?/FFЎt!-JҖ1NӞuA-Pԝ>53UWծ4cYZѶsA׀5,aƶ3=e3~-3Sc6mo2Mq>7ӭn$D~7,y1m}v\/N3#S\gu-mO0C\'_S^|.c.0ל49~s=3d:u)?F;ˮW|;W)vt˽w|=xA;mudlet-2.1/src/irc/doc/ircglobal_8h_source.html0000644000175000017500000001270111513237311021070 0ustar csmallcsmall LibIrcClient-Qt: include/ircglobal.h Source File
Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x65.html0000644000175000017500000002756411513237311017762 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- e -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x6f.html0000644000175000017500000000732211513237311020031 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- o -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_func.html0000644000175000017500000004742711513237311020213 0ustar csmallcsmall LibIrcClient-Qt: Class Members - Functions
 

- a -

- b -

- c -

- d -

- e -

- h -

- i -

- j -

- k -

- l -

- m -

- n -

- o -

- p -

- q -

- r -

- s -

- t -

- u -

- v -

- w -

- ~ -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/classIrc_1_1Session.html0000644000175000017500000036606111513237311020735 0ustar csmallcsmall LibIrcClient-Qt: Irc::Session Class Reference

Irc::Session Class Reference

The Irc::Session class provides an IRC session. More...

#include <ircsession.h>

List of all members.

Public Types

enum  Option { NoOptions = 0x0, StripNicks = 0x1, EchoMessages = 0x2 }

Public Slots

void connectToServer (const QString &hostName=QString(), quint16 port=6667)
void reconnectToServer ()
void disconnectFromServer ()
bool raw (const QString &message)
bool motd ()
bool join (const QString &channel, const QString &key=QString())
bool part (const QString &channel, const QString &reason=QString())
bool quit (const QString &reason=QString())
bool names (const QString &channel)
bool list (const QString &channel=QString())
bool whois (const QString &nick)
bool whowas (const QString &nick)
bool mode (const QString &target, const QString &mode=QString())
bool topic (const QString &channel, const QString &topic=QString())
bool invite (const QString &nick, const QString &channel)
bool kick (const QString &nick, const QString &channel, const QString &reason=QString())
bool message (const QString &receiver, const QString &message)
bool notice (const QString &receiver, const QString &notice)
bool ctcpAction (const QString &receiver, const QString &action)
bool ctcpRequest (const QString &nick, const QString &request)
bool ctcpReply (const QString &nick, const QString &reply)
void requestCapabilities (const QStringList &capabilities)
void clearCapabilities ()
Q_DECL_DEPRECATED bool sendRaw (const QString &message)
Q_DECL_DEPRECATED bool cmdJoin (const QString &channel, const QString &key=QString())
Q_DECL_DEPRECATED bool cmdPart (const QString &channel, const QString &reason=QString())
Q_DECL_DEPRECATED bool cmdQuit (const QString &reason=QString())
Q_DECL_DEPRECATED bool cmdNames (const QString &channel)
Q_DECL_DEPRECATED bool cmdList (const QString &channel=QString())
Q_DECL_DEPRECATED bool cmdWhois (const QString &nick)
Q_DECL_DEPRECATED bool cmdMode (const QString &target, const QString &mode=QString())
Q_DECL_DEPRECATED bool cmdTopic (const QString &channel, const QString &topic=QString())
Q_DECL_DEPRECATED bool cmdInvite (const QString &nick, const QString &channel)
Q_DECL_DEPRECATED bool cmdKick (const QString &nick, const QString &channel, const QString &reason=QString())
Q_DECL_DEPRECATED bool cmdMessage (const QString &receiver, const QString &message)
Q_DECL_DEPRECATED bool cmdNotice (const QString &receiver, const QString &notice)
Q_DECL_DEPRECATED bool cmdCtcpAction (const QString &receiver, const QString &action)
Q_DECL_DEPRECATED bool cmdCtcpRequest (const QString &nick, const QString &request)
Q_DECL_DEPRECATED bool cmdCtcpReply (const QString &nick, const QString &reply)

Signals

void connected ()
void welcomed ()
void reconnecting ()
void disconnected ()
void bufferAdded (Irc::Buffer *buffer)
void bufferRemoved (Irc::Buffer *buffer)
void capabilitiesListed (const QStringList &capabilities)
void capabilitiesAcked (const QStringList &capabilities)
void capabilitiesNotAcked (const QStringList &capabilities)
Q_DECL_DEPRECATED void msgJoined (const QString &origin, const QString &channel)
Q_DECL_DEPRECATED void msgParted (const QString &origin, const QString &channel, const QString &message)
Q_DECL_DEPRECATED void msgQuit (const QString &origin, const QString &message)
Q_DECL_DEPRECATED void msgNickChanged (const QString &origin, const QString &nick)
Q_DECL_DEPRECATED void msgModeChanged (const QString &origin, const QString &receiver, const QString &mode, const QString &args)
Q_DECL_DEPRECATED void msgTopicChanged (const QString &origin, const QString &channel, const QString &topic)
Q_DECL_DEPRECATED void msgInvited (const QString &origin, const QString &receiver, const QString &channel)
Q_DECL_DEPRECATED void msgKicked (const QString &origin, const QString &channel, const QString &nick, const QString &message)
Q_DECL_DEPRECATED void msgMessageReceived (const QString &origin, const QString &receiver, const QString &message)
Q_DECL_DEPRECATED void msgNoticeReceived (const QString &origin, const QString &receiver, const QString &notice)
Q_DECL_DEPRECATED void msgCtcpRequestReceived (const QString &origin, const QString &request)
Q_DECL_DEPRECATED void msgCtcpReplyReceived (const QString &origin, const QString &reply)
Q_DECL_DEPRECATED void msgCtcpActionReceived (const QString &origin, const QString &receiver, const QString &action)
Q_DECL_DEPRECATED void msgNumericMessageReceived (const QString &origin, uint code, const QStringList &params)
Q_DECL_DEPRECATED void msgUnknownMessageReceived (const QString &origin, const QStringList &params)

Public Member Functions

 Session (QObject *parent=0)
 ~Session ()
QStringList autoJoinChannels () const
void addAutoJoinChannel (const QString &channel)
void removeAutoJoinChannel (const QString &channel)
void setAutoJoinChannels (const QStringList &channels)
int autoReconnectDelay () const
void setAutoReconnectDelay (int seconds)
QByteArray encoding () const
void setEncoding (const QByteArray &encoding)
QString ident () const
void setIdent (const QString &ident)
QString nick () const
void setNick (const QString &nick)
QString password () const
void setPassword (const QString &password)
QString realName () const
void setRealName (const QString &realName)
QString host () const
void setHost (const QString &host)
quint16 port () const
void setPort (quint16 port)
Options options () const
void setOptions (Options options)
QAbstractSocket * socket () const
void setSocket (QAbstractSocket *socket)
QList< Buffer * > buffers () const
Bufferbuffer (const QString &receiver=QString()) const
BufferaddBuffer (const QString &receiver)
BufferdefaultBuffer () const
void setDefaultBuffer (Buffer *buffer)
QStringList supportedCapabilities () const
QStringList enabledCapabilities () const
bool capabilityEnabled (const QString &name) const

Protected Member Functions

virtual BuffercreateBuffer (const QString &receiver)

Detailed Description

IRC (Internet Relay Chat protocol) is a simple communication protocol. Irc::Session provides means to establish a connection to an IRC server. Irc::Session works asynchronously. None of the functions block the calling thread but they return immediately and the actual work is done behind the scenes in the event loop.

Example usage:

    Irc::Session* session = new Irc::Session(this);
    session->setNick("jpnurmi");
    session->setIdent("jpn");
    session->setRealName("J-P Nurmi");
    session->connectToServer("irc.freenode.net", 6667);
Note:
Irc::Session supports SSL (Secure Sockets Layer) connections since version 0.3.0

Example SSL usage:

    Irc::Session* session = new Irc::Session(this);
    // ...
    QSslSocket* socket = new QSslSocket(session);
    socket->ignoreSslErrors();
    socket->setPeerVerifyMode(QSslSocket::VerifyNone);
    session->setSocket(socket);
    session->connectToServer("irc.secure.ssl", 6669);
See also:
setSocket()

Member Enumeration Documentation

This enum describes special options that may be used by Irc::Session.

Enumerator:
NoOptions 

Clears options.

StripNicks 

Strips origins automatically.

For every IRC server message, the origin is sent in standard form:

i.e. like jpnurmi!jpnurmi@xob.kapsi.fi. Such origins can not be used in IRC commands but need to be stripped (i.e. ident and host part should be cut off) before using. This can be done either explicitly, by calling Irc::Util::nickFromTarget(), or implicitly for all the messages - by setting this option with Irc::Session::setOptions().

EchoMessages 

Echo own messages, notices and actions.

IRC servers do not echo users own messages, notices or actions. This option makes Irc::Session to echo them to ease up IRC client implementation.


Constructor & Destructor Documentation

Irc::Session::Session ( QObject *  parent = 0  ) 

Constructs a new IRC session with parent.

Irc::Session::~Session (  ) 

Destructs the IRC session.


Member Function Documentation

void Irc::Session::addAutoJoinChannel ( const QString &  channel  ) 

Adds channel to the list of auto-join channels.

Buffer * Irc::Session::addBuffer ( const QString &  receiver  ) 

Adds a buffer for receiver and returns it.

See also:
buffer()
QStringList Irc::Session::autoJoinChannels (  )  const

Returns the list of auto-join channels.

int Irc::Session::autoReconnectDelay (  )  const

Returns the auto-reconnecting delay.

A negative value means no auto-reconnecting.

The default value is -1.

Buffer * Irc::Session::buffer ( const QString &  receiver = QString()  )  const

Returns the buffer for receiver. Returns 0 if the buffer does not exist.

See also:
buffers()
addBuffer()
void Irc::Session::bufferAdded ( Irc::Buffer buffer  )  [signal]

This signal is emitted whenever a buffer was added.

void Irc::Session::bufferRemoved ( Irc::Buffer buffer  )  [signal]

This signal is emitted whenever a buffer was removed.

QList< Buffer * > Irc::Session::buffers (  )  const

Returns all allocated buffers.

See also:
buffer()
void Irc::Session::capabilitiesAcked ( const QStringList &  capabilities  )  [signal]

This signal is emitted when the server acknowledges the use of a previously requested list of capabilities. Note that if you request a list of capabilities, either all of them will be acked, or all of them will be nacked.

void Irc::Session::capabilitiesListed ( const QStringList &  capabilities  )  [signal]

This signal is emitted when the library receives a list of supported capabilities for this session.

See also:
requestCapabilities()
void Irc::Session::capabilitiesNotAcked ( const QStringList &  capabilities  )  [signal]

This signal is emitted when the server disacknowledges enabling a previously requested list of capabilities. This means that none of the requested capabilities will be enabled, even if some of them were valid. (Any previously enabled capabilities will still be enabled.)

bool Irc::Session::capabilityEnabled ( const QString &  name  )  const

Returns whether a capability is enabled for this session.

If you give modifier names along with the name (i.e. '=' or '~'), this method will remove them; it will match them to any name delivered by the server, whether or not it sends any modifiers along. Behaviour when including the 'disabled modifier' ('-') is undefined; you should negate the return value of this method instead.

Note: This does not include the network specific modifier (i.e. '.'). For example, =identify-msg matches ~IDENTIFY-MSG but not .identify-msg.

See also:
enabledCapabilities()
void Irc::Session::clearCapabilities (  )  [slot]

Clear all non-sticky capabilities for this session.

See also:
enabledCapabilities()
requestCapabilities()
supportedCapabilities()
bool Irc::Session::cmdCtcpAction ( const QString &  receiver,
const QString &  action 
) [slot]
bool Irc::Session::cmdCtcpReply ( const QString &  nick,
const QString &  reply 
) [slot]
bool Irc::Session::cmdCtcpRequest ( const QString &  nick,
const QString &  request 
) [slot]
bool Irc::Session::cmdInvite ( const QString &  nick,
const QString &  channel 
) [slot]
bool Irc::Session::cmdJoin ( const QString &  channel,
const QString &  key = QString() 
) [slot]
bool Irc::Session::cmdKick ( const QString &  nick,
const QString &  channel,
const QString &  reason = QString() 
) [slot]
bool Irc::Session::cmdList ( const QString &  channel = QString()  )  [slot]
bool Irc::Session::cmdMessage ( const QString &  receiver,
const QString &  message 
) [slot]
bool Irc::Session::cmdMode ( const QString &  target,
const QString &  mode = QString() 
) [slot]
bool Irc::Session::cmdNames ( const QString &  channel  )  [slot]
bool Irc::Session::cmdNotice ( const QString &  receiver,
const QString &  notice 
) [slot]
bool Irc::Session::cmdPart ( const QString &  channel,
const QString &  reason = QString() 
) [slot]
bool Irc::Session::cmdQuit ( const QString &  reason = QString()  )  [slot]
bool Irc::Session::cmdTopic ( const QString &  channel,
const QString &  topic = QString() 
) [slot]
bool Irc::Session::cmdWhois ( const QString &  nick  )  [slot]
void Irc::Session::connected (  )  [signal]

This signal is emitted after a connection has been successfully established.

void Irc::Session::connectToServer ( const QString &  hostName = QString(),
quint16  port = 6667 
) [slot]

Connects to server with hostName and port.

Buffer * Irc::Session::createBuffer ( const QString &  receiver  )  [protected, virtual]

Returns a new Irc::Buffer object to act as an IRC buffer for receiver.

This virtual factory method can be overridden for example in order to make Irc::Session use a subclass of Irc::Buffer.

bool Irc::Session::ctcpAction ( const QString &  receiver,
const QString &  action 
) [slot]

Sends a CTCP action to receiver.

bool Irc::Session::ctcpReply ( const QString &  nick,
const QString &  reply 
) [slot]

Sends a CTCP reply to receiver.

bool Irc::Session::ctcpRequest ( const QString &  nick,
const QString &  request 
) [slot]

Sends a CTCP request to receiver.

Buffer * Irc::Session::defaultBuffer (  )  const

Returns the default buffer.

void Irc::Session::disconnected (  )  [signal]

This signal is emitted when the session has been disconnected.

void Irc::Session::disconnectFromServer (  )  [slot]

Disconnects from the server.

QStringList Irc::Session::enabledCapabilities (  )  const

Returns the list of enabled capabilities for this session, as reported by the server (including any modifiers).

See also:
requestCapabilities()
QByteArray Irc::Session::encoding (  )  const

Returns the encoding.

The default value is a null QByteArray.

QString Irc::Session::host (  )  const

Returns the host.

QString Irc::Session::ident (  )  const

Returns the ident.

bool Irc::Session::invite ( const QString &  nick,
const QString &  channel 
) [slot]

Sends an invitation to nick.

bool Irc::Session::join ( const QString &  channel,
const QString &  key = QString() 
) [slot]

Joins channel with optional key.

bool Irc::Session::kick ( const QString &  nick,
const QString &  channel,
const QString &  reason = QString() 
) [slot]

Kicks nick from channel with reason.

bool Irc::Session::list ( const QString &  channel = QString()  )  [slot]

Requests the list of channels.

bool Irc::Session::message ( const QString &  receiver,
const QString &  message 
) [slot]

Sends a message to receiver.

bool Irc::Session::mode ( const QString &  target,
const QString &  mode = QString() 
) [slot]

Sends a mode command on target.

bool Irc::Session::motd (  )  [slot]

Requests message of the day.

Q_DECL_DEPRECATED void Irc::Session::msgCtcpActionReceived ( const QString &  origin,
const QString &  receiver,
const QString &  action 
) [signal]
Deprecated:
Use Irc::Buffer::ctcpActionReceived(const QString& origin, const QString& action)
Q_DECL_DEPRECATED void Irc::Session::msgCtcpReplyReceived ( const QString &  origin,
const QString &  reply 
) [signal]
Deprecated:
Use Irc::Buffer::ctcpReplyReceived(const QString& origin, const QString& reply)
Q_DECL_DEPRECATED void Irc::Session::msgCtcpRequestReceived ( const QString &  origin,
const QString &  request 
) [signal]
Deprecated:
Use Irc::Buffer::ctcpRequestReceived(const QString& origin, const QString& request)
Q_DECL_DEPRECATED void Irc::Session::msgInvited ( const QString &  origin,
const QString &  receiver,
const QString &  channel 
) [signal]
Q_DECL_DEPRECATED void Irc::Session::msgJoined ( const QString &  origin,
const QString &  channel 
) [signal]
Q_DECL_DEPRECATED void Irc::Session::msgKicked ( const QString &  origin,
const QString &  channel,
const QString &  nick,
const QString &  message 
) [signal]
Q_DECL_DEPRECATED void Irc::Session::msgMessageReceived ( const QString &  origin,
const QString &  receiver,
const QString &  message 
) [signal]
Deprecated:
Use Irc::Buffer::messageReceived(const QString& origin, const QString& message)
Q_DECL_DEPRECATED void Irc::Session::msgModeChanged ( const QString &  origin,
const QString &  receiver,
const QString &  mode,
const QString &  args 
) [signal]
Q_DECL_DEPRECATED void Irc::Session::msgNickChanged ( const QString &  origin,
const QString &  nick 
) [signal]
Q_DECL_DEPRECATED void Irc::Session::msgNoticeReceived ( const QString &  origin,
const QString &  receiver,
const QString &  notice 
) [signal]
Deprecated:
Use Irc::Buffer::noticeReceived(const QString& origin, const QString& notice)
Q_DECL_DEPRECATED void Irc::Session::msgNumericMessageReceived ( const QString &  origin,
uint  code,
const QStringList &  params 
) [signal]
Q_DECL_DEPRECATED void Irc::Session::msgParted ( const QString &  origin,
const QString &  channel,
const QString &  message 
) [signal]
Q_DECL_DEPRECATED void Irc::Session::msgQuit ( const QString &  origin,
const QString &  message 
) [signal]
Q_DECL_DEPRECATED void Irc::Session::msgTopicChanged ( const QString &  origin,
const QString &  channel,
const QString &  topic 
) [signal]
Q_DECL_DEPRECATED void Irc::Session::msgUnknownMessageReceived ( const QString &  origin,
const QStringList &  params 
) [signal]
bool Irc::Session::names ( const QString &  channel  )  [slot]

Requests the list of names on channel.

QString Irc::Session::nick (  )  const

Returns the nick.

bool Irc::Session::notice ( const QString &  receiver,
const QString &  notice 
) [slot]

Sends a notice to receiver.

Session::Options Irc::Session::options (  )  const

Returns the options.

The default value is StripNicks.

bool Irc::Session::part ( const QString &  channel,
const QString &  reason = QString() 
) [slot]

Parts channel with reason.

QString Irc::Session::password (  )  const

Returns the password.

quint16 Irc::Session::port (  )  const

Returns the port.

bool Irc::Session::quit ( const QString &  reason = QString()  )  [slot]

Quits with optional reason.

bool Irc::Session::raw ( const QString &  message  )  [slot]

Sends a raw message to the server.

QString Irc::Session::realName (  )  const

Returns the real name.

void Irc::Session::reconnecting (  )  [signal]

This signal is emitted when the session is about to reconnect.

void Irc::Session::reconnectToServer (  )  [slot]

Reconnects to server.

void Irc::Session::removeAutoJoinChannel ( const QString &  channel  ) 

Removes channels from the list of auto-join channels.

void Irc::Session::requestCapabilities ( const QStringList &  capabilities  )  [slot]
bool Irc::Session::sendRaw ( const QString &  message  )  [slot]
void Irc::Session::setAutoJoinChannels ( const QStringList &  channels  ) 

Sets the list of auto-join channels.

void Irc::Session::setAutoReconnectDelay ( int  seconds  ) 

Sets auto-reconnecting delay in seconds.

void Irc::Session::setDefaultBuffer ( Buffer buffer  ) 

Sets the default buffer.

void Irc::Session::setEncoding ( const QByteArray &  encoding  ) 

Sets the encoding.

See QTextCodec documentation for supported encodings.

Encoding auto-detection can be turned on by passing a null QByteArray.

The fallback locale is QTextCodec::codecForLocale().

void Irc::Session::setHost ( const QString &  host  ) 

Sets the host.

void Irc::Session::setIdent ( const QString &  ident  ) 

Sets the ident.

Note:
setIdent() has no effect on already established connection.
void Irc::Session::setNick ( const QString &  nick  ) 

Sets the nick.

void Irc::Session::setOptions ( Options  options  ) 

Sets the options.

void Irc::Session::setPassword ( const QString &  password  ) 

Sets the password.

Note:
setPassword() has no effect on already established connection.
void Irc::Session::setPort ( quint16  port  ) 

Sets the port.

void Irc::Session::setRealName ( const QString &  realName  ) 

Sets the realName.

Note:
setRealName() has no effect on already established connection.
void Irc::Session::setSocket ( QAbstractSocket *  socket  ) 

Sets the socket. The previously set socket is deleted if its parent is this.

Irc::Session supports QSslSocket in the way that it automatically calls QSslSocket::startClientEncryption() while connecting.

This function was introduced in version 0.3.0.

QAbstractSocket * Irc::Session::socket (  )  const

Returns the socket.

Irc::Session creates an instance of QTcpSocket by default.

This function was introduced in version 0.3.0.

QStringList Irc::Session::supportedCapabilities (  )  const

Returns the list of capabilities the server supports, as reported by the server (including any modifiers). If empty, the server might not implement the capabilities extension, or it might simply not support any specific capability.

bool Irc::Session::topic ( const QString &  channel,
const QString &  topic = QString() 
) [slot]

Sends a topic command on channel.

void Irc::Session::welcomed (  )  [signal]

This signal is emitted when the welcome message has been received.

See also:
Irc::Rfc::RPL_WELCOME
bool Irc::Session::whois ( const QString &  nick  )  [slot]

Sends a whois command on nick.

bool Irc::Session::whowas ( const QString &  nick  )  [slot]

Sends a whowas command on nick.


The documentation for this class was generated from the following files:

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/namespacemembers_func.html0000644000175000017500000000333211513237311021475 0ustar csmallcsmall LibIrcClient-Qt: Class Members
 
  • version() : Irc

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/namespaces.html0000644000175000017500000000353411513237311017276 0ustar csmallcsmall LibIrcClient-Qt: Namespace Index

Namespace List

Here is a list of all documented namespaces with brief descriptions:
IrcThe Irc namespace contains miscellaneous identifiers used throughout the LibIrcClient-Qt library

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x71.html0000644000175000017500000000727411513237311017753 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- q -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x6e.html0000644000175000017500000001162211513237311020026 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- n -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x69.html0000644000175000017500000000774211513237311017762 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- i -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/tab_b.gif0000644000175000017500000000004311513237311016017 0ustar csmallcsmallGIF89a,D;mudlet-2.1/src/irc/doc/functions_0x63.html0000644000175000017500000001630311513237311017745 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- c -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/classIrc_1_1Rfc-members.html0000644000175000017500000010646411513237311021453 0ustar csmallcsmall LibIrcClient-Qt: Member List

Irc::Rfc Member List

This is the complete list of members for Irc::Rfc, including all inherited members.
ERR_ALREADYREGISTRED enum valueIrc::Rfc
ERR_BADCHANMASK enum valueIrc::Rfc
ERR_BADCHANNELKEY enum valueIrc::Rfc
ERR_BADMASK enum valueIrc::Rfc
ERR_BANLISTFULL enum valueIrc::Rfc
ERR_BANNEDFROMCHAN enum valueIrc::Rfc
ERR_CANNOTSENDTOCHAN enum valueIrc::Rfc
ERR_CANTKILLSERVER enum valueIrc::Rfc
ERR_CHANNELISFULL enum valueIrc::Rfc
ERR_CHANOPRIVSNEEDED enum valueIrc::Rfc
ERR_ERRONEUSNICKNAME enum valueIrc::Rfc
ERR_FILEERROR enum valueIrc::Rfc
ERR_INVITEONLYCHAN enum valueIrc::Rfc
ERR_KEYSET enum valueIrc::Rfc
ERR_NEEDMOREPARAMS enum valueIrc::Rfc
ERR_NICKCOLLISION enum valueIrc::Rfc
ERR_NICKNAMEINUSE enum valueIrc::Rfc
ERR_NOADMININFO enum valueIrc::Rfc
ERR_NOCHANMODES enum valueIrc::Rfc
ERR_NOLOGIN enum valueIrc::Rfc
ERR_NOMOTD enum valueIrc::Rfc
ERR_NONICKNAMEGIVEN enum valueIrc::Rfc
ERR_NOOPERHOST enum valueIrc::Rfc
ERR_NOORIGIN enum valueIrc::Rfc
ERR_NOPERMFORHOST enum valueIrc::Rfc
ERR_NOPRIVILEGES enum valueIrc::Rfc
ERR_NORECIPIENT enum valueIrc::Rfc
ERR_NOSUCHCHANNEL enum valueIrc::Rfc
ERR_NOSUCHNICK enum valueIrc::Rfc
ERR_NOSUCHSERVER enum valueIrc::Rfc
ERR_NOSUCHSERVICE enum valueIrc::Rfc
ERR_NOTEXTTOSEND enum valueIrc::Rfc
ERR_NOTONCHANNEL enum valueIrc::Rfc
ERR_NOTOPLEVEL enum valueIrc::Rfc
ERR_NOTREGISTERED enum valueIrc::Rfc
ERR_PASSWDMISMATCH enum valueIrc::Rfc
ERR_RESTRICTED enum valueIrc::Rfc
ERR_SUMMONDISABLED enum valueIrc::Rfc
ERR_TOOMANYCHANNELS enum valueIrc::Rfc
ERR_TOOMANYTARGETS enum valueIrc::Rfc
ERR_UMODEUNKNOWNFLAG enum valueIrc::Rfc
ERR_UNAVAILRESOURCE enum valueIrc::Rfc
ERR_UNIQOPPRIVSNEEDED enum valueIrc::Rfc
ERR_UNKNOWNCOMMAND enum valueIrc::Rfc
ERR_UNKNOWNMODE enum valueIrc::Rfc
ERR_USERNOTINCHANNEL enum valueIrc::Rfc
ERR_USERONCHANNEL enum valueIrc::Rfc
ERR_USERSDISABLED enum valueIrc::Rfc
ERR_USERSDONTMATCH enum valueIrc::Rfc
ERR_WASNOSUCHNICK enum valueIrc::Rfc
ERR_WILDTOPLEVEL enum valueIrc::Rfc
ERR_YOUREBANNEDCREEP enum valueIrc::Rfc
ERR_YOUWILLBEBANNED enum valueIrc::Rfc
Numeric enum nameIrc::Rfc
RPL_ADMINEMAIL enum valueIrc::Rfc
RPL_ADMINLOC1 enum valueIrc::Rfc
RPL_ADMINLOC2 enum valueIrc::Rfc
RPL_ADMINME enum valueIrc::Rfc
RPL_AWAY enum valueIrc::Rfc
RPL_BANLIST enum valueIrc::Rfc
RPL_BOUNCE enum valueIrc::Rfc
RPL_CHANNELCREATED enum valueIrc::Rfc
RPL_CHANNELMODEIS enum valueIrc::Rfc
RPL_CHANNELURL enum valueIrc::Rfc
RPL_CREATED enum valueIrc::Rfc
RPL_ENDOFBANLIST enum valueIrc::Rfc
RPL_ENDOFEXCEPTLIST enum valueIrc::Rfc
RPL_ENDOFINFO enum valueIrc::Rfc
RPL_ENDOFINVITELIST enum valueIrc::Rfc
RPL_ENDOFLINKS enum valueIrc::Rfc
RPL_ENDOFMOTD enum valueIrc::Rfc
RPL_ENDOFNAMES enum valueIrc::Rfc
RPL_ENDOFSTATS enum valueIrc::Rfc
RPL_ENDOFUSERS enum valueIrc::Rfc
RPL_ENDOFWHO enum valueIrc::Rfc
RPL_ENDOFWHOIS enum valueIrc::Rfc
RPL_ENDOFWHOWAS enum valueIrc::Rfc
RPL_EXCEPTLIST enum valueIrc::Rfc
RPL_INFO enum valueIrc::Rfc
RPL_INVITELIST enum valueIrc::Rfc
RPL_INVITING enum valueIrc::Rfc
RPL_ISON enum valueIrc::Rfc
RPL_LINKS enum valueIrc::Rfc
RPL_LIST enum valueIrc::Rfc
RPL_LISTEND enum valueIrc::Rfc
RPL_LUSERCHANNELS enum valueIrc::Rfc
RPL_LUSERCLIENT enum valueIrc::Rfc
RPL_LUSERME enum valueIrc::Rfc
RPL_LUSEROP enum valueIrc::Rfc
RPL_LUSERUNKNOWN enum valueIrc::Rfc
RPL_MOTD enum valueIrc::Rfc
RPL_MOTDSTART enum valueIrc::Rfc
RPL_MYINFO enum valueIrc::Rfc
RPL_NAMREPLY enum valueIrc::Rfc
RPL_NOTOPIC enum valueIrc::Rfc
RPL_NOUSERS enum valueIrc::Rfc
RPL_NOWAWAY enum valueIrc::Rfc
RPL_REHASHING enum valueIrc::Rfc
RPL_SERVLIST enum valueIrc::Rfc
RPL_SERVLISTEND enum valueIrc::Rfc
RPL_STATSCOMMANDS enum valueIrc::Rfc
RPL_STATSLINKINFO enum valueIrc::Rfc
RPL_STATSOLINE enum valueIrc::Rfc
RPL_STATSUPTIME enum valueIrc::Rfc
RPL_SUMMONING enum valueIrc::Rfc
RPL_TIME enum valueIrc::Rfc
RPL_TOPIC enum valueIrc::Rfc
RPL_TOPICSET enum valueIrc::Rfc
RPL_TRACECLASS enum valueIrc::Rfc
RPL_TRACECONNECTING enum valueIrc::Rfc
RPL_TRACEEND enum valueIrc::Rfc
RPL_TRACEHANDSHAKE enum valueIrc::Rfc
RPL_TRACELINK enum valueIrc::Rfc
RPL_TRACELOG enum valueIrc::Rfc
RPL_TRACENEWTYPE enum valueIrc::Rfc
RPL_TRACEOPERATOR enum valueIrc::Rfc
RPL_TRACESERVER enum valueIrc::Rfc
RPL_TRACESERVICE enum valueIrc::Rfc
RPL_TRACEUNKNOWN enum valueIrc::Rfc
RPL_TRACEUSER enum valueIrc::Rfc
RPL_TRYAGAIN enum valueIrc::Rfc
RPL_UMODEIS enum valueIrc::Rfc
RPL_UNAWAY enum valueIrc::Rfc
RPL_UNIQOPIS enum valueIrc::Rfc
RPL_USERHOST enum valueIrc::Rfc
RPL_USERS enum valueIrc::Rfc
RPL_USERSSTART enum valueIrc::Rfc
RPL_VERSION enum valueIrc::Rfc
RPL_WELCOME enum valueIrc::Rfc
RPL_WHOISCHANNELS enum valueIrc::Rfc
RPL_WHOISIDLE enum valueIrc::Rfc
RPL_WHOISOPERATOR enum valueIrc::Rfc
RPL_WHOISSERVER enum valueIrc::Rfc
RPL_WHOISUSER enum valueIrc::Rfc
RPL_WHOREPLY enum valueIrc::Rfc
RPL_WHOWASUSER enum valueIrc::Rfc
RPL_YOUREOPER enum valueIrc::Rfc
RPL_YOURESERVICE enum valueIrc::Rfc
RPL_YOURHOST enum valueIrc::Rfc
toString(uint code)Irc::Rfc [static]

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_enum.html0000644000175000017500000000412011513237311020203 0ustar csmallcsmall LibIrcClient-Qt: Class Members - Enumerations
 

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/namespaceIrc.html0000644000175000017500000001150711513237311017550 0ustar csmallcsmall LibIrcClient-Qt: Irc Namespace Reference

Irc Namespace Reference

The Irc namespace contains miscellaneous identifiers used throughout the LibIrcClient-Qt library.

Classes

class  Rfc
 The Irc::Rfc class enumerates command responses and error replies. More...
class  Buffer
 The Irc::Buffer class provides an IRC buffer. More...
class  Session
 The Irc::Session class provides an IRC session. More...
class  Util
 The Irc::Util class provides IRC related utility functions. More...

Functions

const char * version ()

Function Documentation

const char * Irc::version (  ) 

Returns the LibIrcClient-Qt version number as string in form M.N.P (M = major, N = minor, P = patch).

Returns the version number of LibIrcClient-Qt at run-time as a string (for example, "1.2.3"). This may be a different version than the version the application was compiled against.

See also:
IRC_VERSION_STR

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/classIrc_1_1Util.html0000644000175000017500000001417711513237311020225 0ustar csmallcsmall LibIrcClient-Qt: Irc::Util Class Reference

Irc::Util Class Reference

The Irc::Util class provides IRC related utility functions.

#include <ircutil.h>

List of all members.

Static Public Member Functions

static QString nickFromTarget (const QString &target)
static QString hostFromTarget (const QString &target)
static QString messageToHtml (const QString &message)
static QString colorNameFromCode (int code)

Member Function Documentation

QString Irc::Util::colorNameFromCode ( int  code  )  [static]

Converts code to a color name.

QString Irc::Util::hostFromTarget ( const QString &  target  )  [static]

Parses and returns the host part from target.

QString Irc::Util::messageToHtml ( const QString &  message  )  [static]

Converts message to HTML. This function parses the message and replaces IRC-style formatting like colors, bold and underline to the corresponding HTML formatting. Furthermore, this function detects URLs and replaces them with appropriate HTML hyperlinks.

QString Irc::Util::nickFromTarget ( const QString &  target  )  [static]

Parses and returns the nick part from target.


The documentation for this class was generated from the following files:

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/classIrc_1_1Rfc.html0000644000175000017500000025303311513237311020016 0ustar csmallcsmall LibIrcClient-Qt: Irc::Rfc Class Reference

Irc::Rfc Class Reference

The Irc::Rfc class enumerates command responses and error replies. More...

#include <irc.h>

List of all members.

Public Types

enum  Numeric {
  RPL_WELCOME = 001, RPL_YOURHOST = 002, RPL_CREATED = 003, RPL_MYINFO = 004,
  RPL_BOUNCE = 005, RPL_USERHOST = 302, RPL_ISON = 303, RPL_AWAY = 301,
  RPL_UNAWAY = 305, RPL_NOWAWAY = 306, RPL_WHOISUSER = 311, RPL_WHOISSERVER = 312,
  RPL_WHOISOPERATOR = 313, RPL_WHOISIDLE = 317, RPL_ENDOFWHOIS = 318, RPL_WHOISCHANNELS = 319,
  RPL_WHOWASUSER = 314, RPL_ENDOFWHOWAS = 369, RPL_LIST = 322, RPL_LISTEND = 323,
  RPL_UNIQOPIS = 325, RPL_CHANNELMODEIS = 324, RPL_CHANNELURL = 328, RPL_CHANNELCREATED = 329,
  RPL_NOTOPIC = 331, RPL_TOPIC = 332, RPL_TOPICSET = 333, RPL_INVITING = 341,
  RPL_SUMMONING = 342, RPL_INVITELIST = 346, RPL_ENDOFINVITELIST = 347, RPL_EXCEPTLIST = 348,
  RPL_ENDOFEXCEPTLIST = 349, RPL_VERSION = 351, RPL_WHOREPLY = 352, RPL_ENDOFWHO = 315,
  RPL_NAMREPLY = 353, RPL_ENDOFNAMES = 366, RPL_LINKS = 364, RPL_ENDOFLINKS = 365,
  RPL_BANLIST = 367, RPL_ENDOFBANLIST = 368, RPL_INFO = 371, RPL_ENDOFINFO = 374,
  RPL_MOTDSTART = 375, RPL_MOTD = 372, RPL_ENDOFMOTD = 376, RPL_YOUREOPER = 381,
  RPL_REHASHING = 382, RPL_YOURESERVICE = 383, RPL_TIME = 391, RPL_USERSSTART = 392,
  RPL_USERS = 393, RPL_ENDOFUSERS = 394, RPL_NOUSERS = 395, RPL_TRACELINK = 200,
  RPL_TRACECONNECTING = 201, RPL_TRACEHANDSHAKE = 202, RPL_TRACEUNKNOWN = 203, RPL_TRACEOPERATOR = 204,
  RPL_TRACEUSER = 205, RPL_TRACESERVER = 206, RPL_TRACESERVICE = 207, RPL_TRACENEWTYPE = 208,
  RPL_TRACECLASS = 209, RPL_TRACELOG = 261, RPL_TRACEEND = 262, RPL_STATSLINKINFO = 211,
  RPL_STATSCOMMANDS = 212, RPL_ENDOFSTATS = 219, RPL_STATSUPTIME = 242, RPL_STATSOLINE = 243,
  RPL_UMODEIS = 221, RPL_SERVLIST = 234, RPL_SERVLISTEND = 235, RPL_LUSERCLIENT = 251,
  RPL_LUSEROP = 252, RPL_LUSERUNKNOWN = 253, RPL_LUSERCHANNELS = 254, RPL_LUSERME = 255,
  RPL_ADMINME = 256, RPL_ADMINLOC1 = 257, RPL_ADMINLOC2 = 258, RPL_ADMINEMAIL = 259,
  RPL_TRYAGAIN = 263, ERR_NOSUCHNICK = 401, ERR_NOSUCHSERVER = 402, ERR_NOSUCHCHANNEL = 403,
  ERR_CANNOTSENDTOCHAN = 404, ERR_TOOMANYCHANNELS = 405, ERR_WASNOSUCHNICK = 406, ERR_TOOMANYTARGETS = 407,
  ERR_NOSUCHSERVICE = 408, ERR_NOORIGIN = 409, ERR_NORECIPIENT = 411, ERR_NOTEXTTOSEND = 412,
  ERR_NOTOPLEVEL = 413, ERR_WILDTOPLEVEL = 414, ERR_BADMASK = 415, ERR_UNKNOWNCOMMAND = 421,
  ERR_NOMOTD = 422, ERR_NOADMININFO = 423, ERR_FILEERROR = 424, ERR_NONICKNAMEGIVEN = 431,
  ERR_ERRONEUSNICKNAME = 432, ERR_NICKNAMEINUSE = 433, ERR_NICKCOLLISION = 436, ERR_UNAVAILRESOURCE = 437,
  ERR_USERNOTINCHANNEL = 441, ERR_NOTONCHANNEL = 442, ERR_USERONCHANNEL = 443, ERR_NOLOGIN = 444,
  ERR_SUMMONDISABLED = 445, ERR_USERSDISABLED = 446, ERR_NOTREGISTERED = 451, ERR_NEEDMOREPARAMS = 461,
  ERR_ALREADYREGISTRED = 462, ERR_NOPERMFORHOST = 463, ERR_PASSWDMISMATCH = 464, ERR_YOUREBANNEDCREEP = 465,
  ERR_YOUWILLBEBANNED = 466, ERR_KEYSET = 467, ERR_CHANNELISFULL = 471, ERR_UNKNOWNMODE = 472,
  ERR_INVITEONLYCHAN = 473, ERR_BANNEDFROMCHAN = 474, ERR_BADCHANNELKEY = 475, ERR_BADCHANMASK = 476,
  ERR_NOCHANMODES = 477, ERR_BANLISTFULL = 478, ERR_NOPRIVILEGES = 481, ERR_CHANOPRIVSNEEDED = 482,
  ERR_CANTKILLSERVER = 483, ERR_RESTRICTED = 484, ERR_UNIQOPPRIVSNEEDED = 485, ERR_NOOPERHOST = 491,
  ERR_UMODEUNKNOWNFLAG = 501, ERR_USERSDONTMATCH = 502
}

Static Public Member Functions

static const char * toString (uint code)

Detailed Description

The Irc::Rfc class enumerates command responses and error replies as defined in RFC 1459 (Internet Relay Chat Protocol - http://www.ietf.org/rfc/rfc1459.txt).

See also:
Irc::Rfc::Numeric

Member Enumeration Documentation

This enum describes the numeric message codes defined in the RFC.

Enumerator:
RPL_WELCOME 

001 Welcome to the Internet Relay Network <nick>!<user>@<host>

The server sends replies 001 to 004 to a user upon successful registration.

RPL_YOURHOST 

002 Your host is <servername>, running version <ver>

The server sends replies 001 to 004 to a user upon successful registration.

RPL_CREATED 

003 This server was created <date>

The server sends replies 001 to 004 to a user upon successful registration.

RPL_MYINFO 

004 <servername> <version> <available user modes> <available channel modes>

The server sends replies 001 to 004 to a user upon successful registration.

RPL_BOUNCE 

005 Try server <server name>, port <port number>

Sent by the server to a user to suggest an alternative server. This is often used when the connection is refused because the server is already full.

RPL_USERHOST 

302 :*1<reply> *(

No description available in RFC

RPL_ISON 

303 :*1<nick> *(

No description available in RFC

RPL_AWAY 

301 <nick> :<away message>

No description available in RFC

RPL_UNAWAY 

305 :You are no longer marked as being away

No description available in RFC

RPL_NOWAWAY 

306 :You have been marked as being away

These replies are used with the AWAY command (if allowed). RPL_AWAY is sent to any client sending a PRIVMSG to a client which is away. RPL_AWAY is only sent by the server to which the client is connected. Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the client removes and sets an AWAY message.

RPL_WHOISUSER 

311 <nick> <user> <host> * :<real name>

No description available in RFC

RPL_WHOISSERVER 

312 <nick> <server> :<server info>

No description available in RFC

RPL_WHOISOPERATOR 

313 <nick> :is an IRC operator

No description available in RFC

RPL_WHOISIDLE 

317 <nick> <integer> :seconds idle

No description available in RFC

RPL_ENDOFWHOIS 

318 <nick> :End of WHOIS list

No description available in RFC

RPL_WHOISCHANNELS 

319 "<nick> :*( ( "@" / "+" ) \<channel\> " " )"

No description available in RFC

RPL_WHOWASUSER 

314 <nick> <user> <host> * :<real name>

No description available in RFC

RPL_ENDOFWHOWAS 

369 <nick> :End of WHOWAS

When replying to a WHOWAS message, a server MUST use the replies RPL_WHOWASUSER, RPL_WHOISSERVER or ERR_WASNOSUCHNICK for each nickname in the presented list. At the end of all reply batches, there MUST be RPL_ENDOFWHOWAS (even if there was only one reply and it was an error).

RPL_LIST 

322 <channel> <# visible> :<topic>

No description available in RFC

RPL_LISTEND 

323 :End of LIST

Replies RPL_LIST, RPL_LISTEND mark the actual replies with data and end of the server's response to a LIST command. If there are no channels available to return, only the end reply MUST be sent.

RPL_UNIQOPIS 

325 <channel> <nickname>

No description available in RFC

RPL_CHANNELMODEIS 

324 <channel> <mode> <mode params>

No description available in RFC

RPL_CHANNELURL 

329 <channel> <url>

No description available in RFC

RPL_CHANNELCREATED 

329 <channel> <datetime>

No description available in RFC

RPL_NOTOPIC 

331 <channel> :No topic is set

No description available in RFC

RPL_TOPIC 

332 <channel> :<topic>

When sending a TOPIC message to determine the channel topic, one of two replies is sent. If the topic is set, RPL_TOPIC is sent back else RPL_NOTOPIC.

RPL_TOPICSET 

333 <channel> <user> <datetime>

No description available in RFC

RPL_INVITING 

341 <channel> <nick>

Returned by the server to indicate that the attempted INVITE message was successful and is being passed onto the end client.

RPL_SUMMONING 

342 <user> :Summoning user to IRC

Returned by a server answering a SUMMON message to indicate that it is summoning that user.

RPL_INVITELIST 

346 <channel> <invitemask>

No description available in RFC

RPL_ENDOFINVITELIST 

347 <channel> :End of channel invite list

When listing the 'invitations masks' for a given channel, a server is required to send the list back using the RPL_INVITELIST and RPL_ENDOFINVITELIST messages. A separate RPL_INVITELIST is sent for each active mask. After the masks have been listed (or if none present) a RPL_ENDOFINVITELIST MUST be sent.

RPL_EXCEPTLIST 

348 <channel> <exceptionmask>

No description available in RFC

RPL_ENDOFEXCEPTLIST 

349 <channel> :End of channel exception list

When listing the 'exception masks' for a given channel, a server is required to send the list back using the RPL_EXCEPTLIST and RPL_ENDOFEXCEPTLIST messages. A separate RPL_EXCEPTLIST is sent for each active mask. After the masks have been listed (or if none present) a RPL_ENDOFEXCEPTLIST MUST be sent.

RPL_VERSION 

351 <version>.<debuglevel> <server> :<comments>

Reply by the server showing its version details. The <version> is the version of the software being used (including any patchlevel revisions) and the <debuglevel> is used to indicate if the server is running in "debug mode". The "comments" field may contain any comments about the version or further version details.

RPL_WHOREPLY 

352 <channel> <user> <host> <server> <nick> <H|G>[*][@|+] :<hopcount> <real name>

No description available in RFC

RPL_ENDOFWHO 

315 <name> :End of WHO list

The RPL_WHOREPLY and RPL_ENDOFWHO pair are used to answer a WHO message. The RPL_WHOREPLY is only sent if there is an appropriate match to the WHO query. If there is a list of parameters supplied with a WHO message, a RPL_ENDOFWHO MUST be sent after processing each list item with <name> being the item

RPL_NAMREPLY 

353 <channel> :[[@|+]<nick> [[@|+]<nick> [...]]]

No description available in RFC

RPL_ENDOFNAMES 

366 <channel> :End of NAMES list

To reply to a NAMES message, a reply pair consisting of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the server back to the client. If there is no channel found as in the query, then only RPL_ENDOFNAMES is returned. The exception to this is when a NAMES message is sent with no parameters and all visible channels and contents are sent back in a series of RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark the end.

RPL_LINKS 

364 <mask> <server> :<hopcount> <server info>

No description available in RFC

RPL_ENDOFLINKS 

365 <mask> :End of LINKS list

In replying to the LINKS message, a server MUST send replies back using the RPL_LINKS numeric and mark the end of the list using an RPL_ENDOFLINKS reply.

RPL_BANLIST 

367 <channel> <banmask>

No description available in RFC

RPL_ENDOFBANLIST 

368 <channel> :End of channel ban list

When listing the active 'bans' for a given channel, a server is required to send the list back using the RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate RPL_BANLIST is sent for each active banmask. After the banmasks have been listed (or if none present) a RPL_ENDOFBANLIST MUST be sent.

RPL_INFO 

371 :<string>

No description available in RFC

RPL_ENDOFINFO 

374 :End of INFO list

A server responding to an INFO message is required to send all its 'info' in a series of RPL_INFO messages with a RPL_ENDOFINFO reply to indicate the end of the replies.

RPL_MOTDSTART 

375 :- <server> Message of the day -

No description available in RFC

RPL_MOTD 

372 :- <text>

No description available in RFC

RPL_ENDOFMOTD 

376 :End of MOTD command

When responding to the MOTD message and the MOTD file is found, the file is displayed line by line, with each line no longer than 80 characters, using RPL_MOTD format replies. These MUST be surrounded by a RPL_MOTDSTART (before the RPL_MOTDs) and an RPL_ENDOFMOTD (after).

RPL_YOUREOPER 

381 :You are now an IRC operator

RPL_YOUREOPER is sent back to a client which has just successfully issued an OPER message and gained operator status.

RPL_REHASHING 

382 <config file> :Rehashing

If the REHASH option is used and an operator sends a REHASH message, an RPL_REHASHING is sent back to the operator.

RPL_YOURESERVICE 

383 You are service <servicename>

Sent by the server to a service upon successful registration.

RPL_TIME 

391 <server> :<string showing server's local time>

When replying to the TIME message, a server MUST send the reply using the RPL_TIME format above. The string showing the time need only contain the correct day and time there. There is no further requirement for the time string.

RPL_USERSSTART 

392 :UserID Terminal Host

No description available in RFC

RPL_USERS 

393 :<username> <ttyline> <hostname>

No description available in RFC

RPL_ENDOFUSERS 

394 :End of users

No description available in RFC

RPL_NOUSERS 

395 :Nobody logged in

If the USERS message is handled by a server, the replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and RPL_NOUSERS are used. RPL_USERSSTART MUST be sent first, following by either a sequence of RPL_USERS or a single RPL_NOUSER. Following this is RPL_ENDOFUSERS.

RPL_TRACELINK 

200 Link <version & debug level> <destination> <next server> V<protocol version> <link uptime in seconds> <backstream sendq> <upstream sendq>

No description available in RFC

RPL_TRACECONNECTING 

201 Try. <class> <server>

No description available in RFC

RPL_TRACEHANDSHAKE 

202 H.S. <class> <server>

No description available in RFC

RPL_TRACEUNKNOWN 

203 ???? <class> [<client IP address in dot form>]

No description available in RFC

RPL_TRACEOPERATOR 

204 Oper <class> <nick>

No description available in RFC

RPL_TRACEUSER 

205 User <class> <nick>

No description available in RFC

RPL_TRACESERVER 

206 Serv <class> <int>S <int>C <server> <nick!user|*!*>@<host|server> V<protocol version>

No description available in RFC

RPL_TRACESERVICE 

207 Service <class> <name> <type> <active type>

No description available in RFC

RPL_TRACENEWTYPE 

208 <newtype> 0 <client name>

No description available in RFC

RPL_TRACECLASS 

209 Class <class> <count>

No description available in RFC

RPL_TRACELOG 

261 File <logfile> <debug level>

No description available in RFC

RPL_TRACEEND 

262 <server name> <version & debug level> :End of TRACE

The RPL_TRACE* are all returned by the server in response to the TRACE message. How many are returned is dependent on the TRACE message and whether it was sent by an operator or not. There is no predefined order for which occurs first. Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and RPL_TRACEHANDSHAKE are all used for connections which have not been fully established and are either unknown, still attempting to connect or in the process of completing the 'server handshake'. RPL_TRACELINK is sent by any server which handles a TRACE message and has to pass it on to another server. The list of RPL_TRACELINKs sent in response to a TRACE command traversing the IRC network should reflect the actual connectivity of the servers themselves along that path. RPL_TRACENEWTYPE is to be used for any connection which does not fit in the other categories but is being displayed anyway. RPL_TRACEEND is sent to indicate the end of the list.

RPL_STATSLINKINFO 

211 <linkname> <sendq> <sent messages> <sent Kbytes> <received messages> <received Kbytes> <time open>

reports statistics on a connection. <linkname> identifies the particular connection, <sendq> is the amount of data that is queued and waiting to be sent <sent messages> the number of messages sent, and <sent Kbytes> the amount of data sent, in Kbytes. <received messages> and <received Kbytes> are the equivalent of <sent messages> and <sent Kbytes> for received data, respectively. <time open> indicates how long ago the connection was opened, in seconds.

RPL_STATSCOMMANDS 

212 <command> <count> <byte count> <remote count>

reports statistics on commands usage.

RPL_ENDOFSTATS 

219 <stats letter> :End of STATS report

No description available in RFC

RPL_STATSUPTIME 

242 :Server Up d days d:02d:02d

reports the server uptime.

RPL_STATSOLINE 

243 O <hostmask> * <name>

reports the allowed hosts from where user may become IRC operators.

RPL_UMODEIS 

221 <user mode string>

To answer a query about a client's own mode, RPL_UMODEIS is sent back.

RPL_SERVLIST 

234 <name> <server> <mask> <type> <hopcount> <info>

No description available in RFC

RPL_SERVLISTEND 

235 <mask> <type> :End of service listing

When listing services in reply to a SERVLIST message, a server is required to send the list back using the RPL_SERVLIST and RPL_SERVLISTEND messages. A separate RPL_SERVLIST is sent for each service. After the services have been listed (or if none present) a RPL_SERVLISTEND MUST be sent.

RPL_LUSERCLIENT 

251 :There are <integer> users and <integer> services on <integer> servers

No description available in RFC

RPL_LUSEROP 

252 <integer> :operator(s) online

No description available in RFC

RPL_LUSERUNKNOWN 

253 <integer> :unknown connection(s)

No description available in RFC

RPL_LUSERCHANNELS 

254 <integer> :channels formed

No description available in RFC

RPL_LUSERME 

255 :I have <integer> clients and <integer> servers

In processing an LUSERS message, the server sends a set of replies from RPL_LUSERCLIENT, RPL_LUSEROP, RPL_USERUNKNOWN, RPL_LUSERCHANNELS and RPL_LUSERME. When replying, a server MUST send back RPL_LUSERCLIENT and RPL_LUSERME. The other replies are only sent back if a non-zero count is found for them.

RPL_ADMINME 

256 <server> :Administrative info

No description available in RFC

RPL_ADMINLOC1 

257 :<admin info>

No description available in RFC

RPL_ADMINLOC2 

258 :<admin info>

No description available in RFC

RPL_ADMINEMAIL 

259 :<admin info>

When replying to an ADMIN message, a server is expected to use replies RPL_ADMINME through to RPL_ADMINEMAIL and provide a text message with each. For RPL_ADMINLOC1 a description of what city, state and country the server is in is expected, followed by details of the institution (RPL_ADMINLOC2) and finally the administrative contact for the server (an email address here is REQUIRED) in RPL_ADMINEMAIL.

RPL_TRYAGAIN 

263 <command> :Please wait a while and try again.

When a server drops a command without processing it, it MUST use the reply RPL_TRYAGAIN to inform the originating client.

ERR_NOSUCHNICK 

401 <nickname> :No such nick/channel

Used to indicate the nickname parameter supplied to a command is currently unused.

ERR_NOSUCHSERVER 

402 <server name> :No such server

Used to indicate the server name given currently does not exist.

ERR_NOSUCHCHANNEL 

403 <channel name> :No such channel

Used to indicate the given channel name is invalid.

ERR_CANNOTSENDTOCHAN 

404 <channel name> :Cannot send to channel

Sent to a user who is either (a) not on a channel which is mode +n or (b) not a chanop (or mode +v) on a channel which has mode +m set or where the user is banned and is trying to send a PRIVMSG message to that channel.

ERR_TOOMANYCHANNELS 

405 <channel name> :You have joined too many channels

Sent to a user when they have joined the maximum number of allowed channels and they try to join another channel.

ERR_WASNOSUCHNICK 

406 <nickname> :There was no such nickname

Returned by WHOWAS to indicate there is no history information for that nickname.

ERR_TOOMANYTARGETS 

407 <target> :<error code> recipients. <abort message>

Returned to a client which is attempting to send a PRIVMSG/NOTICE using the user@host destination format and for a user@host which has several occurrences. - Returned to a client which trying to send a PRIVMSG/NOTICE to too many recipients. - Returned to a client which is attempting to JOIN a safe channel using the shortname when there are more than one such channel.

ERR_NOSUCHSERVICE 

408 <service name> :No such service

Returned to a client which is attempting to send a SQUERY to a service which does not exist.

ERR_NOORIGIN 

409 :No origin specified

PING or PONG message missing the originator parameter.

ERR_NORECIPIENT 

411 :No recipient given (<command>)

No description available in RFC

ERR_NOTEXTTOSEND 

412 :No text to send

No description available in RFC

ERR_NOTOPLEVEL 

413 <mask> :No toplevel domain specified

No description available in RFC

ERR_WILDTOPLEVEL 

414 <mask> :Wildcard in toplevel domain

No description available in RFC

ERR_BADMASK 

415 <mask> :Bad Server/host mask

412 - 415 are returned by PRIVMSG to indicate that the message wasn't delivered for some reason. ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that are returned when an invalid use of "PRIVMSG $\<server\>" or "PRIVMSG #\<host\>" is attempted.

ERR_UNKNOWNCOMMAND 

421 <command> :Unknown command

Returned to a registered client to indicate that the command sent is unknown by the server.

ERR_NOMOTD 

422 :MOTD File is missing

Server's MOTD file could not be opened by the server.

ERR_NOADMININFO 

423 <server> :No administrative info available

Returned by a server in response to an ADMIN message when there is an error in finding the appropriate information.

ERR_FILEERROR 

424 :File error doing <file op> on <file>

Generic error message used to report a failed file operation during the processing of a message.

ERR_NONICKNAMEGIVEN 

431 :No nickname given

Returned when a nickname parameter expected for a command and isn't found.

ERR_ERRONEUSNICKNAME 

432 <nick> :Erroneous nickname

Returned after receiving a NICK message which contains characters which do not fall in the defined set. See section 2.3.1 for details on valid nicknames.

ERR_NICKNAMEINUSE 

433 <nick> :Nickname is already in use

Returned when a NICK message is processed that results in an attempt to change to a currently existing nickname.

ERR_NICKCOLLISION 

436 <nick> :Nickname collision KILL from <user>@<host>

Returned by a server to a client when it detects a nickname collision (registered of a NICK that already exists by another server).

ERR_UNAVAILRESOURCE 

437 <nick/channel> :Nick/channel is temporarily unavailable

Returned by a server to a user trying to join a channel currently blocked by the channel delay mechanism. - Returned by a server to a user trying to change nickname when the desired nickname is blocked by the nick delay mechanism.

ERR_USERNOTINCHANNEL 

441 <nick> <channel> :They aren't on that channel

Returned by the server to indicate that the target user of the command is not on the given channel.

ERR_NOTONCHANNEL 

442 <channel> :You're not on that channel

Returned by the server whenever a client tries to perform a channel affecting command for which the client isn't a member.

ERR_USERONCHANNEL 

443 <user> <channel> :is already on channel

Returned when a client tries to invite a user to a channel they are already on.

ERR_NOLOGIN 

444 <user> :User not logged in

Returned by the summon after a SUMMON command for a user was unable to be performed since they were not logged in.

ERR_SUMMONDISABLED 

445 :SUMMON has been disabled

Returned as a response to the SUMMON command. MUST be returned by any server which doesn't implement it.

ERR_USERSDISABLED 

446 :USERS has been disabled

Returned as a response to the USERS command. MUST be returned by any server which does not implement it.

ERR_NOTREGISTERED 

451 :You have not registered

Returned by the server to indicate that the client MUST be registered before the server will allow it to be parsed in detail.

ERR_NEEDMOREPARAMS 

461 <command> :Not enough parameters

Returned by the server by numerous commands to indicate to the client that it didn't supply enough parameters.

ERR_ALREADYREGISTRED 

462 :Unauthorized command (already registered)

Returned by the server to any link which tries to change part of the registered details (such as password or user details from second USER message).

ERR_NOPERMFORHOST 

463 :Your host isn't among the privileged

Returned to a client which attempts to register with a server which does not been setup to allow connections from the host the attempted connection is tried.

ERR_PASSWDMISMATCH 

464 :Password incorrect

Returned to indicate a failed attempt at registering a connection for which a password was required and was either not given or incorrect.

ERR_YOUREBANNEDCREEP 

465 :You are banned from this server

Returned after an attempt to connect and register yourself with a server which has been setup to explicitly deny connections to you.

ERR_YOUWILLBEBANNED 

466 :You will be banned from this server

Sent by a server to a user to inform that access to the server will soon be denied.

ERR_KEYSET 

467 <channel> :Channel key already set

No description available in RFC

ERR_CHANNELISFULL 

471 <channel> :Cannot join channel (+l)

No description available in RFC

ERR_UNKNOWNMODE 

472 <char> :is unknown mode char to me for <channel>

No description available in RFC

ERR_INVITEONLYCHAN 

473 <channel> :Cannot join channel (+i)

No description available in RFC

ERR_BANNEDFROMCHAN 

474 <channel> :Cannot join channel (+b)

No description available in RFC

ERR_BADCHANNELKEY 

475 <channel> :Cannot join channel (+k)

No description available in RFC

ERR_BADCHANMASK 

476 <channel> :Bad Channel Mask

No description available in RFC

ERR_NOCHANMODES 

477 <channel> :Channel doesn't support modes

No description available in RFC

ERR_BANLISTFULL 

478 <channel> <char> :Channel list is full

No description available in RFC

ERR_NOPRIVILEGES 

481 :Permission Denied- You're not an IRC operator

Any command requiring operator privileges to operate MUST return this error to indicate the attempt was unsuccessful.

ERR_CHANOPRIVSNEEDED 

482 <channel> :You're not channel operator

Any command requiring 'chanop' privileges (such as MODE messages) MUST return this error if the client making the attempt is not a chanop on the specified channel.

ERR_CANTKILLSERVER 

483 :You can't kill a server!

Any attempts to use the KILL command on a server are to be refused and this error returned directly to the client.

ERR_RESTRICTED 

484 :Your connection is restricted!

Sent by the server to a user upon connection to indicate the restricted nature of the connection (user mode "+r").

ERR_UNIQOPPRIVSNEEDED 

485 :You're not the original channel operator

Any MODE requiring "channel creator" privileges MUST return this error if the client making the attempt is not a chanop on the specified channel.

ERR_NOOPERHOST 

491 :No O-lines for your host

If a client sends an OPER message and the server has not been configured to allow connections from the client's host as an operator, this error MUST be returned.

ERR_UMODEUNKNOWNFLAG 

501 :Unknown MODE flag

Returned by the server to indicate that a MODE message was sent with a nickname parameter and that the a mode flag sent was not recognized.

ERR_USERSDONTMATCH 

502 :Cannot change mode for other users

Error sent to any user trying to view or change the user mode for a user other than themselves.


Member Function Documentation

const char * Irc::Rfc::toString ( uint  code  )  [static]

Returns the numeric RFC code as a string or 0 if the code is unknown.


The documentation for this class was generated from the following files:
  • include/irc.h
  • src/irc.cpp

Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/ircsession__p_8h_source.html0000644000175000017500000002651011513237311021774 0ustar csmallcsmall LibIrcClient-Qt: include/ircsession_p.h Source File
Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/doxygen.css0000644000175000017500000001473311513237311016463 0ustar csmallcsmall/* The standard CSS for doxygen */ body, table, div, p, dl { font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; font-size: 12px; } /* @group Heading Levels */ h1 { text-align: center; font-size: 150%; } h2 { font-size: 120%; } h3 { font-size: 100%; } dt { font-weight: bold; } div.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; } p.startli, p.startdd { margin-top: 2px; } p.endli { margin-bottom: 0px; } p.enddd { margin-bottom: 4px; } /* @end */ caption { font-weight: bold; } span.legend { font-size: 70%; text-align: center; } div.qindex, div.navtab{ background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; } div.qindex, div.navpath { width: 100%; line-height: 140%; } div.navtab { margin-right: 15px; } /* @group Link Styling */ a { color: #153788; font-weight: normal; text-decoration: none; } .contents a:visited { color: #1b77c5; } a:hover { text-decoration: underline; } a.qindex { font-weight: bold; } a.qindexHL { font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } .contents a.qindexHL:visited { color: #ffffff; } a.el { font-weight: bold; } a.elRef { } a.code { } a.codeRef { } /* @end */ dl.el { margin-left: -1cm; } .fragment { font-family: monospace, fixed; font-size: 105%; } pre.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; padding: 4px 6px; margin: 4px 8px 4px 2px; } div.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } div.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } div.groupText { margin-left: 16px; font-style: italic; } body { background: white; color: black; margin-right: 20px; margin-left: 20px; } td.indexkey { background-color: #e8eef2; font-weight: bold; border: 1px solid #CCCCCC; margin: 2px 0px 2px 0; padding: 2px 10px; } td.indexvalue { background-color: #e8eef2; border: 1px solid #CCCCCC; padding: 2px 10px; margin: 2px 0px; } tr.memlist { background-color: #f0f0f0; } p.formulaDsp { text-align: center; } img.formulaDsp { } img.formulaInl { vertical-align: middle; } div.center { text-align: center; margin-top: 0px; margin-bottom: 0px; padding: 0px; } div.center img { border: 0px; } img.footer { border: 0px; vertical-align: middle; } /* @group Code Colorization */ span.keyword { color: #008000 } span.keywordtype { color: #604020 } span.keywordflow { color: #e08000 } span.comment { color: #800000 } span.preprocessor { color: #806020 } span.stringliteral { color: #002080 } span.charliteral { color: #008080 } span.vhdldigit { color: #ff00ff } span.vhdlchar { color: #000000 } span.vhdlkeyword { color: #700070 } span.vhdllogic { color: #ff0000 } /* @end */ .search { color: #003399; font-weight: bold; } form.search { margin-bottom: 0px; margin-top: 0px; } input.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } td.tiny { font-size: 75%; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } th.dirtab { background: #e8eef2; font-weight: bold; } hr { height: 0; border: none; border-top: 1px solid #666; } /* @group Member Descriptions */ .mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { background-color: #FAFAFA; border: none; margin: 4px; padding: 1px 0 0 8px; } .mdescLeft, .mdescRight { padding: 0px 8px 4px 8px; color: #555; } .memItemLeft, .memItemRight, .memTemplParams { border-top: 1px solid #ccc; } .memItemLeft, .memTemplItemLeft { white-space: nowrap; } .memTemplParams { color: #606060; white-space: nowrap; } /* @end */ /* @group Member Details */ /* Styles for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; margin-left: 3px; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 0; margin-bottom: 10px; } .memname { white-space: nowrap; font-weight: bold; } .memproto, .memdoc { border: 1px solid #84b0c7; } .memproto { padding: 0; background-color: #d5e1e8; font-weight: bold; -webkit-border-top-left-radius: 8px; -webkit-border-top-right-radius: 8px; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -moz-border-radius-topleft: 8px; -moz-border-radius-topright: 8px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; } .memdoc { padding: 2px 5px; background-color: #eef3f5; border-top-width: 0; -webkit-border-bottom-left-radius: 8px; -webkit-border-bottom-right-radius: 8px; -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -moz-border-radius-bottomleft: 8px; -moz-border-radius-bottomright: 8px; -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; white-space: nowrap; } .paramname em { font-style: normal; } /* @end */ /* @group Directory (tree) */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin: 0.5em; } /* these are for tree view when used as main index */ .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } /* The following two styles can be used to replace the root node title with an image of your choice. Simply uncomment the next two styles, specify the name of your image and be sure to set 'height' to the proper pixel height of your image. */ /* .directory h3.swap { height: 61px; background-repeat: no-repeat; background-image: url("yourimage.gif"); } .directory h3.swap span { display: none; } */ .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } /* these are for tree view when not used as main index */ .directory-alt { font-size: 100%; font-weight: bold; } .directory-alt h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory-alt > h3 { margin-top: 0; } .directory-alt p { margin: 0px; white-space: nowrap; } .directory-alt div { display: none; margin: 0px; } .directory-alt img { vertical-align: -30%; } /* @end */ address { font-style: normal; color: #333; } mudlet-2.1/src/irc/doc/functions_0x75.html0000644000175000017500000000715311513237311017753 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- u -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/doc/functions_0x6b.html0000644000175000017500000000731711513237311020031 0ustar csmallcsmall LibIrcClient-Qt: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- k -


Generated on Fri Nov 5 20:00:41 2010 for LibIrcClient-Qt by  doxygen 1.6.1
mudlet-2.1/src/irc/COPYING0000644000175000017500000006350411513237311014562 0ustar csmallcsmall 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! mudlet-2.1/src/irc/src/0000755000175000017500000000000011624306130014305 5ustar csmallcsmallmudlet-2.1/src/irc/src/ircsession.cpp0000644000175000017500000017164011624306130017203 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #include "../include/ircsession.h" #include "../include/ircsession_p.h" #include "../include/ircbuffer.h" #include "../include/ircbuffer_p.h" #include "../include/ircutil.h" #include #include #include #include #include #include #include #include #ifdef HAVE_ICU #include #endif // HAVE_ICU /*! \class Irc::Session ircsession.h \brief The Irc::Session class provides an IRC session. IRC (Internet Relay Chat protocol) is a simple communication protocol. Irc::Session provides means to establish a connection to an IRC server. Irc::Session works asynchronously. None of the functions block the calling thread but they return immediately and the actual work is done behind the scenes in the event loop. Example usage: \code Irc::Session* session = new Irc::Session(this); session->setNick("jpnurmi"); session->setIdent("jpn"); session->setRealName("J-P Nurmi"); session->connectToServer("irc.freenode.net", 6667); \endcode \note Irc::Session supports SSL (Secure Sockets Layer) connections since version 0.3.0 Example SSL usage: \code Irc::Session* session = new Irc::Session(this); // ... QSslSocket* socket = new QSslSocket(session); socket->ignoreSslErrors(); socket->setPeerVerifyMode(QSslSocket::VerifyNone); session->setSocket(socket); session->connectToServer("irc.secure.ssl", 6669); \endcode \sa setSocket() */ /*! \enum Irc::Session::Option This enum describes special options that may be used by Irc::Session. */ /*! \var Irc::Session::NoOptions Clears options. */ /*! \var Irc::Session::StripNicks Strips origins automatically. For every IRC server message, the origin is sent in standard form: \code nick!ident@host \endcode i.e. like \e jpnurmi!jpnurmi\@xob.kapsi.fi. Such origins can not be used in IRC commands but need to be stripped (i.e. ident and host part should be cut off) before using. This can be done either explicitly, by calling Irc::Util::nickFromTarget(), or implicitly for all the messages - by setting this option with Irc::Session::setOptions(). */ /*! \var Irc::Session::EchoMessages Echo own messages, notices and actions. IRC servers do not echo users own messages, notices or actions. This option makes Irc::Session to echo them to ease up IRC client implementation. */ /*! \fn void Irc::Session::connected() This signal is emitted after a connection has been successfully established. */ /*! \fn void Irc::Session::welcomed() This signal is emitted when the welcome message has been received. \sa Irc::Rfc::RPL_WELCOME */ /*! \fn void Irc::Session::reconnecting() This signal is emitted when the session is about to reconnect. */ /*! \fn void Irc::Session::disconnected() This signal is emitted when the session has been disconnected. */ /*! \fn void Irc::Session::bufferAdded(Irc::Buffer* buffer) This signal is emitted whenever a \a buffer was added. */ /*! \fn void Irc::Session::bufferRemoved(Irc::Buffer* buffer) This signal is emitted whenever a \a buffer was removed. */ /*! \fn void Irc::Session::capabilitiesListed(const QStringList& capabilities) This signal is emitted when the library receives a list of supported capabilities for this session. \sa requestCapabilities() */ /*! \fn void Irc::Session::capabilitiesAcked(const QStringList& capabilities) This signal is emitted when the server acknowledges the use of a previously requested list of capabilities. Note that if you request a list of capabilities, either all of them will be acked, or all of them will be nacked. */ /*! \fn void Irc::Session::capabilitiesNotAcked(const QStringList& capabilities) This signal is emitted when the server disacknowledges enabling a previously requested list of capabilities. This means that none of the requested capabilities will be enabled, even if some of them were valid. (Any previously enabled capabilities will still be enabled.) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgJoined ( const QString &origin, const QString &channel) \deprecated Use Irc::Buffer::joined(const QString& origin) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgParted (const QString &origin, const QString &channel, const QString &message) \deprecated Use Irc::Buffer::parted(const QString& origin, const QString& message) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgQuit (const QString &origin, const QString &message) \deprecated Use Irc::Buffer::quit(const QString& origin, const QString& message) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgNickChanged (const QString &origin, const QString &nick) \deprecated Use Irc::Buffer::nickChanged(const QString& origin, const QString& nick) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgModeChanged (const QString &origin, const QString &receiver, const QString &mode, const QString &args) \deprecated Use Irc::Buffer::modeChanged(const QString& origin, const QString& mode, const QString& args) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgTopicChanged (const QString &origin, const QString &channel, const QString &topic) \deprecated Use Irc::Buffer::topicChanged(const QString& origin, const QString& topic) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgInvited (const QString &origin, const QString &receiver, const QString &channel) \deprecated Use Irc::Buffer::invited(const QString& origin, const QString& receiver, const QString& channel) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgKicked (const QString &origin, const QString &channel, const QString &nick, const QString &message) \deprecated Use Irc::Buffer::kicked(const QString& origin, const QString& nick, const QString& message) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgMessageReceived (const QString &origin, const QString &receiver, const QString &message) \deprecated Use Irc::Buffer::messageReceived(const QString& origin, const QString& message) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgNoticeReceived (const QString &origin, const QString &receiver, const QString ¬ice) \deprecated Use Irc::Buffer::noticeReceived(const QString& origin, const QString& notice) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgCtcpRequestReceived (const QString &origin, const QString &request) \deprecated Use Irc::Buffer::ctcpRequestReceived(const QString& origin, const QString& request) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgCtcpReplyReceived (const QString &origin, const QString &reply) \deprecated Use Irc::Buffer::ctcpReplyReceived(const QString& origin, const QString& reply) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgCtcpActionReceived (const QString &origin, const QString &receiver, const QString &action) \deprecated Use Irc::Buffer::ctcpActionReceived(const QString& origin, const QString& action) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgNumericMessageReceived (const QString &origin, uint code, const QStringList ¶ms) \deprecated Use Irc::Buffer::numericMessageReceived(const QString& origin, uint code, const QStringList& params) */ /*! \fn Q_DECL_DEPRECATED void Irc::Session::msgUnknownMessageReceived (const QString &origin, const QStringList ¶ms) \deprecated Use Irc::Buffer::unknownMessageReceived(const QString& origin, const QStringList& params) */ static QByteArray detectEncoding(const QByteArray& text) { Q_UNUSED(text); QByteArray encoding; #ifdef HAVE_ICU UErrorCode status = U_ZERO_ERROR; UCharsetDetector* detector = ucsdet_open(&status); if (detector && !U_FAILURE(status)) { ucsdet_setText(detector, text.constData(), text.length(), &status); if (!U_FAILURE(status)) { const UCharsetMatch* match = ucsdet_detect(detector, &status); if (match && !U_FAILURE(status)) encoding = ucsdet_getName(match, &status); } } if (U_FAILURE(status)) { qWarning("detectEncoding() failed: %s", u_errorName(status)); } ucsdet_close(detector); #endif // HAVE_ICU return encoding; } namespace Irc { SessionPrivate::SessionPrivate() : q_ptr(0), buffer(), options(Session::StripNicks | Session::EchoMessages), socket(0), ident(QLatin1String("libircclient-qt")), password(), nick(QLatin1String("libircclient")), realName(QLatin1String("libircclient-qt")), host(), port(6667), motd(), channels(), encoding(), delay(-1), timer(), defaultBuffer(), buffers(), welcomed(false), capabilitiesSupported(false) { } void SessionPrivate::init(Session* session) { q_ptr = session; Q_Q(Session); q->setSocket(new QTcpSocket(q)); q->connect(&timer, SIGNAL(timeout()), q, SLOT(_q_reconnect())); } void SessionPrivate::_q_connected() { Q_Q(Session); Q_ASSERT(!nick.isEmpty()); Q_ASSERT(!ident.isEmpty()); // stop autoreconnecting... if (timer.isActive()) timer.stop(); // Send CAP LS first; if the server understands it this will // temporarily pause the handshake until CAP END is sent, so we // know whether the server supports the CAP extension. socket->write("CAP LS\r\n"); if (!password.isEmpty()) socket->write(QString(QLatin1String("PASS %1\r\n")).arg(password).toLocal8Bit()); socket->write(QString(QLatin1String("NICK %1\r\n")).arg(nick).toLocal8Bit()); // RFC 1459 states that "hostname and servername are normally // ignored by the IRC server when the USER command comes from // a directly connected client (for security reasons)", therefore // we don't need them. socket->write(QString(QLatin1String("USER %1 unknown unknown :%2\r\n")).arg(ident, realName).toLocal8Bit()); defaultBuffer = createBuffer(host); emit q->connected(); welcomed = false; capabilitiesSupported = false; } void SessionPrivate::_q_disconnected() { Q_Q(Session); emit q->disconnected(); } void SessionPrivate::_q_reconnect() { if (socket) { socket->connectToHost(host, port); if (socket->inherits("QSslSocket")) QMetaObject::invokeMethod(socket, "startClientEncryption"); } // stop autoreconnecting... if (timer.isActive()) timer.stop(); } void SessionPrivate::_q_error() { Q_Q(Session); // start reconnecting... if (delay >= 0) { timer.start(delay * 1000); emit q->reconnecting(); } } void SessionPrivate::_q_state(QAbstractSocket::SocketState state) { } void SessionPrivate::_q_readData() { buffer += socket->readAll(); // try reading RFC compliant message lines first readLines("\r\n"); // fall back to RFC incompliant lines... readLines("\n"); } QString SessionPrivate::readString(const QByteArray& data) const { QByteArray enc = encoding; if (enc.isNull()) enc = detectEncoding(data); QTextCodec *codec = QTextCodec::codecForName(enc); if (!codec) codec = QTextCodec::codecForLocale(); return codec->toUnicode(data); } void SessionPrivate::readLines(const QByteArray& delimiter) { int i = -1; while ((i = buffer.indexOf(delimiter)) != -1) { QByteArray line = buffer.left(i).trimmed(); buffer = buffer.mid(i + delimiter.length()); if (!line.isEmpty()) processLine(line); } } void SessionPrivate::processLine(const QByteArray& line) { Q_Q(Session); QString process = readString(line); QString prefix, command; QStringList params; // From RFC 1459: // ::= [':' ] // ::= | [ '!' ] [ '@' ] // ::= { } | // ::= ' ' { ' ' } // ::= [ ':' | ] // ::= // ::= // parse if (process.startsWith(QLatin1Char(':'))) { prefix = process.mid(1, process.indexOf(QLatin1Char(' ')) - 1); process.remove(0, prefix.length() + 2); if (options & Session::StripNicks) { int index = prefix.indexOf(QRegExp(QLatin1String("[@!]"))); if (index != -1) prefix.truncate(index); } } // parse command = process.mid(0, process.indexOf(QLatin1Char(' '))); process.remove(0, command.length() + 1); bool isNumeric = false; uint code = command.toInt(&isNumeric); // parse middle/params while (!process.isEmpty()) { if (process.startsWith(QLatin1Char(':'))) { process.remove(0, 1); params << process; process.clear(); } else { QString param = process.mid(0, process.indexOf(QLatin1Char(' '))); process.remove(0, param.length() + 1); params << param; } } // handle PING/PONG if (command == QLatin1String("PING")) { QString arg = params.value(0); q->raw(QString(QLatin1String("PONG %1")).arg(arg)); return; } // and dump if (isNumeric) { switch (code) { case Irc::Rfc::RPL_WELCOME: { Q_ASSERT(defaultBuffer); defaultBuffer->d_func()->setReceiver(prefix, false); emit q->welcomed(); welcomed = true; if (!capabilitiesSupported && !wantedCapabilities.isEmpty()) emit q->capabilitiesNotAcked(wantedCapabilities); wantedCapabilities.clear(); break; } case Irc::Rfc::RPL_TOPIC: { QString topic = params.value(1); QString target = resolveTarget(QString(), topic); Buffer* buffer = createBuffer(target); buffer->d_func()->topic = topic; break; } case Irc::Rfc::RPL_NAMREPLY: { QStringList list = params; list.removeAll(QLatin1String("=")); list.removeAll(QLatin1String("@")); list.removeAll(QLatin1String("*")); QString target = resolveTarget(QString(), list.value(1)); Buffer* buffer = createBuffer(target); QStringList names = list.value(2).split(QLatin1String(" "), QString::SkipEmptyParts); foreach (const QString& name, names) buffer->d_func()->addName(name); break; } case Irc::Rfc::RPL_MOTDSTART: motd.clear(); break; case Irc::Rfc::RPL_MOTD: motd.append(params.value(1) + QLatin1Char('\n')); break; case Irc::Rfc::RPL_ENDOFMOTD: if (defaultBuffer) emit defaultBuffer->motdReceived(motd); motd.clear(); break; default: break; } if (code == Rfc::RPL_TOPICSET && options & Session::StripNicks) { QString user = params.value(2); int index = user.indexOf(QRegExp(QLatin1String("[@!]"))); if (index != -1) { user.truncate(index); params.replace(2, user); } } if (defaultBuffer) emit defaultBuffer->numericMessageReceived(prefix, code, params); // join auto-join channels after MOTD if (code == Rfc::RPL_ENDOFMOTD || code == Rfc::ERR_NOMOTD) { foreach (const QString& channel, channels) q->join(channel); } } else { if (command == QLatin1String("NICK")) { QString oldNick = Util::nickFromTarget(prefix); QString newNick = params.value(0); if (nick == oldNick) nick = newNick; foreach (Buffer* buffer, buffers) { if (buffer->receiver() == oldNick) buffer->d_func()->setReceiver(newNick); if (buffer->names().contains(oldNick)) { buffer->d_func()->removeName(oldNick); buffer->d_func()->addName(newNick); emit buffer->nickChanged(prefix, newNick); } } } else if (command == QLatin1String("QUIT")) { QString reason = params.value(0); QString nick = Util::nickFromTarget(prefix); foreach (Buffer* buffer, buffers) { if (buffer->names().contains(nick)) { buffer->d_func()->removeName(nick); emit buffer->quit(prefix, reason); } } } else if (command == QLatin1String("JOIN")) { QString channel = params.value(0); QString target = resolveTarget(prefix, channel); Buffer* buffer = createBuffer(target); buffer->d_func()->addName(Util::nickFromTarget(prefix)); emit buffer->joined(prefix); } else if (command == QLatin1String("PART")) { QString channel = params.value(0); QString target = resolveTarget(prefix, channel); if (nick != Util::nickFromTarget(prefix)) { QString message = params.value(1); Buffer* buffer = createBuffer(target); buffer->d_func()->removeName(Util::nickFromTarget(prefix)); emit buffer->parted(prefix, message); } else if (buffers.contains(target)) { Buffer* buffer = buffers.value(target); removeBuffer(buffer); buffer->deleteLater(); } } else if (command == QLatin1String("MODE")) { QString receiver = params.value(0); QString mode = params.value(1); QString args = params.value(2); QString target = resolveTarget(prefix, receiver); Buffer* buffer = createBuffer(target); buffer->d_func()->updateMode(args, mode); emit buffer->modeChanged(prefix, mode, args); } else if (command == QLatin1String("TOPIC")) { QString channel = params.value(0); QString topic = params.value(1); QString target = resolveTarget(prefix, channel); Buffer* buffer = createBuffer(target); buffer->d_func()->topic = topic; emit buffer->topicChanged(prefix, topic); } else if (command == QLatin1String("INVITE")) { QString receiver = params.value(0); QString channel = params.value(1); if (defaultBuffer) emit defaultBuffer->invited(prefix, receiver, channel); } else if (command == QLatin1String("KICK")) { QString channel = params.value(0); QString nick = params.value(1); QString message = params.value(2); QString target = resolveTarget(prefix, channel); Buffer* buffer = createBuffer(target); buffer->d_func()->removeName(nick); emit buffer->kicked(prefix, nick, message); } else if (command == QLatin1String("PRIVMSG")) { QString message = params.value(1); Irc::Buffer::MessageFlags flags = getMessageFlags(message); if (message.startsWith(QLatin1Char('\1')) && message.endsWith(QLatin1Char('\1'))) { message.remove(0, 1); message.remove(message.length() - 1, 1); if (message.startsWith(QLatin1String("ACTION "))) { QString receiver = params.value(0); QString target = resolveTarget(prefix, receiver); Buffer* buffer = createBuffer(target); emit buffer->ctcpActionReceived(prefix, message.mid(7), flags); } else { // TODO: check params if (defaultBuffer) emit defaultBuffer->ctcpRequestReceived(prefix, /*receiver,*/ message, flags); } } else { QString receiver = params.value(0); QString target = resolveTarget(prefix, receiver); Buffer* buffer = createBuffer(target); emit buffer->messageReceived(prefix, message, flags); } } else if (command == QLatin1String("NOTICE")) { if (!welcomed) { Q_ASSERT(defaultBuffer); defaultBuffer->d_func()->setReceiver(prefix, false); } QString receiver = params.value(0); QString message = params.value(1); Irc::Buffer::MessageFlags flags = getMessageFlags(message); if (message.startsWith(QLatin1Char('\1')) && message.endsWith(QLatin1Char('\1'))) { message.remove(0, 1); message.remove(message.length() - 1, 1); // TODO: check params if (defaultBuffer) emit defaultBuffer->ctcpReplyReceived(prefix, /*receiver,*/ message, flags); } else { QString target = resolveTarget(prefix, receiver); Buffer* buffer = createBuffer(target); emit buffer->noticeReceived(prefix, message, flags); } } else if (command == QLatin1String("KILL")) { ; // ignore this event - not all servers generate this } else if (command == QLatin1String("CAP")) { QString subcommand = params.at(1); bool endList = params.size() < 3 || params.at(2) != QLatin1String("*"); QString rawCapabilities = params.at(params.size()-1); tempCapabilities.append(rawCapabilities.split(QLatin1String(" "))); if (subcommand == QLatin1String("LS") && endList) { capabilities = tempCapabilities; emit q->capabilitiesListed(capabilities); // Request in-library supported capabilities right away wantedCapabilities.append(QLatin1String("identify-msg")); if (!welcomed) { capabilitiesSupported = true; if (wantedCapabilities.isEmpty()) socket->write("CAP END\r\n"); else q->requestCapabilities(wantedCapabilities); } } else if (subcommand == QLatin1String("LIST") && endList) { enabledCapabilities = tempCapabilities; } else if (subcommand == QLatin1String("ACK") && endList) { foreach (const QString &cap, tempCapabilities) { if (cap.startsWith(QString::fromAscii("-"))) // remove disabled capabilities from the list for (int capi = 0; capi < enabledCapabilities.size(); ++capi) { if (enabledCapabilities.at(capi).compare( cap.mid(1), Qt::CaseInsensitive) == 0) enabledCapabilities.removeAt(capi); } else enabledCapabilities.append(cap); } if (!welcomed) socket->write("CAP END\r\n"); emit q->capabilitiesAcked(tempCapabilities); } else if (subcommand == QLatin1String("NAK") && endList) { if (!welcomed) socket->write("CAP END\r\n"); emit q->capabilitiesNotAcked(tempCapabilities); } tempCapabilities.clear(); } else { // The "unknown" event is triggered upon receipt of any number of // unclassifiable miscellaneous messages, which aren't handled by // the library. if (defaultBuffer) emit defaultBuffer->unknownMessageReceived(prefix, params); } } } Irc::Buffer::MessageFlags SessionPrivate::getMessageFlags(QString& message) const { Q_Q(const Session); if (q->capabilityEnabled(QLatin1String("identify-msg"))) { const QChar identstate = message.at(0); message.remove(0, 1); switch (identstate.toAscii()) { case '+': return Irc::Buffer::IdentifiedFlag; case '-': break; default: qWarning() << "Unknown identification state character" " in PRIVMSG with identify-msg enabled:" << identstate; } } return Irc::Buffer::NoFlags; } bool SessionPrivate::isConnected() const { return socket && (socket->state() == QAbstractSocket::ConnectingState || socket->state() == QAbstractSocket::ConnectedState); } QString SessionPrivate::resolveTarget(const QString& sender, const QString& receiver) const { QString target = receiver; if (target.contains(QLatin1Char('*')) || target.contains(QLatin1Char('?'))) target = nick; if (target == nick) { if (target == sender) target = host; else target = sender; } if (target.isEmpty() || target == QLatin1String("AUTH")) target = host; return target; } Buffer* SessionPrivate::createBuffer(const QString& receiver) { Q_Q(Session); QString lower = receiver.toLower(); QString lowerNick = Util::nickFromTarget(receiver).toLower(); if (lower != lowerNick && buffers.contains(lowerNick)) { Buffer* buffer = buffers.value(lowerNick); buffer->d_func()->setReceiver(lower); buffers.insert(lower, buffer); buffers.remove(lowerNick); } else if (!buffers.contains(lower) && !buffers.contains(lowerNick)) { Buffer* buffer = q->createBuffer(receiver); buffers.insert(lower, buffer); emit q->bufferAdded(buffer); } return buffers.value(lower); } void SessionPrivate::removeBuffer(Buffer* buffer) { Q_Q(Session); QString lower = buffer->receiver().toLower(); if (buffers.take(lower) == buffer) emit q->bufferRemoved(buffer); } #ifndef IRC_NO_DEPRECATED // TODO: for backwards compatibility, to be removed in 1.0 inline void SessionPrivate::emitCompatSignal(const char* signal, const QVariantList& params) { Q_Q(Session); if (q->receivers(signal)) { qWarning("IrcSession::%s [signal] is DEPRECATED", signal+1); QByteArray method(signal); method.remove(0, 1); method.truncate(method.indexOf("(")); QMetaObject::invokeMethod(q, method, params.count() > 0 ? QGenericArgument(QMetaType::typeName(params.at(0).type()), ¶ms[0]) : QGenericArgument(), params.count() > 1 ? QGenericArgument(QMetaType::typeName(params.at(1).type()), ¶ms[1]) : QGenericArgument(), params.count() > 2 ? QGenericArgument(QMetaType::typeName(params.at(2).type()), ¶ms[2]) : QGenericArgument(), params.count() > 3 ? QGenericArgument(QMetaType::typeName(params.at(3).type()), ¶ms[3]) : QGenericArgument()); } } void SessionPrivate::_q_joined(const QString& origin) { Q_Q(Session); Buffer* buffer = qobject_cast(q->sender()); Q_ASSERT(buffer); emitCompatSignal(SIGNAL(msgJoined(QString,QString)), QVariantList() << origin << buffer->receiver()); } void SessionPrivate::_q_parted(const QString& origin, const QString& message) { Q_Q(Session); Buffer* buffer = qobject_cast(q->sender()); Q_ASSERT(buffer); emitCompatSignal(SIGNAL(msgParted(QString,QString,QString)), QVariantList() << origin << buffer->receiver() << message); } void SessionPrivate::_q_quit(const QString& origin, const QString& message) { emitCompatSignal(SIGNAL(msgQuit(QString,QString)), QVariantList() << origin << message); } void SessionPrivate::_q_nickChanged(const QString& origin, const QString& nick) { emitCompatSignal(SIGNAL(msgNickChanged(QString,QString)), QVariantList() << origin << nick); } void SessionPrivate::_q_modeChanged(const QString& origin, const QString& mode, const QString& args) { Q_Q(Session); Buffer* buffer = qobject_cast(q->sender()); Q_ASSERT(buffer); emitCompatSignal(SIGNAL(msgModeChanged(QString,QString,QString,QString)), QVariantList() << origin << buffer->receiver() << mode << args); } void SessionPrivate::_q_topicChanged(const QString& origin, const QString& topic) { Q_Q(Session); Buffer* buffer = qobject_cast(q->sender()); Q_ASSERT(buffer); emitCompatSignal(SIGNAL(msgTopicChanged(QString,QString,QString)), QVariantList() << origin << buffer->receiver() << topic); } void SessionPrivate::_q_invited(const QString& origin, const QString& receiver, const QString& channel) { emitCompatSignal(SIGNAL(msgInvited(QString,QString,QString)), QVariantList() << origin << receiver << channel); } void SessionPrivate::_q_kicked(const QString& origin, const QString& nick, const QString& message) { Q_Q(Session); Buffer* buffer = qobject_cast(q->sender()); Q_ASSERT(buffer); emitCompatSignal(SIGNAL(msgKicked(QString,QString,QString,QString)), QVariantList() << origin << buffer->receiver() << nick << message); } void SessionPrivate::_q_messageReceived(const QString& origin, const QString& message) { Q_Q(Session); Buffer* buffer = qobject_cast(q->sender()); Q_ASSERT(buffer); emitCompatSignal(SIGNAL(msgMessageReceived(QString,QString,QString)), QVariantList() << origin << buffer->receiver() << message); } void SessionPrivate::_q_noticeReceived(const QString& origin, const QString& notice) { Q_Q(Session); Buffer* buffer = qobject_cast(q->sender()); Q_ASSERT(buffer); emitCompatSignal(SIGNAL(msgNoticeReceived(QString,QString,QString)), QVariantList() << origin << buffer->receiver() << notice); } void SessionPrivate::_q_ctcpRequestReceived(const QString& origin, const QString& request) { emitCompatSignal(SIGNAL(msgCtcpRequestReceived(QString,QString)), QVariantList() << origin << request); } void SessionPrivate::_q_ctcpReplyReceived(const QString& origin, const QString& reply) { emitCompatSignal(SIGNAL(msgCtcpReplyReceived(QString,QString)), QVariantList() << origin << reply); } void SessionPrivate::_q_ctcpActionReceived(const QString& origin, const QString& action) { Q_Q(Session); Buffer* buffer = qobject_cast(q->sender()); Q_ASSERT(buffer); emitCompatSignal(SIGNAL(msgCtcpActionReceived(QString,QString,QString)), QVariantList() << origin << buffer->receiver() << action); } void SessionPrivate::_q_numericMessageReceived(const QString& origin, uint code, const QStringList& params) { emitCompatSignal(SIGNAL(msgNumericMessageReceived(QString,uint,QStringList)), QVariantList() << origin << code << params); } void SessionPrivate::_q_unknownMessageReceived(const QString& origin, const QStringList& params) { emitCompatSignal(SIGNAL(msgUnknownMessageReceived(QString,QStringList)), QVariantList() << origin << params); } #endif // IRC_NO_DEPRECATED /*! Constructs a new IRC session with \a parent. */ Session::Session(QObject* parent) : QObject(parent), d_ptr(new SessionPrivate) { Q_D(Session); d->init(this); } /*! Destructs the IRC session. */ Session::~Session() { Q_D(Session); if (d->socket) d->socket->close(); delete d; } /*! Returns the list of auto-join channels. */ QStringList Session::autoJoinChannels() const { Q_D(const Session); return d->channels; } /*! Adds \a channel to the list of auto-join channels. */ void Session::addAutoJoinChannel(const QString& channel) { Q_D(Session); if (!d->channels.contains(channel, Qt::CaseInsensitive)) d->channels.append(channel); } /*! Removes \a channels from the list of auto-join channels. */ void Session::removeAutoJoinChannel(const QString& channel) { Q_D(Session); int index = d->channels.indexOf(QRegExp(channel, Qt::CaseInsensitive)); if (index != -1) d->channels.removeAt(index); } /*! Sets the list of auto-join \a channels. */ void Session::setAutoJoinChannels(const QStringList& channels) { Q_D(Session); d->channels = channels; } /*! Returns the auto-reconnecting delay. A negative value means no auto-reconnecting. The default value is \c -1. */ int Session::autoReconnectDelay() const { Q_D(const Session); return d->delay; } /*! Sets auto-reconnecting delay in \a seconds. */ void Session::setAutoReconnectDelay(int seconds) { Q_D(Session); d->delay = seconds; } /*! Returns the encoding. The default value is a null QByteArray. */ QByteArray Session::encoding() const { Q_D(const Session); return d->encoding; } /*! Sets the \a encoding. See QTextCodec documentation for supported encodings. Encoding auto-detection can be turned on by passing a null QByteArray. The fallback locale is QTextCodec::codecForLocale(). */ void Session::setEncoding(const QByteArray& encoding) { Q_D(Session); d->encoding = encoding; } /*! Returns the ident. */ QString Session::ident() const { Q_D(const Session); return d->ident; } /*! Sets the \a ident. \note setIdent() has no effect on already established connection. */ void Session::setIdent(const QString& ident) { Q_D(Session); if (d->isConnected()) qWarning("Session::setIdent() has no effect until re-connect"); d->ident = ident; } /*! Returns the nick. */ QString Session::nick() const { Q_D(const Session); return d->nick; } /*! Sets the \a nick. */ void Session::setNick(const QString& nick) { Q_D(Session); if (d->nick != nick) { d->nick = nick; if (d->socket) raw(QString(QLatin1String("NICK %1")).arg(nick)); } } /*! Returns the password. */ QString Session::password() const { Q_D(const Session); return d->password; } /*! Sets the \a password. \note setPassword() has no effect on already established connection. */ void Session::setPassword(const QString& password) { Q_D(Session); if (d->isConnected()) qWarning("Session::setPassword() has no effect until re-connect"); d->password = password; } /*! Returns the real name. */ QString Session::realName() const { Q_D(const Session); return d->realName; } /*! Sets the \a realName. \note setRealName() has no effect on already established connection. */ void Session::setRealName(const QString& realName) { Q_D(Session); if (d->isConnected()) qWarning("Session::setRealName() has no effect until re-connect"); d->realName = realName; } /*! Returns the host. */ QString Session::host() const { Q_D(const Session); return d->host; } /*! Sets the \a host. */ void Session::setHost(const QString& host) { Q_D(Session); if (d->isConnected()) qWarning("Session::setHost() has no effect until re-connect"); d->host = host; } /*! Returns the port. */ quint16 Session::port() const { Q_D(const Session); return d->port; } /*! Sets the \a port. */ void Session::setPort(quint16 port) { Q_D(Session); if (d->isConnected()) qWarning("Session::setPort() has no effect until re-connect"); d->port = port; } /*! Returns the options. The default value is \c StripNicks. */ Session::Options Session::options() const { Q_D(const Session); return d->options; } /*! Sets the \a options. */ void Session::setOptions(Options options) { Q_D(Session); d->options = options; } /*! Returns the socket. Irc::Session creates an instance of QTcpSocket by default. This function was introduced in version 0.3.0. */ QAbstractSocket* Session::socket() const { Q_D(const Session); return d->socket; } /*! Sets the \a socket. The previously set socket is deleted if its parent is \c this. Irc::Session supports QSslSocket in the way that it automatically calls QSslSocket::startClientEncryption() while connecting. This function was introduced in version 0.3.0. */ void Session::setSocket(QAbstractSocket* socket) { Q_D(Session); if (d->socket != socket) { if (d->socket) { d->socket->disconnect(this); if (d->socket->parent() == this) d->socket->deleteLater(); } d->socket = socket; if (socket) { connect(socket, SIGNAL(connected()), this, SLOT(_q_connected())); connect(socket, SIGNAL(disconnected()), this, SLOT(_q_disconnected())); connect(socket, SIGNAL(readyRead()), this, SLOT(_q_readData())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(_q_error())); connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(_q_state(QAbstractSocket::SocketState))); } } } /*! Returns the list of capabilities the server supports, as reported by the server (including any modifiers). If empty, the server might not implement the capabilities extension, or it might simply not support any specific capability. */ QStringList Session::supportedCapabilities() const { Q_D(const Session); return d->capabilities; } /*! Returns the list of enabled capabilities for this session, as reported by the server (including any modifiers). \sa requestCapabilities() */ QStringList Session::enabledCapabilities() const { Q_D(const Session); return d->enabledCapabilities; } /*! Returns whether a capability is enabled for this session. If you give modifier names along with the name (i.e. '=' or '~'), this method will remove them; it will match them to any name delivered by the server, whether or not it sends any modifiers along. Behaviour when including the 'disabled modifier' ('-') is undefined; you should negate the return value of this method instead. Note: This does not include the network specific modifier (i.e. '.'). For example, =identify-msg matches ~IDENTIFY-MSG but not .identify-msg. \sa enabledCapabilities() */ bool Session::capabilityEnabled(const QString& name) const { QString cleanName = name; while (cleanName.startsWith(QLatin1Char('=')) || cleanName.startsWith(QLatin1Char('~'))) cleanName.remove(0, 1); foreach (const QString &mod, enabledCapabilities()) { QString copy = mod; while (copy.startsWith(QLatin1Char('=')) || copy.startsWith(QLatin1Char('~'))) copy.remove(0, 1); if (cleanName.compare(copy, Qt::CaseInsensitive) == 0) return true; } return false; } /*! Requests a capability in the server. \sa supportedCapabilities() \sa clearCapabilities() \sa capabilitiesAcked() \sa capabilitiesNotAcked() */ void Session::requestCapabilities(const QStringList& capabilities) { Q_D(Session); if (d->capabilitiesSupported) { // We're far enough in the handshake to send them right away. QString caps; foreach (const QString &rawCap, d->wantedCapabilities) { QString cap = rawCap; cap.remove(QLatin1String("\r")); cap.remove(QLatin1String("\n")); caps.append(cap + QLatin1String(" ")); } d->socket->write(QString::fromAscii("CAP REQ :%1\r\n") .arg(caps).toAscii()); return; } if (!d->welcomed) { // Queue the requested capabilities to request them later. d->wantedCapabilities.append(capabilities); d->wantedCapabilities.removeDuplicates(); return; } // Capabilities are requested while they are not supported. Emit // an artificial NACK emit capabilitiesNotAcked(capabilities); } /*! Clear all non-sticky capabilities for this session. \sa enabledCapabilities() \sa requestCapabilities() \sa supportedCapabilities() */ void Session::clearCapabilities() { Q_D(Session); if (d->welcomed) d->socket->write("CAP CLEAR\r\n"); else d->wantedCapabilities.clear(); } /*! Returns all allocated buffers. \sa buffer() */ QList Session::buffers() const { Q_D(const Session); return d->buffers.values(); } /*! Returns the buffer for \a receiver. Returns \c 0 if the buffer does not exist. \sa buffers() \sa addBuffer() */ Buffer* Session::buffer(const QString& receiver) const { Q_D(const Session); if (receiver.isNull()) return d->buffers.value(d->host.toLower()); return d->buffers.value(receiver.toLower()); } /*! Adds a buffer for \a receiver and returns it. \sa buffer() */ Buffer* Session::addBuffer(const QString& receiver) { Q_D(Session); return d->createBuffer(receiver); } /*! Returns the default buffer. */ Buffer* Session::defaultBuffer() const { Q_D(const Session); return d->defaultBuffer; } /*! Sets the default \a buffer. */ void Session::setDefaultBuffer(Buffer* buffer) { Q_D(Session); d->defaultBuffer = buffer; } /*! Connects to server with \a hostName and \a port. */ void Session::connectToServer(const QString& hostName, quint16 port) { Q_D(Session); if (!hostName.isNull()) d->host = hostName; if (port != 6667) d->port = port; d->_q_reconnect(); } /*! Reconnects to server. */ void Session::reconnectToServer() { Q_D(Session); d->_q_reconnect(); } /*! Disconnects from the server. */ void Session::disconnectFromServer() { Q_D(Session); if (d->socket) d->socket->disconnectFromHost(); } /*! Sends a raw message to the server. */ bool Session::raw(const QString& message) { Q_D(Session); qint64 bytes = -1; if (d->socket) bytes = d->socket->write(message.toUtf8() + QByteArray("\r\n")); return bytes != -1; } /*! Requests message of the day. */ bool Session::motd() { return raw(QLatin1String("MOTD")); } /*! Joins \a channel with optional \a key. */ bool Session::join(const QString& channel, const QString& key) { if (key.isEmpty()) return raw(QString(QLatin1String("JOIN %1")).arg(channel)); else return raw(QString(QLatin1String("JOIN %1 %2")).arg(channel, key)); } /*! Parts \a channel with \a reason. */ bool Session::part(const QString& channel, const QString& reason) { if (reason.isEmpty()) return raw(QString(QLatin1String("PART %1")).arg(channel)); else return raw(QString(QLatin1String("PART %1 :%2")).arg(channel, reason)); } /*! Quits with optional \a reason. */ bool Session::quit(const QString& reason) { return raw(QString(QLatin1String("QUIT :%1")).arg(reason.isEmpty() ? QLatin1String("Quit") : reason)); } /*! Requests the list of names on \a channel. */ bool Session::names(const QString& channel) { return raw(QString(QLatin1String("NAMES %1")).arg(channel)); } /*! Requests the list of channels. */ bool Session::list(const QString& channel) { if (channel.isEmpty()) return raw(QLatin1String("LIST")); else return raw(QString(QLatin1String("LIST %1")).arg(channel)); } /*! Sends a whois command on \a nick. */ bool Session::whois(const QString& nick) { return raw(QString(QLatin1String("WHOIS %1 %2")).arg(nick, nick)); } /*! Sends a whowas command on \a nick. */ bool Session::whowas(const QString& nick) { return raw(QString(QLatin1String("WHOWAS %1 %2")).arg(nick, nick)); } /*! Sends a mode command on \a target. */ bool Session::mode(const QString& target, const QString& mode) { if (mode.isEmpty()) return raw(QString(QLatin1String("MODE %1")).arg(target)); else return raw(QString(QLatin1String("MODE %1 %2")).arg(target, mode)); } /*! Sends a topic command on \a channel. */ bool Session::topic(const QString& channel, const QString& topic) { if (topic.isEmpty()) return raw(QString(QLatin1String("TOPIC %1")).arg(channel)); else return raw(QString(QLatin1String("TOPIC %1 :%2")).arg(channel, topic)); } /*! Sends an invitation to \a nick. */ bool Session::invite(const QString& nick, const QString& channel) { return raw(QString(QLatin1String("INVITE %1 %2")).arg(nick, channel)); } /*! Kicks \a nick from \a channel with \a reason. */ bool Session::kick(const QString& nick, const QString& channel, const QString& reason) { if (reason.isEmpty()) return raw(QString(QLatin1String("KICK %1 %2")).arg(channel, nick)); else return raw(QString(QLatin1String("KICK %1 %2 :%3")).arg(channel, nick, reason)); } /*! Sends a \a message to \a receiver. */ bool Session::message(const QString& receiver, const QString& message) { Q_D(Session); if (d->options & Session::EchoMessages) { Buffer* buffer = d->createBuffer(receiver); emit buffer->messageReceived(d->nick, message, Irc::Buffer::EchoFlag); } return raw(QString(QLatin1String("PRIVMSG %1 :%2")).arg(Util::nickFromTarget(receiver), message)); } /*! Sends a \a notice to \a receiver. */ bool Session::notice(const QString& receiver, const QString& notice) { Q_D(Session); if (d->options & Session::EchoMessages) { Buffer* buffer = d->createBuffer(receiver); emit buffer->noticeReceived(d->nick, notice, Irc::Buffer::EchoFlag); } return raw(QString(QLatin1String("NOTICE %1 :%2")).arg(Util::nickFromTarget(receiver), notice)); } /*! Sends a CTCP \a action to \a receiver. */ bool Session::ctcpAction(const QString& receiver, const QString& action) { Q_D(Session); if (d->options & Session::EchoMessages) { Buffer* buffer = d->createBuffer(receiver); emit buffer->ctcpActionReceived(d->nick, action, Irc::Buffer::EchoFlag); } return raw(QString(QLatin1String("PRIVMSG %1 :\x01" "ACTION %2\x01")).arg(Util::nickFromTarget(receiver), action)); } /*! Sends a CTCP \a request to \a receiver. */ bool Session::ctcpRequest(const QString& nick, const QString& request) { return raw(QString(QLatin1String("PRIVMSG %1 :\x01%2\x01")).arg(Util::nickFromTarget(nick), request)); } /*! Sends a CTCP \a reply to \a receiver. */ bool Session::ctcpReply(const QString& nick, const QString& reply) { return raw(QString(QLatin1String("NOTICE %1 :\x01%2\x01")).arg(Util::nickFromTarget(nick), reply)); } /*! Returns a new Irc::Buffer object to act as an IRC buffer for \a receiver. This virtual factory method can be overridden for example in order to make Irc::Session use a subclass of Irc::Buffer. */ Buffer* Session::createBuffer(const QString& receiver) { Buffer* buffer = new Buffer(receiver, this); #ifndef IRC_NO_DEPRECATED // TODO: for backwards compatibility, to be removed in 1.0 connect(buffer, SIGNAL(joined(QString)), SLOT(_q_joined(QString))); connect(buffer, SIGNAL(parted(QString, QString)), SLOT(_q_parted(QString, QString))); connect(buffer, SIGNAL(quit(QString, QString)), SLOT(_q_quit(QString, QString))); connect(buffer, SIGNAL(nickChanged(QString, QString)), SLOT(_q_nickChanged(QString, QString))); connect(buffer, SIGNAL(modeChanged(QString, QString, QString)), SLOT(_q_modeChanged(QString, QString, QString))); connect(buffer, SIGNAL(topicChanged(QString, QString)), SLOT(_q_topicChanged(QString, QString))); connect(buffer, SIGNAL(invited(QString, QString, QString)), SLOT(_q_invited(QString, QString, QString))); connect(buffer, SIGNAL(kicked(QString, QString, QString)), SLOT(_q_kicked(QString, QString, QString))); connect(buffer, SIGNAL(messageReceived(QString, QString)), SLOT(_q_messageReceived(QString, QString))); connect(buffer, SIGNAL(noticeReceived(QString, QString)), SLOT(_q_noticeReceived(QString, QString))); connect(buffer, SIGNAL(ctcpRequestReceived(QString, QString)), SLOT(_q_ctcpRequestReceived(QString, QString))); connect(buffer, SIGNAL(ctcpReplyReceived(QString, QString)), SLOT(_q_ctcpReplyReceived(QString, QString))); connect(buffer, SIGNAL(ctcpActionReceived(QString, QString)), SLOT(_q_ctcpActionReceived(QString, QString))); connect(buffer, SIGNAL(numericMessageReceived(QString, uint, QStringList)), SLOT(_q_numericMessageReceived(QString, uint, QStringList))); connect(buffer, SIGNAL(unknownMessageReceived(QString, QStringList)), SLOT(_q_unknownMessageReceived(QString, QStringList))); #endif // IRC_NO_DEPRECATED return buffer; } #ifndef IRC_NO_DEPRECATED // TODO: for backwards compatibility, to be removed in 1.0 /*! \deprecated Use Irc::Session::raw() */ bool Session::sendRaw(const QString& message) { qWarning() << "IrcSession::sendRaw(message) [slot] is DEPRECATED"; return Session::raw(message); } /*! \deprecated Use Irc::Session::join() */ bool Session::cmdJoin(const QString& channel, const QString& key) { qWarning() << "IrcSession::cmdJoin(channel, key) [slot] is DEPRECATED"; return Session::join(channel, key); } /*! \deprecated Use Irc::Session::part() */ bool Session::cmdPart(const QString& channel, const QString& reason) { qWarning() << "IrcSession::cmdPart(channel, reason) [slot] is DEPRECATED"; return Session::part(channel, reason); } /*! \deprecated Use Irc::Session::quit() */ bool Session::cmdQuit(const QString& reason) { qWarning() << "IrcSession::cmdQuit(reason) [slot] is DEPRECATED"; return Session::quit(reason); } /*! \deprecated Use Irc::Session::names() */ bool Session::cmdNames(const QString& channel) { qWarning() << "IrcSession::cmdNames(channel) [slot] is DEPRECATED"; return Session::names(channel); } /*! \deprecated Use Irc::Session::list() */ bool Session::cmdList(const QString& channel) { qWarning() << "IrcSession::cmdList(channel) [slot] is DEPRECATED"; return Session::list(channel); } /*! \deprecated Use Irc::Session::whois() */ bool Session::cmdWhois(const QString& nick) { qWarning() << "IrcSession::cmdWhois(nick) [slot] is DEPRECATED"; return Session::whois(nick); } /*! \deprecated Use Irc::Session::mode() */ bool Session::cmdMode(const QString& target, const QString& mode) { qWarning() << "IrcSession::cmdMode(target, mode) [slot] is DEPRECATED"; return Session::mode(target, mode); } /*! \deprecated Use Irc::Session::topic() */ bool Session::cmdTopic(const QString& channel, const QString& topic) { qWarning() << "IrcSession::cmdTopic(channel, topic) [slot] is DEPRECATED"; return Session::topic(channel, topic); } /*! \deprecated Use Irc::Session::invite() */ bool Session::cmdInvite(const QString& nick, const QString& channel) { qWarning() << "IrcSession::cmdInvite(nick, channel) [slot] is DEPRECATED"; return Session::invite(nick, channel); } /*! \deprecated Use Irc::Session::kick() */ bool Session::cmdKick(const QString& nick, const QString& channel, const QString& reason) { qWarning() << "IrcSession::cmdKick(nick, channel, reason) [slot] is DEPRECATED"; return Session::kick(nick, channel, reason); } /*! \deprecated Use Irc::Session::message() */ bool Session::cmdMessage(const QString& receiver, const QString& message) { qWarning() << "IrcSession::cmdMessage(receiver, message) [slot] is DEPRECATED"; return Session::message(receiver, message); } /*! \deprecated Use Irc::Session::notice() */ bool Session::cmdNotice(const QString& receiver, const QString& notice) { qWarning() << "IrcSession::cmdNotice(receiver, notice) [slot] is DEPRECATED"; return Session::notice(receiver, notice); } /*! \deprecated Use Irc::Session::ctcpAction() */ bool Session::cmdCtcpAction(const QString& receiver, const QString& action) { qWarning() << "IrcSession::cmdCtcpAction(receiver, action) [slot] is DEPRECATED"; return Session::ctcpAction(receiver, action); } /*! \deprecated Use Irc::Session::ctcpRequest() */ bool Session::cmdCtcpRequest(const QString& nick, const QString& request) { qWarning() << "IrcSession::cmdCtcpRequest(request) [slot] is DEPRECATED"; return Session::ctcpRequest(nick, request); } /*! \deprecated Use Irc::Session::ctcpReply() */ bool Session::cmdCtcpReply(const QString& nick, const QString& reply) { qWarning() << "IrcSession::cmdCtcpReply(reply) [slot] is DEPRECATED"; return Session::ctcpReply(nick, reply); } #endif // IRC_NO_DEPRECATED } #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug debug, const Irc::Session* session) { if (!session) return debug << "Irc::Session(0x0) "; debug.nospace() << session->metaObject()->className() << '(' << (void*) session; if (!session->objectName().isEmpty()) debug << ", name = " << session->objectName(); if (!session->host().isEmpty()) debug << ", host = " << session->host() << ", port = " << session->port(); debug << ')'; return debug.space(); } #endif // QT_NO_DEBUG_STREAM #include "moc_ircsession.cpp" mudlet-2.1/src/irc/src/ircbuffer.cpp0000644000175000017500000002375111513237311016771 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #include "ircbuffer.h" #include "ircbuffer_p.h" #include "ircsession.h" #include "ircsession_p.h" /*! \class Irc::Buffer ircbuffer.h \brief The Irc::Buffer class provides an IRC buffer. The Irc::Buffer class acts as a buffer for a single receiver. Receivers can be: \li the server \li channels \li queries. Server/channel/query specific messages are delivered to the corresponding buffer. \note Buffers are not intended to be instantiated directly, but via the virtual factory method Irc::Session::createBuffer(). */ /*! \enum Irc::Buffer::MessageFlag This enum describes available message flags. */ /*! \var Irc::Buffer::NoFlags No flags for the message. */ /*! \var Irc::Buffer::IdentifiedFlag Message was sent from an identified nick. */ /*! \var Irc::Buffer::EchoFlag Message echoed back from library. */ /*! \fn void Irc::Buffer::receiverChanged(const QString& receiver) This signal is emitted whenever \a receiver has changed. */ /*! \fn void Irc::Buffer::motdReceived(const QString& motd) This signal is emitted when message of the day \a motd has been received. */ /*! \fn void Irc::Buffer::joined(const QString& origin) This signal is emitted when \a origin has joined. */ /*! \fn void Irc::Buffer::parted(const QString& origin, const QString& message) This signal is emitted when \a origin has parted with \a message. */ /*! \fn void Irc::Buffer::quit(const QString& origin, const QString& message) This signal is emitted when \a origin has quit with \a message. */ /*! \fn void Irc::Buffer::nickChanged(const QString& origin, const QString& nick) This signal is emitted when \a origin has changed \a nick. */ /*! \fn void Irc::Buffer::modeChanged(const QString& origin, const QString& mode, const QString& args) This signal is emitted when \a origin has changed \a mode with \a args. */ /*! \fn void Irc::Buffer::topicChanged(const QString& origin, const QString& topic) This signal is emitted when \a origin has changed \a topic. */ /*! \fn void Irc::Buffer::invited(const QString& origin, const QString& receiver, const QString& channel) This signal is emitted when \a origin has invited \a receiver to \a channel. */ /*! \fn void Irc::Buffer::kicked(const QString& origin, const QString& nick, const QString& message) This signal is emitted when \a origin has kicked \a nick with \a message. */ /*! \fn void Irc::Buffer::messageReceived(const QString& origin, const QString& message, Irc::Buffer::MessageFlags flags = Irc::Buffer::NoFlags) This signal is emitted when \a origin has sent \a message. */ /*! \fn void Irc::Buffer::noticeReceived(const QString& origin, const QString& notice, Irc::Buffer::MessageFlags flags = Irc::Buffer::NoFlags) This signal is emitted when \a origin has sent \a notice. */ /*! \fn void Irc::Buffer::ctcpRequestReceived(const QString& origin, const QString& request, Irc::Buffer::MessageFlags flags = Irc::Buffer::NoFlags) This signal is emitted when \a origin has sent a CTCP \a request. */ /*! \fn void Irc::Buffer::ctcpReplyReceived(const QString& origin, const QString& reply, Irc::Buffer::MessageFlags flags = Irc::Buffer::NoFlags) This signal is emitted when \a origin has sent a CTCP \a reply. */ /*! \fn void Irc::Buffer::ctcpActionReceived(const QString& origin, const QString& action, Irc::Buffer::MessageFlags flags = Irc::Buffer::NoFlags) This signal is emitted when \a origin has sent a CTCP \a action. */ /*! \fn void Irc::Buffer::numericMessageReceived(const QString& origin, uint code, const QStringList& params) This signal is emitted when \a origin has sent a numeric message with \a code and \a params. */ /*! \fn void Irc::Buffer::unknownMessageReceived(const QString& origin, const QStringList& params) This signal is emitted when \a origin has sent an unknown message with \a params. */ namespace Irc { BufferPrivate::BufferPrivate() : q_ptr(0) { } void BufferPrivate::addName(QString name) { QString mode; if (name.startsWith(QLatin1Char('@'))) { mode = QLatin1Char('o'); name = name.remove(0, 1); } else if (name.startsWith(QLatin1Char('+'))) { mode = QLatin1Char('v'); name = name.remove(0, 1); } names.insert(name, mode); } void BufferPrivate::removeName(const QString& name) { names.remove(name); } void BufferPrivate::updateMode(const QString& name, const QString& mode) { bool add = true; QString updated = names.value(name); for (int i = 0; i < mode.size(); ++i) { QChar c = mode.at(i); switch (c.toAscii()) { case '+': add = true; break; case '-': add = false; break; default: if (add) { if (!updated.contains(c)) updated += c; } else { updated.remove(c); } break; } } names.insert(name, updated); } void BufferPrivate::setReceiver(const QString& rec, bool replace) { Q_Q(Buffer); if (receiver != rec) { Session* s = q->session(); if (s) { if (replace) s->d_func()->buffers.remove(receiver); s->d_func()->buffers.insert(rec, q); } receiver = rec; emit q->receiverChanged(receiver); } } /*! Constructs a new IRC buffer with \a receiver and \a parent. \sa Session::createBuffer() */ Buffer::Buffer(const QString& receiver, Session* parent) : QObject(parent), d_ptr(new BufferPrivate) { Q_D(Buffer); d->q_ptr = this; d->receiver = receiver; } Buffer::Buffer(BufferPrivate& dd, const QString& receiver, Session* parent) : QObject(parent), d_ptr(&dd) { Q_D(Buffer); d->q_ptr = this; d->receiver = receiver; } /*! Destructs the IRC buffer. */ Buffer::~Buffer() { Session* s = session(); if (s) s->d_func()->removeBuffer(this); Q_D(Buffer); delete d; } /*! Returns the session. */ Session* Buffer::session() const { return qobject_cast(parent()); } /*! Returns the receiver. */ QString Buffer::receiver() const { Q_D(const Buffer); return d->receiver; } /*! Returns the topic. */ QString Buffer::topic() const { Q_D(const Buffer); return d->topic; } /*! Returns the names. */ QStringList Buffer::names() const { Q_D(const Buffer); return d->names.keys(); } /*! Returns the modes of \a name. */ QString Buffer::modes(const QString& name) const { Q_D(const Buffer); return d->names.value(name); } /*! Returns the visual mode of \a name. */ QString Buffer::visualMode(const QString& name) const { Q_D(const Buffer); QString modes = d->names.value(name); if (modes.contains(QLatin1Char('o'))) return QLatin1String("@"); if (modes.contains(QLatin1Char('v'))) return QLatin1String("+"); return QString(); } /*! This convenience function sends a \a message to the buffer's receiver. \sa Session::message() */ bool Buffer::message(const QString& message) { Q_D(Buffer); Session* s = session(); return s && s->message(d->receiver, message); } /*! This convenience function sends a \a notice to the buffer's receiver. \sa Session::notice() */ bool Buffer::notice(const QString& notice) { Q_D(Buffer); Session* s = session(); return s && s->notice(d->receiver, notice); } /*! This convenience function sends a CTCP \a action to the buffers' receiver. \sa Session::ctcpAction() */ bool Buffer::ctcpAction(const QString& action) { Q_D(Buffer); Session* s = session(); return s && s->ctcpAction(d->receiver, action); } } #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug debug, const Irc::Buffer* buffer) { if (!buffer) return debug << "Irc::Buffer(0x0) "; debug.nospace() << buffer->metaObject()->className() << '(' << (void*) buffer; if (!buffer->objectName().isEmpty()) debug << ", name = " << buffer->objectName(); if (!buffer->receiver().isEmpty()) debug << ", receiver = " << buffer->receiver(); debug << ')'; return debug.space(); } #endif // QT_NO_DEBUG_STREAM #include "moc_ircbuffer.cpp" mudlet-2.1/src/irc/src/ircutil.cpp0000644000175000017500000002016711513237311016473 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #include "../include/ircutil.h" #include #include /*! \class Irc::Util ircutil.h \brief The Irc::Util class provides IRC related utility functions. */ static QRegExp URL_PATTERN(QLatin1String("((www\\.(?!\\.)|(ssh|fish|irc|(f|sf|ht)tp(|s))://)(\\.?[\\d\\w/,\\':~\\^\\?=;#@\\-\\+\\%\\*\\{\\}\\!\\(\\)]|&)+)|([-.\\d\\w]+@[-.\\d\\w]{2,}\\.[\\w]{2,})"), Qt::CaseInsensitive); namespace Irc { /*! Parses and returns the nick part from \a target. */ QString Util::nickFromTarget(const QString& target) { int index = target.indexOf(QLatin1Char('!')); return target.left(index); } /*! Parses and returns the host part from \a target. */ QString Util::hostFromTarget(const QString& target) { int index = target.indexOf(QLatin1Char('!')); return target.mid(index + 1); } /*! Converts \a message to HTML. This function parses the message and replaces IRC-style formatting like colors, bold and underline to the corresponding HTML formatting. Furthermore, this function detects URLs and replaces them with appropriate HTML hyperlinks. */ QString Util::messageToHtml(const QString& message) { QString processed = message; processed.replace(QLatin1Char('&'), QLatin1String("&")); processed.replace(QLatin1Char('<'), QLatin1String("<")); processed.replace(QLatin1Char('>'), QLatin1String(">")); processed.replace(QLatin1Char('\t'), QLatin1String(" ")); enum { None = 0x0, Bold = 0x1, Color = 0x2, Italic = 0x4, StrikeThrough = 0x8, Underline = 0x10, Inverse = 0x20 }; int state = None; int pos = 0; while (pos < processed.size()) { if (state & Color) { QString tmp = processed.mid(pos, 2); processed.remove(pos, 2); processed = processed.arg(colorNameFromCode(tmp.toInt())); state &= ~Color; pos += 2; continue; } QString replacement; switch (processed.at(pos).unicode()) { case '\x02': // bold if (state & Bold) replacement = QLatin1String(""); else replacement = QLatin1String(""); state ^= Bold; break; case '\x03': // color if (state & Color) replacement = QLatin1String(""); else replacement = QLatin1String(""); state ^= Color; break; /*case '\x09': // italic if (state & Italic) replacement = QLatin1String(""); else replacement = QLatin1String(""); state ^= Italic; break;*/ case '\x13': // strike-through if (state & StrikeThrough) replacement = QLatin1String(""); else replacement = QLatin1String(""); state ^= StrikeThrough; break; case '\x15': // underline case '\x1f': // underline if (state & Underline) replacement = QLatin1String(""); else replacement = QLatin1String(""); state ^= Underline; break; case '\x16': // inverse state ^= Inverse; break; case '\x0f': // none replacement = QLatin1String(""); state = None; break; default: break; } if (!replacement.isNull()) { processed.replace(pos, 1, replacement); pos += replacement.length(); } else { ++pos; } } pos = 0; while ((pos = URL_PATTERN.indexIn(processed, pos)) >= 0) { int len = URL_PATTERN.matchedLength(); QString href = processed.mid(pos, len); // Don't consider trailing > as part of the link. QString append; if (href.endsWith(QLatin1String(">"))) { append.append(href.right(4)); href.chop(4); } // Don't consider trailing comma or semi-colon as part of the link. if (href.endsWith(QLatin1Char(',')) || href.endsWith(QLatin1Char(';'))) { append.append(href.right(1)); href.chop(1); } // Don't consider trailing closing parenthesis part of the link when // there's an opening parenthesis preceding in the beginning of the // URL or there is no opening parenthesis in the URL at all. if (pos > 0 && href.endsWith(QLatin1Char(')')) && (processed.at(pos-1) == QLatin1Char('(') || !href.contains(QLatin1Char('(')))) { append.prepend(href.right(1)); href.chop(1); } // Qt doesn't support (?<=pattern) so we do it here if (pos > 0 && processed.at(pos-1).isLetterOrNumber()) { pos++; continue; } QString protocol; if (URL_PATTERN.cap(1).startsWith(QLatin1String("www."), Qt::CaseInsensitive)) protocol = QLatin1String("http://"); else if (URL_PATTERN.cap(1).isEmpty()) protocol = QLatin1String("mailto:"); QString source = href; source.replace(QLatin1String("&"), QLatin1String("&")); QString link = QString(QLatin1String("%3")).arg(protocol, source, href) + append; processed.replace(pos, len, link); pos += link.length(); } return processed; } /*! Converts \a code to a color name. */ QString Util::colorNameFromCode(int code) { switch (code) { case 0: return QLatin1String("white"); case 1: return QLatin1String("black"); case 2: return QLatin1String("navy"); case 3: return QLatin1String("green"); case 4: return QLatin1String("red"); case 5: return QLatin1String("maroon"); case 6: return QLatin1String("purple"); case 7: return QLatin1String("orange"); case 8: return QLatin1String("yellow"); case 9: return QLatin1String("lime"); case 10: return QLatin1String("darkcyan"); case 11: return QLatin1String("cyan"); case 12: return QLatin1String("blue"); case 13: return QLatin1String("magenta"); case 14: return QLatin1String("gray"); case 15: return QLatin1String("lightgray"); default: return QLatin1String("black"); } } } mudlet-2.1/src/irc/src/irc.cpp0000644000175000017500000007461411513237311015603 0ustar csmallcsmall/* * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com * * 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 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. */ #include "../include/irc.h" #include /*! \mainpage LibIrcClient-Qt - a cross-platform C++ IRC library \section Introduction LibIrcClient-Qt is a cross-platform IRC client library written with Qt 4. \section Installation To compile LibIrcClient-Qt, do the standard mantra: \code # qmake -config (debug|release) # make # sudo make install \endcode \section Usage Add the following line to your qmake .pro file: \code CONFIG += libircclient-qt \endcode */ /*! \namespace Irc \brief The Irc namespace contains miscellaneous identifiers used throughout the LibIrcClient-Qt library. */ /*! Returns the LibIrcClient-Qt version number as string in form M.N.P (M = major, N = minor, P = patch). */ /*! Returns the version number of LibIrcClient-Qt at run-time as a string (for example, "1.2.3"). This may be a different version than the version the application was compiled against. \sa IRC_VERSION_STR */ const char* Irc::version() { return IRC_VERSION_STR; } /*! Returns the numeric RFC \a code as a string or \a 0 if the code is unknown. */ const char* Irc::Rfc::toString(uint code) { int index = staticMetaObject.indexOfEnumerator("Numeric"); Q_ASSERT(index != -1); QMetaEnum enumerator = staticMetaObject.enumerator(index); return enumerator.valueToKey(code); } /*! \class Irc::Rfc irc.h \brief The Irc::Rfc class enumerates command responses and error replies. The Irc::Rfc class enumerates command responses and error replies as defined in RFC 1459 (Internet Relay Chat Protocol - http://www.ietf.org/rfc/rfc1459.txt). \sa Irc::Rfc::Numeric */ /*! \enum Irc::Rfc::Numeric This enum describes the numeric message codes defined in the RFC. */ /*! \var Irc::Rfc::RPL_WELCOME \brief 001 Welcome to the Internet Relay Network \!\\@\ The server sends replies 001 to 004 to a user upon successful registration. */ /*! \var Irc::Rfc::RPL_YOURHOST \brief 002 Your host is \, running version \ The server sends replies 001 to 004 to a user upon successful registration. */ /*! \var Irc::Rfc::RPL_CREATED \brief 003 This server was created \ The server sends replies 001 to 004 to a user upon successful registration. */ /*! \var Irc::Rfc::RPL_MYINFO \brief 004 \ \ \ \ The server sends replies 001 to 004 to a user upon successful registration. */ /*! \var Irc::Rfc::RPL_BOUNCE \brief 005 Try server \, port \ Sent by the server to a user to suggest an alternative server. This is often used when the connection is refused because the server is already full. */ /*! \var Irc::Rfc::RPL_USERHOST \brief 302 :*1\ *( No description available in RFC */ /*! \var Irc::Rfc::RPL_ISON \brief 303 :*1\ *( No description available in RFC */ /*! \var Irc::Rfc::RPL_AWAY \brief 301 \ :\ No description available in RFC */ /*! \var Irc::Rfc::RPL_UNAWAY \brief 305 :You are no longer marked as being away No description available in RFC */ /*! \var Irc::Rfc::RPL_NOWAWAY \brief 306 :You have been marked as being away These replies are used with the AWAY command (if allowed). RPL_AWAY is sent to any client sending a PRIVMSG to a client which is away. RPL_AWAY is only sent by the server to which the client is connected. Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the client removes and sets an AWAY message. */ /*! \var Irc::Rfc::RPL_WHOISUSER \brief 311 \ \ \ * :\ No description available in RFC */ /*! \var Irc::Rfc::RPL_WHOISSERVER \brief 312 \ \ :\ No description available in RFC */ /*! \var Irc::Rfc::RPL_WHOISOPERATOR \brief 313 \ :is an IRC operator No description available in RFC */ /*! \var Irc::Rfc::RPL_WHOISIDLE \brief 317 \ \ :seconds idle No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFWHOIS \brief 318 \ :End of WHOIS list No description available in RFC */ /*! \var Irc::Rfc::RPL_WHOISCHANNELS \brief 319 " :*( ( "\@" / "+" ) \ " " )" No description available in RFC */ /*! \var Irc::Rfc::RPL_WHOWASUSER \brief 314 \ \ \ * :\ No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFWHOWAS \brief 369 \ :End of WHOWAS When replying to a WHOWAS message, a server MUST use the replies RPL_WHOWASUSER, RPL_WHOISSERVER or ERR_WASNOSUCHNICK for each nickname in the presented list. At the end of all reply batches, there MUST be RPL_ENDOFWHOWAS (even if there was only one reply and it was an error). */ /*! \var Irc::Rfc::RPL_LIST \brief 322 \ \<# visible\> :\ No description available in RFC */ /*! \var Irc::Rfc::RPL_LISTEND \brief 323 :End of LIST Replies RPL_LIST, RPL_LISTEND mark the actual replies with data and end of the server's response to a LIST command. If there are no channels available to return, only the end reply MUST be sent. */ /*! \var Irc::Rfc::RPL_UNIQOPIS \brief 325 \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_CHANNELMODEIS \brief 324 \ \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_CHANNELURL \brief 329 \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_CHANNELCREATED \brief 329 \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_NOTOPIC \brief 331 \ :No topic is set No description available in RFC */ /*! \var Irc::Rfc::RPL_TOPIC \brief 332 \ :\ When sending a TOPIC message to determine the channel topic, one of two replies is sent. If the topic is set, RPL_TOPIC is sent back else RPL_NOTOPIC. */ /*! \var Irc::Rfc::RPL_TOPICSET \brief 333 \ \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_INVITING \brief 341 \ \ Returned by the server to indicate that the attempted INVITE message was successful and is being passed onto the end client. */ /*! \var Irc::Rfc::RPL_SUMMONING \brief 342 \ :Summoning user to IRC Returned by a server answering a SUMMON message to indicate that it is summoning that user. */ /*! \var Irc::Rfc::RPL_INVITELIST \brief 346 \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFINVITELIST \brief 347 \ :End of channel invite list When listing the 'invitations masks' for a given channel, a server is required to send the list back using the RPL_INVITELIST and RPL_ENDOFINVITELIST messages. A separate RPL_INVITELIST is sent for each active mask. After the masks have been listed (or if none present) a RPL_ENDOFINVITELIST MUST be sent. */ /*! \var Irc::Rfc::RPL_EXCEPTLIST \brief 348 \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFEXCEPTLIST \brief 349 \ :End of channel exception list When listing the 'exception masks' for a given channel, a server is required to send the list back using the RPL_EXCEPTLIST and RPL_ENDOFEXCEPTLIST messages. A separate RPL_EXCEPTLIST is sent for each active mask. After the masks have been listed (or if none present) a RPL_ENDOFEXCEPTLIST MUST be sent. */ /*! \var Irc::Rfc::RPL_VERSION \brief 351 \.\ \ :\ Reply by the server showing its version details. The \ is the version of the software being used (including any patchlevel revisions) and the \ is used to indicate if the server is running in "debug mode". The "comments" field may contain any comments about the version or further version details. */ /*! \var Irc::Rfc::RPL_WHOREPLY \brief 352 \ \ \ \ \ \[*][@|+] :\ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFWHO \brief 315 \ :End of WHO list The RPL_WHOREPLY and RPL_ENDOFWHO pair are used to answer a WHO message. The RPL_WHOREPLY is only sent if there is an appropriate match to the WHO query. If there is a list of parameters supplied with a WHO message, a RPL_ENDOFWHO MUST be sent after processing each list item with \ being the item */ /*! \var Irc::Rfc::RPL_NAMREPLY \brief 353 \ :[[@|+]\ [[@|+]\ [...]]] No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFNAMES \brief 366 \ :End of NAMES list To reply to a NAMES message, a reply pair consisting of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the server back to the client. If there is no channel found as in the query, then only RPL_ENDOFNAMES is returned. The exception to this is when a NAMES message is sent with no parameters and all visible channels and contents are sent back in a series of RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark the end. */ /*! \var Irc::Rfc::RPL_LINKS \brief 364 \ \ :\ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFLINKS \brief 365 \ :End of LINKS list In replying to the LINKS message, a server MUST send replies back using the RPL_LINKS numeric and mark the end of the list using an RPL_ENDOFLINKS reply. */ /*! \var Irc::Rfc::RPL_BANLIST \brief 367 \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFBANLIST \brief 368 \ :End of channel ban list When listing the active 'bans' for a given channel, a server is required to send the list back using the RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate RPL_BANLIST is sent for each active banmask. After the banmasks have been listed (or if none present) a RPL_ENDOFBANLIST MUST be sent. */ /*! \var Irc::Rfc::RPL_INFO \brief 371 :\ No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFINFO \brief 374 :End of INFO list A server responding to an INFO message is required to send all its 'info' in a series of RPL_INFO messages with a RPL_ENDOFINFO reply to indicate the end of the replies. */ /*! \var Irc::Rfc::RPL_MOTDSTART \brief 375 :- \ Message of the day - No description available in RFC */ /*! \var Irc::Rfc::RPL_MOTD \brief 372 :- \ No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFMOTD \brief 376 :End of MOTD command When responding to the MOTD message and the MOTD file is found, the file is displayed line by line, with each line no longer than 80 characters, using RPL_MOTD format replies. These MUST be surrounded by a RPL_MOTDSTART (before the RPL_MOTDs) and an RPL_ENDOFMOTD (after). */ /*! \var Irc::Rfc::RPL_YOUREOPER \brief 381 :You are now an IRC operator RPL_YOUREOPER is sent back to a client which has just successfully issued an OPER message and gained operator status. */ /*! \var Irc::Rfc::RPL_REHASHING \brief 382 \ :Rehashing If the REHASH option is used and an operator sends a REHASH message, an RPL_REHASHING is sent back to the operator. */ /*! \var Irc::Rfc::RPL_YOURESERVICE \brief 383 You are service \ Sent by the server to a service upon successful registration. */ /*! \var Irc::Rfc::RPL_TIME \brief 391 \ :\ When replying to the TIME message, a server MUST send the reply using the RPL_TIME format above. The string showing the time need only contain the correct day and time there. There is no further requirement for the time string. */ /*! \var Irc::Rfc::RPL_USERSSTART \brief 392 :UserID Terminal Host No description available in RFC */ /*! \var Irc::Rfc::RPL_USERS \brief 393 :\ \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_ENDOFUSERS \brief 394 :End of users No description available in RFC */ /*! \var Irc::Rfc::RPL_NOUSERS \brief 395 :Nobody logged in If the USERS message is handled by a server, the replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and RPL_NOUSERS are used. RPL_USERSSTART MUST be sent first, following by either a sequence of RPL_USERS or a single RPL_NOUSER. Following this is RPL_ENDOFUSERS. */ /*! \var Irc::Rfc::RPL_TRACELINK \brief 200 Link \ \ \ V\ \ \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACECONNECTING \brief 201 Try. \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACEHANDSHAKE \brief 202 H.S. \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACEUNKNOWN \brief 203 ???? \ [\] No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACEOPERATOR \brief 204 Oper \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACEUSER \brief 205 User \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACESERVER \brief 206 Serv \ \S \C \ \\@\ V\ No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACESERVICE \brief 207 Service \ \ \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACENEWTYPE \brief 208 \ 0 \ No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACECLASS \brief 209 Class \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACELOG \brief 261 File \ \ No description available in RFC */ /*! \var Irc::Rfc::RPL_TRACEEND \brief 262 \ \ :End of TRACE The RPL_TRACE* are all returned by the server in response to the TRACE message. How many are returned is dependent on the TRACE message and whether it was sent by an operator or not. There is no predefined order for which occurs first. Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and RPL_TRACEHANDSHAKE are all used for connections which have not been fully established and are either unknown, still attempting to connect or in the process of completing the 'server handshake'. RPL_TRACELINK is sent by any server which handles a TRACE message and has to pass it on to another server. The list of RPL_TRACELINKs sent in response to a TRACE command traversing the IRC network should reflect the actual connectivity of the servers themselves along that path. RPL_TRACENEWTYPE is to be used for any connection which does not fit in the other categories but is being displayed anyway. RPL_TRACEEND is sent to indicate the end of the list. */ /*! \var Irc::Rfc::RPL_STATSLINKINFO \brief 211 \ \ \ \ \ \ \
--- %b Abbreviated Month Name --- %B Full Month Name --- %d Day of Month --- %H Hour (24-hour format) --- %I Hour (12-hour format, requires %p as well) --- %p AM or PM --- %m 2-digit month (01-12) --- %M 2-digit minutes (00-59) --- %S 2-digit seconds (00-59) --- %y 2-digit year (00-99), will automatically prepend 20 so 10 becomes 2010 and not 1910. --- %Y 4-digit year. ---
function datetime:parse(source, format, as_epoch) if not format then format = "^%Y-%m-%d %H:%M:%S$" end local fmt = datetime:_get_pattern(format) local m = {fmt:tfind(source)} if m then m = m[3] dt = {} if m.year_half then dt.year = tonumber("20"..m.year_half) elseif m.year_full then dt.year = tonumber(m.year_full) end if m.month then dt.month = tonumber(m.month) elseif m.month_name then dt.month = datetime._month_names[m.month_name:lower()] elseif m.abbrev_month_name then dt.month = datetime._abbrev_month_names[m.abbrev_month_name:lower()] end dt.day = m.day_of_month if m.hour_12 then assert(m.ampm, "You must use %p (AM|PM) with %I (12-hour time)") if m.ampm == "PM" then dt.hour = 12 + tonumber(m.hour_12) else dt.hour = tonumber(m.hour_12) end else dt.hour = tonumber(m.hour_24) end dt.min = tonumber(m.minute) dt.sec = tonumber(m.second) dt.isdst = false if as_epoch then return os.time(dt) else return dt end else return nil end end ----------------------------------------------------------------------------- -- The database wrapper library ----------------------------------------------------------------------------- if package.loaded["luasql.sqlite3"] then require "luasql.sqlite3" end db = {} db.__autocommit = {} db.__schema = {} db.__conn = {} db.debug_sql = false -- NOT LUADOC -- Converts the type of a lua object to the equivalent type in SQL function db:_sql_type(value) local t = type(value) if t == "number" then return "REAL" elseif t == "nil" then return "NULL" elseif t == "table" and value._timestamp ~= nil then return "INTEGER" else return "TEXT" end end -- NOT LUADOC -- Converts a data value in Lua to its SQL equivalent; notably it will also escape single-quotes to -- prevent inadvertant SQL injection. function db:_sql_convert(value) local t = db:_sql_type(value) if value == nil then return "NULL" elseif t == "TEXT" then return '"'..value:gsub("'", "''")..'"' elseif t == "NULL" then return "NULL" elseif t == "INTEGER" then -- With db.Timestamp's, a value of false should be interpreted as nil. if value._timestamp == false then return "NULL" end return tostring(value._timestamp) else return tostring(value) end end -- NOT LUADOC -- Given a sheet name and the details of an index, this function will return a unique index name to -- add to the database. The purpose of this is to create unique index names as indexes are tested -- for existance on each call of db:create and not only on creation. That way new indexes can be -- added after initial creation. function db:_index_name(tbl_name, params) local t = type(params) if t == "string" then return "idx_" .. tbl_name .. "_c_" .. params elseif assert(t == "table", "Indexes must be either a string or a table.") then local parts = {"idx", tbl_name, "c"} for _, v in pairs(params) do parts[#parts+1] = v end return table.concat(parts, "_") end end -- NOT LUADOC -- This function returns true if all of the columns referenced in index_columns also exist within -- the sheet_columns table array. The purpose of this is to raise an error if someone tries to index -- a column which doesn't currently exist in the schema. function db:_index_valid(sheet_columns, index_columns) if type(index_columns) == "string" then if sheet_columns[index_columns] ~= nil then return true else return false end else for _, v in ipairs(index_columns) do if sheet_columns[v] == nil then echo("\n--> Bad index "..v) return false end end end return true end -- NOT LUADOC -- The column_spec is either a string or an indexed table. This function returns either "column" or -- "column1", "column2" for use in the column specification of INSERT. function db:_sql_columns(value) local colstr = '' local t = type(value) if t == "table" then col_chunks = {} for _, v in ipairs(value) do col_chunks[#col_chunks+1] = '"'..v:lower()..'"' end colstr = table.concat(col_chunks, ',') elseif assert(t == "string", "Must specify either a table array or string for index, not "..type(value)) then colstr = '"'..value:lower()..'"' end return colstr end -- NOT LUADOC -- This serves as a very similar function to db:_sql_columns, quoting column names properly but for -- uses outside of INSERTs. function db:_sql_fields(values) local sql_fields = {} for k, v in pairs(values) do sql_fields[#sql_fields+1] = '"'..k..'"' end return "("..table.concat(sql_fields, ",")..")" end -- NOT LUADOC -- This quotes values to be passed into an INSERT or UPDATE operation in a SQL list. Meaning, it turns -- {x="this", y="that", z=1} into ('this', 'that', 1). -- It is intelligent with data-types; strings are automatically quoted (with internal single quotes -- escaped), nil turned into NULL, timestamps converted to integers, and such. function db:_sql_values(values) local sql_values = {} for k, v in pairs(values) do local t = type(v) local s = "" if t == "string" then s = "'"..v:gsub("'", "''").."'" elseif t == "nil" then s = "NULL" elseif t == "table" and t._timestamp ~= nil then if not t._timestamp then return "NULL" else s = tostring(t._timestamp) end else s = tostring(v) end sql_values[#sql_values+1] = s end return "("..table.concat(sql_values, ",")..")" end --- TODO db:safe_name(name) -- On a filesystem level, names are restricted to being alphanumeric only. So, "my_database" becomes -- "mydatabase", and "../../../../etc/passwd" becomes "etcpasswd". This prevents any possible -- security issues with database names. function db:safe_name(name) name = name:gsub("[^%ad]", "") name = name:lower() return name end --- Creates and/or modifies an existing database. This function is safe to define at a top-level of a Mudlet --- script: in fact it is reccommended you run this function at a top-level without any kind of guards. --- If the named database does not exist it will create it. If the database does exist then it will add --- any columns or indexes which didn't exist before to that database. If the database already has all the --- specified columns and indexes, it will do nothing.

--- --- The database will be called Database_.db and will be stored in the --- Mudlet configuration directory.

--- --- Database 'tables' are called 'sheets' consistently throughout this documentation, to avoid confusion --- with Lua tables.

--- --- The schema table must be a Lua table array containing table dictionaries that define the structure and --- layout of each sheet.

--- --- For sheets with unique indexes, you may specify a _violations key to indicate how the db layer handle --- cases where the unique index is violated. The options you may use are: ---
---   FAIL - the default. A hard error is thrown, cancelling the script.
---   IGNORE - The command that would add a record that violates uniqueness just fails silently.
---   REPLACE - The old record which matched the unique index is dropped, and the new one is added to replace it.
---   
--- --- @usage Example bellow will create a database with two sheets; the first is kills and is used to track every successful kill, --- with both where and when the kill happened. It has one index, a compound index tracking the combination of name and area. --- The second sheet has two indexes, but one is unique: it isn't possible to add two items to the enemies sheet with the same name. ---
---   local mydb = db:create("combat_log",
---     {
---       kills = {
---         name = "",
---         area = "",
---         killed = db:Timestamp("CURRENT_TIMESTAMP"),
---         _index = {{"name", "area"}}
---       },
---       enemies = {
---         name = "",
---         city = "",
---         reason = "",
---         enemied = db:Timestamp("CURRENT_TIMESTAMP"),
---         _index = { "city" },
---         _unique = { "name" },
---         _violations = "IGNORE"
---       }
---     }
---   )
---   
--- Note that you have to use double {{ }} if you have composite index/unique constrain. function db:create(db_name, sheets) if not db.__env then db.__env = luasql.sqlite3() end db_name = db:safe_name(db_name) if not db.__conn[db_name] then db.__conn[db_name] = db.__env:connect(getMudletHomeDir() .. "/Database_" .. db_name .. ".db") db.__conn[db_name]:setautocommit(false) db.__autocommit[db_name] = true end db.__schema[db_name] = {} -- We need to separate the actual column configuration from the meta-configuration of the desired -- sheet. {sheet={"column"}} verses {sheet={"column"}, _index={"column"}}. In the former we are -- creating a database with a single field; in the latter we are also adding an index on that -- field. The db package reserves any key that begins with an underscore to be special and syntax -- for its own use. for s_name, sht in pairs(sheets) do options = {} if sht[1] ~= nil then t = {} for k, v in pairs(sht) do t[v] = nil end sht = t else for k, v in pairs(sht) do if string.starts(k, "_") then options[k] = v sht[k] = nil end end end if not options._violations then options._violations = "FAIL" end db.__schema[db_name][s_name] = {columns=sht, options=options} db:_migrate(db_name, s_name) end return db:get_database(db_name) end -- NOT LUADOC -- The migrate function is meant to upgrade an existing database live, to maintain a consistant -- and correct set of sheets and fields, along with their indexes. It should be safe to run -- at any time, and must not cause any data loss. It simply adds to what is there: in perticular -- it is not capable of removing indexes, columns, or sheets after they have been defined. function db:_migrate(db_name, s_name) local conn = db.__conn[db_name] local schema = db.__schema[db_name][s_name] local current_columns = {} -- The PRAGMA table_info command is a query which returns all of the columns currently -- defined in the specified table. The purpose of this section is to see if any new columns -- have been added. local cur = conn:execute("PRAGMA table_info('"..s_name.."')") if cur ~= 0 then local row = cur:fetch({}, "a") while row do current_columns[row.name:lower()] = row.type row = cur:fetch({}, "a") end cur:close() end -- The SQL definition of a column is: -- "column_name" column_type NULL -- The db module does not presently support columns that are required. Everything is optional, -- everything may be NULL / nil. -- If you specify a column's type, you also specify its default value. local sql_column = ', "%s" %s NULL' local sql_column_default = sql_column..' DEFAULT %s' if table.is_empty(current_columns) then -- At this point, we know that the specified table does not exist in the database and so we -- should create it. -- Every sheet has an implicit _row_id column. It is not presently (and likely never will be) -- supported to define the primary key of any sheet. local sql_chunks = {"CREATE TABLE ", s_name, '("_row_id" INTEGER PRIMARY KEY AUTOINCREMENT'} -- We iterate over every defined column, and add a line which creates it. for key, value in pairs(schema.columns) do local sql = "" if value == nil then sql = sql_column:format(key:lower(), db:_sql_type(value)) else sql = sql_column_default:format(key:lower(), db:_sql_type(value), db:_sql_convert(value)) end sql_chunks[#sql_chunks+1] = sql end sql_chunks[#sql_chunks+1] = ")" local sql = table.concat(sql_chunks, "") db:echo_sql(sql) conn:execute(sql) else -- At this point we know that the sheet already exists, but we are concerned if the current -- definition includes columns which may be added. local sql_chunks = {} local sql_add = 'ALTER TABLE %s ADD COLUMN "%s" %s NULL DEFAULT %s' for k, v in pairs(schema.columns) do k = k:lower() t = db:_sql_type(v) v = db:_sql_convert(v) -- Here we test it a given column exists in the sheet already, and if not, we add that -- column. if not current_columns[k] then local sql = sql_add:format(s_name, k, t, v) conn:execute(sql) db:echo_sql(sql) end end end -- On every invocation of db:create we run the code that creates indexes, as that code will -- do nothing if the specific indexes already exist. This is enforced by the db:_index_name -- function creating a unique index. -- -- Note that in no situation will an existing index be deleted. db:_migrate_indexes(conn, s_name, schema, current_columns) db:echo_sql("COMMIT") conn:commit() conn:execute("VACUUM") end -- NOT LUADOC -- Creates any indexes which do not yet exist in the given database. function db:_migrate_indexes(conn, s_name, schema, current_columns) local sql_create_index = "CREATE %s IF NOT EXISTS %s ON %s (%s);" local opt = {_unique = "UNIQUE INDEX", _index = "INDEX"} -- , _check = "CHECK"} for option_type, options in pairs(schema.options) do if option_type == "_unique" or option_type == "_index" then for _, value in pairs(options) do -- If an index references a column which does not presently exist within the schema -- this will fail. if db:_index_valid(current_columns, value) then --assert(db:_index_valid(current_columns, value), -- "In sheet "..s_name.." an index field is specified that does not exist.") sql = sql_create_index:format( opt[option_type], db:_index_name(s_name, value), s_name, db:_sql_columns(value) ) db:echo_sql(sql) conn:execute(sql) end end end end end --- Adds one or more new rows to the specified sheet. If any of these rows would violate a UNIQUE index, --- a lua error will be thrown and execution will cancel. As such it is advisable that if you use a UNIQUE --- index, you test those values before you attempt to insert a new row.

--- --- Each table is a series of key-value pairs to set the values of the sheet, but if any keys do not exist --- then they will be set to nil or the default value. As you can see, all fields are optional. --- --- @usage Adding one record. ---
---   db:add(mydb.enemies, {name="Bob Smith", city="San Francisco"})
---   
--- @usage Adding multiple records. ---
---   db:add(mydb.enemies,
---     {name="John Smith", city="San Francisco"},
---     {name="Jane Smith", city="San Francisco"},
---     {name="Richard Clark"}
---   )
---   
function db:add(sheet, ...) local db_name = sheet._db_name local s_name = sheet._sht_name assert(s_name, "First argument to db:add must be a proper Sheet object.") local conn = db.__conn[db_name] local sql_insert = "INSERT OR %s INTO %s %s VALUES %s" for _, t in ipairs({...}) do if t._row_id then -- You are not permitted to change a _row_id t._row_id = nil end local sql = sql_insert:format(db.__schema[db_name][s_name].options._violations, s_name, db:_sql_fields(t), db:_sql_values(t)) db:echo_sql(sql) assert(conn:execute(sql), "Failed to add item: this is probably a violation of a UNIQUE index or other constraint.") end if db.__autocommit[db_name] then conn:commit() end end --- Execute SQL select query against database. This only useful for some very specific cases.
--- Use db:fetch if possible instead - this function should not be normally used! --- --- @release post Mudlet 1.1.1 (TODO update before release) --- --- @usage Following will select all distinct area from my kills DB. ---
---   db:fetch_sql(mydb.kills, "SELECT distinct area FROM kills")
---   
--- --- @see db:fetch function db:fetch_sql(sheet, sql) local db_name = sheet._db_name local conn = db.__conn[db_name] db:echo_sql(sql) local cur = conn:execute(sql) if cur ~= 0 then local results = {} local row = cur:fetch({}, "a") while row do results[#results+1] = db:_coerce_sheet(sheet, row) row = cur:fetch({}, "a") end cur:close() return results else return nil end end --- Returns a table array containing a table for each matching row in the specified sheet. All arguments --- but sheet are optional. If query is nil, the entire contents of the sheet will be returned.

--- --- Query is a string which should be built by calling the various db: expression functions, such as db:eq, --- db:AND, and such. You may pass a SQL WHERE clause here if you wish, but doing so is very dangerous. --- If you don't know SQL well, its best to build the expression.

--- --- Query may also be a table array of such expressions, if so they will be AND'd together implicitly.

--- --- The results that are returned are not in any guaranteed order, though they are usually the same order --- as the records were inserted. If you want to rely on the order in any way, you must pass a value to the --- order_by field. This must be a table array listing the columns you want to sort by. --- It can be { "column1" }, or { "column1", "column2" }

--- --- The results are returned in ascending (smallest to largest) order; to reverse this pass true into the final field. --- --- @usage The first will fetch all of your enemies, sorted first by the city they reside in and then by their name. ---
---   db:fetch(mydb.enemies, nil, {"city", "name"})
---   
--- @usage The second will fetch only the enemies which are in San Francisco. ---
---   db:fetch(mydb.enemies, db:eq(mydb.enemies.city, "San Francisco"))
---   
--- @usage The third will fetch all the things you've killed in Undervault which have Drow in their name. ---
---   db:fetch(mydb.kills,
---      {
---         db:eq(mydb.kills.area, "Undervault"),
---         db:like(mydb.kills.name, "%Drow%")
---      }
---   )
---   
--- --- @see db:fetch_sql function db:fetch(sheet, query, order_by, descending) local s_name = sheet._sht_name local sql = "SELECT * FROM "..s_name if query then if type(query) == "table" then sql = sql.." WHERE "..db:AND(unpack(query)) else sql = sql.." WHERE "..query end end if order_by then local o = {} for _, v in ipairs(order_by) do assert(v.name, "You must pass field instances (as obtained from yourdb.yoursheet.yourfield) to sort.") o[#o+1] = v.name end sql = sql.." ORDER BY "..db:_sql_columns(o) if descending then sql = sql.." DESC" end end return db:fetch_sql(sheet, sql) end --- Returns the result of calling the specified aggregate function on the field and its sheet.

--- --- The supported aggregate functions are: ---
---   COUNT - Returns the total number of records that are in the sheet or match the query.
---   AVG   - Returns the average of all the numbers in the specified field.
---   MAX   - Returns the highest number in the specified field.
---   MIN   - Returns the lowest number in the specified field.
---   TOTAL - Returns the value of adding all the contents of the specified field.
---   
--- --- @param query optional --- --- @usage Example: ---
---   local mydb = db:get_database("my database")
---   echo(db:aggregate(mydb.enemies.name, "count"))
---   
function db:aggregate(field, fn, query) local db_name = field.database local s_name = field.sheet local conn = db.__conn[db_name] assert(type(field) == "table", "Field must be a field reference.") assert(field.name, "Field must be a real field reference.") local sql_chunks = {"SELECT", fn, "(", field.name, ")", "AS", fn, "FROM", s_name} if query then if type(query) == "table" then sql_chunks[#sql_chunks+1] = db:AND(unpack(query)) else sql_chunks[#sql_chunks+1] = query end end if order_by then local o = {} for _, v in ipairs(order_by) do assert(v.name, "You must pass field instances (as obtained from yourdb.yoursheet.yourfield) to sort.") o[#o+1] = v.name end sql_chunks[#sql_chunks+1] = "ORDER BY" sql_chunks[#sql_chunks+1] = db:_sql_columns(o) if descending then sql_chunks[#sql_chunks+1] = "DESC" end end local sql = table.concat(sql_chunks, " ") db:echo_sql(sql) local cur = conn:execute(sql) if cur ~= 0 then local row = cur:fetch({}, "a") local count = row[fn] cur:close() return count else return 0 end end --- Deletes rows from the specified sheet. The argument for query tries to be intelligent:
--- * if it is a simple number, it deletes a specific row by _row_id
--- * if it is a table that contains a _row_id (e.g., a table returned by db:get) it deletes just that record.
--- * Otherwise, it deletes every record which matches the query pattern which is specified as with db:get.
--- * If the query is simply true, then it will truncate the entire contents of the sheet.
--- --- @usage When passed an actual result table that was obtained from db:fetch, it will delete the record for that table. ---
---   enemies = db:fetch(mydb.enemies)
---   db:delete(mydb.enemies, enemies[1])
---   
--- @usage When passed a number, will delete the record for that _row_id. This example shows getting the row id from a table. ---
---   enemies = db:fetch(mydb.enemies)
---   db:delete(mydb.enemies, enemies[1]._row_id)
---   
--- @usage As above, but this example just passes in the row id directly. ---
---   db:delete(mydb.enemies, 5)
---   
--- @usage Here, we will delete anything which matches the same kind of query as db:fetch uses - namely, --- anyone who is in the city of San Francisco. ---
---   db:delete(mydb.enemies, db:eq(mydb.enemies.city, "San Francisco"))
---   
--- @usage And finally, we will delete the entire contents of the enemies table. ---
---   db:delete(mydb.enemies, true)
---   
function db:delete(sheet, query) local db_name = sheet._db_name local s_name = sheet._sht_name local conn = db.__conn[db_name] assert(query, "must pass a query argument to db:delete()") if type(query) == "number" then query = "_row_id = "..tostring(query) elseif type(query) == "table" then assert(query._row_id, "Passed a non-result table to db:delete, need a _row_id field to continue.") query = "_row_id = "..tostring(query._row_id) end local sql = "DELETE FROM "..s_name if query ~= true then sql = sql.." WHERE "..query end db:echo_sql(sql) assert(conn:execute(sql)) if db.__autocommit[db_name] then conn:commit() end end --- Merges the specified table array into the sheet, modifying any existing rows and adding any that don't exist. --- --- This function is a convenience utility that allows you to quickly modify a sheet, changing --- existing rows and add new ones as appropriate. It ONLY works on sheets which have a unique --- index, and only when that unique index is only on a single field. For more complex situations --- you'll have to do the logic yourself. --- --- The table array may contain tables that were either returned previously by db:fetch, or new tables --- that you've constructed with the correct fields, or any mix of both. Each table must have a value --- for the unique key that has been set on this sheet. --- --- @usage For example, consider this database: ---
---   local mydb = db:create("peopledb",
---     {
---       friends = {
---         name = "",
---         race = "",
---         level = 0,
---         city = "",
---         _index = { "city" },
---         _unique = { "name" }
---       }
---     }
---   )
---   
--- --- Here you have a database with one sheet, which contains your friends, their race, level, --- and what city they live in. Let's say you want to fetch everyone who lives in San Francisco, you could do: ---
---   local results = db:fetch(mydb.friends, db:eq(mydb.friends.city, "San Francisco"))
---   
--- --- The tables in results are static, any changes to them are not saved back to the database. --- But after a major radioactive cataclysm rendered everyone in San Francisco a mutant, --- you could make changes to the tables as so: ---
---   for _, friend in ipairs(results) do
---     friend.race = "Mutant"
---   end
---   
--- --- If you are also now aware of a new arrival in San Francisco, you could add them to that existing table array: ---
---   results[#results+1] = {name="Bobette", race="Mutant", city="San Francisco"}
---   
--- --- And commit all of these changes back to the database at once with: ---
---   db:merge_unique(mydb.friends, results)
---   
--- --- The db:merge_unique function will change the 'city' values for all the people who we previously fetched, but then add a new record as well. function db:merge_unique(sheet, tables) local db_name = sheet._db_name local s_name = sheet._sht_name local unique_options = db.__schema[db_name][s_name].options._unique assert(unique_options, "db:merge_unique only works on a sheet with a unique index.") assert(#unique_options == 1, "db:merge_unique only works on a sheet with a single unique index.") local unique_index = unique_options[1] local unique_key = "" if type(unique_index) == "table" then assert(#unique_index == 1, "db:merge_unique currently only supports sheets with a single unique index with a single column.") unique_key = unique_index[1] else unique_key = unique_index end db:echo_sql(":: Unique index = "..unique_key) local conn = db.__conn[db_name] local mydb = db:get_database(db_name) mydb:_begin() for _, tbl in ipairs(tables) do assert(tbl[unique_key], "attempting to db:merge_unique with a table that does not have the unique key.") local results = db:fetch(sheet, db:eq(sheet[unique_key], tbl[unique_key])) if results and results[1] then local t = results[1] for k, v in pairs(tbl) do t[k] = v end db:update(sheet, t) else db:add(sheet, tbl) end end mydb:_commit() mydb:_end() end --- This function updates a row in the specified sheet, but only accepts a row which has been previously --- obtained by db:fetch. Its primary purpose is that if you do a db:fetch, then change the value of a field --- or tow, you can save back that table. --- --- @usage This obtains a database reference, and queries the friends sheet for someone named Bob. As this --- returns a table array containing only one item, it assigns that one item to the local variable named bob. --- We then change the notes on Bob, and pass it into db:update() to save the changes back. ---
---   local mydb = db:get_database("my database")
---   local bob = db:fetch(mydb.friends, db:eq(mydb.friends.name, "Bob"))[1]
---   bob.notes = "He's a really awesome guy."
---   db:update(mydb.friends, bob)
---   
function db:update(sheet, tbl) assert(tbl._row_id, "Can only update a table with a _row_id") assert(not table.is_empty(tbl), "An empty table was passed to db:update") local db_name = sheet._db_name local s_name = sheet._sht_name local conn = db.__conn[db_name] local sql_chunks = {"UPDATE OR", db.__schema[db_name][s_name].options._violations, s_name, "SET"} local set_chunks = {} local set_block = [["%s" = %s]] for k, v in pairs(db.__schema[db_name][s_name]['columns']) do if tbl[k] then local field = sheet[k] set_chunks[#set_chunks+1] = set_block:format(k, db:_coerce(field, tbl[k])) end end sql_chunks[#sql_chunks+1] = table.concat(set_chunks, ",") sql_chunks[#sql_chunks+1] = "WHERE _row_id = "..tbl._row_id local sql = table.concat(sql_chunks, " ") db:echo_sql(sql) assert(conn:execute(sql)) if db.__autocommit[db_name] then conn:commit() end end --- The db:set function allows you to set a certain field to a certain value across an entire sheet. --- Meaning, you can change all of the last_read fields in the sheet to a certain value, or possibly only --- the last_read fields which are in a certain city. The query argument can be any value which is appropriate --- for db:fetch, even nil which will change the value for the specified column for EVERY row in the sheet. --- --- For example, consider a situation in which you are tracking how many times you find a certain --- type of egg during Easter. You start by setting up your database and adding an Eggs sheet, and --- then adding a record for each type of egg. ---
---   local mydb = db:create("egg database", {eggs = {color = "", last_found = db.Timestamp(false), found = 0}})
---   db:add(mydb.eggs,
---     {color = "Red"},
---     {color = "Blue"},
---     {color = "Green"},
---     {color = "Yellow"},
---     {color = "Black"}
---   )
---   
--- --- Now, you have three columns. One is a string, one a timestamp (that ends up as nil in the database), --- and one is a number.

--- --- You can then set up a trigger to capture from the mud the string, "You pick up a (.*) egg!", and you --- end up arranging to store the value of that expression in a variable called "myegg".

--- --- To increment how many we found, we will do this: ---
---   myegg = "Red" -- We will pretend a trigger set this.
---   db:set(mydb.eggs.found, db:exp("found + 1"), db:eq(mydb.eggs.color, myegg))
---   db:set(mydb.eggs.last_found, db.Timestamp("CURRENT_TIMESTAMP"), db:eq(mydb.eggs.color, myegg))
---   
--- --- This will go out and set two fields in the Red egg sheet; the first is the found field, which will --- increment the value of that field (using the special db:exp function). The second will update the --- last_found field with the current time.

--- --- Once this contest is over, you may wish to reset this data but keep the database around. --- To do that, you may use a more broad use of db:set as such: ---
---   db:set(mydb.eggs.found, 0)
---   db:set(mydb.eggs.last_found, nil)
---   
function db:set(field, value, query) local db_name = sheet._db_name local s_name = sheet._sht_name local conn = db.__conn[db_name] local sql_update = [[UPDATE OR %s %s SET "%s" = %s]] if query then sql_update = sql_update .. [[ WHERE %s]] end local sql = sql_update:format(db.__schema[db_name][s_name].options._violations, s_name, field.name, db:_coerce(field, value), query) db:echo_sql(sql) assert(conn:execute(sql)) if db.__autocommit[db_name] then conn:commit() end end --- This is a debugging function, which echos any SQL commands if db.debug_sql is true. --- You should not call this function directly from Mudlet. --- --- @usage Set following lua variable to enable SQL echos. ---
---   db.debug_sql=true
---   
function db:echo_sql(sql) if db.debug_sql then echo("\n"..sql.."\n") end end -- NOT LUADOC -- After a table so retrieved from the database, this function coerces values to -- their proper types. Specifically, numbers and datetimes become the proper -- types. function db:_coerce_sheet(sheet, tbl) if tbl then tbl._row_id = tonumber(tbl._row_id) for k, v in pairs(tbl) do if k ~= "_row_id" then local field = sheet[k] if field.type == "number" then tbl[k] = tonumber(tbl[k]) or tbl[k] elseif field.type == "datetime" then tbl[k] = db:Timestamp(datetime:parse(tbl[k], nil, true)) end end end return tbl end end -- NOT LUADOC -- The function converts a Lua value into its SQL representation, depending on the -- type of the specified field. Strings will be single-quoted (and single-quotes -- within will be properly escaped), numbers will be rendered properly, and such. function db:_coerce(field, value) if field.type == "number" then return tonumber(value) or "'"..value.."'" elseif field.type == "datetime" then if value._timestamp == false then return "NULL" else return tonumber(value._timestamp) or "'"..value.."'" end else return "'"..tostring(value):gsub("'", "''").."'" end end --- Returns a database expression to test if the field in the sheet is equal to the value. --- --- @see db:fetch function db:eq(field, value, case_insensitive) if case_insensitive then local v = db:_coerce(field, value):lower() return "lower("..field.name..") == "..v else local v = db:_coerce(field, value) return field.name.." == "..v end end --- Returns a database expression to test if the field in the sheet is NOT equal to the value. --- --- @see db:fetch function db:not_eq(field, value, case_insensitive) if case_insensitive then local v = db:_coerce(field, value):lower() return "lower("..field.name..") != "..v else local v = db:_coerce(field, value) return field.name.." != "..v end end --- Returns a database expression to test if the field in the sheet is less than the value. --- --- @see db:fetch function db:lt(field, value) local v = db:_coerce(field, value) return field.name.." < "..v end --- Returns a database expression to test if the field in the sheet is less than or equal to the value. --- --- @see db:fetch function db:lte(field, value) local v = db:_coerce(field, value) return field.name.." <= "..v end --- Returns a database expression to test if the field in the sheet is greater than to the value. --- --- @see db:fetch function db:gt(field, value) local v = db:_coerce(field, value) return field.name.." > "..v end --- Returns a database expression to test if the field in the sheet is greater than or equal to the value. --- --- @see db:fetch function db:gte(field, value) local v = db:_coerce(field, value) return field.name.." >= "..v end --- Returns a database expression to test if the field in the sheet is nil. --- --- @see db:fetch function db:is_nil(field) return field.name.." IS NULL" end --- Returns a database expression to test if the field in the sheet is not nil. --- --- @see db:fetch function db:is_not_nil(field) return field.name.." IS NOT NULL" end --- Returns a database expression to test if the field in the sheet matches the specified pattern.

--- --- LIKE patterns are not case-sensitive, and allow two wild cards. The first is an underscore which matches --- any single one character. The second is a percent symbol which matches zero or more of any character. ---
---   LIKE with "_" is therefore the same as the "." regular expression.
---   LIKE with "%" is therefore the same as ".*" regular expression.
---   
--- --- @see db:not_like --- @see db:fetch function db:like(field, value) local v = db:_coerce(field, value) return field.name.." LIKE "..v end --- Returns a database expression to test if the field in the sheet does not match the specified pattern. --- --- LIKE patterns are not case-sensitive, and allow two wild cards. The first is an underscore which matches --- any single one character. The second is a percent symbol which matches zero or more of any character. ---
---   LIKE with "_" is therefore the same as the "." regular expression.
---   LIKE with "%" is therefore the same as ".*" regular expression.
---   
--- --- @see db:like --- @see db:fetch function db:not_like(field, value) local v = db:_coerce(field, value) return field.name.." NOT LIKE "..v end --- Returns a database expression to test if the field in the sheet is a value between lower_bound and upper_bound. --- This only really makes sense for numbers and Timestamps. --- --- @see db:not_between --- @see db:fetch function db:between(field, left_bound, right_bound) local x = db:_coerce(field, left_bound) local y = db:_coerce(field, right_bound) return field.name.." BETWEEN "..x.." AND "..y end --- Returns a database expression to test if the field in the sheet is NOT a value between lower_bound and upper_bound. --- This only really makes sense for numbers and Timestamps. --- --- @see db:between --- @see db:fetch function db:not_between(field, left_bound, right_bound) local x = db:_coerce(field, left_bound) local y = db:_coerce(field, right_bound) return field.name.." NOT BETWEEN "..x.." AND "..y end --- Returns a database expression to test if the field in the sheet is one of the values in the table array.

--- --- First, note the trailing underscore carefully! It is required. --- --- @usage The following example illustrates the use of in_: --- This will obtain all of your kills which happened in the Undervault, Hell or Purgatory. Every db:in_ expression --- can be written as a db:OR, but that quite often gets very complex. ---
---   local mydb = db:get_database("my database")
---   local areas = {"Undervault", "Hell", "Purgatory"}
---   db:fetch(mydb.kills, db:in_(mydb.kills.area, areas))
---   
--- --- @see db:fetch function db:in_(field, tbl) local parts = {} for _, v in ipairs(tbl) do parts[#parts+1] = db:_coerce(field, v) end return field.name.." IN ("..table.concat(parts, ",")..")" end --- Returns a database expression to test if the field in the sheet is not one of the values in the table array. --- --- @see db:in_ --- @see db:fetch function db:not_in(field, tbl) local parts = {} for _, v in ipairs(tbl) do parts[#parts+1] = db:_coerce(field, v) end return field.name.." NOT IN ("..table.concat(parts, ",")..")" end --- Returns the string as-is to the database.

--- --- Use this function with caution, but it is very useful in some circumstances. One of the most --- common of such is incrementing an existing field in a db:set() operation, as so: ---
---   db:set(mydb.enemies, db:exp("kills + 1"), db:eq(mydb.enemies.name, "Ixokai"))
---   
--- --- This will increment the value of the kills field for the row identified by the name Ixokai.

--- --- But there are other uses, as the underlining database layer provides many functions you can call --- to do certain things. If you want to get a list of all your enemies who have a name longer then --- 10 characters, you may do: ---
---   db:fetch(mydb.enemies, db:exp("length(name) > 10"))
---   
--- --- Again, take special care with this, as you are doing SQL syntax directly and the library can't --- help you get things right. --- --- @see db:fetch function db:exp(text) return text end --- Returns a compound database expression that combines all of the simple expressions passed into it. --- These expressions should be generated with other db: functions such as db:eq, db:like, db:lt and the like.

--- --- This compound expression will only find items in the sheet if all sub-expressions match. --- --- @see db:fetch function db:AND(...) local parts = {} for _, expression in ipairs({...}) do parts[#parts+1] = "("..expression..")" end return "("..table.concat(parts, " AND ")..")" end --- Returns a compound database expression that combines both of the simple expressions passed into it. --- These expressions should be generated with other db: functions such as db:eq, db:like, db:lt and the like.

--- --- This compound expression will find any item that matches either the first or the second sub-expression. --- --- @see db:fetch function db:OR(left, right) if not string.starts(left, "(") then left = "("..left..")" end if not string.starts(right, "(") then right = "("..right..")" end return left.." OR "..right end --- TODO function db:close() for _, c in pairs(db.__conn) do c:close() end db.__env:close() end -- Timestamp support db.__Timestamp = {} db.__TimestampMT = { __index = db.__Timestamp } function db.__Timestamp:as_string(format) if not format then format = "%m-%d-%Y %H:%M:%S" end return os.date(format, self._timestamp) end function db.__Timestamp:as_table() return os.date("*t", self._timestamp) end function db.__Timestamp:as_number() return self._timestamp end --- TODO function db:Timestamp(ts, fmt) local dt = {} if type(ts) == "table" then dt._timestamp = os.time(ts) elseif type(ts) == "number" then dt._timestamp = ts elseif type(ts) == "string" and assert(ts == "CURRENT_TIMESTAMP", "The only strings supported by db.DateTime:new is CURRENT_TIMESTAMP") then dt._timestamp = "CURRENT_TIMESTAMP" elseif ts == nil then dt._timestamp = false else assert(nil, "Invalid value passed to db.Timestamp()") end return setmetatable(dt, db.__TimestampMT) end -- function db.Timestamp:new(ts, fmt) -- local dt = {} -- if type(ts) == "table" then -- dt._timestamp = os.time(ts) -- elseif type(ts) == "number" then -- dt._timestamp = ts -- elseif assert(ts == "CURRENT_TIMESTAMP", "The only strings supported by db.DateTime:new is CURRENT_TIMESTAMP") then -- dt._timestamp = "CURRENT_TIMESTAMP" -- end -- return setmetatable(dt, db.__TimestampMT) -- end db.Field = {} db.__FieldMT = { __index = db.Field } db.Sheet = {} db.__SheetMT = { __index = function(t, k) local v = rawget(db.Sheet, k) if v then return v end local db_name = rawget(t, "_db_name") local sht_name = rawget(t, "_sht_name") local f_name = k:lower() local errormsg = "Attempt to access field %s in sheet %s in database %s that does not exist." local field = db.__schema[db_name][sht_name]['columns'][f_name] if assert(field, errormsg:format(k, sht_name, db_name)) then type_ = type(field) if type_ == "table" and field._timestamp then type_ = "datetime" end rt = setmetatable({database=db_name, sheet=sht_name, type=type_, name=f_name}, db.__FieldMT) rawset(t,k,rt) return rt end end } db.Database = {} db.__DatabaseMT = { __index = function(t, k) local v = rawget(t, k) if v then return v end local v = rawget(db.Database, k) if v then return v end local db_name = rawget(t, "_db_name") if assert(db.__schema[db_name][k:lower()], "Attempt to access sheet '"..k:lower().."'in db '"..db_name.."' that does not exist.") then rt = setmetatable({_db_name = db_name, _sht_name = k:lower()}, db.__SheetMT) rawset(t,k,rt) return rt end end } function db.Database:_begin() db.__autocommit[self._db_name] = false end function db.Database:_commit() local conn = db.__conn[self._db_name] conn:commit() end function db.Database:_rollback() local conn = db.__conn[self._db_name] conn:rollback() end function db.Database:_end() db.__autocommit[self._db_name] = true end function db.Database._drop(s_name) local conn = db.__conn[self._db_name] local schema = db.__schema[self._db_name] if schema.options._index then for _, value in schema.options._index do conn:execute("DROP INDEX IF EXISTS " .. db:_index_name(s_name, value)) end end if schema.options._unique then for _, value in schema.options._unique do conn:execute("DROP INDEX IF EXISTS " .. db:_index_name(s_name, value)) end end conn:execute("DROP TABLE IF EXISTS "..s_name) conn:commit() end --- Returns a reference of an already existing database. This instance can be used to get references --- to the sheets (and from there, fields) that are defined within the database. You use these --- references to construct queries.

--- --- These references do not contain any actual data, they only point to parts of the database structure. --- --- @usage If a database has a sheet named enemies, you can obtain a reference to that sheet by simply doing: ---
---   local mydb = db:get_database("my database")
---   local enemies_ref = mydb.enemies
---   local name_ref = mydb.enemies.name
---   
function db:get_database(db_name) db_name = db:safe_name(db_name) assert(db.__schema[db_name], "Attempt to access database that does not exist.") db_inst = {_db_name = db_name} return setmetatable(db_inst, db.__DatabaseMT) end mudlet-2.1/src/old_mudlet-lua/lua/Logging.lua0000644000175000017500000002160512070466513020536 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Logging ---------------------------------------------------------------------------------- --
-- The basic design of this system is inspired by Python's logging module, which is
-- in turn inspired by log4J. However it does diverge from both.
--
-- The system creates a hierarchy of Loggers. A logger is the interface through which
-- code sends messages into the logging system. These messages can be simple strings
-- (commonly), or tables. In either case, the logger converts the message into an
-- event which is a table with certain standard keys, and a number of custom keys
-- that a logger can provide if it wishes.
--
-- Events have a number of standard properties: a timestamp, the name of the logger,
-- a severity(level) of the event, and the message itself.
--
-- By default, a logger has a level of ANY, which means that any events passed into
-- it are handled. You can set this level higher if you want, in which case the
-- logger will ignore any events which are of a lesser severity.
--
-- The level of severities are:
--   ANY, DEBUG, INFO, WARNING, ERROR, CRITICAL
--
-- A logger can have any number of handlers assigned to it.
--
-- A handler is responsible for actually writing/saving the data to the device,
-- and has a formatter associated with it.
--
-- Precisely what a "device" is depends on the type of handler; for a FileHandler,
-- its an actual filename. For a ConsoleHandler, its always just true as it writes
-- to the main console. For a MiniConsoleHandler, its the name of a miniconsole.
-- For a SheetHandler, its a db frontend sheet reference, e.g:
--    local mydb = db:get_database("tracker")
--    local device = mydb.kills
--
-- Each handler can also have its own severity, which means it will ignore any
-- events that are below that. This is useful if you want a logger to write only
-- important messages to the screen, but write more to a file.
--
-- Every logger has a "propagate" property which defaults to true. When true,
-- any events it handles will propagate to the parent logger. Its important to note
-- that a single event will only ever be written to a certain device once, so its
-- safe to propagate up the chain even if a parent logger would write things out
-- too. Whatever handler is assigned to the event first for a given device, wins.
-- 
logging = { -- Formatters are used to convert a logging event into a form which is appropriate -- for a certain kind of output device. Handlers actually write to such a device, -- but formatters are used by handlers. -- -- By default, there are four kinds of output devices that are supported and thus -- four default formatters that are used when outputting to devices of that type. -- A specific logger can override this for specific handlers, of course. -- -- The file default is used when writing to the actual filesystem, and is the -- most verbose output format. -- -- The console default is meant to write to the actual main mud window. -- -- The miniconsole is meant to write to miniconsoles, which we assume may be -- much smaller then the main window and so we write only the message by default. -- -- Finally, the sheet default is meant to be used with the handler that writes -- logging events to database sheets that are constructed with Mudlet's db -- frontend. This formatter is a table and not a string, and contains a key -- for each field in the table you want to add, and either a function that -- returns what value to write, or a string which is the key of the given -- event. _formatters = { default_file = "[${timestamp}] ${system} [${levelname:pad:8}]: ${message}\n", default_console = "[${system} ${levelname:pad:8}]: ${message}\n", default_miniconsole = "${message}\n", default_sheet = { timestamp = os.time, system="system", level="levelname", message="message" } }, _timestamp = { display = "%Y-%m-%d %H:%M:%S", filesystem = "%Y-%m-%d_%H.%M.%S" }, -- Levels: ANY = 0, DEBUG = 10, INFO = 20, WARNING = 30, ERROR = 40, CRITICAL = 50, _levelnames = { [0] = "ANY", [10] = "DEBUG", [20] = "INFO", [30] = "WARNING", [40] = "ERROR", [50] = "CRITICAL" } } -- Handler Interface logging.Handler = {} logging.__handlerMT = {__index=logging.Handler} --- logging.Handler:create(name, device) function logging.Handler:create(name, device) assert(name) assert(device) local handler = {_name=name, _device=device, emit=function() end} setmetatable(handler, logging.__handlerMT) return handler end --- logging.Handler:process(event) function logging.Handler:process(event) if event.level >= self.level then if self.emit then self.emit(self, event) end end end logging.FileHandler = {} --- logging.FileHandler:create(path) function logging.FileHandler:create(path) end -- Logger Interface logging.Logger = {} logging.__loggerMT = {__index=logging.Logger} --- logging.Logger:create(name, parent) function logging.Logger:create(name, parent) local logger = { _name=name, _parent=parent, _children={}, _handlers = {}, _customizers = {}, propagate=true, level=logging.ANY, } setmetatable(logger, logging.__loggerMT) return logger end --- logging.Logger:add_event_customizer(fn) function logging.Logger:add_event_customizer(fn) local customizers = self._customizers customizers[#customizers+1] = fn end --- logging.Logger:clear_event_customizers() function logging.Logger:clear_event_customizers() self._customizers = {} end --- logging.Logger:_prepare_event(event) function logging.Logger:_prepare_event(event) local name_chunks = {self._name} if self._name ~= "mudlet" then parent = self._parent while parent._name ~= "mudlet" do name_chunks[#name_chunks+1] = parent._name parent = parent._parent end end event.system = table.concat(name_chunks, ".") event.timestamp = os.time() return event end --- logging.Logger:_customize_event(event) function logging.Logger:_customize_event(event) for _, customizer in ipairs(self._customizers) do customizer(event) end return event end --- logging.Logger:_do_log(evt, extras, level) function logging.Logger:_do_log(evt, extras, level) if type(evt) == "string" then evt = {message=evt} else assert(type(evt)=="table", "The first argument to the logging call must be a string or table.") assert(evt.message, "If passing a table to the logging call, it must contain a message value.") end assert(level) evt.level = level if extras then for k, v in pairs(extras) do evt[k] = v end end self:_log_event(self:_prepare_event(evt)) end --- logging.Logger:_log_event(evt) function logging.Logger:_log_event(evt) local event = self._customize_event(evt) if event.level >= self.level then for _, handler in self._handlers do handler:process(event) end end if self.propagate then self._parent:_log_event(event) end end --- logging.Logger:debug(event, extras) function logging.Logger:debug(event, extras) return self:_do_log(event, extras, logging.DEBUG) end --- logging.Logger:info(event, extras) function logging.Logger:info(event, extras) return self:_do_log(event, extras, logging.INFO) end --- logging.Logger:warning(event, extras) function logging.Logger:warning(event, extras) return self:_do_log(event, extras, logging.WARNING) end --- logging.Logger:error(event, extras) function logging.Logger:error(event, extras) return self:_do_log(event, extras, logging.ERROR) end --- logging.Logger:critical(event, extras) function logging.Logger:critical(event, extras) return self:_do_log(event, extras, logging.CRITICAL) end -- General Logging System logging._root = logging.Logger:create("mudlet", nil) --- logging:get_logger(name) function logging:get_logger(name) local name = name or "mudlet" local loggers = name:split(".") local parent = logging._root for _, logger in ipairs(loggers) do if parent._children[logger] == nil then local child = logging.Logger:create(logger, parent) parent._children[logger] = child parent = child else parent = parent._children[logger] end end return parent end --- logging:format_event(event, formatter) function logging:format_event(event, formatter) local format = formatter or logging._formatters.default_file local pattern = [[(\${(.-)})]] local output = format:gsub(pattern, function(complete, chunk) local compound = {chunk:match("([^:]+):([^:]+):(.+)")} if table.is_empty(compound) then return event[chunk] or complete else local value = event[compound[1]] or complete if compound[2] == "pad" then return string.format("%"..compound[3].."s", value) else return complete end end end ) return output end logging:format_event({timestamp=os.date(logging._timestamp.display, os.time()), system="crucible.core", levelname="ERROR", message="Err"}) local log = logging:get_logger("crucible.core") local root = logging:get_logger() log:add_event_customizer( function(evt) evt["test"] = 1 end ) mudlet-2.1/src/old_mudlet-lua/lua/DebugTools.lua0000644000175000017500000001405212070466513021215 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Debug Tools ---------------------------------------------------------------------------------- --- Function colorizes all matched regex capture groups on the screen. --- This is very handy if you make complex regex and want to see what really matches in the text. --- --- @see matches function showCaptureGroups() for k, v in pairs ( matches ) do selectCaptureGroup( tonumber(k) ) setFgColor( math.random(0,255), math.random(0,255), math.random(0,255) ) setBgColor( math.random(0,255), math.random(0,255), math.random(0,255) ) end end --- Prints the content of the table multimatches[n][m] to the screen. This is meant --- as a tool to help write multiline trigger scripts. This helps you to easily see --- what your multiline trigger actually captured in all regex. You can use these values --- directly in your script by referring to it with multimatches[regex-number][capturegroup]. --- --- @usage Just call this s function from your trigger to show the info. ---
---   showMultimatches()
---   
--- --- @see multimatches function showMultimatches() echo("\n-------------------------------------------------------"); echo("\nThe table multimatches[n][m] contains:"); echo("\n-------------------------------------------------------"); for k,v in ipairs(multimatches) do echo("\nregex " .. k .. " captured: (multimatches["..k .."][1-n])"); for k2,v2 in ipairs(v) do echo("\n key="..k2.." value="..v2); end end echo("\n-------------------------------------------------------\n"); end --- get the Lua keywords as a set-like table. -- So res["and"] etc would be true. -- @return a table local function get_keywords () if not lua_keyword then lua_keyword = { ["and"] = true, ["break"] = true, ["do"] = true, ["else"] = true, ["elseif"] = true, ["end"] = true, ["false"] = true, ["for"] = true, ["function"] = true, ["if"] = true, ["in"] = true, ["local"] = true, ["nil"] = true, ["not"] = true, ["or"] = true, ["repeat"] = true, ["return"] = true, ["then"] = true, ["true"] = true, ["until"] = true, ["while"] = true } end return lua_keyword end local function quote_if_necessary (v) if not v then return '' else if v:find ' ' then v = '"'..v..'"' end end return v end local keywords local function is_identifier (s) return type(s) == 'string' and s:find('^[%a_][%w_]*$') and not keywords[s] end local function quote (s) if type(s) == 'table' then return pretty.write(s,'') else return ('%q'):format(tostring(s)) end end local function index (numkey,key) if not numkey then key = quote(key) end return '['..key..']' end --- Create a string representation of a Lua table. (From Steve Donovans Penlight library) -- This function never fails, but may complain by returning an -- extra value. Normally puts out one item per line, using -- the provided indent; set the second parameter to '' if -- you want output on one line. -- @param tbl {table} Table to serialize to a string. -- @param space {string} (optional) The indent to use. -- Defaults to two spaces; make it the empty string for no indentation -- @param not_clever {bool} (optional) Use for plain output, e.g {['key']=1}. -- Defaults to false. -- @return a string -- @return a possible error message local append = table.insert function display (tbl,space,not_clever) if type(tbl) ~= 'table' then echo(tostring(tbl)..'\n') return end if not keywords then keywords = get_keywords() end local set = ' = ' if space == '' then set = '=' end space = space or ' ' local lines = {} local line = '' local tables = {} local function put(s) if #s > 0 then line = line..s end end local function putln (s) if #line > 0 then line = line..s append(lines,line) line = '' else append(lines,s) end end local function eat_last_comma () local n,lastch = #lines local lastch = lines[n]:sub(-1,-1) if lastch == ',' then lines[n] = lines[n]:sub(1,-2) end end local writeit writeit = function (t,oldindent,indent) local tp = type(t) if tp ~= 'string' and tp ~= 'table' then putln(quote_if_necessary(tostring(t))..',') elseif tp == 'string' then if t:find('\n') then putln('[[\n'..t..']],') else putln(quote(t)..',') end elseif tp == 'table' then if tables[t] then putln(',') return end tables[t] = true local newindent = indent..space putln('{') local used = {} if not not_clever then for i,val in ipairs(t) do put(indent) writeit(val,indent,newindent) used[i] = true end end for key,val in pairs(t) do local numkey = type(key) == 'number' if not_clever then key = tostring(key) put(indent..index(numkey,key)..set) writeit(val,indent,newindent) else if not numkey or not used[key] then -- non-array indices if numkey or not is_identifier(key) then key = index(numkey,key) end put(indent..key..set) writeit(val,indent,newindent) end end end eat_last_comma() putln(oldindent..'},') else putln(tostring(t)..',') end end writeit(tbl,'',space) eat_last_comma() echo(table.concat(lines,#space > 0 and '\n' or '')..'\n') end mudlet-2.1/src/old_mudlet-lua/lua/StringUtils.lua0000644000175000017500000001076012070466513021437 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet String Utils ---------------------------------------------------------------------------------- --- Cut string to specified maximum length. --- --- @release post Mudlet 1.1.1 (TODO update before release) --- --- @usage Following call will return 'abc'. ---
---   string.cut("abcde", 3)
---   
--- @usage You can easily pad string to certain length. --- Example bellow will print 'abcde ' e.g. pad/cut string to 10 characters. ---
---   local s = "abcde"
---   s = string.cut(s .. "          ", 10)   -- append 10 spaces
---   echo("'" .. s .. "'")
---   
function string.cut(s, maxLen) if string.len(s) > maxLen then return string.sub(s, 1, maxLen) else return s end end --- Enclose string by long brackets.
function string.enclose(s, maxlevel) s = "["..s.."]" local level = 0 while 1 do if maxlevel and level == maxlevel then error( "error: maxlevel too low, "..maxlevel ) elseif string.find( s, "%["..string.rep( "=", level ).."%[" ) or string.find( s, "]"..string.rep( "=", level ).."]" ) then level = level + 1 else return "["..string.rep( "=", level )..s..string.rep( "=", level ).."]" end end end --- Test if string is ending with specified suffix. --- --- @see string.starts function string.ends(String, Suffix) return Suffix=='' or string.sub(String,-string.len(Suffix))==Suffix end --- Generate case insensitive search pattern from string. --- --- @release post Mudlet 1.1.1 (TODO update before release) --- --- @return case insensitive pattern string --- --- @usage Following example will generate and print "123[aA][bB][cC]" string. ---
---   echo(string.genNocasePattern("123abc"))
---   
function string.genNocasePattern(s) s = string.gsub(s, "%a", function (c) return string.format("[%s%s]", string.lower(c), string.upper(c)) end) return s end --- Return first matching substring or nil. --- --- @release post Mudlet 1.1.1 (TODO update before release) --- --- @return nil or first matching substring --- --- @usage Following example will print: "I did find: Troll" string. ---
---   local match = string.findPattern("Troll is here!", "Troll")
---   if match then
---      echo("I did find: " .. match)
---   end
---   
--- @usage This example will find substring regardless of case. ---
---   local match = string.findPattern("Troll is here!", string.genNocasePattern("troll"))
---   if match then
---      echo("I did find: " .. match)
---   end
---   
--- --- @see string.genNocasePattern function string.findPattern(text, pattern) if string.find(text, pattern, 1) then return string.sub(text, string.find(text, pattern, 1)) else return nil end end --- Splits a string into a table by the given delimiter. --- --- @usage Split string by ", " delimiter. ---
---   names = "Alice, Bob, Peter"
---   name_table = names:split(", ")
---   display(name_table)
---   
--- --- Previous code will print out: ---
---   table {
---     1: 'Alice'
---     2: 'Bob'
---     3: 'Peter'
---   }
---   
--- --- @return array with split strings function string:split(delimiter) local result = { } local from = 1 local delim_from, delim_to = string.find( self, delimiter, from ) while delim_from do table.insert( result, string.sub( self, from , delim_from-1 ) ) from = delim_to + 1 delim_from, delim_to = string.find( self, delimiter, from ) end table.insert( result, string.sub( self, from ) ) return result end --- Test if string is starting with specified prefix. --- --- @see string.ends function string.starts(String, Prefix) return string.sub(String,1,string.len(Prefix))==Prefix end --- Capitalize first character in a string. --- --- @usage Variable testname is now Anna. ---
---   testname = string.title("anna")
---   
--- @usage Example will set test to "Bob". ---
---   test = "bob"
---   test = string.title(test)
---   
function string:title() self = self:gsub("^%l", string.upper, 1) return self end --- Trim string (remove all white spaces around string). --- --- @release post Mudlet 1.1.1 (TODO update before release) --- --- @usage Example will print 'Troll is here!'. ---
---   local str = string.trim("  Troll is here!  ")
---   echo("'" .. str .. "'")
---   
function string.trim(s) if s then return string.gsub(s, "^%s*(.-)%s*$", "%1") else return s end end mudlet-2.1/src/old_mudlet-lua/lua/geyser/0000755000175000017500000000000012070466513017737 5ustar csmallcsmallmudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserLabel.lua0000644000175000017500000000727112070466513022647 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Represents a label like we all know and love. -- @class table -- @name Geyser.Label -- @field fillBg 1 if the background is to be filled, 0 for no background. Geyser.Label = Geyser.Window:new({ name = "LabelClass", format = "", args = "", fillBg = 1, }) --- Prints a message to the window. All parameters are optional and if not -- specified will use the last set value. -- @param message The message to print. Can contain html formatting. -- @param color The color to use. -- @param format A format list to use. 'c' - center, 'b' - bold, 'i' - italics, -- 'u' - underline, '##' - font size. For example, "cb18" -- specifies center bold 18pt font be used. Order doesn't matter. function Geyser.Label:echo(message, color, format) message = message or self.message self.message = self.message format = format or self.format self.format = format color = color or self.fgColor self.fgColor = color local fs = "" -- check for formatting commands if format then if string.find(format, "b") then message = "" .. message .. "" end if string.find(format, "i") then message = "" .. message .. "" end if string.find(format, "c") then message = "
" .. message .. "" end if string.find(format, "u") then message = "" .. message .. "" end fs = string.gmatch(format, "%d+")() if not fs then fs = tostring(self.fontSize) end fs = "font-size: " .. fs .. "pt; " end message = [[
]] .. message .. [[
]] echo(self.name, message) end function Geyser.Label:setFgColor(color) self:echo(nil,color,nil) end function Geyser.Label:setFormat(format) self:echo(nil,nil,format) end --- Sets a background image for this label. -- @param imageFileName The image to use for a background image. function Geyser.Label:setBackgroundImage (imageFileName) setBackgroundImage(self.name, imageFileName) end --- Sets a tiled background image for this label. -- @param imageFileName The image to use for a background image. function Geyser.Label:setTiledBackgroundImage (imageFileName) self:setStyleSheet("background-image: url(" .. imageFileName .. ");") end --- Sets a callback to be used when this label is clicked. -- @param func The function to use. -- @param ... Parameters to pass to the function. Must be strings or numbers. function Geyser.Label:setClickCallback (func, ...) setLabelClickCallback(self.name, func, ...) end --- Sets the style sheet of the label -- @param css The style sheet string function Geyser.Label:setStyleSheet(css) setLabelStyleSheet(self.name, css) end -- Save a reference to our parent constructor Geyser.Label.parent = Geyser.Window -- Overridden constructor function Geyser.Label:new (cons, container) -- Initiate and set label specific things cons = cons or {} cons.type = cons.type or "label" -- Call parent's constructor local me = self.parent:new(cons, container) -- Set the metatable. setmetatable(me, self) self.__index = self -- Create the label using primitives createLabel(me.name, me:get_x(), me:get_y(), me:get_width(), me:get_height(), me.fillBg) -- Set any defined colors Geyser.Color.applyColors(me) me:echo() -- Set up the callback if we have one if me.callback then me:setClickCallback(me.callback, me.args) end --print(" New in " .. self.name .. " : " .. me.name) return me end mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserGeyser.lua0000644000175000017500000000456712070466513023073 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --================================================== -- Create the Geyser Root Container --================================================== --- Create the Geyser namespace. -- Geyser is considered to be a "container window" for the purposes -- of default limits for new windows, in fact, it is the root container -- window, and is the metatable for Geyser.Container. It has the -- minimum number of functions needed to behave as a Container. Geyser = Geyser or {i = 0, x = 0, y = 0} --Layout policies. Fixed = Do not stretch/shrink, Dynamic = Do stretch/shrink Geyser.Fixed, Geyser.Dynamic = 0, 1 Geyser.width, Geyser.height = getMainWindowSize() Geyser.get_x = function () return 0 end Geyser.get_y = function () return 0 end Geyser.get_width = function () return getMainWindowSize() end Geyser.get_height = function () local w,h = getMainWindowSize() return h end Geyser.name = "Geyser Root Window" Geyser.__index = Geyser -- Create the window list for updates Geyser.windowList = Geyser.windowList or {} Geyser.windows = Geyser.windows or {} Geyser.defer_updates = false function Geyser:begin_update() self.defer_updates = true end function Geyser:end_update() self.defer_updates = false self:reposition() end function Geyser:reposition() if not self.defer_updates then GeyserReposition() end end --- Add a window to the list that this container manages. -- @param window The window to add this container function Geyser:add (window, cons) cons = cons or window -- 'cons' is optional -- Stop other container from controlling this window if window.container then window.container:remove(window) end -- Assume control of this window window.container = self self.windowList[window.name] = window table.insert(self.windows, window.name) Geyser.set_constraints(window, cons, self) if not self.defer_updates then window:reposition() end window:show() end --- Removes a window from the list that it manages -- @param window The window to remove from this container's -- windowList function Geyser:remove (window) self.windowList[window.name] = nil index = table.index_of(self.windows, window.name) or 0 table.remove(self.windows, index) end mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserGauge.lua0000644000175000017500000001065412070466513022657 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Represents a gauge that can be either vertical or horizontal. -- @class table -- @name Geyser.Gauge -- @field value Percentage value of how "full" the gauge is. -- @field orientation "horizontal" is the default and creates a horizontal -- gauge that fills from left to right. "vertical" creates -- a gauge that fills from bottom to top. "goofy" is -- horizontal but fills right to left. "batty" is -- vertical but fills from top to bottom. -- @field color Color base for this gauge. Default is #808080 Geyser.Gauge = Geyser.Container:new({ name = "GaugeClass", value = 100, -- ranges from 0 to 100 color = "#808080", orientation = "horizontal"}) --- Sets the gauge amount. -- @param currentValue Current numeric value, or if maxValue is ommitted, then -- it is assumed that currentValue is a value between 0 and 100 and is -- used to set the gauge. -- @param maxValue Maximum numeric value. Optionally nil, see above. -- @param text The text to display on the gauge, it is optional. function Geyser.Gauge:setValue (currentValue, maxValue, text) -- Use sensible defaults for missing parameters. if currentValue < 0 then currentValue = 0 end if maxValue then self.value = currentValue/maxValue * 100 else self.value = currentValue end -- Update gauge in the requested orientation local shift = tostring(self.value) .. "%" if self.orientation == "horizontal" then self.front:resize(shift, "100%") elseif self.orientation == "vertical" then self.front:move("0px", "-" .. shift) self.front:resize("100%", "-0px") -- bind to bottom container border elseif self.orientation == "goofy" then self.front:move("-" .. shift, "0px") self.front:resize("-0px", "100%") -- bind to right container border else -- batty self.front:resize("100%", shift) end if text then self.front:echo(text) self.back:echo(text) end end --- Sets the gauge color. -- @param r The red component, or a named color like "green". -- @param g the green component, or nil if using a named color. -- @param b the blue component, or nil if using a named color. -- @param text The text to display on the gauge, it is optional. function Geyser.Gauge:setColor (r, g, b, text) r,g,b = Geyser.Color.parse(r,g,b) self.front:setColor(r,g,b) self.back:setColor(r,g,b,100) if text then self.front:echo(text) self.back:echo(text) end end --- Sets the text on the gauge. -- @param text The text to set. function Geyser.Gauge:setText (text) if text then self.front:echo(text) self.back:echo(text) end end -- Sets the style sheet for the gauge -- @param css Style sheet for the front label -- @param cssback Style sheet for the back label function Geyser.Gauge:setStyleSheet(css, cssback) self.front:setStyleSheet(css) self.back:setStyleSheet(cssback or css) end -- Save a reference to our parent constructor Geyser.Gauge.parent = Geyser.Container -- Overridden constructor function Geyser.Gauge:new (cons, container) -- Initiate and set gauge specific things cons = cons or {} cons.type = cons.type or "gauge" -- Call parent's constructor local me = self.parent:new(cons, container) -- Set the metatable. setmetatable(me, self) self.__index = self ----------------------------------------------------------- -- Now create the Gauge using primitives and tastey classes -- Set up the constraints for the front label, the label that changes size to -- indicated levels in the gauges. local front = Geyser.copyTable(cons) front.name = me.name .. "_front" front.color = me.color front.x, front.y, front.width, front.height = 0,0,"100%","100%" -- Set up the constraints for the back label, which is always the size of the gauge. local back = Geyser.copyTable(front) back.name = me.name .. "_back" local br, bg, bb = Geyser.Color.parse(me.color) back.color = Geyser.Color.hexa(br,bg,bb,100) -- Create back first so that the labels are stacked correctly. me.back = Geyser.Label:new(back, me) me.front = Geyser.Label:new(front, me) --print(" New in " .. self.name .. " : " .. me.name) return me end mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserMiniConsole.lua0000644000175000017500000001103012070466513024033 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Represents a miniconsole primitive -- @class table -- @name Geyser.MiniConsole -- @field wrapAt Where line wrapping occurs. Default is 300 characters. Geyser.MiniConsole = Geyser.Window:new({ name = "MiniConsoleClass", wrapAt = 300,}) --- Replaces the currently selected text. -- @param with The text to use as a replacement. function Geyser.MiniConsole:replace (with) replace(self.name, with) end --- Sets the size of this miniconsole's buffer. -- @param linesLimit The number of lines to store - same limitations as Mudlet -- function of the same name. -- @param sizeOfBatchDeletion See Mudlet documentation. (I don't know offhand =) function Geyser.MiniConsole:setBufferSize (linesLimit, sizeOfBatchDeletion) setConsoleBufferSize(self.name, linesLimit, sizeOfBatchDeletion) end --- Sets the point at which text is wrapped in this miniconsole -- @param wrapAt The number of characters to start wrapping. function Geyser.MiniConsole:setWrap (wrapAt) if wrapAt then self.wrapAt = wrapAt end setWindowWrap(self.name, self.wrapAt) end --- Sets the text format for this window. Note that the *echo() -- functions will override these settings. -- @param r1 The red foreground component. -- @param g1 The green foreground component. -- @param b1 The blue foreground component. -- @param r2 The red background component. -- @param g2 The green background component. -- @param b2 The blue background component. -- @param bold The bolded status. 1 is bold, 0 is normal. -- @param underline The underlined status. 1 is underlined, 0 is normal. -- @param italics The italicized status. 1 is italicized, 0 is normal. function Geyser.MiniConsole:setTextFormat(r1, g1, b1, r2, g2, b2, bold, underline, italics) self.fgColor:set(r1,g1,b1) self.bgColor:set(r2,b2,g2) setTextFormat(self.name, r1, g1, b1, r2, g2, b2, bold, underline, italics) end --- Sets bold status for this miniconsole -- @param bool True for bolded function Geyser.MiniConsole:setBold(bool) setBold(self.name, val) end --- Sets underline status for this miniconsole -- @param bool True for underlined function Geyser.MiniConsole:setUnderline(bool) setUnderline(self.name, val) end --- Sets italics status for this miniconsole -- @param bool True for italicized function Geyser.MiniConsole:setItalics(bool) setItalics(self.name, val) end --- Sets the font size for this miniconsole. -- @param size The font size. function Geyser.MiniConsole:setFontSize(size) self.parent:setFontSize(size) setMiniConsoleFontSize(self.name, size) end --- Appends copied selection to this miniconsole. function Geyser.MiniConsole:appendBuffer() appendBuffer(self.name) end --- sets the current foreground color of cursor in this miniconsole. function Geyser.MiniConsole:fg(color) fg(self.name, color) end --- sets the current background color of cursor in this miniconsole. function Geyser.MiniConsole:bg(color) bg(self.name, color) end --- inserts clickable text into the miniconsole at the end of the current line function Geyser.MiniConsole:echoLink(...) echoLink(self.name, ...) end --- inserts clickable text into the miniconsole at the current cursor position function Geyser.MiniConsole:insertLink(...) insertLink(self.name, ...) end --- turns selected text info clickable text into the miniconsole function Geyser.MiniConsole:setLink(...) setLink(self.name, ...) end -- Save a reference to our parent constructor Geyser.MiniConsole.parent = Geyser.Window -- Overridden constructor function Geyser.MiniConsole:new (cons, container) -- Initiate and set gauge specific things cons = cons or {} cons.type = cons.type or "miniConsole" -- Call parent's constructor local me = self.parent:new(cons, container) -- Set the metatable. setmetatable(me, self) self.__index = self ----------------------------------------------------------- -- Now create the MiniConsole using primitives createMiniConsole(me.name, me:get_x(), me:get_y(), me:get_width(), me:get_height()) -- Set any defined colors Geyser.Color.applyColors(me) if cons.wrapAt then me:setWrap(cons.wrapAt) end if cons.fontSize then me:setFontSize(cons.fontSize) elseif container then me:setFontSize(container.fontSize) else me:setFontSize(8) end --print(" New in " .. self.name .. " : " .. me.name) return me end mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserMapper.lua0000644000175000017500000000302412070466513023044 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- createMapper support by Vadi -- -- -- -------------------------------------- --- Represents a mapper primitive -- @class table -- @name Geyser.Mapper -- @field wrapAt Where line wrapping occurs. Default is 300 characters. Geyser.Mapper = Geyser.Window:new({ name = "MapperClass" }) -- Save a reference to our parent constructor Geyser.Mapper.parent = Geyser.Window -- Overridden reposition function - mapper does it differently right now function Geyser.Mapper:reposition() if self.hidden then return end createMapper(self:get_x(), self:get_y(), self:get_width(), self:get_height()) end function Geyser.Mapper:hide_impl() createMapper(self:get_x(), self:get_y(), 0, 0) end function Geyser.Mapper:show_impl() createMapper(self:get_x(), self:get_y(), self:get_width(), self:get_height()) end -- Overridden constructor function Geyser.Mapper:new (cons, container) cons = cons or {} cons.type = cons.type or "mapper" -- Call parent's constructor local me = self.parent:new(cons, container) me.was_hidden = false -- Set the metatable. setmetatable(me, self) self.__index = self ----------------------------------------------------------- -- Now create the Mapper using primitives createMapper(me:get_x(), me:get_y(), me:get_width(), me:get_height()) -- Set any defined colors Geyser.Color.applyColors(me) --print(" New in " .. self.name .. " : " .. me.name) return me endmudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserUtil.lua0000644000175000017500000000273212070466513022542 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Generate a window name unique to this session. function Geyser.nameGen (type) local index = Geyser.i local t = type or "window" Geyser.i = Geyser.i + 1 return "anon_" .. t .. "_" .. index end --- Hide all managed windows. function Geyser.hideAll(type) for _,v in pairs(Geyser.windowList) do if v.type == type or not type then v:hide() end end end --- Show all managed windows. function Geyser.showAll(type) for _,v in pairs(Geyser.windowList) do if v.type == type or not type then v:show() end end end --- Non-recursive display of an item, because the normal 'display' was -- causing Mudlet to hang. Not sure why. function Geyser.display (table) echo("------ " .. type(table) .. " ------\n") if type(table) == "table" then for k,v in pairs(table) do echo("'" .. tostring(k) .. "' - " .. tostring(v) .. "\n") end else echo(tostring(table) .. "\n") end end --- Clone a table, for good fun and profit. function Geyser.copyTable (table) local copy = {} if table then for k,v in pairs(table) do -- do deep copy on a table if it requests one by having the __clone function defined. if type(v) == "table" and v.__clone then copy[k] = v.__clone() else copy[k] = v end end end return copy end mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserVBox.lua0000644000175000017500000000306512070466513022503 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -- VBox by Beliar -- -- -- -------------------------------------- Geyser.VBox = Geyser.Container:new({ name = "VBoxClass" }) function Geyser.VBox:add (window, cons) Geyser.add(self, window, cons) if not self.defer_updates then self:reposition() end end --- Responsible for placing/moving/resizing this window to the correct place/size. -- Called on window resize events. function Geyser.VBox:reposition() self.parent:reposition() local window_height = self:calculate_dynamic_window_size().height local start_y = 0 for _, window_name in ipairs(self.windows) do local window = self.windowList[window_name] window:move(0, start_y) local width = window.width local height = window.height if window.h_policy == Geyser.Dynamic then width = self:get_width() end if window.v_policy == Geyser.Dynamic then height = window_height * window.v_stretch_factor end window:resize(width, height) start_y = start_y + window:get_height() end end Geyser.VBox.parent = Geyser.Container function Geyser.VBox:new(cons, container) -- Initiate and set Window specific things cons = cons or {} cons.type = cons.type or "VBox" -- Call parent's constructor local me = self.parent:new(cons, container) setmetatable(me, self) self.__index = self return me endmudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserContainer.lua0000644000175000017500000002366412070466513023556 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Represents a generic container with positional information. -- Has no notion of contents and is used to contain other windows -- and impose some sense of order. -- @class table -- @name Geyser.Container -- @field parent The parent class of this window -- @field type The type of this window, usually lowercase of the classname and -- can be used in checks for certain types. For a Container -- instance, type is “container.” -- @field name The name of this window. This is the same name that Mudlet will -- use internally for primitive types like labels and -- miniconsoles. If not specified in the constraints table during -- creation, an anonymous name unique to this session will be -- made up. -- @field x The x-coordinate relative to this window's container, not absolute -- from the Mudlet main window. This is not a number, but a -- constraint specification. To find out the numeric x-coordinate in -- terms of pixels from the Mudlet main window's origin, use the -- get_x() method. Default is "10px". -- @field y The y-coordinate relative to this window's container, not absolute -- from the Mudlet main window. This is not a number, but a -- constraint specification. To find out the numeric y-coordinate in -- terms of pixels from the Mudlet main window's origin, use the -- get_y() method. Default is "10px". -- @field width The width of this window, possibly relative to the window's -- container. This is not a number, but a constraint -- specification. To find out the numeric width in terms of -- pixels, use the get_width() method. Default is "300px". -- @field height The height of this window, possibly relative to the window's -- container. This is not a number, but a constraint -- specification. To find out the numeric width in terms of -- pixels, use the get_width() method. Default is "200px". -- @field windowList This is a list of all windows held by this container. It -- used to handle proper resizing of held windows as well as -- during show()s and hide()s to recursive show and hide all -- children windows. -- @field windows This is an ordered list of the names of the window held by this container. -- @field fontSize The default size font used when calculating dimensions -- based on the character constraint. Default is 8. -- @field h_policy This sets if this widget should be stretched/shrinked horizontally or not -- @field v_policy This sets if this widget should be stretched/shrinked vertically or not -- @field v_stretch_factor This sets by how much more then window will be stretched horizontally in comparison to -- other windows -- @field v_stretch_factor This sets by how much more then window will be stretched vertically in comparison to -- other windows Geyser.Container = { name = "ContainerClass", x = "10px", y = "10px", height = "200px", width = "300px", windowList = {}, windows = {}, fontSize = 8, h_policy = Geyser.Dynamic, v_policy = Geyser.Dynamic, h_stretch_factor = 1.0, v_stretch_factor = 1.0, } function Geyser.Container:calculate_dynamic_window_size() local total_count = #self.windows local fixed_horizontal_count = 0 local fixed_vertical_count = 0 local fixed_width_sum = 0 local fixed_height_sum = 0 local ret_size = {} ret_size.width = self.get_width() ret_size.height = self.get_height() local dynamic_horizontal_count = 0.0 local dynamic_vertical_count = 0.0 if total_count <= 1 then --If there is only one window it can have all the width/height, if there are none then it doesn't matter return ret_size end for _, window in pairs(self.windowList) do if window.h_policy == Geyser.Fixed then fixed_horizontal_count = fixed_horizontal_count + 1 fixed_width_sum = fixed_width_sum + window.get_width() else dynamic_horizontal_count = dynamic_horizontal_count + window.h_stretch_factor - 1.0 end if window.v_policy == Geyser.Fixed then fixed_vertical_count = fixed_vertical_count + 1 fixed_height_sum = fixed_height_sum + window.get_height() else dynamic_vertical_count = dynamic_vertical_count + window.v_stretch_factor - 1.0 end end dynamic_horizontal_count = dynamic_horizontal_count + total_count - fixed_horizontal_count dynamic_vertical_count = dynamic_vertical_count + total_count - fixed_vertical_count if dynamic_horizontal_count == 0 then ret_size.width = 0 else ret_size.width = (self.get_width() - fixed_width_sum) / dynamic_horizontal_count end if dynamic_vertical_count == 0 then ret_size.height = 0 else ret_size.height = (self.get_height() - fixed_height_sum) / dynamic_vertical_count end return ret_size end --- Responsible for placing/moving/resizing this window to the correct place/size. -- Called on window resize events. function Geyser.Container:reposition () local x,y,w,h = self:get_x(), self:get_y(), self:get_width(), self:get_height() moveWindow(self.name, self:get_x(), self:get_y()) resizeWindow(self.name, self:get_width(), self:get_height()) -- deal with all children of this container for k,v in pairs(self.windowList) do if k ~= self then v:reposition() end end -- Calls optional redraw method if it is available to cause a gui element to -- redraw itself after moving. if self.redraw then self:redraw() end end --- Hides this window and all its contained windows. function Geyser.Container:hide (auto) if not (self.hidden or self.auto_hidden) then self:hide_impl() end auto = auto or false if auto then self.auto_hidden=true else self.hidden=true end for _,v in pairs(self.windowList) do v:hide(true) end end function Geyser.Container:hide_impl() hideWindow(self.name) end --- Shows this window and all windows it contains. function Geyser.Container:show (auto) auto = auto or false if auto then self.auto_hidden=false else self.hidden=false end if not self.hidden and not self.auto_hidden then self:show_impl() end for _,v in pairs(self.windowList) do v:show(true) end end function Geyser.Container:show_impl() showWindow(self.name) end --- Moves this window according to the new x and y contraints set. -- @param x New x constraint to use. If nil, uses current value. -- @param y New y constraint to use. If nil, uses current value. function Geyser.Container:move (x, y) self.x = x or self.x self.y = y or self.y self:set_constraints(self) end --- Resizes this window according to the new width and height constraints set. -- @param width New width constraint to use. If nil, uses current value. -- @param height New height constraint to use. If nil, uses current value. function Geyser.Container:resize (width, height) self.width = width or self.width self.height = height or self.height self:set_constraints(self) end --- Sets the default font size for this window. -- Will resizes this window if necessary to meet constraints. -- @param fontSize The new font size to use. function Geyser.Container:setFontSize (fontSize) if type(fontSize) ~= "number" then error("fontSize must be a number") return end self.fontSize = fontSize or self.fontSize self:set_constraints() end --- Sets all contraints (x, y, width, height) for this window. -- @param cons Any Lua table that contains appropriate constraint entries. function Geyser.Container:set_constraints (cons) cons = cons or self Geyser.set_constraints(self, cons, self.container) for k,v in pairs(self.windowList) do v:set_constraints(v) end end --- Flashes a white box over the dimensions of this container. -- This is very useful to see where a container actually is if you've -- forgotten its details. -- @param time Time in seconds to flash for, default is 1.0s. function Geyser.Container:flash (time) local time = time or 1.0 local x, y, width, height = self.get_x(), self.get_y(), self.get_width(), self.get_height() local name = self.name .. "_dimensions_flash" createLabel(name, x, y, width, height, 1) resizeWindow(name, width, height) moveWindow(name, x, y) setBackgroundColor(name, 190, 190, 190, 128) showWindow(name) tempTimer(time, "hideWindow(\"" .. name .. "\")") end Geyser.Container.parent = Geyser.Container -- I'm my own grandpa too! -- Someone has to be the root! setmetatable(Geyser.Container, Geyser) --- Constructor for containers. -- This function creates a new container/window -- @param cons Any Lua table that contains appropriate constraint entries. -- Include any parameter such as name or fontSize in cons -- that are to be used for the new window. function Geyser.Container:new(cons, container) -- create new table for the container and copy over constraints local me = Geyser.copyTable(cons) -- enforce a default type, name and parent me.type = me.type or "container" me.name = me.name or Geyser.nameGen() me.windowList = {} me.windows = {} me.hidden = false me.auto_hidden = false -- Set the metatable. setmetatable(me, self) self.__index = self -- If we're not not a class definition then add to a controlling -- container. if not string.find(me.name, ".*Class") then -- If passed in a container, add me to that container if container then container:add(me) else -- Else assume the root window is my container Geyser:add(me) end end --print("New in " .. self.name .. " : " .. me.name) return me end mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserTests.lua0000644000175000017500000001351512070466513022730 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- -- TESTS FOR GEYSER -- --- Test labels. Creates 101 Labels of varying hue and transparency. function Geyser.testLabels() labelTestContainer = Geyser.Container:new({x=0,y=0,width="100%",height="100%",name="labelTestContainer"}) for i=0,90,10 do for j=0,90,10 do local myName = "TestLabel_" .. i .. "_" .. j local l = Geyser.Label:new({ name = myName, x = i .. "%", y = j .. "%", width = "8%", height = "8%", message = myName, fgColor = "white"}, labelTestContainer) l:setColor(i,j,100, i*j/8100 * 128 + 127) end end Geyser.Label:new({ name = "Clickable", fontSize = 22, message = [[

Click me

]], x = "53%", y = "53%", width = "-40px", height = "-3c", backgroundAlpha = 240, callback = "echo", args = "You Clicked Me!!\n"}, labelTestContainer) end --- Test gauges. Creates 100 gauges of varying fullness. function Geyser.testGauges() gaugeTestContainer = Geyser.Container:new({x=0,y=0,width="100%",height="100%",name="gaugeTestContainer"}) for i=0,90,10 do for j=0,90,10 do local myName = "TestGauge_" .. i .. "_" .. j local g = Geyser.Gauge:new({name = myName, x = i .. "%", y = j .. "%", width = "9%", height = "9%", message = myName, fgColor = "red",}, gaugeTestContainer) g:setValue(1.0 * i) --g:setText(myName) end end end --- Used by Geyser.demo1(). Sorry about the namespace polution, -- but callbacks can't use functions contained in a table. Anyway, -- it just echoes some status info to the two miniconsoles. function demoCallback1 (value) local g1 = geyserDemoContainer.windowList.myGauge local g2 = geyserDemoContainer.windowList.myGoofyGauge local c1 = geyserDemoContainer.windowList["console 1"] local c2 = geyserDemoContainer.windowList["console 2"] g1:setValue((g1.value - value) % 100) g2:setValue((g2.value - 2*value) % 100) local v1 = tostring(g1.value) local v2 = tostring(g2.value) c1:decho(string.format("<90,90,%d> You are at %d \n", v1, v1)) c2:decho(string.format("<90,%d,%d> You are at %d \n", 255-v2, v2, v2)) end local myDemoState = 0 --- Used by Geyser.demo1(). It moves the location of the -- container window. Look how easy it is to shift around all those -- gui elements! function demoCallback2 () if myDemoState == 0 then geyserDemoContainer:resize(nil, "50%") geyserDemoContainer:move("-90c") myDemoState = 1 else geyserDemoContainer:resize(nil, "100%") geyserDemoContainer:move("-42c") myDemoState = 0 end end --- This demonstrates some of the neat features in Geyser. function Geyser.demo1() ---------------------------------------- -- 1. Create a container on the left side of the screen wide -- enough for 40 characters geyserDemoContainer = Geyser.Container:new( { x = "-42c", y = "0px", width = "40c", height = "100%", name = "myContainer"}) ---------------------------------------- -- 2. Add a miniconsole to the top of the container, -- full width, with 20 lines of text local console1 = Geyser.MiniConsole:new( { x = "0px", y = "0px", width = "100%", height = "20c", name = "console 1"}, geyserDemoContainer) -- add console1 to container directly console1:setColor(80,40,20,255) console1:echo("Go ahead - resize the Mudlet window\n") ---------------------------------------- -- 3. Add two gauges and a clickable label just below the -- miniconsole local g1 = Geyser.Gauge:new( { x = "0px", y = console1.height, width = "60%", height = "4c", orientation = "batty", color = "violet", name = "myGauge"}) g1:setValue(77) geyserDemoContainer:add(g1) -- add gauge after creation local g2 = Geyser.Gauge:new( { x = "10%", y = console1.height, width = "50%", height = "4c", orientation = "goofy", name = "myGoofyGauge"}, geyserDemoContainer) -- add gauge directly g2:setValue(55) g2:setColor("cyan") local label1 = Geyser.Label:new( { x = g1.width, y = console1.height, width = "40%", height = "4c", name = "label with callback", callback = "demoCallback1", args=5, fontSize = 8, fgColor = "white", message = "Click me"}) geyserDemoContainer:add(label1) -- you know the drill ---------------------------------------- -- 4. Add another miniconsole below the gauge that extends -- to the bottom of the screen and wraps at 40 characters and -- another clickable label. echo("adfa\n") local console2 = Geyser.MiniConsole:new({ x = "0px", y = "24c", width = "100%", height = "-0px", name = "console 2", wrapAt = 40, color = "<10,20,40>",}, geyserDemoContainer) -- add console2 to geyserDemoContainer directly console2:echo("Vampire Gauges!\n") local label2 = Geyser.Label:new( { x = g1.width, y = "60%", width = "40%", height = "4c", name = "label with another callback and a long name!", callback = "demoCallback2", message = [[
and me
]]}) geyserDemoContainer:add(label2) -- same here ---------------------------------------- -- 5. hide all windows just created geyserDemoContainer:hide() ---------------------------------------- -- 6. now show them again geyserDemoContainer:show() end mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserWindow.lua0000644000175000017500000001240412070466513023071 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- local cparse = Geyser.Color.parse --- Represents an abstract window class designed to be subclassed for windows -- that are built on Mudlet primitives, like labels. -- @class table -- @name Geyser.Window -- @field message The message last *echo()'d to this window. Default is “”. -- @field bgColor Text background color, default "white" -- @field fgColor Text foreground color, default "black" -- @field color Window background color, default "#202020" Geyser.Window = Geyser.Container:new({ name = "WindowClass", message = "", -- default colors. The are boring fgColor = "white", bgColor = "black", color = "#202020", }) -- Add regular window methods, these are mostly just OO-ized wrappers --- Prints a message to the window -- @param message The message to print. Can contain html formatting. function Geyser.Window:echo(message) self.message = message echo(self.name, self.message) end --- Prints a message to the window. -- @param message The message to print. Uses color formatting information - -- a message of "Hi" would make 'Hi' red. function Geyser.Window:cecho(message) self.message = message or self.message cecho(self.name, self.message) end --- Prints a message to the window. -- @param message The message to print. Uses color formatting information - -- a message of "<255,0,0>Hi" would make 'Hi' red. function Geyser.Window:decho(message) self.message = message or self.message decho(self.name, self.message) end --- Prints a message to the window. -- @param message The message to print. Uses color formatting information - -- a message of "|cff0000Hi" would make 'Hi' red. function Geyser.Window:hecho(message) self.message = message or self.message hecho(self.name, self.message) end --- Get the window's foreground color. -- @return The foreground color of this window primitive as a Geyser.Color object. function Geyser.Window:getFgColor () return getFgColor(self.name) end --- Get the window's background color -- @return The background color of this window primitive as a Geyser.Color object. function Geyser.Window:getBgColor () return getBgColor(self.name) end --- Sets the background color of this window primitive. If this primitive -- was using a shared color, then it creates a new, personal color. -- @param r The red value, or a quoted color name, like "green". -- @param g The green value, or nil if using a name. -- @param b The blue value, or nil if using a name. function Geyser.Window:setBgColor (r,g,b) setBgColor(self.name, cparse(r,g,b)) end --- Sets the foreground color of this window primitive. If this primitive -- was using a shared color, then it creates a new, personal color. -- @param r The red value, or a quoted color name, like "green". -- @param g The green value, or nil if using a name. -- @param b The blue value, or nil if using a name. function Geyser.Window:setFgColor (r,g,b) setFgColor(self.name, cparse(r,g,b)) end --- Sets the background color and alpha. If this primitive -- was using a shared color, then it creates a new, personal color. -- @param r The red component of the color, or a named color like "green". -- @param g The green component, or nil if using named colors. -- @param b The blue component, or nil if using named colors. -- @param a The alpha component. If nil, uses current alpha value. function Geyser.Window:setColor (r,g,b,a) setBackgroundColor(self.name, cparse(r,g,b,a)) end --- Pastes text from the clipboard into this window primitive. function Geyser.Window:paste () paste(self.name) end --- Sets the text format for this window. Note that the *echo() -- functions will override these settings. -- @param r1 The red foreground component. -- @param g1 The green foreground component. -- @param b1 The blue foreground component. -- @param r2 The red background component. -- @param g2 The green background component. -- @param b2 The blue background component. -- @param bold The bolded status. 1 is bold, 0 is normal. -- @param underline The underlined status. 1 is underlined, 0 is normal. -- @param italics The italicized status. 1 is italicized, 0 is normal. function Geyser.Window:setTextFormat(r1, g1, b1, r1, g2, b2, bold, underline, italics) setTextFormat(self.name, r1, g1, b1, r1, g2, b2, bold, underline, italics) end --- Sets bolded text. -- @param bool True for bold. function Geyser.Window:setBold(bool) setBold(self.name, bool) end --- Sets underlined text. -- @param bool True for underlined. function Geyser.Window:setUnderline(bool) setUnderline(self.name, bool) end --- Sets italicized text. -- @param bool True for italicized. function Geyser.Window:setItalics(bool) setItalics(self.name, bool) end -- Save a reference to our parent's constructor Geyser.Window.parent = Geyser.Container function Geyser.Window:new (cons, container) -- Initiate and set Window specific things cons = cons or {} cons.type = cons.type or "window" -- Call parent's constructor local me = self.parent:new(cons, container) -- Set the metatable. setmetatable(me, self) self.__index = self --print(" New in " .. self.name .. " : " .. me.name) return me end mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserSetConstraints.lua0000644000175000017500000001255112070466513024610 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- This function sets the constraints of a window. -- It doesn't mess with anything other than positioning data. It -- creates get_x(), get_y(), get_width(), and get_height() functions -- for 'window' -- @param window The window to create the constraints for. -- @param cons A table that holds the constraints. -- @param container A table that holds maximum position values and -- represents the dimensions of the "window" that holds whatever -- widget is being created. function Geyser.set_constraints (window, cons, container) oldlocale = os.setlocale(nil, "numeric") os.setlocale("C", "numeric") -- If container is nil then by default it is the dimensions of the main window container = container or Geyser -- GENERATE CONSTRAINT AWARE POSITIONING FUNCTIONS -- Parse the position constraints to generate functions that will get -- window dimensions according to those constraints. Also, update position -- information. The order that the dimensions are specified in the for -- loop is important so that get_x() and get_y() are defined before they -- needed by width and height. for _,v in ipairs{"x", "y", "width", "height"} do local getter = "get_" .. v -- name of the function to calculate the -- if passed a number assume pixels are meant if type(cons[v]) == "number" then cons[v] = string.format("%dpx", cons[v]) end -- Parse the constraint if string.find(cons[v], "%%") then -- This handles dimensions as a percentage of the container. -- Negative percentages are converted to the equivalent positive. -------------------------------------------------------------- -- scale is a value between 0 and 1 local scale = tonumber((string.gsub(cons[v], "%%", ""))) / 100.0 if scale < 0 then scale = 1 + scale end local dim = "" local min, max = 0,0 if v == "x" then min = "container.get_x()" max = "container.get_width()" elseif v == "width" then max = "container.get_width()" elseif v == "y" then min = "container.get_y()" max = "container.get_height()" else max = "container.get_height()" end -- Define the getter function -- Heiko: on European locales this leads to compile errors because -- scale will be "0,5" instead of "0.5"-> syntax error -- Need to find out if there's more such cases in Geyse -- Need to find out if there's more such cases in Geyser h_scale = tostring(scale) local src = "local self,container = ... return function () return " .. min .. " + (" .. h_scale .. " * " .. max .. ") end" -- compile the getter window[getter] = assert(loadstring(src, "getter for " .. v))(window,container) else -- This handles absolute positioning and character positioning -- Negative values indicated positioning from the anti-origin. -- Pre: cons[v] must contain "px" or "c" -------------------------------------------------------------- -- Create default values local x_mult, y_mult = 1,1 -- by default assume not "c" local negative = string.find(cons[v], "-") or false -- detect "negative" 0 -- As is, font size is considered a constraint if string.find(cons[v], "c") then x_mult, y_mult = calcFontSize(window.fontSize) end local pos = tonumber((string.gsub(cons[v], "%a", ""))) local max = 0 local min = 0 if v == "x" then min = "container.get_x()" pos = x_mult * pos elseif v == "width" then pos = x_mult * pos elseif v == "y" then min = "container.get_y()" pos = y_mult * pos else pos = y_mult * pos end -- Treat negative values differently if negative then if v == "x" then min = "container.get_x()" max = "container.get_width()" elseif v == "width" then min = "container.get_x()" max = "container.get_width()" pos = string.format("(%d - self:get_x())", pos) elseif v == "y" then min = "container.get_y()" max = "container.get_height()" else -- v == "height" min = "container.get_y()" max = "container.get_height()" pos = string.format("(%d - self:get_y())", pos) end end -- Define the getter function local src = "local self, container = ... return function () return " .. max .. " + " .. min .. " + " .. pos .. " end" -- compile the getter window[getter] = assert(loadstring(src, "getter for " .. v))(window, container) end -- Here the actual value of the dimension is set according to the -- constraints requested. --window[v] = window[getter]() end -- END for that generates POSITION FUNCTIONS os.setlocale(oldlocale, "numeric") window:reposition() end mudlet-2.1/src/old_mudlet-lua/lua/geyser/Geyser.lua0000644000175000017500000000135412070466513021703 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- -- -- Load code in following order: -- Geyser.lua -- GeyserGeyser.lua -- GeyserUtil.lua -- GeyserColor.lua -- GeyserSetConstraints.lua -- GeyserContainer.lua -- GeyserWindow.lua -- GeyserLabel.lua -- GeyserGauge.lua -- GeyserMiniConsole.lua -- GeyserMapper.lua -- GeyserReposition.lua -- GeyserTests.lua -- UNCOMMENT EVERYTHING BELOW THIS LINE FOR VERSIONS PRIOR TO 1.1.0 --myoldresizer = myoldresizer or handleWindowResizeEvent --function handleWindowResizeEvent() -- raiseEvent("sysWindowResizeEvent") --end mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserReposition.lua0000644000175000017500000000075512070466513023763 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- --- Responds to sysWindowResizeEvent and causes all windows managed -- by Geyser to update their sizes and positions. function GeyserReposition() for _,window in pairs(Geyser.windowList) do window:reposition() end end registerAnonymousEventHandler("sysWindowResizeEvent", "GeyserReposition") mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserColor.lua0000644000175000017500000001356312070466513022707 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -------------------------------------- Geyser.Color = {} --- Converts color to 3 hex values as a string, no alpha, css style -- @return The color formatted as a hex string, as accepted by html/css function Geyser.Color.hex (r,g,b) return string.format("#%02x%02x%02x", Geyser.Color.parse(r, g, b)) end --- Converts color to 4 hex values as a string, with alpha, css style -- @return The color formatted as a hex string, as accepted by html/css function Geyser.Color.hexa (r,g,b,a) return string.format("#%02x%02x%02x%02x", Geyser.Color.parse(r, g, b, a)) end --- Converts color to 3 hex values as a string, no alpha, hecho style -- @return The color formatted as a hex string, as accepted by hecho function Geyser.Color.hhex (r,g,b) return string.format("|c%02x%02x%02x", Geyser.Color.parse(r, g, b)) end --- Converts color to 4 hex values as a string, with alpha, hecho style -- @return The color formatted as a hex string, as accepted by hecho function Geyser.Color.hhexa (r,g,b,a) return string.format("|c%02x%02x%02x%02x", Geyser.Color.parse(r, g, b, a)) end --- Converts color to 3 decimal values as a string, no alpha, decho style -- @return The color formatted as a decho() style string function Geyser.Color.hdec (r,g,b) return string.format("<%d,%d,%d>", Geyser.Color.parse(r, g, b)) end --- Converts color to 4 decimal values as a string, with alpha, decho style -- @return The color formatted as a decho() style string function Geyser.Color.hdeca (r,g,b,a) return string.format("<%d,%d,%d,%d>", Geyser.Color.parse(r, g, b, a)) end --- Returns 4 color components from (nearly any) acceptable format. Colors can be -- specified in two ways. First: as a single word in english ("purple") or -- hex ("#AA00FF", "|cAA00FF", or "0xAA00FF") or decimal ("<190,0,255>"). If -- the hex or decimal representations contain a fourth element then alpha is -- set too - otherwise alpha can't be set this way. Second: by passing in -- distinct components as unsigned integers (e.g. 23 or 0xA7). When using the -- second way, at least three values must be passed. If only three are -- passed, then alpha is 255. Third: by passing in a table that has explicit -- values for some, all or none of the keys r,g,b, and a. -- @param red Either a valid string representation or the red component. -- @param green The green component. -- @param blue The blue component. -- @param alpha The alpha component. function Geyser.Color.parse(red, green, blue, alpha) local r,g,b,a = 0,0,0,255 -- have to have something to set, else can't do anything! if not red then print("No color supplied.\n") return end -- function to return next number local next_num = nil local base = 10 -- assigns all the colors, used after we figure out how the color is -- represented as a string local assign_colors = function () r = tonumber(next_num(), base) g = tonumber(next_num(), base) b = tonumber(next_num(), base) local has_a = next_num() if has_a then a = tonumber(has_a, base) end end -- Check if we were passed a string or table that needs to be parsed, i.e., -- there is only a valid red value, and other params are nil. if not green or not blue then if type(red) == "table" then -- Here just copy over the appropriate values with sensible defaults r = red.r or 127 g = red.g or 127 b = red.b or 127 a = red.a or 255 return r,g,b,a elseif type(red) == "string" then -- first case is a hex string, where first char is '#' if string.find(red, "^#") then local pure_hex = string.sub(red, 2) -- strip format char next_num = string.gmatch(pure_hex, "%w%w") base = 16 -- second case is a hex string, where first chars are '|c' or '0x' elseif string.find(red, "^[|0][cx]") then local pure_hex = string.sub(red, 3) -- strip format chars next_num = string.gmatch(pure_hex, "%w%w") base = 16 -- third case is a decimal string, of the format "" elseif string.find(red, "^<") then next_num = string.gmatch(red, "%d+") -- fourth case is a named string elseif color_table[red] then local i = 0 local n = #color_table[red] next_num = function () -- create a simple iterator i = i + 1 if i <= n then return color_table[red][i] else return nil end end else -- finally, no matches, do nothing return end end else -- Otherwise we weren't passed a complete string, but instead discrete -- components as either decimal or hex -- Yes, this is a little silly to do this way, but it fits with the -- rest of the parsing going on... local i = 0 next_num = function () i = i + 1 if i == 1 then return red elseif i == 2 then return green elseif i == 3 then return blue elseif i == 4 then return alpha else return nil end end end assign_colors() return r,g,b,a end --- Applies colors to a window drawing from defaults and overridden values. -- @param cons The window to apply colors to function Geyser.Color.applyColors(cons) cons:setFgColor(cons.fgColor) cons:setBgColor(cons.bgColor) cons:setColor(cons.color) end mudlet-2.1/src/old_mudlet-lua/lua/geyser/GeyserHBox.lua0000644000175000017500000000310712070466513022462 0ustar csmallcsmall-------------------------------------- -- -- -- The Geyser Layout Manager by guy -- -- -- -- HBox by Beliar -- -- -- -------------------------------------- Geyser.HBox = Geyser.Container:new({ name = "HBoxClass" }) function Geyser.HBox:add (window, cons) Geyser.add(self, window, cons) if not self.defer_updates then self:reposition() end end --- Responsible for placing/moving/resizing this window to the correct place/size. -- Called on window resize events. function Geyser.HBox:reposition() self.parent:reposition() local window_width = self:calculate_dynamic_window_size().width local start_x = 0 for _, window_name in ipairs(self.windows) do local window = self.windowList[window_name] local width = window.width local height = window.height window:move(start_x, 0) if window.h_policy == Geyser.Dynamic then width = window_width * window.h_stretch_factor end if window.v_policy == Geyser.Dynamic then height = self:get_height() end window:resize(width, height) start_x = start_x + window:get_width() end end Geyser.HBox.parent = Geyser.Container function Geyser.HBox:new(cons, container) -- Initiate and set Window specific things cons = cons or {} cons.type = cons.type or "hbox" -- Call parent's constructor local me = self.parent:new(cons, container) setmetatable(me, self) self.__index = self me:reposition() return me endmudlet-2.1/src/old_mudlet-lua/lua/Other.lua0000644000175000017500000003733112070466513020234 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Unsorted Stuff ---------------------------------------------------------------------------------- -- Extending default libraries makes Babelfish happy. setmetatable( _G, { ["__call"] = function(func, ...) if type(func) == "function" then return func(...) else local h = metatable(func).__call if h then return h(func, ...) elseif _G[type(func)][func] then _G[type(func)][func](...) end end end, }) --- Mudlet's support for ATCP. This is primarily available on IRE-based MUDs, but Mudlets impelementation is generic enough --- such that any it should work on others.

--- --- The latest ATCP data is stored in the atcp table. Whenever new data arrives, the previous is overwritten. An event is also --- raised for each ATCP message that arrives. To find out the available messages available in the atcp table and the event names, --- you can use display(atcp).

--- --- Note that while the typical message comes in the format of Module.Submodule, ie Char.Vitals or Room.Exits, in Mudlet the dot is --- removed - so it becomes CharVitals and RoomExits. Here's an example: ---
---   room_number = tonumber(atcp.RoomNum)
---   echo(room_number)
---   
--- --- Triggering on ATCP events:
--- If you'd like to trigger on ATCP messages, then you need to create scripts to attach handlers to the ATCP messages. --- The ATCP handler names follow the same format as the atcp table - RoomNum, RoomExits, CharVitals and so on.

--- --- While the concept of handlers for events is to be explained elsewhere in the manual, the quick rundown is this - place --- the event name you'd like your script to listen to into the Add User Defined Event Handler: field and press the + button --- to register it. Next, because scripts in Mudlet can have multiple functions, you need to tell Mudlet which function --- should it call for you when your handler receives a message. You do that by setting the Script name: to the function --- name in the script you'd like to be called.

--- --- For example, if you'd like to listen to the RoomExits event and have it call the process_exits() function - --- register RoomExits as the event handler, make the script name be process_exits, and use this in the script: ---
---   function process_exits(event, args)
---       echo("Called event: " .. event .. "\nWith args: " .. args)
---   end
---   
--- --- Feel free to experiment with this to achieve the desired results. A ATCP demo package is also available on the forums --- for using event handlers and parsing its messages into Lua datastructures.
--- --- @release Mudlet 1.0.6 --- --- @see sendATCP --- --- @class function --- @name atcp atcp = {} --- TODO Table walklist. --- --- @class function --- @name walklist walklist = {} --- TODO Variable walkdelay. --- --- @class function --- @name walkdelay walkdelay = 0 --- TODO Table SavedVariables. --- --- @class function --- @name SavedVariables SavedVariables = {} --- Sends a list of commands to the MUD. You can use this to send some things at once instead of having --- to use multiple send() commands one after another. --- --- @param ... list of commands --- @param echoTheValue optional boolean flag (default value is true) which determine if value should --- be echoed back on client. --- --- @usage Use sendAll instead of multiple send commands. ---
---   sendAll("stand", "wield shield", "say ha!")
---   
--- Instead of calling: ---
---   send ("stand")
---   send ("wield shield")
---   send ("say ha!")
---   
--- @usage Use sendAll and do not echo sent commnad on the main window. ---
---   sendAll("stand", "wield shield", "say ha!", false)
---   
--- --- @see send function sendAll(...) local args = {...} local echo = true if type(args[#args]) == 'boolean' then echo = table.remove(args, #args) end for i, v in ipairs(args) do if type(v) == 'string' then send(v, echo) end end end --- Creates a group of a given type that will persist through sessions. --- --- @param name name of the teim --- @param itemtype type of the item - can be trigger, alias, or timer --- --- @usage ---
---   --create a new trigger group
---   permGroup("Combat triggers", "trigger")
--- 
--- @usage ---
---   --create a new alias group only if one doesn't exist already
---   if exists("Defensive aliases", "alias") == 0 then
---     permGroup("Defensive aliases", "alias")
---   end
--- 
function permGroup(name, itemtype) assert(type(name) == "string", "permGroup: need a name for the new thing") local t = { timer = function(name) return (permTimer(name, "", 0, "") == -1) and false or true end, trigger = function(name) return (permSubstringTrigger(name, "", {""}, "") == -1) and false or true end, alias = function(name) return (permAlias(name, "", "", "") == -1) and false or true end } assert(t[itemtype], "permGroup: "..tostring(itemtype).." isn't a valid type") return t[itemtype](name) end --- Checks to see if a given file or folder exists. If it exists, it'll return the Lua true boolean value, otherwise false. --- --- @usage ---
---   if io.exists("/home/user/Desktop") then
---      echo("This folder exists!")
---   else
---      echo("This folder doesn't exist.")
---   end
---
---   if io.exists("/home/user/Desktop/file.txt") then
---      echo("This file exists!")
---   else
---      echo("This file doesn't exist.")
---   end
---   
--- --- @return true or false function io.exists(fileOfFolderName) local f = io.open(fileOfFolderName) if f then io.close(f) return true end return false end --- Implementation of boolean exclusive or. --- --- @usage All following will return false. ---
---   xor(false, false)
---   xor(true, true)
---   
--- --- @return true or false function xor(a, b) if (a and (not b)) or (b and (not a)) then return true else return false end end --- Determine operating system. --- --- @usage ---
---   if "linux" == getOS() then
---	     echo("We are using GNU/Linux!")
---   end
---   
--- --- @return "linux", "mac" or "windows" string function getOS() if string.char(getMudletHomeDir():byte()) == "/" then if string.find(os.getenv("HOME"), "home") == 2 then return "linux" else return "mac" end else return "windows" end end --- This function flags a variable to be saved by Mudlet's variable persistence system. --- Variables are automatically unpacked into the global namespace when the profile is loaded. --- They are saved to "SavedVariables.lua" when the profile is closed or saved. --- --- @usage remember("varName") --- --- @see loadVars function remember(varName) if not _saveTable then _saveTable = {} end _saveTable[varName] = _G[varName] end --- This function should be primarily used by Mudlet. It loads saved settings in from the Mudlet home directory --- and unpacks them into the global namespace. --- --- @see remember function loadVars() if string.char(getMudletHomeDir():byte()) == "/" then _sep = "/" else _sep = "\\" end local l_SettingsFile = getMudletHomeDir() .. _sep .. "SavedVariables.lua" local lt_VariableHolder = {} if (io.exists(l_SettingsFile)) then table.load(l_SettingsFile, lt_VariableHolder) for k,v in pairs(lt_VariableHolder) do _G[k] = v end end end --- This function should primarily be used by Mudlet. It saves the contents of _saveTable into a file for persistence. --- --- @see loadVars function saveVars() if string.char(getMudletHomeDir():byte()) == "/" then _sep = "/" else _sep = "\\" end local l_SettingsFile = getMudletHomeDir() .. _sep .. "SavedVariables.lua" for k,_ in pairs(_saveTable) do remember(k) end table.save(l_SettingsFile, _saveTable) end --- The below functions (table.save, table.load) can be used to save individual Lua tables to disc and load --- them again at a later time e.g. make a database, collect statistical information etc. --- These functions are also used by Mudlet to load & save the entire Lua session variables.

--- --- Original code written by CHILLCODE™ on https://board.ptokax.ch, distributed under the same terms as Lua itself.

--- --- Notes:
--- Userdata and indices of these are not saved
--- Functions are saved via string.dump, so make sure it has no upvalues
--- References are saved
--- --- @usage Saves the globals table (minus some lua enviroment stuffs) into a file (only Mudlet should use this). ---
---   table.save(file)
---   
--- @usage Saves the given table into the given file. ---
---   table.save(file, table)
---   
--- --- @see table.load function table.save( sfile, t ) assert(type(sfile) == "string", "table.save requires a file path to save to") local tables = {} table.insert( tables, t ) local lookup = { [t] = 1 } local file = io.open( sfile, "w" ) file:write( "return {" ) for i,v in ipairs( tables ) do table.pickle( v, file, tables, lookup ) end file:write( "}" ) file:close() end --- TODO table.pickle( t, file, tables, lookup ) function table.pickle( t, file, tables, lookup ) file:write( "{" ) for i,v in pairs( t ) do -- escape functions if type( v ) ~= "function" and type( v ) ~= "userdata" and (i ~= "string" and i ~= "xpcall" and i ~= "package" and i ~= "os" and i ~= "io" and i ~= "math" and i ~= "debug" and i ~= "coroutine" and i ~= "_G" and i ~= "_VERSION" and i ~= "table") then -- handle index if type( i ) == "table" then if not lookup[i] then table.insert( tables, i ) lookup[i] = table.maxn( tables ) end file:write( "[{"..lookup[i].."}] = " ) else local index = ( type( i ) == "string" and "[ "..string.enclose( i, 50 ).." ]" ) or string.format( "[%d]", i ) file:write( index.." = " ) end -- handle value if type( v ) == "table" then if not lookup[v] then table.insert( tables, v ) lookup[v] = table.maxn( tables ) end file:write( "{"..lookup[v].."}," ) else local value = ( type( v ) == "string" and string.enclose( v, 50 ) ) or tostring( v ) file:write( value.."," ) end end end file:write( "},\n" ) end --- Restores a Lua table from a data file that has been saved with table.save(). --- --- @usage Loads a serialized file into the globals table (only Mudlet should use this). ---
---   table.load(file)
---   
--- @usage Loads a serialized file into the given table. ---
---   table.load(file, table)
---   
--- --- @see table.save function table.load( sfile, loadinto ) assert(type(sfile) == "string", "table.load requires a file path to load") local tables = dofile( sfile ) if tables then if loadinto ~= nil and type(loadinto) == "table" then table.unpickle( tables[1], tables, loadinto ) else table.unpickle( tables[1], tables, _G ) end end end --- TODO table.unpickle( t, tables, tcopy, pickled ) function table.unpickle( t, tables, tcopy, pickled ) pickled = pickled or {} pickled[t] = tcopy for i,v in pairs( t ) do local i2 = i if type( i ) == "table" then local pointer = tables[ i[1] ] if pickled[pointer] then i2 = pickled[pointer] else i2 = {} table.unpickle( pointer, tables, i2, pickled ) end end local v2 = v if type( v ) == "table" then local pointer = tables[ v[1] ] if pickled[pointer] then v2 = pickled[pointer] else v2 = {} table.unpickle( pointer, tables, v2, pickled ) end end tcopy[i2] = v2 end end --- TODO speedwalktimer() function speedwalktimer() send(walklist[1]) table.remove(walklist, 1) if #walklist>0 then tempTimer(walkdelay, [[speedwalktimer()]]) end end --- TODO speedwalk(dirString, backwards, delay) function speedwalk(dirString, backwards, delay) local dirString = dirString:lower() walklist = {} walkdelay = delay local reversedir = { n = "s", en = "sw", e = "w", es = "nw", s = "n", ws = "ne", w = "e", wn = "se", u = "d", d = "u", ni = "out", tuo = "in" } if not backwards then for count, direction in string.gmatch(dirString, "([0-9]*)([neswudio][ewnu]?t?)") do count = (count == "" and 1 or count) for i=1, count do if delay then walklist[#walklist+1] = direction else send(direction) end end end else for direction, count in string.gmatch(dirString:reverse(), "(t?[ewnu]?[neswudio])([0-9]*)") do count = (count == "" and 1 or count) for i=1, count do if delay then walklist[#walklist+1] = reversedir[direction] else send(reversedir[direction]) end end end end if walkdelay then speedwalktimer() end end --- TODO _comp(a, b) function _comp(a, b) if type(a) ~= type(b) then return false end if type(a) == 'table' then for k, v in pairs(a) do if not b[k] then return false end if not _comp(v, b[k]) then return false end end else if a ~= b then return false end end return true end --- TODO phpTable(...) - abuse to: http://richard.warburton.it function phpTable(...) local newTable, keys, values = {}, {}, {} newTable.pairs = function(self) -- pairs iterator local count = 0 return function() count = count + 1 return keys[count], values[keys[count]] end end setmetatable(newTable, { __newindex = function(self, key, value) if not self[key] then table.insert(keys, key) elseif value == nil then -- Handle item delete local count = 1 while keys[count] ~= key do count = count + 1 end table.remove(keys, count) end values[key] = value -- replace/create end, __index=function(self, key) return values[key] end, isPhpTable = true, }) local args = {...} for x=1, #args do for k, v in pairs(args[x]) do newTable[k] = v end end return newTable end --- TODO getColorWildcard(color) function getColorWildcard(color) local color = tonumber(color) local startc local endc local results = {} for i = 1, string.len(line) do selectSection(i, 1) if isAnsiFgColor(color) then if not startc then if i == 1 then startc = 1 else startc = i + 1 end else endc = i + 1 if i == line:len() then results[#results + 1] = line:sub(startc, endc) end end elseif startc then results[#results + 1] = line:sub(startc, endc) startc = nil end end return results[1] and results or false end do local oldsetExit = setExit local exitmap = { n = 1, ne = 2, nw = 3, e = 4, w = 5, s = 6, se = 7, sw = 8, u = 9, d = 10, ["in"] = 11, out = 12 } function setExit(from, to, direction) if type(direction) == "string" and not exitmap[direction] then return false end return oldsetExit(from, to, type(direction) == "string" and exitmap[direction] or direction) end end do local oldlockExit = lockExit local oldhasExitLock = hasExitLock local exitmap = { n = 1, north = 1, ne = 2, northeast = 2, nw = 3, northwest = 3, e = 4, east = 4, w = 5, west = 5, s = 6, south = 6, se = 7, southeast = 7, sw = 8, southwest = 8, u = 9, up = 9, d = 10, down = 10, ["in"] = 11, out = 12 } function lockExit(from, direction, status) if type(direction) == "string" and not exitmap[direction] then return false end return oldlockExit(from, type(direction) == "string" and exitmap[direction] or direction, status) end function hasExitLock(from, direction) if type(direction) == "string" and not exitmap[direction] then return false end return oldhasExitLock(from, type(direction) == "string" and exitmap[direction] or direction) end end function print(...) local t, echo, tostring = {...}, echo, tostring for i = 1, #t do echo((tostring(t[i]) or '?').." ") end echo("\n") end mudlet-2.1/src/old_mudlet-lua/lua/GMCP.lua0000644000175000017500000001006612070466513017675 0ustar csmallcsmall-- [[ A framework to track GMCP module usage ]] -- module("gmod",package.seeall) local registeredUsers = registeredUsers or {} local registeredModules = registeredModules or {} -- Central text output function for the module. function print(text) cecho(string.format("\n[GMCP Tracker] %s\n",text)) end -- Register a user to the system. function registerUser(user) if registeredUsers[user] then return "user exists" else registeredUsers[user] = true end return "user registered" end -- Add a user to a module local function addUser(user,module) registeredModules[module][user] = true return "user added" end -- Drop a user from a module local function dropUser(user,module) if not registeredModules[module] then return "no registered module" end if not registeredModules[module][user] then return "user not linked" end registeredModules[module][user] = nil return "user dropped" end -- Get the user count of a module. local function getUserCount(module) if not registeredModules[module] then return 0 end local count = 0 for i,v in pairs(registeredModules[module]) do count = count + 1 end return count end -- Check to see if the module is registered. Return a user list if it is. function isRegisteredModule(mod) if not registeredModules[mod] then return false end return registeredModules[mod] end -- Enable a module that isn't already enabled, and register it's use to a user. function enableModule(user,module) registerUser(user) -- Check to see if the module is already enabled. if not isRegisteredModule(module) then local addString = nil local ttlString = "" for _,mod in pairs(module:split(".")) do if not addString then addString = mod else addString = string.format("%s.%s",addString,mod) end ttlString = string.format("%s\"%s 1\",",ttlString,addString) end ttlString = string.format("[%s]",ttlString:gsub("(.+),","%1")) sendGMCP(string.format([[Core.Supports.Add %s ]],ttlString)) registeredModules[module] = {} end -- Add the user to the module's user list. addUser(user,module) end -- Send the module list again on reconnect, so activated modules stay enabled during -- a session unless explicitly disabled function gmod.reenableModules() local list = {} for module, users in pairs(registeredModules) do list[#list+1] = module.." 1" end sendGMCP("Core.Supports.Set "..yajl.to_string(list)) end registerAnonymousEventHandler("sysConnectionEvent", "gmod.reenableModules") -- Remove a user from a module's user list. Disable the module if nobody is using it. function disableModule(user,module) registerUser(user) -- Make sure the module is enabled in the first place if not isRegisteredModule(module) then return "no registered module" end dropUser(user,module) -- The user is now removed from the list. Check the user count. if getUserCount(module) < 1 then sendGMCP(string.format([[Core.Supports.Remove ["%s"] ]],module)) registeredModules[module] = nil end end function printModules(user) -- If a user is specified, print the name of all associated modules. if user then if not registeredUsers[user] then print(string.format("%s is not a registered user.",user)) return end cecho(string.format("\n\nModule listing for user: %s",user)) cecho(string.format("\n%s",string.rep("-",45))) for i,v in pairs(registeredModules) do if v[user] then cecho(string.format("\n%s",i)) end end return end -- No user specified, print all existing Modules with a user list. print("Current modules:") for i,v in pairs(registeredModules) do cecho(string.format("\n%s\n ",i)) local doComma = false for j,_ in pairs(v) do if not doComma then doComma = true else cecho(", ") end cecho(string.format("%s",j)) end end end mudlet-2.1/src/old_mudlet-lua/lua/GUIUtils.lua0000644000175000017500000010176512070466513020623 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet GUI Utils ---------------------------------------------------------------------------------- --- The gaugesTable table. First we need to make this table which will be --- used later to store important data in. --- --- @class function --- @name gaugesTable gaugesTable = {} --- The color_table table holds definition of color names. These are intended to be --- used in conjunction with fg() and bg() colorizer functions. --- --- @see showColors --- @see bg --- @see fg --- --- @class function --- @name color_table color_table = { snow = {255, 250, 250}, ghost_white = {248, 248, 255}, GhostWhite = {248, 248, 255}, white_smoke = {245, 245, 245}, WhiteSmoke = {245, 245, 245}, gainsboro = {220, 220, 220}, floral_white = {255, 250, 240}, FloralWhite = {255, 250, 240}, old_lace = {253, 245, 230}, OldLace = {253, 245, 230}, linen = {250, 240, 230}, antique_white = {250, 235, 215}, AntiqueWhite = {250, 235, 215}, papaya_whip = {255, 239, 213}, PapayaWhip = {255, 239, 213}, blanched_almond = {255, 235, 205}, BlanchedAlmond = {255, 235, 205}, bisque = {255, 228, 196}, peach_puff = {255, 218, 185}, PeachPuff = {255, 218, 185}, navajo_white = {255, 222, 173}, NavajoWhite = {255, 222, 173}, moccasin = {255, 228, 181}, cornsilk = {255, 248, 220}, ivory = {255, 255, 240}, lemon_chiffon = {255, 250, 205}, LemonChiffon = {255, 250, 205}, seashell = {255, 245, 238}, honeydew = {240, 255, 240}, mint_cream = {245, 255, 250}, MintCream = {245, 255, 250}, azure = {240, 255, 255}, alice_blue = {240, 248, 255}, AliceBlue = {240, 248, 255}, lavender = {230, 230, 250}, lavender_blush = {255, 240, 245}, LavenderBlush = {255, 240, 245}, misty_rose = {255, 228, 225}, MistyRose = {255, 228, 225}, white = {255, 255, 255}, black = {0, 0, 0}, dark_slate_gray = {47, 79, 79}, DarkSlateGray = {47, 79, 79}, dark_slate_grey = {47, 79, 79}, DarkSlateGrey = {47, 79, 79}, dim_gray = {105, 105, 105}, DimGray = {105, 105, 105}, dim_grey = {105, 105, 105}, DimGrey = {105, 105, 105}, slate_gray = {112, 128, 144}, SlateGray = {112, 128, 144}, slate_grey = {112, 128, 144}, SlateGrey = {112, 128, 144}, light_slate_gray = {119, 136, 153}, LightSlateGray = {119, 136, 153}, light_slate_grey = {119, 136, 153}, LightSlateGrey = {119, 136, 153}, gray = {190, 190, 190}, grey = {190, 190, 190}, light_grey = {211, 211, 211}, LightGrey = {211, 211, 211}, light_gray = {211, 211, 211}, LightGray = {211, 211, 211}, midnight_blue = {25, 25, 112}, MidnightBlue = {25, 25, 112}, navy = {0, 0, 128}, navy_blue = {0, 0, 128}, NavyBlue = {0, 0, 128}, cornflower_blue = {100, 149, 237}, CornflowerBlue = {100, 149, 237}, dark_slate_blue = {72, 61, 139}, DarkSlateBlue = {72, 61, 139}, slate_blue = {106, 90, 205}, SlateBlue = {106, 90, 205}, medium_slate_blue = {123, 104, 238}, MediumSlateBlue = {123, 104, 238}, light_slate_blue = {132, 112, 255}, LightSlateBlue = {132, 112, 255}, medium_blue = {0, 0, 205}, MediumBlue = {0, 0, 205}, royal_blue = {65, 105, 225}, RoyalBlue = {65, 105, 225}, blue = {0, 0, 255}, dodger_blue = {30, 144, 255}, DodgerBlue = {30, 144, 255}, deep_sky_blue = {0, 191, 255}, DeepSkyBlue = {0, 191, 255}, sky_blue = {135, 206, 235}, SkyBlue = {135, 206, 235}, light_sky_blue = {135, 206, 250}, LightSkyBlue = {135, 206, 250}, steel_blue = {70, 130, 180}, SteelBlue = {70, 130, 180}, light_steel_blue = {176, 196, 222}, LightSteelBlue = {176, 196, 222}, light_blue = {173, 216, 230}, LightBlue = {173, 216, 230}, powder_blue = {176, 224, 230}, PowderBlue = {176, 224, 230}, pale_turquoise = {175, 238, 238}, PaleTurquoise = {175, 238, 238}, dark_turquoise = {0, 206, 209}, DarkTurquoise = {0, 206, 209}, medium_turquoise = {72, 209, 204}, MediumTurquoise = {72, 209, 204}, turquoise = {64, 224, 208}, cyan = {0, 255, 255}, light_cyan = {224, 255, 255}, LightCyan = {224, 255, 255}, cadet_blue = {95, 158, 160}, CadetBlue = {95, 158, 160}, medium_aquamarine = {102, 205, 170}, MediumAquamarine = {102, 205, 170}, aquamarine = {127, 255, 212}, dark_green = {0, 100, 0}, DarkGreen = {0, 100, 0}, dark_olive_green = {85, 107, 47}, DarkOliveGreen = {85, 107, 47}, dark_sea_green = {143, 188, 143}, DarkSeaGreen = {143, 188, 143}, sea_green = {46, 139, 87}, SeaGreen = {46, 139, 87}, medium_sea_green = {60, 179, 113}, MediumSeaGreen = {60, 179, 113}, light_sea_green = {32, 178, 170}, LightSeaGreen = {32, 178, 170}, pale_green = {152, 251, 152}, PaleGreen = {152, 251, 152}, spring_green = {0, 255, 127}, SpringGreen = {0, 255, 127}, lawn_green = {124, 252, 0}, LawnGreen = {124, 252, 0}, green = {0, 255, 0}, chartreuse = {127, 255, 0}, medium_spring_green = {0, 250, 154}, MediumSpringGreen = {0, 250, 154}, green_yellow = {173, 255, 47}, GreenYellow = {173, 255, 47}, lime_green = {50, 205, 50}, LimeGreen = {50, 205, 50}, yellow_green = {154, 205, 50}, YellowGreen = {154, 205, 50}, forest_green = {34, 139, 34}, ForestGreen = {34, 139, 34}, olive_drab = {107, 142, 35}, OliveDrab = {107, 142, 35}, dark_khaki = {189, 183, 107}, DarkKhaki = {189, 183, 107}, khaki = {240, 230, 140}, pale_goldenrod = {238, 232, 170}, PaleGoldenrod = {238, 232, 170}, light_goldenrod_yellow= {250, 250, 210}, LightGoldenrodYellow = {250, 250, 210}, light_yellow = {255, 255, 224}, LightYellow = {255, 255, 224}, yellow = {255, 255, 0}, gold = {255, 215, 0}, light_goldenrod = {238, 221, 130}, LightGoldenrod = {238, 221, 130}, goldenrod = {218, 165, 32}, dark_goldenrod = {184, 134, 11}, DarkGoldenrod = {184, 134, 11}, rosy_brown = {188, 143, 143}, RosyBrown = {188, 143, 143}, indian_red = {205, 92, 92}, IndianRed = {205, 92, 92}, saddle_brown = {139, 69, 19}, SaddleBrown = {139, 69, 19}, sienna = {160, 82, 45}, peru = {205, 133, 63}, burlywood = {222, 184, 135}, beige = {245, 245, 220}, wheat = {245, 222, 179}, sandy_brown = {244, 164, 96}, SandyBrown = {244, 164, 96}, tan = {210, 180, 140}, chocolate = {210, 105, 30}, firebrick = {178, 34, 34}, brown = {165, 42, 42}, dark_salmon = {233, 150, 122}, DarkSalmon = {233, 150, 122}, salmon = {250, 128, 114}, light_salmon = {255, 160, 122}, LightSalmon = {255, 160, 122}, orange = {255, 165, 0}, dark_orange = {255, 140, 0}, DarkOrange = {255, 140, 0}, coral = {255, 127, 80}, light_coral = {240, 128, 128}, LightCoral = {240, 128, 128}, tomato = {255, 99, 71}, orange_red = {255, 69, 0}, OrangeRed = {255, 69, 0}, red = {255, 0, 0}, hot_pink = {255, 105, 180}, HotPink = {255, 105, 180}, deep_pink = {255, 20, 147}, DeepPink = {255, 20, 147}, pink = {255, 192, 203}, light_pink = {255, 182, 193}, LightPink = {255, 182, 193}, pale_violet_red = {219, 112, 147}, PaleVioletRed = {219, 112, 147}, maroon = {176, 48, 96}, medium_violet_red = {199, 21, 133}, MediumVioletRed = {199, 21, 133}, violet_red = {208, 32, 144}, VioletRed = {208, 32, 144}, magenta = {255, 0, 255}, violet = {238, 130, 238}, plum = {221, 160, 221}, orchid = {218, 112, 214}, medium_orchid = {186, 85, 211}, MediumOrchid = {186, 85, 211}, dark_orchid = {153, 50, 204}, DarkOrchid = {153, 50, 204}, dark_violet = {148, 0, 211}, DarkViolet = {148, 0, 211}, blue_violet = {138, 43, 226}, BlueViolet = {138, 43, 226}, purple = {160, 32, 240}, medium_purple = {147, 112, 219}, MediumPurple = {147, 112, 219}, thistle = {216, 191, 216} } --- Move a custom gauge. --- --- @usage This would move the health bar gauge to the location 1200, 400. ---
---   moveGauge("healthBar", 1200, 400)
---   
--- --- @see createGauge function moveGauge(gaugeName, newX, newY) local newX, newY = newX, newY assert(gaugesTable[gaugeName], "moveGauge: no such gauge exists.") assert(newX and newY, "moveGauge: need to have both X and Y dimensions.") moveWindow(gaugeName, newX, newY) moveWindow(gaugeName .. "_back", newX, newY) gaugesTable[gaugeName].xpos, gaugesTable[gaugeName].ypos = newX, newY end --- Hide a custom gauge. --- --- @usage This should hide the given gauge. ---
---   hideGauge("healthBar")
---   
--- --- @see createGauge, moveGauge, showGauge function hideGauge(gaugeName) assert(gaugesTable[gaugeName], "hideGauge: no such gauge exists.") hideWindow(gaugeName) hideWindow(gaugeName .. "_back", newX) end --- Show a custom gauge. --- --- @usage This should show the given gauge. ---
---   showGauge("healthBar")
---   
--- --- @see createGauge, moveGauge, hideGauge function showGauge(gaugeName) assert(gaugesTable[gaugeName], "showGauge: no such gauge exists.") showWindow(gaugeName) showWindow(gaugeName .. "_back", newX) end --- Set the text on a custom gauge. --- --- @usage ---
---   setGaugeText("healthBar", "HP: 100%", 40, 40, 40)
---   
--- @usage ---
---   setGaugeText("healthBar", "HP: 100%", "red")
---   
--- --- @param gaugeName --- @param gaugeText An empty gaugeText will clear the text entirely. --- @param color1 Colors are optional and will default to 0,0,0(black) if not passed as args. --- @param color2 --- @param color3 --- --- @see createGauge function setGaugeText(gaugeName, gaugeText, color1, color2, color3) assert(gaugesTable[gaugeName], "setGauge: no such gauge exists.") local red,green,blue = 0,0,0 local l_labelText = gaugeText if color1 ~= nil then if color2 == nil then red, green, blue = getRGB(color1) else red, green, blue = color1, color2, color3 end end -- Check to make sure we had a text to apply, if not, clear the text if l_labelText == nil then l_labelText = "" end local l__Echostring = [[]] .. l_labelText .. [[]] echo(gaugeName, l__Echostring) -- do not set the text for the back, because
tags mess with the alignment --echo(gaugeName .. "_back", l__Echostring) gaugesTable[gaugeName].text = l__Echostring gaugesTable[gaugeName].color1, gaugesTable[gaugeName].color2, gaugesTable[gaugeName].color3 = color1, color2, color3 end --- Pads a hex number to ensure a minimum of 2 digits. --- --- @usage Following command will returns "F0". ---
---   PadHexNum("F")
---   
function PadHexNum(incString) local l_Return = incString if tonumber(incString,16)<16 then if tonumber(incString,16)<10 then l_Return = "0" .. l_Return elseif tonumber(incString,16)>10 then l_Return = l_Return .. "0" end end return l_Return end --- Converts an RGB value into an HTML compliant(label usable) HEX number. --- This function is colorNames aware and can take any defined global color as its first argument. --- --- @usage Both following commands will returns "FFFFFF". ---
---   RGB2Hex(255,255,255)
---   RGB2Hex("white")
---   
--- --- @see showColor function RGB2Hex(red, green, blue) local l_Red, l_Green, l_Blue = 0,0,0 if green == nil then -- Not an RGB but a "color" instead! l_Red, l_Green, l_Blue = getRGB(red) else -- Nope, true color here l_Red, l_Green, l_Blue = red, green, blue end return PadHexNum(string.format("%X",l_Red)) .. PadHexNum(string.format("%X",l_Green)) .. PadHexNum(string.format("%X",l_Blue)) end --- Get RGB component from color name. --- --- @usage Following will display "0.255.0" on your screen. ---
---   local red, green, blue = getRGB("green")
---   echo(red .. "." .. green .. "." .. blue )
---   
function getRGB(colorName) local red = color_table[colorName][1] local green = color_table[colorName][2] local blue = color_table[colorName][3] return red, green, blue end --- Make your very own customized gauge with this function. --- --- @usage This would make a gauge at that's 300px width, 20px in height, located at Xpos and Ypos and is green. ---
---   createGauge("healthBar", 300, 20, 30, 300, nil, 0, 255, 0)
---   
--- @usage The second example is using the same names you'd use for something like fg() or bg(). ---
---   createGauge("healthBar", 300, 20, 30, 300, nil, "green")
---   
--- @usage Finally we'll add some text to our gauche. ---
---   createGauge("healthBar", 300, 20, 30, 300, "Now with some text", "green")
---   
function createGauge(gaugeName, width, height, Xpos, Ypos, gaugeText, color1, color2, color3) -- make a nice background for our gauge createLabel(gaugeName .. "_back",0,0,0,0,1) if color2 == nil then local red, green, blue = getRGB(color1) setBackgroundColor(gaugeName .. "_back", red , green, blue, 100) else setBackgroundColor(gaugeName .. "_back", color1 ,color2, color3, 100) end moveWindow(gaugeName .. "_back", Xpos, Ypos) resizeWindow(gaugeName .. "_back", width, height) showWindow(gaugeName .. "_back") -- make a nicer front for our gauge createLabel(gaugeName,0,0,0,0,1) if color2 == nil then local red, green, blue = getRGB(color1) setBackgroundColor(gaugeName, red , green, blue, 255) else setBackgroundColor(gaugeName, color1 ,color2, color3, 255) end moveWindow(gaugeName, Xpos, Ypos) resizeWindow(gaugeName, width, height) showWindow(gaugeName) -- store important data in a table gaugesTable[gaugeName] = {width = width, height = height, xpos = Xpos, ypos = Ypos,text = gaugeText, color1 = color1, color2 = color2, color3 = color3} -- Set Gauge text (Defaults to black) -- If no gaugeText was passed, we'll just leave it blank! if gaugeText ~= nil then setGaugeText(gaugeName, gaugeText, "black") else setGaugeText(gaugeName) end end --- Use this function when you want to change the gauges look according to your values. --- Typical usage would be in a prompt with your current health or whatever value, and throw --- in some variables instead of the numbers. --- --- @usage In that example, we'd change the looks of the gauge named healthBar and make it fill --- to half of its capacity. The height is always remembered. ---
---   setGauge("healthBar", 200, 400)
---   
--- @usage Change the text on your gauge. ---
---   setGauge("healthBar", 200, 400, "some text")
---   
function setGauge(gaugeName, currentValue, maxValue, gaugeText) assert(gaugesTable[gaugeName], "setGauge: no such gauge exists.") assert(currentValue and maxValue, "setGauge: need to have both current and max values.") resizeWindow(gaugeName, gaugesTable[gaugeName].width/100*((100/maxValue)*currentValue), gaugesTable[gaugeName].height) -- if we wanted to change the text, we do it if gaugeText ~= nil then echo(gaugeName .. "_back", gaugeText) echo(gaugeName, gaugeText) gaugesTable[gaugeName].text = gaugeText end end --- Make a new console window with ease. The default background is black and text color white. --- If you wish to change the color you can easily do this when updating your text or manually somewhere, using --- setFgColor() and setBackgroundColor(). --- --- @usage This will create a miniconsole window that has a font size of 8pt, will display 80 characters in width, --- hold a maximum of 20 lines and be place at 200x400 of your Mudlet window. ---
---   createConsole("myConsoleWindow", 8, 80, 20, 200, 400)
---   
function createConsole(consoleName, fontSize, charsPerLine, numberOfLines, Xpos, Ypos) createMiniConsole(consoleName,0,0,1,1) setMiniConsoleFontSize(consoleName, fontSize) local x,y = calcFontSize( fontSize ) resizeWindow(consoleName, x*charsPerLine, y*numberOfLines) setWindowWrap(consoleName, charsPerLine) moveWindow(consoleName, Xpos, Ypos) setBackgroundColor(consoleName,0,0,0,0) setFgColor(consoleName, 255,255,255) end --- Suffixes text at the end of the current line when used in a trigger. --- --- @see prefix function suffix(what, func, fg, bg, window) local length = string.len(line) moveCursor(window or "main", length-1, getLineNumber()) if func and (func == cecho or func == decho or func == hecho) then func(what, fg, bg, true, window) else insertText(what) end end --- Prefixes text at the beginning of the current line when used in a trigger. --- --- @usage Prefix the hours, minutes and seconds onto our prompt even though Mudlet has a button for that. ---
---   prefix(os.date("%H:%M:%S "))
---   
--- --- @see suffix function prefix(what, func, fg, bg, window) moveCursor(window or "main", 0, getLineNumber()); if func and (func == cecho or func == decho or func == hecho) then func(what, fg, bg, true, window) else insertText(what) end end --- Function will gag the whole line. Use deleteLine() instead. function gagLine() deleteLine() end --- Replaces all occurrences of what in the current line with with. --- --- @usage This will replace all occurrences of John with the word Doe. ---
---   replaceAll("John", "Doe")
---
---   -- also handles recursive matches:
---   replaceAll("you", "you and me")
---   
function replaceAll(word, what) local startp, endp = 1, 1 while true do startp, endp = getCurrentLine():find(word, endp+(#what-#word)+1) if not startp then break end selectSection(startp-1, endp-startp+1) replace(what) end end --- Replace the whole with a string you'd like. --- --- @see deleteLine function replaceLine(what) selectString(line, 1) replace("") insertText(what) end --- Default resizeEvent handler function. Overwrite this function to make a custom event handler --- if the main window is being resized.

--- --- The standard implementation of this function does nothing. However, this function gets called whenever --- the main window is being manually resized. You can overwrite this function in your own scripts to handle window --- resize events yourself and e.g. adjust the screen position and size of your mini console windows, labels or --- other relevant GUI elements in your scripts that depend on the size of the main Window. To override this --- function you can simply put a function with the same name in one of your scripts thus overwriting the --- original empty implementation of this function. ---
---   function handleWindowResizeEvent()
---      -- determine the size of your screen
---      WindowWidth=0;
---      WindowHeight=0;
---      WindowWidth, WindowHeight = getMainWindowSize();
---      -- move mini console "sys" to the far right side of the screen whenever the screen gets resized
---      moveWindow("sys",WindowWidth-300,0)
---   end
---   
function handleWindowResizeEvent() end --- Clears the current selection in the main window or miniConsole window.
--- (Note: deselect(windowName) is implemented in Core Mudlet.) --- --- @usage Clear selection in main window. ---
---   deselect()
---   
--- @usage Clear selection in myMiniConsole window. ---
---   deselect("myMiniConsole")
---   
function deselect() selectString("", 1) end --- Sets current background color to a named color. --- --- @usage Set background color to magenta. ---
---   bg("magenta")
---
---   bg("my miniconsole", "blue")
---   
--- --- @see fg --- @see showColors function bg(console, colorName) local colorName = colorName or console assert(color_table[colorName], "bg: no such colour name") if console == colorName then setBgColor(color_table[colorName][1], color_table[colorName][2], color_table[colorName][3]) else setBgColor(console, color_table[colorName][1], color_table[colorName][2], color_table[colorName][3]) end end --- Sets current foreground color to a named color. --- --- @usage Set foreground color to black. ---
---   fg("black")
---   
--- --- @see bg --- @see showColors function fg(console, colorName) local colorName = colorName or console assert(color_table[colorName], "fg: no such colour name") if console == colorName then setFgColor(color_table[colorName][1], color_table[colorName][2], color_table[colorName][3]) else setFgColor(console, color_table[colorName][1], color_table[colorName][2], color_table[colorName][3]) end end --- Replaces the given wildcard (as a number) with the given text. --- --- @usage Replace "goodbye" with "hello" on a trigger of "^You wave (goodbye)\.$" ---
---   replaceWildcard(2, "hello")
---   
--- Is equivalent to doing: ---
---   selectString(matches[2], 1)
---   replace("hello")
---   
function replaceWildcard(what, replacement) if replacement == nil or what == nil then return end selectCaptureGroup(what) replace(replacement) end --- Prints out a formatted list of all available named colors, optional arg specifies number of columns to print in, defaults to 3 --- --- @usage Print list in 3 columns by default. ---
---   showColors()
---   
--- @usage Print list in 2 columns. ---
---   showColors(2)
---   
--- --- @see color_table function showColors(...) local cols = ... or 3 local i = 1 for k,v in pairs(color_table) do local fg local luminosity = (0.2126 * ((v[1]/255)^2.2)) + (0.7152 * ((v[2]/255)^2.2)) + (0.0722 * ((v[3]/255)^2.2)) if luminosity > 0.5 then fg = "black" else fg = "white" end cecho(string.format("<%s:%s>%s%s", fg, k, k, string.rep(" ", 23-k:len()))) echo" " if i == cols then echo"\n" i = 1 else i = i + 1 end end end --- TODO resizeGauge(gaugeName, width, height) function resizeGauge(gaugeName, width, height) assert(gaugesTable[gaugeName], "resizeGauge: no such gauge exists.") assert(width and height, "resizeGauge: need to have both width and height.") resizeWindow(gaugeName, width, height) resizeWindow(gaugeName .. "_back", width, height) -- save in the table gaugesTable[gaugeName].width, gaugesTable[gaugeName].height = width, height end --- TODO setGaugeStyleSheet(gaugeName, css, cssback) function setGaugeStyleSheet(gaugeName, css, cssback) if not setLabelStyleSheet then return end-- mudlet 1.0.5 and lower compatibility assert(gaugesTable[gaugeName], "setGaugeStyleSheet: no such gauge exists.") setLabelStyleSheet(gaugeName, css) setLabelStyleSheet(gaugeName .. "_back", cssback or css) end if rex then _Echos = { Patterns = { Hex = { [[(\x5c?\|c[0-9a-fA-F]{6}?(?:,[0-9a-fA-F]{6})?)|(\|r)]], rex.new[[\|c(?:([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2}))?(?:,([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2}))?]], }, Decimal = { -- [[(\x5c?<[0-9,:]+>)|()]], [[(<[0-9,:]+>)|()]], rex.new[[<(?:([0-9]{1,3}),([0-9]{1,3}),([0-9]{1,3}))?(?::(?=>))?(?::([0-9]{1,3}),([0-9]{1,3}),([0-9]{1,3}))?>]], }, Color = { [[(<[a-zA-Z_,:]+>)]], rex.new[[<([a-zA-Z_]+)?(?:[:,](?=>))?(?:[:,]([a-zA-Z_]+))?>]], }, Ansi = { [[(<[0-9,:]+>)]], rex.new[[<([0-9]{1,2})?(?::([0-9]{1,2}))?>]], }, }, Process = function(str, style) local t = {} local tonumber = tonumber for s, c, r in rex.split(str, _Echos.Patterns[style][1]) do if c and (c:byte(1) == 92) then c = c:sub(2) if s then s = s .. c else s = c end c = nil end if s then t[#t+1] = s end if r then t[#t+1] = "\27reset" end if c then if style == 'Hex' or style == 'Decimal' then local fr, fg, fb, br, bg, bb = _Echos.Patterns[style][2]:match(c) local color = {} if style == 'Hex' then if fr and fg and fb then fr, fg, fb = tonumber(fr, 16), tonumber(fg, 16), tonumber(fb, 16) end if br and bg and bb then br, bg, bb = tonumber(br, 16), tonumber(bg, 16), tonumber(bb, 16) end end if fr and fg and fb then color.fg = { fr, fg, fb } end if br and bg and bb then color.bg = { br, bg, bb } end t[#t+1] = color elseif style == 'Color' then if c == "" then t[#t+1] = "\27reset" else local fcolor, bcolor = _Echos.Patterns[style][2]:match(c) local color = {} if fcolor and color_table[fcolor] then color.fg = color_table[fcolor] end if bcolor and color_table[bcolor] then color.bg = color_table[bcolor] end if color.fg or color.bg then t[#t+1] = color else t[#t+1] = c end end end end end return t end, } --- Generic color echo and insert function (allowing hecho, decho, cecho, hinsertText, dinsertText and cinsertText). --- --- @param style Hex, Decimal or Color --- @param insert boolean flag to determine echo/insert behaviour --- @param win windowName optional --- @param str text with embedded color information --- --- @see cecho --- @see decho --- @see hecho --- @see cinsertText --- @see dinsertText --- @see hinsertText function xEcho(style, func, ...) local win, str, cmd, hint, fmt local out, reset local args = {...} local n = #args if func == 'echoLink' then if n < 3 then error'Insufficient arguments, usage: ([window, ] string, command, hint)' elseif n == 3 then str, cmd, hint = ... elseif n == 4 and type(args[4]) == 'boolean' then str, cmd, hint, fmt = ... elseif n >= 4 and type(args[4]) == 'string' then win, str, cmd, hint = ... else error'Improper arguments, usage: ([window, ] string, command, hint)' end else if args[1] and args[2] then win, str = args[1], args[2] else str = args[1] end end out = function(...) _G[func](...) end if win then reset = function() resetFormat(win) end else reset = function() resetFormat() end end local t = _Echos.Process(str, style) deselect() reset() for _, v in ipairs(t) do if type(v) == 'table' then if v.fg then local fr, fg, fb = unpack(v.fg) if win then setFgColor(win, fr, fg, fb) else setFgColor(fr, fg, fb) end end if v.bg then local br, bg, bb = unpack(v.bg) if win then setBgColor(win, br, bg, bb) else setBgColor(br, bg, bb) end end elseif v == "\27reset" then reset() else if func == 'echo' or func == 'insertText' then if win then out(win, v) else out(v) end if func == 'insertText' then moveCursor(window or "main", getColumnNumber() + string.len(v), getLineNumber()) end else -- if win and fmt then setUnderline(win, true) elseif fmt then setUnderline(true) end -- not sure if underline is necessary unless asked for if win then out(win, v, cmd, hint, fmt) else out(v, cmd, hint, fmt) end end end end reset() end --- Echo string with embedded hex color information.

--- --- Color changes can be made within the string using the format |cFRFGFB,BRBGBB where FR is the foreground red value, --- FG is the foreground green value, FB is the foreground blue value, BR is the background red value, etc., BRBGBB is optional. --- |r can be used within the string to reset the colors to default. --- --- @usage Print red test on green background. ---
---   hecho("|cff0000,00ff00test")
---   
--- --- @see xEcho --- @see hinsertText function hecho(...) xEcho("Hex", "echo", ...) end --- Echo string with embedded decimal color information.

--- --- Color changes can be made using the format <FR,FG,FB:BR,BG,BB> where each field is a number from 0 to 255. --- The background portion can be omitted using <FR,FG,FB> or the foreground portion can be omitted using <:BR,BG,BB>. --- --- @usage Print red test on green background. ---
---   decho("<255,0,0:0,255,0>test")
---   
--- --- @see xEcho --- @see dinsertText function decho(...) xEcho("Decimal", "echo", ...) end --- Echo string with embedded color name information. --- --- @usage Consider following example: ---
---   cecho("<green>green text <blue>blue text <red>red text")
---   
--- --- @see xEcho --- @see cinsertText function cecho(...) xEcho("Color", "echo", ...) end --- Inserts string with embedded hex color information. --- --- @see xEcho --- @see hecho function hinsertText(...) xEcho("Hex", "insertText", ...) end --- Inserts string with embedded decimal color information. --- --- @see xEcho --- @see decho function dinsertText(...) xEcho("Decimal", "insertText", ...) end --- Inserts string with embedded color name information. --- --- @see xEcho --- @see cecho function cinsertText(...) xEcho("Color", "insertText", ...) end --- Echos a link with embedded hex color information. --- --- @usage hechoLink([window, ] string, command, hint) --- --- @see xEcho --- @see hecho function hechoLink(...) xEcho("Hex", "echoLink", ...) end --- Echos a link with embedded decimal color information. --- --- @usage dechoLink([window, ] string, command, hint) --- --- @see xEcho --- @see decho function dechoLink(...) xEcho("Decimal", "echoLink", ...) end --- Echos a link with embedded color name information. --- --- @usage cechoLink([window, ] string, command, hint) --- --- @see xEcho --- @see cecho function cechoLink(...) xEcho("Color", "echoLink", ...) end -- Backwards compatibility checho = cecho else -- NOT LUADOC -- See xEcho/another cecho for description. function cecho(window, text) local win = text and window local s = text or window if win then resetFormat(win) else resetFormat() end for color,text in string.gmatch(""..s, "<([a-z_0-9, :]+)>([^<>]+)") do local colist = string.split(color..":", "%s*:%s*") local fgcol = colist[1] ~= "" and colist[1] or "white" local bgcol = colist[2] ~= "" and colist[2] or "black" local FGrgb = color_table[fgcol] or string.split(fgcol, ",") local BGrgb = color_table[bgcol] or string.split(bgcol, ",") if win then setFgColor(win, FGrgb[1], FGrgb[2], FGrgb[3]) setBgColor(win, BGrgb[1], BGrgb[2], BGrgb[3]) echo(win,text) else setFgColor(FGrgb[1], FGrgb[2], FGrgb[3]) setBgColor(BGrgb[1], BGrgb[2], BGrgb[3]) echo(text) end end if win then resetFormat(win) else resetFormat() end end -- NOT LUADOC -- See xEcho/another decho for description. function decho(window, text) local win = text and window local s = text or window local reset if win then reset = function() resetFormat(win) end else reset = function() resetFormat() end end reset() for color, text in s:gmatch("<([0-9,:]+)>([^<>]+)") do if color == "reset" then reset() if win then echo(win, text) else echo(text) end else local colist = string.split(color..":", "%s*:%s*") local fgcol = colist[1] ~= "" and colist[1] or "white" local bgcol = colist[2] ~= "" and colist[2] or "black" local FGrgb = color_table[fgcol] or string.split(fgcol, ",") local BGrgb = color_table[bgcol] or string.split(bgcol, ",") if win then setFgColor(win, FGrgb[1], FGrgb[2], FGrgb[3]) setBgColor(win, BGrgb[1], BGrgb[2], BGrgb[3]) echo(win,text) else setFgColor(FGrgb[1], FGrgb[2], FGrgb[3]) setBgColor(BGrgb[1], BGrgb[2], BGrgb[3]) echo(text) end end end reset() end end do local oldreplace = replace function replace(text, keep_color) local text = text or "" if keep_color then setBgColor(getBgColor()) setFgColor(getFgColor()) end oldreplace(text) end end mudlet-2.1/src/old_mudlet-lua/lua/TableUtils.lua0000644000175000017500000002070312070466513021216 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Table Utils ---------------------------------------------------------------------------------- --- Tests if a table is empty: this is useful in situations where you find --- yourself wanting to do 'if my_table == {}' and such. --- --- @usage Testing if the table is empty. ---
---   myTable = {}
---   if table.is_empty(myTable) then
---      echo("myTable is empty")
---   end
---   
function table.is_empty(tbl) for k, v in pairs(tbl) do return false end return true end --- Lua debug function that prints the content of a Lua table on the screen, split up in keys and values. --- Useful if you want to see what the capture groups contain i. e. the Lua table "matches". --- --- @see display function printTable( map ) echo("-------------------------------------------------------\n"); for k, v in pairs( map ) do echo( "key=" .. k .. " value=" .. v .. "\n" ) end echo("-------------------------------------------------------\n"); end -- NOT LUADOC -- This is supporting function for printTable(). function __printTable( k, v ) insertText ("\nkey = " .. tostring (k) .. " value = " .. tostring( v ) ) end --- Lua debug function that prints the content of a Lua table on the screen.
--- There are currently 3 functions with similar behaviour. --- --- @see display --- @see printTable function listPrint( map ) echo("-------------------------------------------------------\n"); for k,v in ipairs( map ) do echo( k .. ". ) "..v .. "\n" ); end echo("-------------------------------------------------------\n"); end --- TODO listAdd( list, what ) function listAdd( list, what ) table.insert( list, what ); end --- TODO listRemove( list, what ) function listRemove( list, what ) for k,v in ipairs( list ) do if v == what then table.remove( list, k ) end end end --- Gets the actual size of non-index based tables.

--- --- For index based tables you can get the size with the # operator:
--- This is the standard Lua way of getting the size of index tables i.e. ipairs() type of tables with --- numerical indices. To get the size of tables that use user defined keys instead of automatic indices --- (pairs() type) you need to use the function table.size() referenced above. ---
---   myTableSize = # myTable
---   
function table.size(t) if not t then return 0 end local i = 0 for k, v in pairs(t) do i = i + 1 end return i end --- Determines if a table contains a value as a key or as a value (recursive). function table.contains(t, value) for k, v in pairs(t) do if v == value then return true elseif k == value then return true elseif type(v) == "table" then if table.contains(v, value) then return true end end end return false end --- Table Union. --- --- @return Returns a table that is the union of the provided tables. This is a union of key/value --- pairs. If two or more tables contain different values associated with the same key, --- that key in the returned table will contain a subtable containing all relevant values. --- See table.n_union() for a union of values. Note that the resulting table may not be --- reliably traversable with ipairs() due to the fact that it preserves keys. If there --- is a gap in numerical indices, ipairs() will cease traversal. --- --- @usage Example: ---
---   tableA = {
---      [1] = 123,
---      [2] = 456,
---      ["test"] = "test",
---   }
---
---   tableB = {
---      [1] = 23,
---      [3] = 7,
---      ["test2"] = function() return true end,
---   }
---
---   tableC = {
---      [5] = "c",
---   }
---
---   table.union(tableA, tableB, tableC) will return:
---   {
---      [1] = {
---         123,
---         23,
---      },
---      [2] = 456,
---      [3] = 7,
---      [5] = "c",
---      ["test"] = "test",
---      ["test2"] = function() return true end,
---   }
---   
function table.union(...) local sets = {...} local union = {} for _, set in ipairs(sets) do for key, val in pairs(set) do if union[key] and union[key] ~= val then if type(union[key]) == 'table' then table.insert(union[key], val) else union[key] = { union[key], val } end else union[key] = val end end end return union end --- Table Union. --- --- @return Returns a numerically indexed table that is the union of the provided tables. This is --- a union of unique values. The order and keys of the input tables are not preserved. function table.n_union(...) local sets = {...} local union = {} local union_keys = {} for _, set in ipairs(sets) do for key, val in pairs(set) do if not union_keys[val] then union_keys[val] = true table.insert(union, val) end end end return union end --- Table Intersection. --- --- @return Returns a table that is the intersection of the provided tables. This is an --- intersection of key/value pairs. See table.n_intersection() for an intersection of values. --- Note that the resulting table may not be reliably traversable with ipairs() due to --- the fact that it preserves keys. If there is a gap in numerical indices, ipairs() will --- cease traversal. --- --- @usage Example: ---
---   tableA = {
---      [1] = 123,
---      [2] = 456,
---      [4] = { 1, 2 },
---      [5] = "c",
---      ["test"] = "test",
---   }
---
---   tableB = {
---      [1] = 123,
---      [2] = 4,
---      [3] = 7,
---      [4] = { 1, 2 },
---      ["test"] = function() return true end,
---   }
---
---   tableC = {
---      [1] = 123,
---      [4] = { 1, 2 },
---      [5] = "c",
---   }
---
---   table.intersection(tableA, tableB, tableC) will return:
---   {
---      [1] = 123,
---      [4] = { 1, 2 },
---   }
---   
function table.intersection(...) sets = {...} if #sets < 2 then return false end local intersection = {} local function intersect(set1, set2) local result = {} for key, val in pairs(set1) do if set2[key] then if _comp(val, set2[key]) then result[key] = val end end end return result end intersection = intersect(sets[1], sets[2]) for i, _ in ipairs(sets) do if i > 2 then intersection = intersect(intersection, sets[i]) end end return intersection end --- Table Intersection. --- --- @return Returns a numerically indexed table that is the intersection of the provided tables. --- This is an intersection of unique values. The order and keys of the input tables are --- not preserved. function table.n_intersection(...) sets = {...} if #sets < 2 then return false end local intersection = {} local function intersect(set1, set2) local intersection_keys = {} local result = {} for _, val1 in pairs(set1) do for _, val2 in pairs(set2) do if _comp(val1, val2) and not intersection_keys[val1] then table.insert(result, val1) intersection_keys[val1] = true end end end return result end intersection = intersect(sets[1], sets[2]) for i, _ in ipairs(sets) do if i > 2 then intersection = intersect(intersection, sets[i]) end end return intersection end --- Table Complement. --- --- @return Returns a table that is the relative complement of the first table with respect to --- the second table. Returns a complement of key/value pairs. function table.complement(set1, set2) if not set1 and set2 then return false end if type(set1) ~= 'table' or type(set2) ~= 'table' then return false end local complement = {} for key, val in pairs(set1) do if not _comp(set2[key], val) then complement[key] = val end end return complement end --- Table Complement. --- --- @return Returns a table that is the relative complement of the first table with respect to --- the second table. Returns a complement of values. function table.n_complement(set1, set2) if not set1 and set2 then return false end local complement = {} for _, val1 in pairs(set1) do local insert = true for _, val2 in pairs(set2) do if _comp(val1, val2) then insert = false end end if insert then table.insert(complement, val1) end end return complement end --- TODO table:update(t1, t2) function table:update(t1, t2) for k,v in pairs(t2) do if type(v) == "table" then t1[k] = self.update(t1[k] or {}, v) else t1[k] = v end end return t1 end ---Returns the index of the value in a table function table.index_of(table, element) for index, value in ipairs(table) do if value == element then return index end end return nil end mudlet-2.1/src/old_mudlet-lua/lua/LuaGlobal.lua0000644000175000017500000000553712070466513021020 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Lua packages loader ---------------------------------------------------------------------------------- if package.loaded["rex_pcre"] then rex = require "rex_pcre" end if package.loaded["lpeg"] then lpeg = require "lpeg" end if package.loaded["zip"] then zip = require "zip" end if package.loaded["lfs"] then lfs = require "lfs" end -- TODO this is required by DB.lua, so we might load it all at one place --if package.loaded["luasql.sqlite3"] then require "luasql.sqlite3" end json_to_value = yajl.to_value gmcp = {} function __gmcp_merge_gmcp_sub_tables( a, key ) local _m = a.__needMerge; for k,v in pairs(_m) do a[key][k] = v; end a.__needMerge = nil end function unzip( what, dest ) cecho("\nunpacking package:<"..what.."< to <"..dest..">\n") local z, err = zip.open( what ) if not z then cecho("\nerror unpacking: "..err) return end local createdDirs = {} for file in z:files() do local _f, err = z:open( file.filename ) local _data = _f:read("*a") local _path = dest .. file.filename local _dir = string.split( file.filename, '/' ) local created = dest; for k,v in ipairs( _dir ) do if k < # _dir then created = created .. '/'.. v; if not table.contains( createdDirs, created ) then table.insert( createdDirs, created ); lfs.mkdir( created ); cecho("--> creating dir:" .. created .. "\n"); end elseif file.uncompressed_size == 0 then if not table.contains( createdDirs, created ) then cecho("--> creating dir:" .. file.filename .. "\n") table.insert( createdDirs, created ); lfs.mkdir( file.filename ) end end end local _path = dest .. file.filename if file.uncompressed_size > 0 then local out = io.open( _path, "wb" ) if out then cecho("unpacking file:".._path.."\n") out:write( _data ) out:close() else echo("ERROR: can't write file:".._path.."\n") end end _f:close(); end z:close() end function onConnect() end function handleWindowResizeEvent() end local packages = { "StringUtils.lua", "TableUtils.lua", "Logging.lua", "DebugTools.lua", "DB.lua", "geyser/Geyser.lua", "geyser/GeyserGeyser.lua", "geyser/GeyserUtil.lua", "geyser/GeyserColor.lua", "geyser/GeyserSetConstraints.lua", "geyser/GeyserContainer.lua", "geyser/GeyserWindow.lua", "geyser/GeyserLabel.lua", "geyser/GeyserGauge.lua", "geyser/GeyserMiniConsole.lua", "geyser/GeyserMapper.lua", "geyser/GeyserReposition.lua", "geyser/GeyserHBox.lua", "geyser/GeyserVBox.lua", -- TODO probably don't need to load this file "geyser/GeyserTests.lua", "GUIUtils.lua", "Other.lua", "GMCP.lua", } for _, package in ipairs(packages) do local result = pcall(dofile, "./mudlet-lua/lua/" .. package) or echo("Error attempting to load file: " .. package .. "\n") end mudlet-2.1/src/old_mudlet-lua/lua/CoreMudlet.lua0000644000175000017500000021150712070466513021215 0ustar csmallcsmall---------------------------------------------------------------------------------- --- Mudlet Core Lua Functions --- (file holds LuaDoc for all function implemented with in Mudlet Core) ---------------------------------------------------------------------------------- -- ensure that those function will not get defined if false then --- Pastes the previously copied rich text (including text formats like color) into user window name. --- --- @usage ---
---   selectString(line, 1)
---   copy()
---   appendBuffer("chat")
---   
--- --- @see selectString --- @see copy --- @see echo function appendBuffer(windowName) end --- This returns you the height and the length of letters for the given font size. As the primary intended --- usage is for calculating the needed dimensions of a miniConsole, it doesn't accept a font argument - --- as the miniConsoles currently only work with the default font for the sake of portability. --- --- @usage Get font dimensions in pixes. ---
---   x,y = calcFontSize(10)
---   
--- @usage Create a miniConsole that is 45 letters in length and 25 letters in height for font size 7 ---
---   font_size = 7
---   local x, y = calcFontSize( font_size )
---   createMiniConsole("map",0,0,0,0)
---   setMiniConsoleFontSize("map", font_size)
---   resizeWindow( "map", x*45, y*25 )
---   
function calcFontSize(fontSize) end --- The channel102 table is used by Aardwolf mud for returning various information about you state.
--- Read http://www.aardwolf.com/blog/2008/07/10/telnet-negotiation-control-mud-client-interaction/ --- page for details. --- --- @usage Display content of channel10 table. ---
---   display(channel102)
---   
--- @usage Function for detecting AFK status on Aardwolf mud. ---
---   function amIafk()
---      for k,v in pairs(channel102) do
---         if k==100 and v==4 then
---            return true
---         end
---      end
---      return false
---   end
---   
--- --- @see sendTelnetChannel102 --- --- @class function --- @name channel102 channel102 = {} --- Clears the user window or a mini console with the name given as argument. --- TODO is this still working? function clearUserWindow(windowName) end --- TODO clearWindow - TLuaInterpreter::clearUserWindow function clearWindow(windowName) end --- Clears the user window or a mini console with the name given as argument. --- --- @param windowName optinal function closeUserWindow(windowName) end --- The command variable holds initial user command e.g. unchanged by any aliases or triggers. --- This is typically used in alias scripts. --- --- @see line --- --- @class function --- @name command command = "" --- Copies the current selection to the clipboard. This function operates on rich text, i.e. --- the selected text including all its format codes like colors, fonts etc. in the clipboard --- until it gets overwritten by another copy operation. example: This script copies the current --- line on the main screen to a user window (mini console) named chat and gags the output on --- the main screen. --- --- @usage ---
---   selectString(line)
---   copy()
---   appendBuffer("chat")
---   replace("This line has been moved to the chat window!")
---   
--- --- @see paste --- @see appendBuffer function copy() end --- Creates a named buffer for formatted text, much like a user terminal window, but the buffer --- cannot be shown on the screen; intended for temporary buffer work function createBuffer(name) end --- TODO createButton - TLuaInterpreter::createButton function createButton() end --- Labels are intended for very small variable or prompt displays or images. labels are clickable and if you specify a callback function with --- setLabelClickCallback( labelName, myLabelOnClickFunction ) your function will get called if the user clicks on the label with the mouse. --- If fillBackground = 0, the background will be hidden, if fillBackground = 1 the background will be shown i.e. you can see the background color. --- labels can be transparent. You can place labels anywhere within then main display, also als overlays over the main displays e.g. for on --- screen buttons, micro display, etc. DON'T use labels for larger text displays because they are a lot slower than the highspeed mini consoles. ---

--- Labels accept some HTML and CSS code for text formating. --- --- @return true or false --- --- @usage This example creates a transparent overlay message box to show a big warning message "You are under attack!" in the middle of the screen. --- Because the background color has a transparency level of 150 (0-255, with 0 being completely transparent and 255 non-transparent) the background --- text can still be read through. The message box will disappear after 2.3 seconds. ---
---   local width, height = getMainWindowSize()
---   createLabel("messageBox",(width/2)-300,(height/2)-100,250,150,1)
---   resizeWindow("messageBox",500,70)
---   moveWindow("messageBox", (width/2)-300,(height/2)-100 )
---   setBackgroundColor("messageBox", 150,100,100,200)
---   echo("messageBox", [[<p style="font-size:35px"><b><center><font color="red">You are under attack!</font></center></b></p>]] )
---   showWindow("messageBox")
---   -- close the warning message box after 2.3 seconds
---   tempTimer(2.3, [[hideWindow("messageBox")]] )
---   
--- @usage see forum for more examples ---
---  http://mudlet.sourceforge.net/phpBB3/viewtopic.php?f=6&t=95
---  http://mudlet.sourceforge.net/phpBB3/viewtopic.php?f=6&t=865
---  
--- --- @see createMiniConsole --- @see hideWindow --- @see showWindow --- @see resizeWindow --- @see setLabelClickCallback --- @see setTextFormat --- @see moveWindow --- @see setMiniConsoleFontSize --- @see handleWindowResizeEvent --- @see setBorderTop --- @see setBorderColor function createLabel(name, posX, posY, width, height, fillBackground) end --- Opens a console window inside the main window of Mudlet. MiniConsole is openes at position posX/posY with size --- according to width/height (values depend on your own screen resolution usually between 0-1600 for x and 0-1024 --- for y). This console is the ideal fast colored text display for everything that requires a bit more text e.g. --- status screens, log windows, chat windows etc.. You can use clearWindow/moveCursor etc. functions for this window --- for custom printing as well as copy & paste functions for colored text copies from the main window or normal --- echoUserWindow(name, text) for normal printing. To set word wrap see setWindowWrap. To move the main window to --- make room for miniconsole windows on your screen (if you want to do this as you can also layer mini console --- and label windows) see setBorderTop, setBorderColor To have your screen layout adjusted after the window size --- of the main screen gets resized see handleWindowResizeEvent --- --- @usage Set up the small system message window in the top right corner ---
---   -- determine the size of your screen
---   WindowWidth = 0
---   WindowHeight = 0
---   WindowWidth, WindowHeight = getMainWindowSize()
---
---   createMiniConsole("sys",WindowWidth-650,0,650,300)
---   setBackgroundColor("sys",85,55,0,255)
---   setMiniConsoleFontSize("sys", 8)
---   -- wrap lines in window "sys" at 65 characters per line
---   setWindowWrap("sys", 40)
---   -- set default font colors and font style for window "sys"
---   setTextFormat("sys",0,35,255,50,50,50,0,0,0)
---
---   echo("sys","Hello world!")
---   
--- --- @see createLabel --- @see hideWindow --- @see showWindow --- @see resizeWindow --- @see setTextFormat --- @see moveWindow --- @see setMiniConsoleFontSize --- @see handleWindowResizeEvent --- @see setBorderTop --- @see setBorderColor --- @see setWindowWrap --- --- @return true or false function createMiniConsole(name, posX, posY, width, height) end --- This function creates a stop watch. It is high resolution time --- measurement tool. Stop watches can be started, stopped, reset and asked --- how much time has passed since the stop watch has been started. Returns --- the ID of a high resolution clock with milliseconds to measure time more --- accurately than what is possible with std. Lua routines ? --- startStopWatch, stopStopWatch, resetStopWatch, getStopWatchTime example: --- In a global script you create all stop watches that you need in your --- system and store the respective stopWatch-IDs in global variables: --- --- @return stop watch ID --- --- @usage ---
---   fightStopWatchID = createStopWatch()
---   -- you store the watchID in a global variable to access it from anywhere
---   startStopWatch(fightStopWatch)
---   -- To stop the watch and measure its time in e.g. a trigger script you can write:
---   fightTime = stopStopWatch(fightStopWatchID)
---   echo("The fight lasted for " .. fightTime .. " seconds.")
---   resetStopWatch(fightStopWatchID)
---   
--- --- @see startStopWatch --- @see resetStopWatch --- @see getStopWatchTime function createStopWatch() end --- TODO cut - TLuaInterpreter::cut function cut() end --- Deletes the current Line under the user cursor. Note: This is a high speed gagging tool --- and it is very good at this task. It is meant to be used when the line can be omitted --- entirely in the output. If you want to replace this line with something else have a look --- at the replace() functions below.

--- --- Note that scripts such as: deleteLine(); echo("this line is gone"); will not work because --- lines that have been gagged with deleteLine() will not be rendered even if there is text --- in the buffer. See wrapLine for details on how to force a re-render if this is necessary --- for some reason. This is not the recommended way of replacing text. --- --- @see wrapLine --- @see replace function deleteLine() end --- Disables/deactivates an alias with the given name. This means that when you type in text that should --- match it's pattern, it won't match and will be sent to the MUD. If several aliases have this name, they'll all be disabled. function disableAlias(name) end --- Uses trigger name as id or the id returned by tempTrigger() TODO tempKey? function disableKey(name) end --- Disables a timer from running it's script when it fires - so the timer --- cycles will still be happening, just no action on them. If you'd like to --- permanently delete it, use killTimer() instead.

--- --- Use timer name or the id returned by tempTimer() to identify the timer --- that you want to disable. --- --- @see tempTimer --- @see killTimer function disableTimer(name) end --- Use trigger name or the id returned by tempTrigger() to identify the --- timer that you want to disable. --- --- @see tempTrigger function disableTrigger(name) end --- Disconnect from current session without a proper logout. --- --- @see reconnect function disconnect() end --- This function appends text at the end of the current line. The current cursor position is ignored. --- Use moveCursor() and insertText() if you want to print at a different cursor position.
--- If the first argument is omitted the main console is used, otherwise the mini console windowName. --- --- @param windowName optional --- --- @usage Writes text to main window. ---
---   echo("Hello world\n")
---   
--- @usage Writes text to the mini console named "info" if such a window exists. ---
---   echo("info", "Hello this is the info window\n")
---   
--- --- @see moveCursor --- @see insertText function echo(windowName, text) end --- Echos a piece of text as a clickable link.
--- --- @release Mudlet 1.1.0-pre1 --- --- @usage Following will create "click me now" link. ---
---   echoLink("hi", [[echo("hey bub!")]], "click me now")
---   
--- --- @param windowName optional window name --- @param text to display in the echo. Same as a normal echo(). --- @param command lua code to do when the link is clicked. --- @param hint text for the tooltip to be displayed when the mouse is over the link. --- @param useCurrentFormat true/false - controls whenever the current text formatting (colors, underline, bold, etc) --- should be used, or the default link format. --- --- @see setLink --- @see insertLink function echoLink(windowName, text, command, hint, useCurrentFormat) end --- Same as setPopup() except it doesn't require a selection. Method echoPopup creates a link from the given text that it echos. --- --- @release Mudlet 1.1.0-pre1 --- --- @usage ---
---   echoPopup("activities to do", {[[send "sleep"]], [[send "sit"]], [[send "stand"]]}, {"sleep", "sit", "stand"})
---   
--- --- @see setPopup --- @see insertPopup function echoPopup() end --- This function will print text to both mini console windows, dock windows and labels. --- This function is outdated. Use echo( windowName, text ) instead. --- --- @see echo function echoUserWindow(windowName, text) end --- Enables/activates the alias by it's name. If several aliases have this name, they'll all be enabled. function enableAlias(name) end --- Enable key or key group "name" (hot keys or action keys). function enableKey(name) end --- Enables or activates a timer that was previously disabled. The parameter --- "name" expects the timer ID that was returned by tempTimer() on creation --- of the timer or the name of the timer in case of a GUI timer function enableTimer(name) end --- Enables a Trigger. see enableTimer() for more details. --- --- @see enableTimer function enableTrigger(name) end --- Tells you how many things of the given type exist. --- --- @param type can be "alias", "trigger", or "timer". --- --- @return number --- --- @usage ---
---   echo("I have " .. exists("my trigger", "trigger") .. " triggers called 'my trigger'!")
---   
--- @usage You can also use this alias to avoid creating duplicate things, for example: ---
---   -- this code doesn't check if an alias already exists and will keep creating new aliases
---   permAlias("Attack", "General", "^aa$", [[send ("kick rat")]])
---
---   -- while this code will make sure that such an alias doesn't exist first
---   -- we do == 0 instead of 'not exists' because 0 is considered true in Lua
---   if exists("Attack", "alias") == 0 then
---       permAlias("Attack", "General", "^aa$", [[send ("kick rat")]])
---   end
---   
--- --- @see isActive function exists(name, type) end --- Like send(), but without bypassing alias expansion. This function may lead to infinite recursion if --- you are not careful!

--- --- Now, while in Mudlet you can call another alias with the expandAlias() function, this is strongly --- discouraged. What you do instead if create a function (for example, send() and echo() are functions) --- that you can then call from your alias or trigger. This has many advantages - it's faster, you can --- easily give your function values, and your function can return you values, too.

--- --- Note: The variable "command" contains what was entered in the command line or issued via the expandAlias() --- function. If you use expandAlias( command ) inside an alias script the command would be doubled. You have --- to use send( ) inside an alias script to prevent recursion. This will send the data directly and bypass --- the alias expansion. --- --- @see send function expandAlias(command, print=1) end --- This function will have Mudlet parse the given text as if it came from the MUD - one great application --- is trigger testing. You can use \n to represent a new line. The function also accept ANSI color codes that --- are used in MUDs. A sample table can be found here. --- --- @usage Usage of new line characters. ---
---   feedTriggers("\nYou sit yourself down.\n")
---   
--- @usage Demonstration of ANSI color.
---
---   feedTriggers("\nThis is \27[1;32mgreen\27[0;37m, \27[1;31mred\27[0;37m, " ..
---      "\27[46mcyan background\27[0;37m,\27[32;47mwhite background and green foreground\27[0;37m.\n")
---   
function feedTriggers(text) end --- Get the RGB values of the first character of the current selection. --- --- @param windowName optional --- --- @usage Getting RGB component. ---
---   r,g,b = getBgColor(windowName)
---   
--- --- @see getFgColor function getBgColor(windowName) end --- This function can be used in checkbox button scripts (2-state buttons) to determine the current state of the checkbox. --- --- @usage ---
---   checked = getButtonStated()
---   if checked == 1 then
---       hideExits()
---   else
---       showExits()
---   end
---   
--- --- @return numneric state; state = 1 button is checked and state = 0, button is not checked function getButtonState() end --- Gets the absolute column number of the current user cursor. function getColumnNumber() end --- Returns the content of the current line under the user cursor in the --- buffer. The Lua variable line holds the content of getCurrentLine() --- before any triggers have been run on this line. When triggers change the --- content of the buffer, the variable line will not be adjusted and thus --- hold an outdated string. line = getCurrentLine() will update line to the --- real content of the current buffer. This is important if you want to --- copy the current line after it has been changed by some triggers. --- selectString( line,1 ) will return false and won't select anything --- because line no longer equals getCurrentLine(). Consequently, --- selectString( getCurrentLine(), 1 ) is what you need. --- --- @usage Update line variable with content of current line. ---
---   line = getCurrentLine()
---   
--- --- @see selectString function getCurrentLine() end --- This function returns the RGB values of the color of the first character of the current selection --- on mini console (window) windowName. --- --- @param windowName optional - if windowName is omitted Mudlet will use the main screen. --- --- @usage ---
---   r,g,b = getFgColor(windowName)
---   
--- @usage ---
---   local r,g,b
---   selectString("troll", 1)
---   r,g,b = getFgColor()
---   if r == 255 and g == 0 and b == 0 then
---       echo("HELP! troll is written in red letters, the monster is aggressive!\n")
---   end
---   
--- --- @see getBgColor function getFgColor(windowName) end --- Returns number of the last line in the text buffer. function getLastLineNumber() end --- Gets the absolute amount of lines in the current console buffer. --- --- @return number function getLineCount() end --- Gets the absolute line number of the current user cursor. function getLineNumber() end --- Returns a Lua table with the content of the lines on a per line basis. Absolute line numbers are used. --- --- @return section of the content of the screen text buffer. The form of the return value is: Lua_table[relative_linenumber, content] function getLines(from_line_number, to_line_number) end --- Return window width and window height (function have two return values). This is useful for calculating the window dimensions and --- placement of custom GUI toolkit items like labels, buttons, mini consoles etc. --- --- @usage ---
---   mainWindowWidth, mainWindowHeight = getMainWindowSize()
---   
--- --- @return 2 numbers, width and height in pixels function getMainWindowSize() end --- Returns the current home directory of the current profile. This can be used to store data, --- save statistical information or load resource files. --- --- @usage Get directory to current profile. ---
---   homedir = getMudletHomeDir()
---   
function getMudletHomeDir() end --- Returns the last measured response time between the sent command and the server reply. --- --- @return number of seconds (0.058 (=58 milliseconds lag) or 0.309 (=309 milliseconds)) function getNetworkLatency() end --- Returns the time without stoping stop watch (milliseconds based) in form of 0.058 --- (= clock ran for 58 milliseconds before it was stopped). --- @see createStopWatch function getStopWatchTime(watchID) end --- Return time information. --- --- @release Mudlet 1.0.6 --- --- @usage Get time as a table. ---
---   getTime()
---   
--- @usage Get time as a string (with default formatting). ---
---   getTime(true)
---   
--- @usage Get time as a string with user defined formatting. ---
---   getTime(true, "hh:mm")
---   
--- --- @param returnType Takes a boolean value (in Lua anything but false or nil will translate to true). If true, --- the function will return a table in the following format:
--- { hour = #, min = #, sec = #, msec = # }
--- If false or nil, it will return the time as a string using a format passed to the second arg or the --- default of hh:mm:ss.zzz --- --- @param format Format expressions built from following elements: ---
---   h               the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
---   hh              the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
---   H               the hour without a leading zero (0 to 23, even with AM/PM display)
---   HH              the hour with a leading zero (00 to 23, even with AM/PM display)
---   m               the minute without a leading zero (0 to 59)
---   mm              the minute with a leading zero (00 to 59)
---   s               the second without a leading zero (0 to 59)
---   ss              the second with a leading zero (00 to 59)
---   z               the milliseconds without leading zeroes (0 to 999)
---   zzz             the milliseconds with leading zeroes (000 to 999)
---   AP or A         use AM/PM display. AP will be replaced by either "AM" or "PM".
---   ap or a         use am/pm display. ap will be replaced by either "am" or "pm".
---
---   d               the day as number without a leading zero (1 to 31)
---   dd              the day as number with a leading zero (01 to 31)
---   ddd             the abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses QDate::shortDayName().
---   dddd            the long localized day name (e.g. 'Monday' to 'Qt::Sunday'). Uses QDate::longDayName().
---   M               the month as number without a leading zero (1-12)
---   MM              the month as number with a leading zero (01-12)
---   MMM             the abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses QDate::shortMonthName().
---   MMMM            the long localized month name (e.g. 'January' to 'December'). Uses QDate::longMonthName().
---   yy              the year as two digit number (00-99)
---   yyyy            the year as four digit number
---   
--- All other input characters will be ignored. Any sequence of characters that are enclosed in singlequotes will be treated as text and not be --- used as an expression. Two consecutive singlequotes ("''") are replaced by a singlequote in the output. function getTime(returnType, format) end --- Returns the timestamp string as it's seen when you enable the timestamps view (blue 'i' button bottom right of the Mudlet screen). --- --- @release Mudlet 1.1.0-pre1 --- --- @usage Echo the timestamp of the current line in a trigger. ---
---   echo( getTimestamp(getLineCount()) )
---   
--- --- @param console_name optional parameter function getTimestamp(console_name, lineNumber) end --- TODO hasFocus - TLuaInterpreter::hasFocus function hasFocus() end --- Hides tool bar name and makes it disappear. If all tool bars of a tool bar area (top, left, right) --- are hidden, the entire tool bar area disappears automatically. function hideToolBar(name) end --- This function hides a mini console label. To show it again use showWindow. --- --- @see showWindow --- @see createMiniConsole function hideWindow(name) end --- TODO insertHTML - TLuaInterpreter::insertHTML function insertHTML() end --- Same as echoLink() but inserts the text at the current cursor position, while echoLink inserts at the end --- of the current line. --- --- @release Mudlet 1.1.0-pre1 --- --- @see echoLink --- @see setLink function insertLink(windowName, text, command, hint, useCurrentFormat) end --- Same as echoPopup(), but inserts text at the current cursor position. --- --- @release Mudlet 1.1.0-pre1 --- --- @see setPopup --- @see echoPopup function insertPopup(windowName, text, commands, hints, useCurrentFormat) end --- Inserts text at the current cursor position in the main window. If the cursor has not been explicitly --- moved this function will always print at the beginning of the line whereas the echo() function will --- always print at the end of the line. --- --- @param windowName optional --- --- @see echo function insertText(windowName, text) end --- Opens a file chooser dialog, allowing the user to select a file or a folder visually. The function returns --- the selected path or nil if there was none chosen. --- --- @usage ---
---   local path = invokeFileDialog(false, "Find me the gfx folder, please")
---   if path then
---      echo(path)
---   end
---   
--- --- @param selection true for file selection, false for folder selection. --- @param dialogTitle name that the dialog (file chooser window) will have function invokeFileDialog(selection, dialogTitle) end --- You can use this function to check if something, or somethings, are active. Type can be either --- "alias", "trigger", or "timer", and name is the name of the said item you'd like to check. --- --- @param type could be "alias", "trigger", or "timer" --- --- @usage This will check is my "my trigger" is active. ---
---   echo("I have " .. isActive("my trigger", "trigger") .. " currently active triggers called 'my trigger'!")
---   
function isActive(name, type) end --- This function tests if the first character of the current selection has the background color specified by ansiBgColorCode. --- --- @see isAnsiFgColor function isAnsiBgColor(ansiBgColorCode) end --- This function tests if the first character of the current selection has the foreground color specified by --- ansiFgColorCode. Codes are: --- ---
---   0 = default text color
---   1 = light black
---   2 = dark black
---   3 = light red
---   4 = dark red
---   5 = light green
---   6 = dark green
---   7 = light yellow
---   8 = dark yellow
---   9 = light blue
---   10 = dark blue
---   11 = light magenta
---   12 = dark magenta
---   13 = light cyan
---   14 = dark cyan
---   15 = light white
---   16 = dark white
---   
--- --- @usage ---
---   selectString(matches[1], 1)
---   if isAnsiFgColor(5) then
---       bg("red")
---       resetFormat()
---       echo("yes, the text is light green")
---   else
---       echo( "no sorry, some other foreground color" )
---   end
---   
--- --- Note that matches[1] holds the matched trigger pattern - even in substring, exact match, begin of line substring trigger --- patterns or even color triggers that do not know about the concept of capture groups. Consequently, you can always test --- if the text that has fired the trigger has a certain color and react accordingly. This function is faster than using --- getFgColor() and then handling the color comparison in Lua. function isAnsiFgColor(ansiFgColorCode) end --- Returns true or false depending on if the current line being processed is a prompt. This infallible --- feature is available for MUDs that supply GA events (to check if yours is one, look to bottom-right --- of the main window - if it doesn't say <No GA>, then it supplies them). --- --- @return true/false function isPrompt() end --- Deletes an alias with the given name. If several aliases have this name, they'll all be deleted. --- --- @see killTimer --- @see killTrigger function killAlias(name) end --- Deletes a tempTimer. Use the Timer ID returned by tempTimer() as name parameter. ID is a string and not a number. --- This function returns true on success and false if the timer id doesn't exist anymore (=timer has already fired) --- or the timer is not a temp timer. Note that non-temporary timers that you have set up in the GUI cannot be deleted --- with this function. Use disableTimer() to turn them on or off. --- --- @see killAlias --- @see killTrigger --- --- @return true or false function killTimer(id) end --- Deletes a tempTrigger according to trigger ID. ID is a string value, not a number. --- --- @see killAlias --- @see killTimer --- --- @return true or false function killTrigger(id) end --- The line variable holds the content of the current line as being processed by the trigger engine. --- The engine runs all triggers on each line as it arrives from the MUD. --- --- @see command --- --- @class function --- @name line line = "" --- TODO loadRawFile - TLuaInterpreter::loadRawFile function loadRawFile() end --- The matches table contains captured group. This available only within trigger context. --- First item of matches table (matches[1]) holds current line, all other contains capture groups --- defined by regular expression trigger. --- --- @usage Let say that you defined following trigger to detect and get dropped items. ---
---   RegEx:
---      ^The (.*) drops (.*)\.$
---   Code:
---      display(matches)
---      send("get " .. matches[3])
---   
--- --- Now let's say that MUD will send you following text (which will invoke your trigger). ---
---   The skeleton drops scimitar.
---   
--- --- This will send "get scimitar" to your MUD and also print following table: ---
---   table {
---     1: 'The skeleton drops scimitar.'
---     2: 'skeleton'
---     3: 'scimitar'
---   }
---   
--- --- @see showCaptureGroups --- @see multimatches --- @fee feedTriggers --- --- @class function --- @name matches matches = {} --- Moves the user cursor of the window windowName to the absolute point (x,y). This function returns false --- if such a move is impossible e.g. the coordinates don't exist. To determine the correct coordinates use --- getLineNumber(), getColumnNumber() and getLastLineNumber(). The trigger engine will always place the user --- cursor at the beginning of the current line before the script is run. If you omit the windowName argument, --- the main screen will be used. --- --- @return true or false --- --- @usage Set up the small system message window in the top right corner. ---
---   -- determine the size of your screen
---   WindowWidth=0;
---   WindowHeight=0;
---   WindowWidth, WindowHeight = getMainWindowSize();
---
---   -- define a mini console named "sys" and set its background color
---   createMiniConsole("sys",WindowWidth-650,0,650,300)
---   setBackgroundColor("sys",85,55,0,255);
---
---   -- you *must* set the font size, otherwise mini windows will not work properly
---   setMiniConsoleFontSize("sys", 12);
---   -- wrap lines in window "sys" at 65 characters per line
---   setWindowWrap("sys", 60);
---   -- set default font colors and font style for window "sys"
---   setTextFormat("sys",0,35,255,50,50,50,0,0,0);
---   -- clear the window
---   clearUserWindow("sys")
---
---   moveCursorEnd("sys")
---   setFgColor("sys", 10,10,0)
---   setBgColor("sys", 0,0,255)
---   echo("sys", "test1---line1\n\n\n")
---   echo("sys", "test1---line2\n")
---   echo("sys", "test1---line3\n")
---   setTextFormat("sys",158,0,255,255,0,255,0,0,0);
---   --setFgColor("sys",255,0,0);
---   echo("sys", "test1---line4\n")
---   echo("sys", "test1---line5\n")
---   moveCursor("sys", 1,1)
---
---   -- deleting lines 2+3
---   deleteLine("sys");
---   deleteLine("sys");
---
---   -- inserting a line at pos 5,2
---   moveCursor("sys", 5,2);
---   setFgColor("sys", 100,100,0)
---   setBgColor("sys", 255,100,0)
---   insertText("sys","############## line inserted at pos 5/2 ##############");
---
---   -- inserting a line at pos 0,0
---   moveCursor("sys", 0,0)
---   selectCurrentLine("sys");
---   setFgColor("sys", 255,155,255);
---   setBold( "sys", true );
---   setUnderline( "sys", true );
---   setItalics( "sys", true );
---   insertText("sys", "------- line inserted at: 0/0 -----\n");
---
---   setBold( "sys", true )
---   setUnderline( "sys", false )
---   setItalics( "sys", false )
---   setFgColor("sys", 255,100,0)
---   setBgColor("sys", 155,155,0)
---   echo("sys", "*** This is the end. ***\n");
---   
function moveCursor(windowName, x, y) end --- Moves the cursor to the end of the buffer. "main" is the name of the main window, otherwise use the name of your user window. --- --- @return true or false --- --- @see moveCursor function moveCursorEnd(windowName) end --- This function moves window name to the given x/y coordinate. The main screen cannot --- be moved. Instead you'll have to set appropriate border values in preferences to move --- the main screen e.g. to make room for chat or information mini consoles, or other GUI --- elements. In the future moveWindow() will set the border values automatically if the name --- parameter is omitted. --- --- @see createMiniConsole --- @see createLabel --- @see handleWindowResizeEvent --- @see resizeWindow --- @see setBorderTop function moveWindow(name, x, y) end --- The multimatches table is being used by Mudlet in the context of multiline triggers that use Perl regular expression. --- It holds the table matches[n] as described above for each Perl regular expression based condition of the multiline trigger. --- multimatches[5][4] may hold the 3rd capture group of the 5th regex in the multiline trigger. This way you can examine and --- process all relevant data within a single script.

--- --- What makes multiline triggers really shine is the ability to react to MUD output that is spread over multiple lines --- and only fire the action (=run the script) if all conditions have been fulfilled in the specified amount of lines. --- --- @usage Have a look at this example (can be tested on the MUD batmud.bat.org).
--- In the case of a multiline trigger with these 2 Perl regex as conditions: ---
---   ^You have (\w+) (\w+) (\w+) (\w+)
---   ^You are (\w+).*(\w+).*
---   
--- The command "score" generates the following output on batMUD: ---
---   You have an almost non-existent ability for avoiding hits.
---   You are irreproachably kind.
---   You have not completed any quests.
---   You are refreshed, hungry, very young and brave.
---   Conquer leads the human race.
---   Hp:295/295 Sp:132/132 Ep:182/181 Exp:269 >
---   
--- If you add this script to the trigger: ---
---   showMultimatches()
---   
--- The script, i.e. the call to the function showMultimatches() generates this output: ---
---   -------------------------------------------------------
---   The table multimatches[n][m] contains:
---   -------------------------------------------------------
---   regex 1 captured: (multimatches[1][1-n])
---             key=1 value=You have not completed any quests
---             key=2 value=not
---             key=3 value=completed
---             key=4 value=any
---             key=5 value=quests
---   regex 2 captured: (multimatches[2][1-n])
---             key=1 value=You are refreshed, hungry, very young and brave
---             key=2 value=refreshed
---             key=3 value=young
---             key=4 value=and
---             key=5 value=brave
---   -------------------------------------------------------
---   
--- The function showMultimatches() prints out the content of the table multimatches[n][m]. You can now see what the table --- multimatches[][] contains in this case. The first trigger condition (=regex 1) got as the first full match --- "You have not completed any quests". This is stored in multimatches[1][1] as the value of key=1 in the sub-table matches[1] --- which, in turn, is the value of key=1 of the table multimatches[n][m].

--- --- Following script would use matched values from previously defined regex in the multiline trigger: ---
---   myGold = myGold + tonumber( multimatches[1][2] )
---   mySilver = mySilver + tonumber( multimatches[1][3] )
---   
--- --- @see showMultimatches --- @see matches --- --- @class function --- @name multimatches multimatches = {} --- Opens a user dockable console window for user output e.g. statistics, chat etc. If a window of such --- a name already exists, nothing happens. You can move these windows, dock them, make them into notebook --- tabs or float them.

--- --- Note: There isn't currently way how to set size and position of user windows at the moment, so you might --- consider to use mini console instead. --- --- @usage This command will open new user windows with name "Chat". ---
---   openUserWindow("Chat")
---   
--- --- @see createMiniConsole function openUserWindow(windowName) end --- Pastes the previously copied text including all format codes like color, font etc. at the current user --- cursor position. The copy() and paste() functions can be used to copy formated text from the main window --- to a user window without losing colors e. g. for chat windows, map windows etc. --- --- @see copy function paste(windowName) end --- TODO pasteWindow - TLuaInterpreter::pasteWindow function pasteWindow() end --- Creates a persistent alias that stays after Mudlet is restarted and shows up in the Script Editor.

--- --- Note that Mudlet by design allows duplicate names - so calling permAlias with the same name will keep creating --- new aliases. You can check if an alias already exists with the exists() function. --- --- @param name is the name you'd like the alias to have. --- @param parent is the name of the group, or another alias you want the trigger to go in - however if such a group/alias --- doesn't exist, it won't do anything. Use "" to make it not go into any groups. --- @param regex is the pattern that you'd like the alias to use. --- @param luaCode is the script the alias will do when it matches. --- --- @usage Creates an alias called "new alias" in a group called "my group". ---
---   permAlias("new alias", "my group", "^test$", [[echo ("say it works! This alias will show up in the script editor too.")]])
---   
--- --- @see exists function permAlias(name, parent, regex, luaCode) end --- Creates a persistent trigger with a begin of line substring pattern that shows up in the Script Editor --- and stays after Mudlet is restarted.
---
--- Note that Mudlet by design allows duplicate names - so calling permBeginOfLineStringTrigger with the same --- name will keep creating new triggers. You can check if a trigger already exists with the exists() function. --- --- @param name is the name you'd like the trigger to have. --- @param parent is the name of the group, or another trigger you want the trigger to go in - however --- if such a group/trigger doesn't exist, it won't do anything. Use "" to make it not go into any groups. --- @param patternTable is a table of patterns that you'd like the trigger to use - it can be one or many. --- @param luaCode is the script the trigger will do when it matches. --- --- @usage Create a trigger that will match on anything that starts with "You sit" and do "stand". --- It will not go into any groups, so it'll be on the top. ---
---   permBeginOfLineStringTrigger("Stand up", "", {"You sit"}, [[send ("stand")]])
---   
--- @usage Another example - lets put our trigger into a "General" folder and give it several patterns. ---
---   permBeginOfLineStringTrigger("Stand up", "General", {"You sit", "You fall", "You are knocked over by"}, [[send ("stand")]])
---   
function permBeginOfLineStringTrigger(name, parent, patternTable, luaCode) end --- Creates a persistent trigger with a regex pattern that stays after Mudlet is restarted and shows up in the --- Script Editor.

--- --- Note that Mudlet by design allows duplicate names - so calling permRegexTrigger with the same name will keep creating --- new aliases. You can check if an alias already exists with the exists() function. --- --- @param name is the name you'd like the alias to have. --- @param parent is the name of the group, or another alias you want the trigger to go in - however if such a group/alias --- doesn't exist, it won't do anything. Use "" to make it not go into any groups. --- @param regex is the pattern that you'd like the alias to use. --- @param luaCode is the script the alias will do when it matches. --- --- @usage Create a regex trigger that will match on the prompt to record your status. ---
---   permRegexTrigger("Prompt", "", {"^(\d+)h, (\d+)m"}, [[health = tonumber(matches[2]; mana = tonumber(matches[3])]]
---   
--- --- @see exists function permRegexTrigger(name, parent, pattern, luaCode) end --- Creates a persistent trigger with a substring pattern that stays after Mudlet is restarted and shows up in --- the Script Editor.

--- --- Note that Mudlet by design allows duplicate names - so calling permSubstringTrigger with the same name will keep creating --- new aliases. You can check if an alias already exists with the exists() function. --- --- @param name is the name you'd like the alias to have. --- @param parent is the name of the group, or another alias you want the trigger to go in - however if such a group/alias --- doesn't exist, it won't do anything. Use "" to make it not go into any groups. --- @param regex is the pattern that you'd like the alias to use. --- @param luaCode is the script the alias will do when it matches. --- --- @usage Create a trigger to highlight the word "pixie" for us. ---
---   permSubstringTrigger("Highlight stuff", "General", {"pixie"}, [[selectString(line, 1) bg("yellow") resetFormat()]])
---   
--- @usage Another trigger to highlight several different things. ---
---   permSubstringTrigger("Highlight stuff", "General", {"pixie", "cat", "dog", "rabbit"}, [[selectString(line, 1) fg ("blue") bg("yellow") resetFormat()]])
---   
--- --- @see exists function permSubstringTrigger(name, parent, pattern, luaCode) end --- Creates a persistent timer that stays after Mudlet is restarted and shows up in the Script Editor.

--- --- Note that Mudlet by design allows duplicate names - so calling permTimer with the same name will keep creating --- new timers. You can check if a timer already exists with the exists() function. --- --- @param name timer name, parent is the name of the timer group you want the timer to go in. --- @param seconds number specifying a delay after which the timer will execute the lua code. --- @param luaCode code to execute --- --- @usage Creates new time that will tick each 4.5s. ---
---   permTimer("my timer", "first timer group", 4.5, [[send ("my timer that's in my first timer group fired!")]])
---   
function permTimer(name, parent, seconds, luaCode) end --- This function plays a sound file. To make sound work on your operating system you may need to install additional packages:
--- Microsoft Windows: The underlying multimedia system is used; only WAVE format sound files are supported. (works out of the box)
--- Mac OS X: NSSound is used. All formats that NSSound supports, including QuickTime formats, are supported by Qt for Mac OS X --- (should work out of the box).
--- X11: The Network Audio System is used if available, otherwise all operations work silently. NAS supports WAVE and AU files. Please use --- following workaround for Linux systems: ---
---   if "linux" == getOS() then
---	     os.execute("aplay /usr/share/sounds/alsa/Front_Center.wav")
---   end
---   
function playSoundFile(fileName) end --- Raises the event event_name. The event system will call the main --- function (the one that is called exactly like the script name) of all --- such scripts that have registered event handlers. If an event is raised, --- but no event handler scripts have been registered with the event system, --- the event is ignored and nothing happens. This is convenient as you can --- raise events in your triggers, timers, scripts etc. without having to --- care if the actual event handling has been implemented yet - or more --- specifically how it is implemented. Your triggers raise an event to tell --- the system that they have detected a certain condition to be true or --- that a certain event has happened. How - and if - the system is going to --- respond to this event is up to the system and your trigger scripts don't --- have to care about such details. For small systems it will be more --- convenient to use regular function calls instead of events, however, the --- more complicated your system will get, the more important events will --- become because they help reduce complexity very much.

--- --- The corresponding event handlers that listen to the events raised with --- raiseEvent() need to use the script name as function name and take the --- correct number of arguments. NOTE: If you raise an event with 5 --- arguments but your event handlers functions only take 2,10 or 0 --- arguments, the functions will not be called. For example: --- raiseEvent("fight") a correct event handler function would be: --- myScript(event_name). In this example raiseEvent uses minimal arguments, name --- the event name. There can only be one event handler function per script, --- but a script can still handle multiple events as the first argument is --- always the event name. So you can call your own special handlers for --- individual events. The reason behind this is that you should rather use --- many individual scripts instead of one huge script that has all your --- function code etc. Scripts can be organized very well in trees and thus --- help reduce complexity on large systems.

--- --- As an example, your prompt trigger could raise an onPrompt event if you want to attach 2 functions to it. --- In your prompt trigger, all you'd need to do is raiseEvent("onPrompt") Now we go about creating functions --- that attach to the event. Lets say the first one is check_health_stuff() and the other is check_salve_stuff(). --- We would like these to be executed when the event is raised. So create a script and give it a name of check_health_stuff. --- In the Add user defined event handler, type onPrompt, and press enter to add it to the list. In the script box, --- create: function check_health_stuff()blah blah end. When the onPrompt event comes along, that script catches it, --- and does check_health_stuff() for you.

--- --- Default events raised by Mudlet
--- Mudlet itself also creates events for your scripts to hook on. The following events are generated currently:
--- --- sysWindowResizeEvent
--- Raised when the main window is resized, with the new height and width coordinates passed to the event. --- A common usecase for this event is to move/resize your UI elements according to the new dimensions. --- This sample code will echo whenever a resize happened with the new dimensions: ---
---   function resizeEvent( event, x, y )
---      echo("RESIZE EVENT: event="..event.." x="..x.." y="..y.."\n")
---   end
---   
--- --- sysWindowMousePressEvent
--- Raised when a mouse button is pressed down anywhere on the main window (note that a click is composed of a mouse --- press and mouse release). The button number and the x,y coordinates of the click are reported. ---
---   function onClickHandler( event, button, x, y )
---      echo("CLICK event:"..event.." button="..button.." x="..x.." y="..y.."\n")
---   end
---   
--- --- sysWindowMouseReleaseEvent
--- Raised when a mouse button is released after being pressed down anywhere on the main window (note that a click is composed --- of a mouse press and mouse release). See sysWindowMousePressEvent for example use. --- --- ATCP events

--- Mudlets ATCP implementation generates events for each message that comes, allowing you to trigger on them easily. --- Since ATCP messages vary in name, event names will vary as well. See the atcp section on how to use them. function raiseEvent(eventName, ...) end --- Reconnect to currect session. --- --- @see disconnect function reconnect() end --- Replaces the currently selected text with the new text. To select text, use selectString() and similar function. --- --- @usage Replace word "troll" with "cute trolly". ---
---   selectString("troll",1)
---   replace("cute trolly")
---   
--- --- @usage Lets replace the whole line. If you'd like to delete/gag the whole line, use deleteLine()! ---
---   selectString(line, 1)
---   replace("Out with the old, in with the new!")
---   
--- --- @see selectString --- @see deleteLine function replace(with) end --- Resets the character format to default. This should be used after you have highlighted some text --- or changed the current foreground or background color, but you don't want to keep using these --- colors for further prints. If you set a foreground or background color, the color will be used --- until you call resetFormat() on all further print commands. --- --- @param windowName optional function resetFormat(windowName) end --- This function resets the time to 0:0:0.0, but does not start the stop watch. You can start it with startStopWatch. --- --- @see createStopWatch --- @see startStopWatch function resetStopWatch(watchID) end --- Resizes a mini console or label. --- --- @see createMiniConsole --- @see createLabel --- @see handleWindowResizeEvent --- @see setBorderTop function resizeWindow(name, width, height) end --- Selects the content of the capture group number in your Perl regular expression e.g. "you have (\d+) Euro". --- If you want to color the amount of money you have green you do: --- --- @usage ---
---   setFgColor(0,255,0)
---   selectCaptureGroup(1)
---   
--- --- @param groupNumber with first group = 1 function selectCaptureGroup() end --- Selects the content of the current buffer line. ---
TODO It this valid? selectCurrentLine("sys")
function selectCurrentLine() end --- Select text on the line under the current cursor position. Use absolute column number for start of selection --- and length of selection The function returns true on success and false if the selection is not possible. --- --- @param windowName is optional function selectSection(windowName, from, lengthOfString) end --- Selects a substring from the line where the user cursor is currently positioned. You can move --- the user cursor with moveCursor(). When a new line arrives from the MUD, the user cursor is --- positioned at the beginning of the line. However, if one of your trigger scripts moves the --- cursor around you need to take care of the cursor position yourself and make sure that the --- cursor is in the correct line if you want to call one of the select functions. To deselect --- text, see deselect(). --- --- @usage Select "big monster" in the line. ---
---   selectString("big monster", 1)
---   
--- @usage Note: To prevent selection of random data use the error return if not found like this. ---
---   if selectString("big monster", 1) > -1 then
---      setFgColor(255,0,0)
---   end
---   
--- @usage In a trigger, lets color all words on the current line green. ---
---   selectString(line, 1)
---   fg("green")
---   resetFormat()
---   
--- --- @return returns position in line or -1 on error (text not found in line) --- --- @see deselect function selectString(text, numberOfMatch) end --- This sends "command" directly to the network layer, skipping the alias matching. The optional --- second argument of type boolean (print) determines if the outgoing command is to be echoed on the screen. --- Send honours command separator defined within Mudlet settings. If you want your command to be checked --- if it's an alias, use expandAlias() instead. --- --- @usage Echos the command on the screen. ---
---   send("Hello Jane")
---   
--- @usage Echos the command on the screen. ---
---   send("Hello Jane", true)
---   
--- @usage Does not echo the command on the screen. ---
---   send("Hello Jane", false)
---   
--- --- @param echoTheValue optional boolean flag (default value is true) which determine if value should --- be echoed back on client. --- --- @see expandAlias --- @see sendAll function send(command, echoTheValue) end --- TODO sendATCP - TLuaInterpreter::sendATCP --- @see atcp function sendATCP() end --- Send telnet channel 102 commands to MUD. This is widely used on Aardwolf for setting up user tags. --- --- @usage Following command will enable all Aardwolf channel tags. You need to have active session. ---
---   sendTelnetChannel102("\5\1")
---   
--- --- @see channel102 function sendTelnetChannel102() end --- Sets RGB color values and the transparency for the given window. Colors are from 0 to 255 (0 being black), --- and transparency is from - to 255 (0 being completely transparent).

--- --- Note that transparency only works on labels, not miniConsoles for efficiency reasons. function setBackgroundColor(windowName, red, green, blue, transparency) end -- Loads an image file (png) as a background image for a label. This can be used to display clickable images etc. function setBackgroundImage(labelName, imageFileName) end --- Sets the current text background color in window windowName (or in main windows if you haven't specified that). If you have selected --- text prior to this call, the selection will be highlightd otherwise the current text background color will be changed. If you set a --- foreground or background color, the color will be used until you call resetFormat() on all further print commands. --- --- @param windowName optional --- --- @usage Highlights the first occurrence of the string "Tom" in the current line with a red background color. ---
---   selectString( "Tom", 1 )
---   setBgColor( 255,0,0 )
---   
--- --- @usage Prints "Hello" on red background and "You" on blue. ---
---   setBgColor(255,0,0)
---   echo("Hello")
---   setBgColor(0,0,255)
---   echo(" You!")
---   resetFormat()
---   
--- --- @see setFgColor function setBgColor(windowName, r, g, b) end --- Sets the current text font to bold (true) or non-bold (false) mode. If the windowName parameters omitted, the main screen will be used. --- --- @param windowName optional function setBold(windowName, bool) end --- Sets the height of the bottom border to size pixel and thus effectively moves down the main console --- window by size pixels to make room for e.g. mini console windows, buttons etc.. --- --- @see setBorderTop --- @see setBorderLeft --- @see setBorderRight function setBorderBottom(size) end --- Sets the color of the border in RGB color. --- --- @usage Sets the border to red. ---
---   setBorderColor( 255, 0, 0 )
---   
function setBorderColor(red, green, blue) end --- Sets the width of the left border and thus effectively moves down the main console --- window by size pixels to make room for e.g. mini console windows, buttons etc.. --- @see setBorderTop --- @see setBorderBottom --- @see setBorderRight function setBorderLeft(size) end --- Sets the width of the right border and thus effectively moves down the main console --- window by size pixels to make room for e.g. mini console windows, buttons etc.. --- --- @see setBorderTop --- @see setBorderBottom --- @see setBorderLeft function setBorderRight(size) end --- Sets the height of the top border to size pixel and thus effectively moves down the main console --- window by size pixels to make room for e.g. mini console windows, buttons etc.. --- --- @see setBorderBottom --- @see setBorderLeft --- @see setBorderRight function setBorderTop(size) end --- Set the scrollback buffer size to linesLimit and determine how many lines are deleted at once in --- case the lines limit is reached. The lower the limit the less memory being used. On machines with --- low RAM you should consider limiting the size of buffers that don't need a lot of scrollback --- e.g. system notification windows, chat windows etc..
--- Default values are linesLimit = 100000 lines with 10000 lines of batch deletion.
--- Minimum buffer size is 100 lines with 10 lines batch deletion. function setConsoleBufferSize(consoleName, linesLimit, sizeOfBatchDeletion) end --- Sets the current text foreground color in the main window. Values are RGB: red, green, blue ranging from 0-255 e.g. --- --- @param windowName optional --- --- @usage Set blue foreground. ---
---   setBgColor(0,0,255)
---   
--- @param windowName optional --- --- @setBgColor function setFgColor(windowName, r, g, b) end --- Sets the current text font to italics/non-italics mode. If the windowName parameters omitted, the main screen will be used. --- --- @param windowName optional function setItalics(windowName, bool) end --- Specify a Lua function to be called if the user clicks on the --- label/image. E.g. setLabelClickCallback( "compassNorthImage", "onClickGoNorth" )

--- --- UPDATE: this function can now pass any number of string or integer number values as additional parameters. --- These parameters are then used in the callback. Thus you can associate data with the label/button. --- Check the forum for more information on how to use this. FIXME function setLabelClickCallback(labelName, luaFunctionName, ...) end --- TODO setLabelStyleSheet - TLuaInterpreter::setLabelStyleSheet function setLabelStyleSheet() end --- Turns the selected text into a clickable link - upon being clicked, the link will do the command code. --- Tooltip is a string which will be displayed when the mouse is over the selected text. --- --- @release Mudlet 1.1.0-pre1 --- --- @usage In a sewer grate substring trigger, the following code will make clicking on the words do the send("enter grate") command: ---
---   selectString(matches[1], 1)
---   setLink([[send("enter grate")]], "Clicky to enter grate")
---   
--- --- @see echoLink --- @see insertLink function setLink(command, tooltip) end --- Sets the font size of the mini console. --- --- @see createMiniConsole --- @see createLabel function setMiniConsoleFontSize(name, fontSize) end --- Turns the selected text into a left-clickable link, and a right-click menu. The selected text, --- upon being left-clicked, will do the first command in the list. Upon being right-clicked, it'll --- display a menu with all possible commands. The menu will be populated with hints, one for each line. --- --- @release Mudlet 1.1.0-pre1 --- --- @usage In a Raising your hand in greeting, you say "Hello!" exact match trigger, the following code will --- make left-clicking on Hello show you an echo, while left-clicking will show some commands you can do. ---
---   selectString("Hello", 1)
---   setPopup("main", {[[send("bye")]], [[echo("hi!")]]}, {"left-click or right-click and do first item to send bye", "click to echo hi"})
---   
--- --- @param name the name of the console to operate on. If not using this in a miniConsole, use "main" as the name. --- @param commands a table of lua code strings to do e.g. {[[send("hello")]], [[echo("hi!"]]}. --- @param hints a table of strings which will be shown on the popup and right-click menu e.g. {"send the hi command", "echo hi to yourself"}. function setPopup(name, commands, hints) end --- Sets current text format of window. A more convenient way to control the text format in a mini console is to --- use setFgColor, setBold, setItalics, setUnderline etc. --- --- @param windowName --- @param fgR foreground color(r,g,b) --- @param fgG foreground color(r,g,b) --- @param fgB foreground color(r,g,b) --- @param bgR background color(r,g,b) --- @param bgG background color(r,g,b) --- @param bgB background color(r,g,b) --- @param bold bold flag (1/0) --- @param underline underline flag (1/0) --- @param italics italics flag (1/0) --- --- @usage This script would create a mini text console and write with yellow foreground color and blue background color "This is a test". ---
---   createMiniConsole("con1", 0, 0, 300, 100)
---   setTextFormat("con1", 0,0,255, 255,255,0, 1,1,1)
---   echo("con1", "This is a test")
---   
--- --- @see createMiniConsole --- @see setBold --- @see setBgColor --- @see setFgColor --- @see setItalics --- @see setUnderline function setTextFormat(windowName, fgR, fgG, fgB, bgR, bgG, bgB, bold, underline, italics) end --- Set for how many more lines a trigger script should fire or a chain should stay open after the trigger has matched. --- The main use of this function is to close a chain when a certain condition has been met. --- --- @param number should be 0 to close the chain, or a positive number to keep the chain open that much longer. function setTriggerStayOpen(name, number) end --- Sets the current text font to underline/non-underline mode. If the windowName parameters omitted, the main screen will be used. --- --- @param windowName optional function setUnderline(windowName, bool) end --- Sets at what position in the line the console or miniconsole will start word wrap. function setWindowWrap(windowName, wrapAt) end --- TODO setWindowWrapIndent - TLuaInterpreter::setWindowWrapIndent function setWindowWrapIndent() end --- Shows tool bar name on the screen. function showToolBar(name) end --- This function shows a mini console or label. To hide it use hideWindow. --- @see hideWindow --- @see createMiniConsole --- @see createLabel function showWindow(name) end --- TODO spawn - TLuaInterpreter::spawn function spawn() end --- TODO startLogging - TLuaInterpreter::startLogging function startLogging() end --- Starts the stop watch. --- @see createStopWatch function startStopWatch(watchID) end --- Stops the stop watch and returns the elapsed time in milliseconds in form of 0.001. --- @see createStopWatch --- @return returns time as a number function stopStopWatch() end --- Creates a temporary (lasts only until the profile is closed) alias. This means that it won't exist anymore after Mudlet restarts. --- --- @usage This triggers waits for "hi" string. ---
---   tempAlias("^hi$", [[send ("hi") echo ("we said hi!")]]
---   
--- --- @return id function tempAlias(regex, luaCode) end --- Makes a color trigger that triggers on the specified foreground and background color. Both colors need to be --- supplied in form of these simplified ANSI 16 color mode codes: --- ---
---   0 = default text color
---   1 = light black
---   2 = dark black
---   3 = light red
---   4 = dark red
---   5 = light green
---   6 = dark green
---   7 = light yellow
---   8 = dark yellow
---   9 = light blue
---   10 = dark blue
---   11 = light magenta
---   12 = dark magenta
---   13 = light cyan
---   14 = dark cyan
---   15 = light white
---   16 = dark white
---   
--- --- @usage This script will re-highlight all text in blue foreground colors on a black background with a red foreground --- color on a blue background color until another color in the current line is being met. temporary color triggers --- do not offer match_all or filter options like the GUI color triggers because this is rarely necessary for scripting. --- A common usage for temporary color triggers is to schedule actions on the basis of forthcoming text colors --- in a particular context. ---
---   tempColorTrigger(9,2,[[selectString(matches[1],1); fg("red"); bg("blue");]] );
---   
function tempColorTrigger(foregroundColor, backgqroundColor, luaCode) end --- TODO example with luaCode - --- Temporary trigger that will fire on n consecutive lines following the --- current line. This is useful to parse output that is known to arrive in --- a certain line margin or to delete unwanted output from the MUD. --- --- @return the string ID of the newly created temporary trigger. --- You can use this ID to enable/disable or kill this trigger later on. --- --- @usage Following will fire 3 times starting with the line from the MUD. ---
---   tempLineTrigger( 1, 3, [[send("shout Help")]])
---   
--- @usage This will fire 20 lines after the current line and fire twice on 2 consecutive lines. ---
---   tempLineTrigger( 20, 2, [[send("shout Help")]])
---   
function tempLineTrigger(from, howMany, luaCode) end --- Temporary trigger using Perl regex pattern matching. --- --- @return the string ID of the newly created temporary trigger. --- You can use this ID to enable/disable or kill --- this trigger later on. --- --- @see killTrigger --- @see tempTrigger function tempRegexTrigger(regex, luaCode) end --- Creates a temporary single shot timer and returns the timer ID for subsequent enableTimer(), disableTimer() and killTimer() calls. --- You can use 2.3 seconds or 0.45 etc. After it has fired, the timer will be deactivated and killed.

--- --- Note [[ ]] can be used to quote strings in Lua. The difference to the usual `" " quote syntax is that `[[ ]] also accepts the --- character ". Consequently, you don't have to escape the " character in the above script. The other advantage is that it can be --- used as a multiline quote. --- --- @usage This script will send the command "kill rat" 0.3 seconds after this function has been called. Note that this function --- does not wait until 0.3 seconds have been passed, but it will start a timer that will run the Lua script that you have provided --- as a second argument after 0.3 seconds. ---
---   tempTimer(0.3, [[send("kill rat")]] )
---   
--- --- @usage Also note that the Lua code that you provide as an argument is compiled from a string value when the timer fires. --- This means that if you want to pass any parameters by value e.g. you want to make a function call that uses the value --- of your variable myGold as a parameter you have to do things like this: ---
---   tempTimer(3.8, [[echo("at the time of the tempTimer call I had ]] .. myGold .. [[ gold.")]] )
---   
--- --- @return timer ID, ID is a string and not a number. function tempTimer(seconds, luaCode) end --- This function creates a temporary trigger using substring matching. --- Contrary to tempTimers, tempTriggers lives throughout the entire session --- until it is explicitly disabled or killed. Disabled tempTimers can be --- re-enabled with enableTrigger(). This is much faster than killing the --- trigger and creating a new one. This is the second fastest trigger (with --- begin of line substring patterns being the fastest) and should be used --- instead of regex triggers whenever possible. --- --- @return trigger ID, ID is a string and not a number. --- --- @usage You can put the following script into your targeting alias highlight your target.
--- (Note: trigger will stay active unless you'll kill it.) ---
---   target = "rat"
---   if id then
---      killTrigger(id)
---   end
---   id = tempTrigger(target, [[selectString("]] .. target .. [[", 1) fg("gold") resetFormat()]])
---   
--- --- @see killTrigger --- @see tempRegexTrigger function tempTrigger(string, luaCode) end --- Wait for specified time in milliseconds. --- Use tempTimer instead! Don't use this function, because it freezes main thread. --- --- @usage Preferred use of tempTimer - wait for 2 seconds and than send "kill rat". ---
---   tempTimer(2, [[send("kill rat")]] )
---   
--- @usage Discouraged use of wait function. ---
---   -- This will freeze Mudlet for 2 seconds!!!
---   wait(2000)
---   send("kill rat")
---   
--- @usage This example is demonstrating transition from Nexus/Zmud wait. --- You can simply rewrote following nexus/zmud code bellow with tempTimers. ---
---   #send jerk fish
---   #wait 1500
---   #send pull line
---   #wait 500
---   #send jump
---   
--- Since timers are created instantly, if you want two or more, or means the times --- for consecutive timers should be to the starting point, unlike relatives times you do with waits. ---
---   -- Mudlet code
---   send ("jerk fish")
---   tempTimer (1.5, [[send ("pull line")]])
---   tempTimer (2,   [[send ("jump")]])
---   
--- --- @see tempTimer function wait(time) end --- Wrap line lineNumber of mini console (window) windowName. This function will interpret \n characters, --- apply word wrap and display the new lines on the screen. This function may be necessary if you use --- deleteLine() and thus erase the entire current line in the buffer, but you want to do some further --- echo() calls after calling deleteLine(). You will then need to re-wrap the last line of the buffer --- to actually see what you have echoed and get you \n interpreted as newline characters properly.

--- --- Using this function is not good programming practice and should be avoided. There are better ways of --- handling situations where you would call deleteLine() and echo afterwards e.g.: ---
---   selectString(line,1)
---   replace("")
---   
--- This will effectively have the same result as a call to deleteLine() but the buffer line will not --- be entirely removed. Consequently, further calls to echo() etc. sort of functions are possible --- without using wrapLine() unnecessarily. function wrapLine() end end mudlet-2.1/src/old_mudlet-lua/lua/luadoc/0000755000175000017500000000000012070466513017710 5ustar csmallcsmallmudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/0000755000175000017500000000000012070466513021162 5ustar csmallcsmallmudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/mudlet.lua0000644000175000017500000002260112070466513023160 0ustar csmallcsmall------------------------------------------------------------------------------- -- Doclet that generates HTML output. This doclet generates a set of html files -- based on a group of templates. The main templates are: --
    --
  • index.lp: index of modules and files;
  • --
  • file.lp: documentation for a lua file;
  • --
  • module.lp: documentation for a lua module;
  • --
  • function.lp: documentation for a lua function. This is a -- sub-template used by the others.
  • --
-- -- @release $Id: html.lua,v 1.29 2007/12/21 17:50:48 tomas Exp $ ------------------------------------------------------------------------------- local assert, getfenv, ipairs, loadstring, pairs, setfenv, tostring, tonumber, type = assert, getfenv, ipairs, loadstring, pairs, setfenv, tostring, tonumber, type local io = require"io" local lfs = require "lfs" local lp = require "luadoc.lp" local luadoc = require"luadoc" local package = package local string = require"string" local table = require"table" module "luadoc.doclet.mudlet" ------------------------------------------------------------------------------- -- Looks for a file `name' in given path. Removed from compat-5.1 -- @param path String with the path. -- @param name String with the name to look for. -- @return String with the complete path of the file found -- or nil in case the file is not found. local function search (path, name) for c in string.gfind(path, "[^;]+") do c = string.gsub(c, "%?", name) local f = io.open(c) if f then -- file exist? f:close() return c end end return nil -- file not found end ------------------------------------------------------------------------------- -- Include the result of a lp template into the current stream. function include (template, env) -- template_dir is relative to package.path local templatepath = options.template_dir .. template -- search using package.path (modified to search .lp instead of .lua local search_path = string.gsub(package.path, "%.lua", "") local templatepath = search(search_path, templatepath) assert(templatepath, string.format("template `%s' not found", template)) env = env or {} env.table = table env.io = io env.lp = lp env.ipairs = ipairs env.tonumber = tonumber env.tostring = tostring env.type = type env.luadoc = luadoc env.options = options return lp.include(templatepath, env) end ------------------------------------------------------------------------------- -- Returns a link to a html file, appending "../" to the link to make it right. -- @param html Name of the html file to link to -- @return link to the html file function link (html, from) local h = html from = from or "" string.gsub(from, "/", function () h = "../" .. h end) return h end ------------------------------------------------------------------------------- -- Returns the name of the html file to be generated from a module. -- Files with "lua" or "luadoc" extensions are replaced by "html" extension. -- @param modulename Name of the module to be processed, may be a .lua file or -- a .luadoc file. -- @return name of the generated html file for the module function module_link (modulename, doc, from) -- TODO: replace "." by "/" to create directories? -- TODO: how to deal with module names with "/"? assert(modulename) assert(doc) from = from or "" if doc.modules[modulename] == nil then -- logger:error(string.format("unresolved reference to module `%s'", modulename)) return end local href = "modules/" .. modulename .. ".html" string.gsub(from, "/", function () href = "../" .. href end) return href end ------------------------------------------------------------------------------- -- Returns the name of the html file to be generated from a lua(doc) file. -- Files with "lua" or "luadoc" extensions are replaced by "html" extension. -- @param to Name of the file to be processed, may be a .lua file or -- a .luadoc file. -- @param from path of where am I, based on this we append ..'s to the -- beginning of path -- @return name of the generated html file function file_link (to, from) assert(to) from = from or "" local href = to href = string.gsub(href, "lua$", "html") href = string.gsub(href, "luadoc$", "html") href = "files/" .. href string.gsub(from, "/", function () href = "../" .. href end) return href end ------------------------------------------------------------------------------- -- Returns a link to a function or to a table -- @param fname name of the function or table to link to. -- @param doc documentation table -- @param kind String specying the kinf of element to link ("functions" or "tables"). function link_to (fname, doc, module_doc, file_doc, from, kind) assert(fname) assert(doc) from = from or "" kind = kind or "functions" if file_doc then for _, func_name in pairs(file_doc[kind]) do if func_name == fname then return file_link(file_doc.name, from) .. "#" .. fname end end end local _, _, modulename, fname = string.find(fname, "^(.-)[%.%:]?([^%.%:]*)$") assert(fname) -- if fname does not specify a module, use the module_doc if string.len(modulename) == 0 and module_doc then modulename = module_doc.name end local module_doc = doc.modules[modulename] if not module_doc then -- logger:error(string.format("unresolved reference to function `%s': module `%s' not found", fname, modulename)) return end for _, func_name in pairs(module_doc[kind]) do if func_name == fname then return module_link(modulename, doc, from) .. "#" .. fname end end -- logger:error(string.format("unresolved reference to function `%s' of module `%s'", fname, modulename)) end ------------------------------------------------------------------------------- -- Make a link to a file, module or function function symbol_link (symbol, doc, module_doc, file_doc, from) assert(symbol) assert(doc) local href = -- file_link(symbol, from) or module_link(symbol, doc, from) or link_to(symbol, doc, module_doc, file_doc, from, "functions") or link_to(symbol, doc, module_doc, file_doc, from, "tables") if not href then logger:error(string.format("unresolved reference to symbol `%s'", symbol)) end return href or "" end ------------------------------------------------------------------------------- --- Generate link to function e.g. CoreMudlet.html#wait. function genLinkToFunction(doc, funcId) if funcId then funcIdTrim = string.gsub(funcId, "^%s*(.-)%s*$", "%1") -- trim local miFunc = doc.mIndex[funcIdTrim] if miFunc then local htmlFile = string.gsub(miFunc.filename, "[.]lua", ".html") return string.format("%s", (htmlFile .. "#" .. funcIdTrim), funcIdTrim) else return "MISSING LINK: '" .. funcId .. "'" end end end ------------------------------------------------------------------------------- -- Assembly the output filename for an input file. -- TODO: change the name of this function function out_file (filename) local h = filename h = string.gsub(h, "lua$", "html") h = string.gsub(h, "luadoc$", "html") h = "files/" .. h -- h = options.output_dir .. string.gsub (h, "^.-([%w_]+%.html)$", "%1") h = options.output_dir .. h return h end ------------------------------------------------------------------------------- -- Assembly the output filename for a module. -- TODO: change the name of this function function out_module (modulename) local h = modulename .. ".html" h = "modules/" .. h h = options.output_dir .. h return h end ----------------------------------------------------------------- -- Generate the output. -- @param doc Table with the structured documentation. function start (doc) -- Generate index file -- if (#doc.files > 0 or #doc.modules > 0) and (not options.noindexpage) then -- local filename = options.output_dir.."index.html" -- logger:info(string.format("generating file `%s'", filename)) -- local f = lfs.open(filename, "w") -- assert(f, string.format("could not open `%s' for writing", filename)) -- io.output(f) -- include("index.lp", { doc = doc }) -- f:close() -- end -- Generate Mudlet master index file if (#doc.mIndex > 0) and (not options.noindexpage) then local filename = options.output_dir.."index.html" logger:info(string.format("generating file `%s'", filename)) local f = lfs.open(filename, "w") assert(f, string.format("could not open `%s' for writing", filename)) io.output(f) include("mIndex.lp", { doc = doc }) f:close() end -- Process modules if not options.nomodules then for _, modulename in ipairs(doc.modules) do local module_doc = doc.modules[modulename] -- assembly the filename local filename = out_module(modulename) logger:info(string.format("generating file `%s'", filename)) local f = lfs.open(filename, "w") assert(f, string.format("could not open `%s' for writing", filename)) io.output(f) include("module.lp", { doc = doc, module_doc = module_doc }) f:close() end end -- Process files if not options.nofiles then for _, filepath in ipairs(doc.files) do local file_doc = doc.files[filepath] -- assembly the filename local filename = out_file(file_doc.name) logger:info(string.format("generating file `%s'", filename)) local f = lfs.open(filename, "w") assert(f, string.format("could not open `%s' for writing", filename)) io.output(f) include("file.lp", { doc = doc, file_doc = file_doc} ) f:close() end end -- copy extra files local f = lfs.open(options.output_dir.."luadoc.css", "w") io.output(f) include("luadoc.css") f:close() end mudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/html/0000755000175000017500000000000012070466513022126 5ustar csmallcsmallmudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/html/file.lp0000644000175000017500000000554712070466513023415 0ustar csmallcsmall Reference

File <%=file_doc.name%>

<%if file_doc.description then%>

<%=file_doc.description%>

<%end%> <%if file_doc.author then%>

<%= #file_doc.author>1 and "Authors" or "Author" %>: <%for _, author in ipairs(file_doc.author) do%> <%end%>
<%= author %>

<%end%> <%if file_doc.copyright then%>

Copyright ©<%=file_doc.copyright%>

<%end%> <%if file_doc.release then%>

Release: <%=file_doc.release%>

<%end%> <%if #file_doc.functions > 0 then%>

Functions

<%for _, func_name in ipairs(file_doc.functions) do local func_data = file_doc.functions[func_name]%> <%end%>
<%=func_data.private and "local " or ""%><%=func_name%> (<%=table.concat(func_data.param, ", ")%>) <%=func_data.summary%>
<%end%> <%if #file_doc.tables > 0 then%>

Tables

<%for _, tab_name in ipairs(file_doc.tables) do%> <%end%>
<%=tab_name%> <%=file_doc.tables[tab_name].summary%>
<%end%>

<%if #file_doc.functions > 0 then%>

Functions

<%for _, func_name in ipairs(file_doc.functions) do%> <%=luadoc.doclet.mudlet.include("function.lp", { doc=doc, file_doc=file_doc, func=file_doc.functions[func_name] })%> <%end%>
<%end%> <%if #file_doc.tables > 0 then%>

Tables

<%for _, tab_name in ipairs(file_doc.tables) do%> <%=luadoc.doclet.mudlet.include("table.lp", { doc=doc, file_doc=file_doc, tab=file_doc.tables[tab_name] })%> <%end%>
<%end%>

Valid XHTML 1.0!

mudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/html/menu.lp0000644000175000017500000000210112070466513023421 0ustar csmallcsmall<% if module_doc then from = "modules/"..module_doc.name elseif file_doc then from = "files/.."..file_doc.name else from = "" end %>

LuaDoc

    <%if not module_doc and not file_doc then%>
  • Index
  • <%else%>
  • ">Index
  • <%end%>
<%if not options.nomodules and #doc.modules > 0 then%>

Modules

    <%for _, modulename in ipairs(doc.modules) do if module_doc and module_doc.name == modulename then%>
  • <%=modulename%>
  • <%else%>
  • <%=modulename%>
  • <% end end%>
<%end%> <%if not options.nofiles and #doc.files > 0 then%>

Files

    <%for _, filepath in ipairs(doc.files) do if file_doc and file_doc.name == filepath then%>
  • <%=filepath%>
  • <%else%>
  • <%=filepath%>
  • <% end end%>
<%end%> mudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/html/module.lp0000644000175000017500000000564312070466513023760 0ustar csmallcsmall Reference

Module <%=module_doc.name%>

<%=module_doc.description%>

<%if module_doc.author then%>

<%= #module_doc.author>1 and "Authors" or "Author" %>: <%for _, author in ipairs(module_doc.author) do%> <%end%>
<%= author %>

<%end%> <%if module_doc.copyright then%>

Copyright© <%=module_doc.copyright%>

<%end%> <%if module_doc.release then%>

Release: <%=module_doc.release%>

<%end%> <%if #module_doc.functions > 0 then%>

Functions

<%for _, func_name in ipairs(module_doc.functions) do local func_data = module_doc.functions[func_name]%> <%end%>
<%=func_data.private and "local " or ""%><%=func_name%> (<%=table.concat(module_doc.functions[func_name].param, ", ")%>) <%=module_doc.functions[func_name].summary%>
<%end%> <%if #module_doc.tables > 0 then%>

Tables

<%for _, tab_name in ipairs(module_doc.tables) do%> <%end%>
<%=tab_name%> <%=module_doc.tables[tab_name].summary%>
<%end%>

<%if #module_doc.functions > 0 then%>

Functions

<%for _, func_name in ipairs(module_doc.functions) do%> <%=luadoc.doclet.mudlet.include("function.lp", { doc=doc, module_doc=module_doc, func=module_doc.functions[func_name] })%> <%end%>
<%end%> <%if #module_doc.tables > 0 then%>

Tables

<%for _, tab_name in ipairs(module_doc.tables) do%> <%=luadoc.doclet.mudlet.include("table.lp", { doc=doc, module_doc=module_doc, tab=module_doc.tables[tab_name] })%> <%end%>
<%end%>

Valid XHTML 1.0!

mudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/html/function.lp0000644000175000017500000000262312070466513024313 0ustar csmallcsmall<% if module_doc then from = "modules/"..module_doc.name elseif file_doc then from = "files/.."..file_doc.name else from = "" end %>
<%=func.private and "local " or ""%> <%=func.name%> (<%=table.concat(func.param, ", ")%>)
<%=func.description or ""%> <%if func.release then%>
Release: <%=func.release%> <%end%>
<%if type(func.param) == "table" and #func.param > 0 then%> Parameters
    <%for p = 1, #func.param do%>
  • <%=func.param[p]%>: <%=func.param[func.param[p]] or ""%>
  • <%end%>
<%end%> <%if type(func.usage) == "string" then%> Usage:
  • <%=func.usage%>
<%elseif type(func.usage) == "table" then%> Usage
    <%for _, usage in ipairs(func.usage) do%>
  • <%= usage %> <%end%>
<%end%> <%if type(func.ret) == "string" then%> Return value:
  • <%=func.ret%>
<%elseif type(func.ret) == "table" then%> Return values:
    <%for _, ret in ipairs(func.ret) do%>
  1. <%= ret %> <%end%>
<%end%> <%if type(func.see) == "string" then %> See also:
  • <%=luadoc.doclet.mudlet.genLinkToFunction(doc, func.see)%>
<%elseif type(func.see) == "table" and #func.see > 0 then %> See also:
    <%for i = 1, #func.see do%>
  • <%=luadoc.doclet.mudlet.genLinkToFunction(doc, func.see[i])%> <%end%>
<%end%>
mudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/html/table.lp0000644000175000017500000000045712070466513023560 0ustar csmallcsmall
<%=tab.name%>
<%=tab.description%> <%if type(tab.field) == "table" and #tab.field > 0 then%> Fields
    <%for p = 1, #tab.field do%>
  • <%=tab.field[p]%>: <%=tab.field[tab.field[p]] or ""%>
  • <%end%>
<%end%>
mudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/html/mIndex.lp0000644000175000017500000000262312070466513023712 0ustar csmallcsmall Reference " type="text/css" />
<%if not options.nofiles and #doc.files > 0 then%>

All Functions

<%for _,funcId in ipairs(doc.mIndex) do%> <%end%>
<%=doc.mIndex[funcId].filename%> <%=doc.mIndex[funcId].name%> <%=doc.mIndex[funcId].summary%>
<%end%>

Valid XHTML 1.0!

mudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/html/luadoc.css0000644000175000017500000001260512070466513024113 0ustar csmallcsmallbody { margin-left: 1em; margin-right: 1em; font-family: arial, helvetica, geneva, sans-serif; background-color:#ffffff; margin:0px; } code { font-family: "Andale Mono", monospace; } tt { font-family: "Andale Mono", monospace; } body, td, th { font-size: 11pt; } h1, h2, h3, h4 { margin-left: 0em; } textarea, pre, tt { font-size:10pt; } body, td, th { color:#000000; } small { font-size:0.85em; } h1 { font-size:1.5em; } h2 { font-size:1.25em; } h3 { font-size:1.15em; } h4 { font-size:1.06em; } pre { border:1px solid silver; background-color:#f4fff4; padding-top:0.5em; width: 80% } a:link { font-weight:bold; color: #004080; text-decoration: none; } a:visited { font-weight:bold; color: #006699; text-decoration: none; } a:link:hover { text-decoration:underline; } hr { color:#cccccc } img { border-width: 0px; } h3 { padding-top: 1em; } p { margin-left: 1em; } p.name { font-family: "Andale Mono", monospace; padding-top: 1em; margin-left: 0em; } blockquote { margin-left: 3em; } pre.example { background-color: rgb(245, 245, 245); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: silver; border-right-color: silver; border-bottom-color: silver; border-left-color: silver; padding: 1em; margin-left: 1em; margin-right: 1em; font-family: "Andale Mono", monospace; font-size: smaller; } hr { margin-left: 0em; background: #00007f; border: 0px; height: 1px; } ul { list-style-type: disc; } table.index { border: 1px #00007f; } table.index td { text-align: left; vertical-align: top; } table.index ul { padding-top: 0em; margin-top: 0em; } table { border: 1px solid black; border-collapse: collapse; margin-left: auto; margin-right: auto; } th { border: 1px solid black; padding: 0.5em; } td { border: 1px solid black; padding: 0.5em; } div.header, div.footer { margin-left: 0em; } #container { margin-left: 1em; margin-right: 1em; background-color: #f0f0f0; } #product { text-align: center; border-bottom: 1px solid #cccccc; background-color: #ffffff; } #product big { font-size: 2em; } #product_logo { } #product_name { } #product_description { } #main { background-color: #f0f0f0; border-left: 2px solid #cccccc; } #navigation { float: left; width: 18em; margin: 0; vertical-align: top; background-color: #f0f0f0; overflow:visible; position:fixed; left: 17px; top: 1px } #navigation h1 { background-color:#e7e7e7; font-size:1.1em; color:#000000; text-align:left; margin:0px; padding:0.2em; border-top:1px solid #dddddd; border-bottom:1px solid #dddddd; } #navigation ul { font-size:1em; list-style-type: none; padding: 0; margin: 1px; } #navigation li { text-indent: -1em; margin: 0em 0em 0em 0.5em; display: block; padding: 3px 0px 0px 12px; } #navigation li li a { padding: 0px 3px 0px -1em; } #content { margin-left: 18em; padding: 1em; border-left: 2px solid #cccccc; border-right: 2px solid #cccccc; background-color: #ffffff; } #about { clear: both; margin: 0; padding: 5px; border-top: 2px solid #cccccc; background-color: #ffffff; } @media print { body { font: 12pt "Times New Roman", "TimeNR", Times, serif; } a { font-weight:bold; color: #004080; text-decoration: underline; } #main { background-color: #ffffff; border-left: 0px; } #container { margin-left: 2%; margin-right: 2%; background-color: #ffffff; } #content { margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff; } #navigation { display: none; } pre.example { font-family: "Andale Mono", monospace; font-size: 10pt; page-break-inside: avoid; } } table.module_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.module_list td.name { background-color: #f0f0f0; } table.module_list td.summary { width: 100%; } table.file_list { border-width: 1px; border-style: solid; border-color: #cccccc; border-collapse: collapse; } table.file_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.file_list td.name { background-color: #f0f0f0; } table.file_list td.summary { width: 100%; } table.function_list { border-width: 1px; border-style: solid; border-color: #cccccc; border-collapse: collapse; } table.function_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.function_list td.name { background-color: #f0f0f0; } table.function_list td.summary { width: 100%; } table.table_list { border-width: 1px; border-style: solid; border-color: #cccccc; border-collapse: collapse; } table.table_list td { border-width: 1px; padding: 3px; border-style: solid; border-color: #cccccc; } table.table_list td.name { background-color: #f0f0f0; } table.table_list td.summary { width: 100%; } dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} dl.function dd {padding-bottom: 1em;} dl.function h3 {padding: 0; margin: 0; font-size: medium;} dl.table dt {border-top: 1px solid #ccc; padding-top: 1em;} dl.table dd {padding-bottom: 1em;} dl.table h3 {padding: 0; margin: 0; font-size: medium;} #TODO: make module_list, file_list, function_list, table_list inherit from a list mudlet-2.1/src/old_mudlet-lua/lua/luadoc/doclet/html/index.lp0000644000175000017500000000332412070466513023574 0ustar csmallcsmall Reference " type="text/css" />
<%if not options.nomodules and #doc.modules > 0 then%>

Modules

<%for _, modulename in ipairs(doc.modules) do%> <%end%>
<%=modulename%> <%=doc.modules[modulename].summary%>
<%end%> <%if not options.nofiles and #doc.files > 0 then%>

Files

<%for _, filepath in ipairs(doc.files) do%> <%end%>
<%=filepath%>
<%end%>

Valid XHTML 1.0!

mudlet-2.1/src/old_mudlet-lua/lua/luadoc/taglet/0000755000175000017500000000000012070466513021170 5ustar csmallcsmallmudlet-2.1/src/old_mudlet-lua/lua/luadoc/taglet/standard/0000755000175000017500000000000012070466513022770 5ustar csmallcsmallmudlet-2.1/src/old_mudlet-lua/lua/luadoc/taglet/standard/tags.lua0000644000175000017500000001221312070466513024430 0ustar csmallcsmall-- added filename tag ------------------------------------------------------------------------------- -- Handlers for several tags -- @release $Id: tags.lua,v 1.8 2007/09/05 12:39:09 tomas Exp $ ------------------------------------------------------------------------------- local luadoc = require "luadoc" local util = require "luadoc.util" local string = require "string" local table = require "table" local assert, type, tostring = assert, type, tostring module "luadoc.taglet.standard.tags" ------------------------------------------------------------------------------- local function author (tag, block, text) block[tag] = block[tag] or {} if not text then luadoc.logger:warn("author `name' not defined [["..text.."]]: skipping") return end table.insert (block[tag], text) end ------------------------------------------------------------------------------- -- Set the class of a comment block. Classes can be "module", "function", -- "table". The first two classes are automatic, extracted from the source code local function class (tag, block, text) block[tag] = text end ------------------------------------------------------------------------------- local function copyright (tag, block, text) block[tag] = text end ------------------------------------------------------------------------------- local function description (tag, block, text) block[tag] = text end ------------------------------------------------------------------------------- local function filename (tag, block, text) block[tag] = text end ------------------------------------------------------------------------------- local function field (tag, block, text) if block["class"] ~= "table" then luadoc.logger:warn("documenting `field' for block that is not a `table'") end block[tag] = block[tag] or {} local _, _, name, desc = string.find(text, "^([_%w%.]+)%s+(.*)") assert(name, "field name not defined") table.insert(block[tag], name) block[tag][name] = desc end ------------------------------------------------------------------------------- -- Set the name of the comment block. If the block already has a name, issue -- an error and do not change the previous value local function name (tag, block, text) if block[tag] and block[tag] ~= text then luadoc.logger:error(string.format("block name conflict: `%s' -> `%s'", block[tag], text)) end block[tag] = text end ------------------------------------------------------------------------------- -- Processes a parameter documentation. -- @param tag String with the name of the tag (it must be "param" always). -- @param block Table with previous information about the block. -- @param text String with the current line beeing processed. local function param (tag, block, text) block[tag] = block[tag] or {} -- TODO: make this pattern more flexible, accepting empty descriptions local _, _, name, desc = string.find(text, "^([_%w%.]+)%s+(.*)") if not name then luadoc.logger:warn("parameter `name' not defined [["..text.."]]: skipping") return end local i = table.foreachi(block[tag], function (i, v) if v == name then return i end end) if i == nil then luadoc.logger:warn(string.format("documenting undefined parameter `%s'", name)) table.insert(block[tag], name) end block[tag][name] = desc end ------------------------------------------------------------------------------- local function release (tag, block, text) block[tag] = text end ------------------------------------------------------------------------------- local function ret (tag, block, text) tag = "ret" if type(block[tag]) == "string" then block[tag] = { block[tag], text } elseif type(block[tag]) == "table" then table.insert(block[tag], text) else block[tag] = text end end ------------------------------------------------------------------------------- -- @see ret local function see (tag, block, text) -- see is always an array block[tag] = block[tag] or {} -- remove trailing "." text = string.gsub(text, "(.*)%.$", "%1") local s = util.split("%s*,%s*", text) table.foreachi(s, function (_, v) table.insert(block[tag], v) end) end ------------------------------------------------------------------------------- -- @see ret local function usage (tag, block, text) if type(block[tag]) == "string" then block[tag] = { block[tag], text } elseif type(block[tag]) == "table" then table.insert(block[tag], text) else block[tag] = text end end ------------------------------------------------------------------------------- local handlers = {} handlers["author"] = author handlers["class"] = class handlers["copyright"] = copyright handlers["description"] = description handlers["field"] = field handlers["name"] = name handlers["param"] = param handlers["release"] = release handlers["return"] = ret handlers["see"] = see handlers["usage"] = usage handlers["filename"] = filename ------------------------------------------------------------------------------- function handle (tag, block, text) if not handlers[tag] then luadoc.logger:error(string.format("undefined handler for tag `%s'", tag)) return end -- assert(handlers[tag], string.format("undefined handler for tag `%s'", tag)) return handlers[tag](tag, block, text) end mudlet-2.1/src/old_mudlet-lua/lua/luadoc/taglet/mudlet.lua0000644000175000017500000004114112070466513023166 0ustar csmallcsmall------------------------------------------------------------------------------- -- This is just copy of standard.lua with support for
 tag in 
-- documentation. See example bellow:
-- 
--	if info ~= nil then
--		assert(info.name, "function name undefined")
--	end
-- 
-- -- -- LuaDoc modules functionality was amended (misused) to generate -- index of all functions. -- ------------------------------------------------------------------------------- -- @release $Id: standard.lua,v 1.39 2007/12/21 17:50:48 tomas Exp $ ------------------------------------------------------------------------------- local assert, pairs, tostring, type = assert, pairs, tostring, type local io = require "io" local lfs = require "lfs" local luadoc = require "luadoc" local util = require "luadoc.util" local tags = require "luadoc.taglet.standard.tags" local string = require "string" local table = require "table" module 'luadoc.taglet.mudlet' ------------------------------------------------------------------------------- -- Creates an iterator for an array base on a class type. -- @param t array to iterate over -- @param class name of the class to iterate over function class_iterator (t, class) return function () local i = 1 return function () while t[i] and t[i].class ~= class do i = i + 1 end local v = t[i] i = i + 1 return v end end end -- Patterns for function recognition local identifiers_list_pattern = "%s*(.-)%s*" local identifier_pattern = "[^%(%s]+" local function_patterns = { "^()%s*function%s*("..identifier_pattern..")%s*%("..identifiers_list_pattern.."%)", "^%s*(local%s)%s*function%s*("..identifier_pattern..")%s*%("..identifiers_list_pattern.."%)", "^()%s*("..identifier_pattern..")%s*%=%s*function%s*%("..identifiers_list_pattern.."%)", } ------------------------------------------------------------------------------- -- Checks if the line contains a function definition -- @param line string with line text -- @return function information or nil if no function definition found local function check_function (line) line = util.trim(line) local info = table.foreachi(function_patterns, function (_, pattern) local r, _, l, id, param = string.find(line, pattern) if r ~= nil then return { name = id, private = (l == "local"), param = util.split("%s*,%s*", param), } end end) -- TODO: remove these assert's? if info ~= nil then assert(info.name, "function name undefined") assert(info.param, string.format("undefined parameter list for function `%s'", info.name)) end return info end ------------------------------------------------------------------------------- -- Checks if the line contains a module definition. -- @param line string with line text -- @param currentmodule module already found, if any -- @return the name of the defined module, or nil if there is no module -- definition local function check_module (line, currentmodule) line = util.trim(line) -- module"x.y" -- module'x.y' -- module[[x.y]] -- module("x.y") -- module('x.y') -- module([[x.y]]) -- module(...) local r, _, modulename = string.find(line, "^module%s*[%s\"'(%[]+([^,\"')%]]+)") if r then -- found module definition logger:debug(string.format("found module `%s'", modulename)) return modulename end return currentmodule end ------------------------------------------------------------------------------- -- Extracts summary information from a description. The first sentence of each -- doc comment should be a summary sentence, containing a concise but complete -- description of the item. It is important to write crisp and informative -- initial sentences that can stand on their own -- @param description text with item description -- @return summary string or nil if description is nil local function parse_summary (description) -- summary is never nil... description = description or "" -- append an " " at the end to make the pattern work in all cases description = description.." " -- read until the first period followed by a space or tab local summary = string.match(description, "(.-%.)[%s\t]") -- if pattern did not find the first sentence, summary is the whole description summary = summary or description return summary end ------------------------------------------------------------------------------- -- @param f file handle -- @param line current line being parsed -- @param modulename module already found, if any -- @return current line -- @return code block -- @return modulename if found local function parse_code (f, line, modulename) local code = {} while line ~= nil do if string.find(line, "^[\t ]*%-%-%-") then -- reached another luadoc block, end this parsing return line, code, modulename else -- look for a module definition modulename = check_module(line, modulename) table.insert(code, line) line = f:read() end end -- reached end of file return line, code, modulename end ------------------------------------------------------------------------------- -- Simply tests if trimmed line without pre /pre tags is blank -- @return true/false function skipNewline(line) if string.find(line, "<[pP][rR][eE]>") or string.find(line, "") then line = string.gsub(line, "<[pP][rR][eE]>", "") line = string.gsub(line, "", "") line = string.gsub(line, "^%s*(.-)%s*$", "%1") return line == "" else return false end end ------------------------------------------------------------------------------- -- Simply tests if trimmed line without @usage tags is blank -- @return true/false function addNewlineAfterUsage(line) line = string.gsub(line, "@usage", "") line = string.gsub(line, "^%s*(.-)%s*$", "%1") return line == "" end ------------------------------------------------------------------------------- -- Removes lua comment from the begining of the line and add newLine char. -- This was implemented to add
 support to LuaDoc.
-- @param s string to be trimmed
-- @return trimmed string
local function trim_comment_pre(s) 
	-- detect start/end of pre block - case sensitive
	if string.find(s, "<[pP][rR][eE]>") then luadoc_taglet_mudlet_pre = true end
	if string.find(s, "") then luadoc_taglet_mudlet_pre = false end
	-- process line
	s = string.gsub(s, "%-%-+(.*)$", "%1")
	if luadoc_taglet_mudlet_pre then
		if not skipNewline(s) then
			return s .. "\n"
		else
			return s
		end 
	else
		s = string.gsub(s, "^%s*(.-)%s*$", "%1")
		if string.find(s, "@usage") then 
			if addNewlineAfterUsage(s) then
				s = s .. "\n"
			end
		end
		return s
	end
end


-------------------------------------------------------------------------------
-- Parses the information inside a block comment
-- @param block block with comment field
-- @return block parameter

local function parse_comment (block, first_line)

	-- get the first non-empty line of code
	local code = table.foreachi(block.code, function(_, line)
		if not util.line_empty(line) then
			-- `local' declarations are ignored in two cases:
			-- when the `nolocals' option is turned on; and
			-- when the first block of a file is parsed (this is
			--	necessary to avoid confusion between the top
			--	local declarations and the `module' definition.
			if (options.nolocals or first_line) and line:find"^%s*local" then
				return
			end
			return line
		end
	end)
	
	-- parse first line of code
	if code ~= nil then
		local func_info = check_function(code)
		local module_name = check_module(code)
		if func_info then
			block.class = "function"
			block.name = func_info.name
			block.param = func_info.param
			block.private = func_info.private
		elseif module_name then
			block.class = "module"
			block.name = module_name
			block.param = {}
		else
			block.param = {}
		end
	else
		-- TODO: comment without any code. Does this means we are dealing
		-- with a file comment?
	end

	-- parse @ tags
	local currenttag = "description"
	local currenttext
	
	table.foreachi(block.comment, function (_, line)
		-- added new line char to support 
 formatted code
		line = trim_comment_pre(line)

		local r, _, tag, text = string.find(line, "@([_%w%.]+)%s+(.*)")
		if r ~= nil then
			-- found new tag, add previous one, and start a new one
			-- TODO: what to do with invalid tags? issue an error? or log a warning?
			tags.handle(currenttag, block, currenttext)
			
			currenttag = tag
			currenttext = text
		else
			currenttext = util.concat(currenttext, line)
-- commented out, so I can user 
 formatted code
--			assert(string.sub(currenttext, 1, 1) ~= " ", string.format("`%s', `%s'", currenttext, line))
		end
	end)
	tags.handle(currenttag, block, currenttext)

	-- Store file name info
	tags.handle("filename", block, luadoc_taglet_mudlet_filename)

	-- extracts summary information from the description
	block.summary = parse_summary(block.description)
-- commented out, so I can user 
 formatted code
--	assert(string.sub(block.description, 1, 1) ~= " ", string.format("`%s'", block.description))

	return block
end

-------------------------------------------------------------------------------
-- Parses a block of comment, started with ---. Read until the next block of
-- comment.
-- @param f file handle
-- @param line being parsed
-- @param modulename module already found, if any
-- @return line
-- @return block parsed
-- @return modulename if found

local function parse_block (f, line, modulename, first)
	local block = {
		comment = {},
		code = {},
	}

	while line ~= nil do
		if string.find(line, "^[\t ]*%-%-") == nil then
			-- reached end of comment, read the code below it
			-- TODO: allow empty lines
			line, block.code, modulename = parse_code(f, line, modulename)
			
			-- parse information in block comment
			block = parse_comment(block, first)

			return line, block, modulename
		else
			table.insert(block.comment, line)
			line = f:read()
		end
	end
	-- reached end of file
	
	-- parse information in block comment
	block = parse_comment(block, first)
	
	return line, block, modulename
end

-------------------------------------------------------------------------------
-- Parses a file documented following luadoc format.
-- @param filepath full path of file to parse
-- @param doc table with documentation
-- @return table with documentation

function parse_file (filepath, doc)
	local blocks = {}
	local modulename = nil
	
	-- read each line
	local f = io.open(filepath, "r")
	local i = 1
	local line = f:read()
	local first = true
	while line ~= nil do
		if string.find(line, "^[\t ]*%-%-%-") then
			-- reached a luadoc block
			local block
			line, block, modulename = parse_block(f, line, modulename, first)
			table.insert(blocks, block)
		else
			-- look for a module definition
			modulename = check_module(line, modulename)
			
			-- TODO: keep beginning of file somewhere
			
			line = f:read()
		end
		first = false
		i = i + 1
	end
	f:close()
	-- store blocks in file hierarchy
	assert(doc.files[filepath] == nil, string.format("doc for file `%s' already defined", filepath))
	table.insert(doc.files, filepath)
	doc.files[filepath] = {
		type = "file",
		name = filepath,
		doc = blocks,
--		functions = class_iterator(blocks, "function"),
--		tables = class_iterator(blocks, "table"),
	}

	-- added initial file comment
	local first = doc.files[filepath].doc[1]
	if first and modulename then
		doc.files[filepath].author = first.author
		doc.files[filepath].copyright = first.copyright
		doc.files[filepath].description = first.description
		doc.files[filepath].release = first.release
		doc.files[filepath].summary = first.summary
	end

	-- if module definition is found, store in module hierarchy
	if modulename ~= nil then
		if modulename == "..." then
				modulename = string.gsub (filepath, "%.lua$", "")
				modulename = string.gsub (modulename, "/", ".")
		end
		if doc.modules[modulename] ~= nil then
			-- module is already defined, just add the blocks
			table.foreachi(blocks, function (_, v)
				table.insert(doc.modules[modulename].doc, v)
			end)
		else
			-- TODO: put this in a different module
			table.insert(doc.modules, modulename)
			doc.modules[modulename] = {
				type = "module",
				name = modulename,
				doc = blocks,
--				functions = class_iterator(blocks, "function"),
--				tables = class_iterator(blocks, "table"),
				author = first and first.author,
				copyright = first and first.copyright,
				description = "",
				release = first and first.release,
				summary = "",
			}
			
			-- find module description
			for m in class_iterator(blocks, "module")() do
				doc.modules[modulename].description = util.concat(
					doc.modules[modulename].description, 
					m.description)
				doc.modules[modulename].summary = util.concat(
					doc.modules[modulename].summary, 
					m.summary)
				if m.author then
					doc.modules[modulename].author = m.author
				end
				if m.copyright then
					doc.modules[modulename].copyright = m.copyright
				end
				if m.release then
					doc.modules[modulename].release = m.release
				end
				if m.name then
					doc.modules[modulename].name = m.name
				end
			end
			doc.modules[modulename].description = doc.modules[modulename].description or (first and first.description) or ""
			doc.modules[modulename].summary = doc.modules[modulename].summary or (first and first.summary) or ""
		end
		
		-- make functions table
		doc.modules[modulename].functions = doc.modules[modulename].functions or {}
		for f in class_iterator(blocks, "function")() do
			table.insert(doc.modules[modulename].functions, f.name)
			doc.modules[modulename].functions[f.name] = f
		end
		
		-- make tables table
		doc.modules[modulename].tables = {}
		for t in class_iterator(blocks, "table")() do
			table.insert(doc.modules[modulename].tables, t.name)
			doc.modules[modulename].tables[t.name] = t
		end
	end
	
	-- make functions table
	doc.files[filepath].functions = {}
	for f in class_iterator(blocks, "function")() do
		table.insert(doc.files[filepath].functions, f.name)
		-- added link, so we can refer this function later
		f.link = string.gsub(filepath, ".lua", ".html") .. "#" .. f.name
		doc.files[filepath].functions[f.name] = f
		-- new array for master index of all functions
		local funcId = f.name
		table.insert(doc.mIndex, funcId)
		doc.mIndex[funcId] = f
	end
	
	-- make tables table
	doc.files[filepath].tables = {}
	for t in class_iterator(blocks, "table")() do
		table.insert(doc.files[filepath].tables, t.name)
		doc.files[filepath].tables[t.name] = t
	end
	
	return doc
end

-------------------------------------------------------------------------------
-- Checks if the file is terminated by ".lua" or ".luadoc" and calls the 
-- function that does the actual parsing
-- @param filepath full path of the file to parse
-- @param doc table with documentation
-- @return table with documentation
-- @see parse_file

function file (filepath, doc)
	local patterns = { "%.lua$", "%.luadoc$" }
	local valid = table.foreachi(patterns, function (_, pattern)
		if string.find(filepath, pattern) ~= nil then
			return true
		end
	end)
	
	if valid then
		logger:info(string.format("processing file `%s'", filepath))
		doc = parse_file(filepath, doc)
	end
	
	return doc
end

-------------------------------------------------------------------------------
-- Recursively iterates through a directory, parsing each file
-- @param path directory to search
-- @param doc table with documentation
-- @return table with documentation

function directory (path, doc)
	for f in lfs.dir(path) do
		local fullpath = path .. "/" .. f
		local attr = lfs.attributes(fullpath)
		assert(attr, string.format("error stating file `%s'", fullpath))
		
		if attr.mode == "file" then
			doc = file(fullpath, doc)
		elseif attr.mode == "directory" and f ~= "." and f ~= ".." then
			doc = directory(fullpath, doc)
		end
	end
	return doc
end

-- Recursively sorts the documentation table
local function recsort (tab)
	table.sort (tab)
	-- sort list of functions by name alphabetically
	for f, doc in pairs(tab) do
		if doc.functions then
			table.sort(doc.functions)
		end
		if doc.tables then
			table.sort(doc.tables)
		end
	end
end

-------------------------------------------------------------------------------

function start (files, doc)
	assert(files, "file list not specified")
	
	-- Create an empty document, or use the given one
	doc = doc or {
		files = {},
		modules = {},
		mIndex = {}, -- master index
	}
	assert(doc.files, "undefined `files' field")
	assert(doc.modules, "undefined `modules' field")
	
	table.foreachi(files, function (_, path)
		local attr = lfs.attributes(path)
		assert(attr, string.format("error stating path `%s'", path))
	
		-- current file
		luadoc_taglet_mudlet_filename = path
	
		if attr.mode == "file" then
			doc = file(path, doc)
		elseif attr.mode == "directory" then
			doc = directory(path, doc)
		end
	end)
	
	-- order arrays alphabetically
	recsort(doc.files)
	recsort(doc.modules)
	table.sort(doc.mIndex)

	return doc
end
mudlet-2.1/src/old_mudlet-lua/TODO0000644000175000017500000000106512070466513016352 0ustar  csmallcsmallneed to sort out single GIT repozitory for all mudlet code
	(well it's not so bad now ... there is one for lua and one for rest)


Lua Code
	test it properly e.g. that all functions are working
	test new loading
	clean up lua dependences rex_pcre, lpeg, luasql.sqlite3


LuaDoc
	gen LuaDoc and link it from main manual (this will be just API documentation)
		e.g. LuaDoc will replace Alphabetic Function List, but still need most of original doc

	make generated LuaDoc more appealing (check lua/luadoc/doclet/html folder for it)
		this mainly includes better css

mudlet-2.1/src/old_mudlet-lua/genDoc.sh0000644000175000017500000000016212070466513017412 0ustar  csmallcsmall
cd lua
luadoc *.lua geyser/*.lua -d ../mudlet-lua-doc --taglet luadoc.taglet.mudlet -doclet luadoc.doclet.mudlet
mudlet-2.1/src/EActionGroup.h0000644000175000017500000000342211513237311015453 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef _eaction_group_h
#define _eaction_group_h
#include 
#include "mudlet.h"
#include "Host.h"

class EActionGroup : public QActionGroup
{
    Q_OBJECT
        
        public:
        
        EActionGroup(QObject* parent, QString name);
    void triggered();    
    
    int    mID;
    Host * mpHost;
    
public slots:
    
    void trigger();//{QAction::trigger();}
    
    
    
    
};

#endif

mudlet-2.1/src/TRoom.cpp0000644000175000017500000001271112070466512014516 0ustar  csmallcsmall
#include 
#include "TRoom.h"

#include 

TRoom::TRoom()
: id( 0 )
, area( 0 )
, x( 0 )
, y( 0 )
, z( 0 )
, north( -1 )
, northeast( -1 )
, east( -1 )
, southeast( -1 )
, south( -1 )
, southwest( -1 )
, west( -1 )
, northwest( -1 )
, up( -1 )
, down( -1 )
, in( -1 )
, out( -1 )
, environment( -1 )
, weight(1)
, isLocked( false )
, c( 0 )
, highlight( false )
, highlightColor( QColor( 255,150,0 ) )
, rendered(false)
, min_x( 0 )
, max_x( 0 )
, min_y( 0 )
, max_y( 0 )
{
}

int TRoom::hasExitStub(int direction){
    if (exitStubs.contains(direction))
        return 1;
    else
        return 0;
}

void TRoom::setExitStub(int direction, int status){
    if (status)
        exitStubs.append(direction);
    else
        exitStubs.removeOne(direction);
}

void TRoom::setWeight( int w )
{
    weight = w;
}

bool TRoom::hasExit( int id )
{
    if( north == id )
        return true;
    else if( south == id )
        return true;
    else if( northwest == id )
        return true;
    else if( northeast == id )
        return true;
    else if( southwest == id )
        return true;
    else if( southeast == id )
        return true;
    else if( east == id )
        return true;
    else if( west == id )
        return true;
    else if( up == id )
        return true;
    else if( down == id )
        return true;
    else if( out == id )
        return true;
    else if( in == id )
        return true;
    else
        return false;
}

void TRoom::setExitLock(int exit, bool state )
{
    if( ! state )
    {
        exitLocks.removeAll( exit );
        return;
    }
    switch( exit )
    {
        case DIR_NORTH: exitLocks.push_back(DIR_NORTH); break;
        case DIR_NORTHEAST: exitLocks.push_back(DIR_NORTHEAST); break;
        case DIR_NORTHWEST: exitLocks.push_back(DIR_NORTHWEST); break;
        case DIR_SOUTHEAST: exitLocks.push_back(DIR_SOUTHEAST); break;
        case DIR_SOUTHWEST: exitLocks.push_back(DIR_SOUTHWEST); break;
        case DIR_SOUTH: exitLocks.push_back(DIR_SOUTH); break;
        case DIR_EAST: exitLocks.push_back(DIR_EAST); break;
        case DIR_WEST: exitLocks.push_back(DIR_WEST); break;
        case DIR_UP: exitLocks.push_back(DIR_UP); break;
        case DIR_DOWN: exitLocks.push_back(DIR_DOWN); break;
        case DIR_IN: exitLocks.push_back(DIR_IN); break;
        case DIR_OUT: exitLocks.push_back(DIR_OUT); break;
    }
}

void TRoom::setSpecialExitLock(int to, QString cmd, bool doLock)
{
    QMapIterator it( other );
    while(it.hasNext() )
    {
        it.next();
        if( it.key() != to ) continue;
        if( it.value().size() < 1 ) continue;
        if( it.value().mid(1) != cmd )
        {
            if( it.value() != cmd )
            {
                continue;
            }
        }
        if( doLock )
        {
            QString _cmd = it.value();
            _cmd.replace( 0, 1, '1' );
            other.replace( to, _cmd );
        }
        else
        {
            QString _cmd = it.value();
            _cmd.replace( 0, 1, '0');
            other.replace( to, _cmd );
        }
        return;
    }
}

bool TRoom::hasExitLock( int exit )
{
    return exitLocks.contains(exit);
}

// 0=offen 1=zu
bool TRoom::hasSpecialExitLock(int to, QString cmd)
{
    if( other.contains( to ) )
    {
        QMapIterator it( other );
        while(it.hasNext() )
        {
            it.next();
            if( it.key() != to ) continue;
            if( it.value().size() < 2 ) continue;
            return it.value().mid(0,1) == "1";
        }
        return false;
    }
    else
        return false;
}

void TRoom::addSpecialExit( int to, QString cmd )
{
    // replace if this special exit exists, otherwise add
    QMapIterator it( other );
    while(it.hasNext() )
    {
        it.next();
        if( it.key() != to ) continue;
        if( it.value().size() > 0 )
        {
            QString _cmd;
            if( cmd.startsWith('0') || cmd.startsWith('1') )
            {
                _cmd = cmd;
            }
            else
            {
                _cmd.prepend("0");
                _cmd.append( cmd );
            }

            other.replace( to, _cmd );
            return;
        }
    }
    // it doesnt exit -> add
    QString _cmd;
    if( cmd.startsWith('0') || cmd.startsWith('1') )
    {
        _cmd = cmd;
    }
    else
    {
        _cmd.prepend("0");
        _cmd.append( cmd );
    }
    other.insertMulti( to, _cmd );
}


void TRoom::removeSpecialExit( int to, QString cmd )
{
    other.remove(to, cmd.prepend("0"));
    other.remove(to, cmd.prepend("1"));
}

void TRoom::calcRoomDimensions()
{
    QMapIterator > it(customLines);
    while( it.hasNext() )
    {
        it.next();
        const QString & _e = it.key();
        const QList & _pL= it.value();
        if( _pL.size() < 1 ) continue;
        if( min_x == min_y == max_x == max_y == 1 )
        {
            min_x = _pL[0].x();
            max_x = min_x;
            min_y = _pL[0].y();
            max_y = min_y;
        }
        for( int i=0; i<_pL.size(); i++ )
        {
            qreal _x = _pL[i].x();
            qreal _y = _pL[i].y();
            if( min_x > _x )
                min_x = _x;
            if( max_x < _x )
                max_x = _x;
            if( min_y > _y )
                min_y = _y;
            if( max_y < _y )
                max_y = _y;
        }
        qDebug()<<"custom lines span: x("<
#include 
#include 
#include 

class TScript;
class Host;

class ScriptUnit
{
    friend class XMLexport;
    friend class XMLimport;

public:

    ScriptUnit( Host * pHost ) : mpHost(pHost), mMaxID(0) {;}
    std::list  getScriptRootNodeList()   { QMutexLocker locker(& mScriptUnitLock); return mScriptRootNodeList; }
    TScript *             getScript( int id );
    void                  compileAll();
    bool                  registerScript( TScript * pT );
    void                  unregisterScript( TScript * pT );
    void                  reParentScript( int childID, int oldParentID, int newParentID, int parentPosition = -1, int childPosition = -1 );
    void                  stopAllTriggers();
    void                  uninstall( QString );
    void                  _uninstall( TScript * pChild, QString packageName );
    qint64                getNewID();
    QMutex                mScriptUnitLock;
    QList        uninstallList;

private:

    ScriptUnit(){;}
    TScript *             getScriptPrivate( int id );
    void                  addScriptRootNode( TScript * pT, int parentPosition = -1, int childPosition = -1 );
    void                  addScript( TScript * pT );
    void                  removeScriptRootNode( TScript * pT );
    void                  removeScript( TScript *);
    Host *                mpHost;
    QMap  mScriptMap;
    std::list  mScriptRootNodeList;
    qint64                mMaxID;


};


#endif

mudlet-2.1/src/dlgSourceEditorArea.h0000644000175000017500000000354411513237311017010 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef dlg_source_editor_area_h
#define dlg_source_editor_area_h

#include "ui_source_editor_area.h"
#include 

class THighlighter;

//#include 
//#include 

class dlgSourceEditorArea : public QWidget , public Ui::source_editor_area
{
    Q_OBJECT
        
        public:
        
        dlgSourceEditorArea(QWidget*);
        THighlighter * highlighter;
    //QsciLexerLua * mpLuaLexer;
    
signals:
    
    
public slots:
    
    
};

#endif

mudlet-2.1/src/KeyUnit.cpp0000644000175000017500000005024512020507606015045 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn                                     *
 *   KoehnHeiko@googlemail.com                                             *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include 
#include 
#include 
#include 
#include  // NULL
#include 
#include 
#include 
#include 
#include "Host.h"
#include "TLuaInterpreter.h"
#include 
#include "KeyUnit.h"

#include 

using namespace std;

KeyUnit::KeyUnit( Host * pHost )
: mpHost(pHost)
, mMaxID(0)
{
    setupKeyNames();
}


void KeyUnit::_uninstall( TKey * pChild, QString packageName )
{
    typedef list::const_iterator I;
    list * childrenList = pChild->mpMyChildrenList;
    for( I it2 = childrenList->begin(); it2 != childrenList->end(); it2++)
    {
        TKey * pT = *it2;
        _uninstall( pT, packageName );
        uninstallList.append( pT );
    }
}


void KeyUnit::uninstall( QString packageName )
{
    typedef std::list::iterator IT;
    for( IT it = mKeyRootNodeList.begin(); it != mKeyRootNodeList.end(); it ++ )
    {
        TKey * pT = *it;

        if( pT->mPackageName == packageName )
        {
            _uninstall( pT, packageName );
            uninstallList.append( pT );
        }
    }
    for( int i=0; i::const_iterator I;
    for( I it = mKeyRootNodeList.begin(); it != mKeyRootNodeList.end(); it++)
    {
        TKey * pChild = *it;
        if( pChild->match( key, modifier ) ) return true;
    }

    return false;
}

void KeyUnit::compileAll()
{
    typedef list::const_iterator I;
    for( I it = mKeyRootNodeList.begin(); it != mKeyRootNodeList.end(); it++)
    {
        TKey * pChild = *it;
        if( pChild->isActive() )
        {
            pChild->compileAll();
        }
    }
}

bool KeyUnit::enableKey( QString & name )
{
    bool found = false;
    QMutexLocker locker(& mKeyUnitLock);
    typedef list::const_iterator I;
    for( I it = mKeyRootNodeList.begin(); it != mKeyRootNodeList.end(); it++)
    {
        TKey * pChild = *it;
        pChild->enableKey( name );
        found = true;
    }
    return found;
}

bool KeyUnit::disableKey( QString & name )
{
    bool found = false;
    QMutexLocker locker(& mKeyUnitLock);
    typedef list::const_iterator I;
    for( I it = mKeyRootNodeList.begin(); it != mKeyRootNodeList.end(); it++)
    {
        TKey * pChild = *it;
        pChild->disableKey( name );
        found = true;
    }
    return found;
}

void KeyUnit::addKeyRootNode( TKey * pT, int parentPosition, int childPosition )
{
    if( ! pT ) return;
    if( ! pT->getID() )
    {
        pT->setID( getNewID() );
    }

    if( ( parentPosition == -1 ) || ( childPosition >= static_cast(mKeyRootNodeList.size()) ) )
    {
        mKeyRootNodeList.push_back( pT );
    }
    else
    {
        // insert item at proper position
        int cnt = 0;
        typedef std::list::iterator IT;
        for( IT it = mKeyRootNodeList.begin(); it != mKeyRootNodeList.end(); it ++ )
        {
            if( cnt >= childPosition )
            {
                mKeyRootNodeList.insert( it, pT );
                break;
            }
            cnt++;
        }
    }

    if( mKeyMap.find( pT->getID() ) == mKeyMap.end() )
    {
        mKeyMap.insert( pT->getID(), pT );
    }
}

void KeyUnit::reParentKey( int childID, int oldParentID, int newParentID, int parentPosition, int childPosition )
{
    QMutexLocker locker(& mKeyUnitLock);

    TKey * pOldParent = getKeyPrivate( oldParentID );
    TKey * pNewParent = getKeyPrivate( newParentID );
    TKey * pChild = getKeyPrivate( childID );
    if( ! pChild )
    {
        return;
    }
    if( pOldParent )
    {
        pOldParent->popChild( pChild );
    }
    if( ! pOldParent )
    {
        removeKeyRootNode( pChild );
    }
    if( pNewParent )
    {
        pNewParent->addChild( pChild, parentPosition, childPosition );
        if( pChild )
        {
            pChild->setParent( pNewParent );
        }
        //cout << "dumping family of newParent:"<Dump();
    }
    else
    {
        pChild->Tree::setParent( 0 );
        addKeyRootNode( pChild, parentPosition, childPosition );
    }
}

void KeyUnit::removeKeyRootNode( TKey * pT )
{
    if( ! pT ) return;
    mKeyRootNodeList.remove( pT );
}

TKey * KeyUnit::getKey( int id )
{
    QMutexLocker locker(& mKeyUnitLock);
    if( mKeyMap.find( id ) != mKeyMap.end() )
    {
        return mKeyMap.value( id );
    }
    else
    {
        return 0;
    }
}



TKey * KeyUnit::getKeyPrivate( int id )
{
    if( mKeyMap.find( id ) != mKeyMap.end() )
    {
        return mKeyMap.value( id );
    }
    else
    {
        return 0;
    }
}

bool KeyUnit::registerKey( TKey * pT )
{
    if( ! pT ) return false;

    if( pT->getParent() )
    {
        addKey( pT );
        return true;
    }
    else
    {
        addKeyRootNode( pT );
        return true;
    }
}

void KeyUnit::unregisterKey( TKey * pT )
{
    if( ! pT ) return;
    if( pT->getParent() )
    {
        removeKey( pT );
        return;
    }
    else
    {
        removeKeyRootNode( pT );
        return;
    }
}


void KeyUnit::addKey( TKey * pT )
{
    if( ! pT ) return;

    pT->setID( getNewID() );

    mKeyMap.insert( pT->getID(), pT );
}

void KeyUnit::removeKey( TKey * pT )
{
    if( ! pT ) return;
    mKeyMap.remove( pT->getID() );
}


qint64 KeyUnit::getNewID()
{
    return ++mMaxID;
}

QString KeyUnit::getKeyName( int keyCode, int modifierCode )
{
    QString name;
    /*
     Qt::NoModifier      0x00000000 No modifier key is pressed.
     Qt::ShiftModifier   0x02000000 A Shift key on the keyboard is pressed.
     Qt::ControlModifier 0x04000000 A Ctrl key on the keyboard is pressed.
     Qt::AltModifier     0x08000000 An Alt key on the keyboard is pressed.
     Qt::MetaModifier    0x10000000 A Meta key on the keyboard is pressed.
     Qt::KeypadModifier  0x20000000 A keypad button is pressed.
     Qt::GroupSwitchModifier 0x40000000 X11 only. A Mode_switch key on the keyboard is pressed.
    */
    if( modifierCode == 0x00000000 ) name += "no modifiers + ";
    if( modifierCode & 0x02000000 ) name += "shift + ";
    if( modifierCode & 0x04000000 ) name += "control + ";
    if( modifierCode & 0x08000000 ) name += "alt + ";
    if( modifierCode & 0x10000000 ) name += "meta + ";
    if( modifierCode & 0x20000000 ) name += "keypad + ";
    if( modifierCode & 0x40000000 ) name += "groupswitch + ";
    if( mKeys.contains( keyCode ) )
    {
        name += mKeys[keyCode];
        return name;
    }
    else return QString("undefined key");
}



void KeyUnit::setupKeyNames()
{
    mKeys[0x01000000]=QString("Escape");
    mKeys[0x01000001]=QString("Tab");
    mKeys[0x01000002]=QString("Backtab");
    mKeys[0x01000003]=QString("Backspace");
    mKeys[0x01000004]=QString("Return");
    mKeys[0x01000005]=QString("Enter");
    mKeys[0x01000006]=QString("Insert");
    mKeys[0x01000007]=QString("Delete");
    mKeys[0x01000008]=QString("Pause");
    mKeys[0x01000009]=QString("Print");
    mKeys[0x0100000a]=QString("SysReq");
    mKeys[0x0100000b]=QString("Clear");
    mKeys[0x01000010]=QString("Home");
    mKeys[0x01000011]=QString("End");
    mKeys[0x01000012]=QString("Left");
    mKeys[0x01000013]=QString("Up");
    mKeys[0x01000014]=QString("Right");
    mKeys[0x01000015]=QString("Down");
    mKeys[0x01000016]=QString("PageUp");
    mKeys[0x01000017]=QString("PageDown");
    mKeys[0x01000020]=QString("Shift");
    mKeys[0x01000021]=QString("Control");
    mKeys[0x01000022]=QString("Meta");
    mKeys[0x01000023]=QString("Alt");
    mKeys[0x01001103]=QString("AltGr");
    mKeys[0x01000024]=QString("CapsLock");
    mKeys[0x01000025]=QString("NumLock");
    mKeys[0x01000026]=QString("ScrollLock");
    mKeys[0x01000030]=QString("F1");
    mKeys[0x01000031]=QString("F2");
    mKeys[0x01000032]=QString("F3");
    mKeys[0x01000033]=QString("F4");
    mKeys[0x01000034]=QString("F5");
    mKeys[0x01000035]=QString("F6");
    mKeys[0x01000036]=QString("F7");
    mKeys[0x01000037]=QString("F8");
    mKeys[0x01000038]=QString("F9");
    mKeys[0x01000039]=QString("F10");
    mKeys[0x0100003a]=QString("F11");
    mKeys[0x0100003b]=QString("F12");
    mKeys[0x0100003c]=QString("F13");
    mKeys[0x0100003d]=QString("F14");
    mKeys[0x0100003e]=QString("F15");
    mKeys[0x0100003f]=QString("F16");
    mKeys[0x01000040]=QString("F17");
    mKeys[0x01000041]=QString("F18");
    mKeys[0x01000042]=QString("F19");
    mKeys[0x01000043]=QString("F20");
    mKeys[0x01000044]=QString("F21");
    mKeys[0x01000045]=QString("F22");
    mKeys[0x01000046]=QString("F23");
    mKeys[0x01000047]=QString("F24");
    mKeys[0x01000048]=QString("F25");
    mKeys[0x01000049]=QString("F26");
    mKeys[0x0100004a]=QString("F27");
    mKeys[0x0100004b]=QString("F28");
    mKeys[0x0100004c]=QString("F29");
    mKeys[0x0100004d]=QString("F30");
    mKeys[0x0100004e]=QString("F31");
    mKeys[0x0100004f]=QString("F32");
    mKeys[0x01000050]=QString("F33");
    mKeys[0x01000051]=QString("F34");
    mKeys[0x01000052]=QString("F35");
    mKeys[0x01000053]=QString("Super_L");
    mKeys[0x01000054]=QString("Super_R");
    mKeys[0x01000055]=QString("Menu");
    mKeys[0x01000056]=QString("Hyper_L");
    mKeys[0x01000057]=QString("Hyper_R");
    mKeys[0x01000058]=QString("Help");
    mKeys[0x01000059]=QString("Direction_L");
    mKeys[0x01000060]=QString("Direction_R");
    mKeys[0x20]=QString("Space");
    mKeys[0x21]=QString("Exclam");
    mKeys[0x22]=QString("QuoteDbl");
    mKeys[0x23]=QString("NumberSign");
    mKeys[0x24]=QString("Dollar");
    mKeys[0x25]=QString("Percent");
    mKeys[0x26]=QString("Ampersand");
    mKeys[0x27]=QString("Apostrophe");
    mKeys[0x28]=QString("ParenLeft");
    mKeys[0x29]=QString("ParenRight");
    mKeys[0x2a]=QString("Asterisk");
    mKeys[0x2b]=QString("Plus");
    mKeys[0x2c]=QString("Comma");
    mKeys[0x2d]=QString("Minus");
    mKeys[0x2e]=QString("Period");
    mKeys[0x2f]=QString("Slash");
    mKeys[0x30]=QString("0");
    mKeys[0x31]=QString("1");
    mKeys[0x32]=QString("2");
    mKeys[0x33]=QString("3");
    mKeys[0x34]=QString("4");
    mKeys[0x35]=QString("5");
    mKeys[0x36]=QString("6");
    mKeys[0x37]=QString("7");
    mKeys[0x38]=QString("8");
    mKeys[0x39]=QString("9");
    mKeys[0x3a]=QString("Colon");
    mKeys[0x3b]=QString("Semicolon");
    mKeys[0x3c]=QString("Less");
    mKeys[0x3d]=QString("Equal");
    mKeys[0x3e]=QString("Greater");
    mKeys[0x3f]=QString("Question");
    mKeys[0x40]=QString("At");
    mKeys[0x41]=QString("A");
    mKeys[0x42]=QString("B");
    mKeys[0x43]=QString("C");
    mKeys[0x44]=QString("D");
    mKeys[0x45]=QString("E");
    mKeys[0x46]=QString("F");
    mKeys[0x47]=QString("G");
    mKeys[0x48]=QString("H");
    mKeys[0x49]=QString("I");
    mKeys[0x4a]=QString("J");
    mKeys[0x4b]=QString("K");
    mKeys[0x4c]=QString("L");
    mKeys[0x4d]=QString("M");
    mKeys[0x4e]=QString("N");
    mKeys[0x4f]=QString("O");
    mKeys[0x50]=QString("P");
    mKeys[0x51]=QString("Q");
    mKeys[0x52]=QString("R");
    mKeys[0x53]=QString("S");
    mKeys[0x54]=QString("T");
    mKeys[0x55]=QString("U");
    mKeys[0x56]=QString("V");
    mKeys[0x57]=QString("W");
    mKeys[0x58]=QString("X");
    mKeys[0x59]=QString("Y");
    mKeys[0x5a]=QString("Z");
    mKeys[0x5b]=QString("BracketLeft");
    mKeys[0x5c]=QString("Backslash");
    mKeys[0x5d]=QString("BracketRight");
    mKeys[0x5e]=QString("AsciiCircum");
    mKeys[0x5f]=QString("Underscore");
    mKeys[0x60]=QString("QuoteLeft");
    mKeys[0x7b]=QString("BraceLeft");
    mKeys[0x7c]=QString("Bar");
    mKeys[0x7d]=QString("BraceRight");
    mKeys[0x7e]=QString("AsciiTilde");
    mKeys[0x0a0]=QString("nobreakspace");
    mKeys[0x0a1]=QString("exclamdown");
    mKeys[0x0a2]=QString("cent");
    mKeys[0x0a3]=QString("sterling");
    mKeys[0x0a4]=QString("currency");
    mKeys[0x0a5]=QString("yen");
    mKeys[0x0a6]=QString("brokenbar");
    mKeys[0x0a7]=QString("section");
    mKeys[0x0a8]=QString("diaeresis");
    mKeys[0x0a9]=QString("copyright");
    mKeys[0x0aa]=QString("ordfeminine");
    mKeys[0x0ab]=QString("guillemotleft");
    mKeys[0x0ac]=QString("notsign");
    mKeys[0x0ad]=QString("hyphen");
    mKeys[0x0ae]=QString("registered");
    mKeys[0x0af]=QString("macron");
    mKeys[0x0b0]=QString("degree");
    mKeys[0x0b1]=QString("plusminus");
    mKeys[0x0b2]=QString("twosuperior");
    mKeys[0x0b3]=QString("threesuperior");
    mKeys[0x0b4]=QString("acute");
    mKeys[0x0b5]=QString("mu");
    mKeys[0x0b6]=QString("paragraph");
    mKeys[0x0b7]=QString("periodcentered");
    mKeys[0x0b8]=QString("cedilla");
    mKeys[0x0b9]=QString("onesuperior");
    mKeys[0x0ba]=QString("masculine");
    mKeys[0x0bb]=QString("guillemotright");
    mKeys[0x0bc]=QString("onequarter");
    mKeys[0x0bd]=QString("onehalf");
    mKeys[0x0be]=QString("threequarters");
    mKeys[0x0bf]=QString("questiondown");
    mKeys[0x0c0]=QString("Agrave");
    mKeys[0x0c1]=QString("Aacute");
    mKeys[0x0c2]=QString("Acircumflex");
    mKeys[0x0c3]=QString("Atilde");
    mKeys[0x0c4]=QString("Adiaeresis");
    mKeys[0x0c5]=QString("Aring");
    mKeys[0x0c6]=QString("AE");
    mKeys[0x0c7]=QString("Ccedilla");
    mKeys[0x0c8]=QString("Egrave");
    mKeys[0x0c9]=QString("Eacute");
    mKeys[0x0ca]=QString("Ecircumflex");
    mKeys[0x0cb]=QString("Ediaeresis");
    mKeys[0x0cc]=QString("Igrave");
    mKeys[0x0cd]=QString("Iacute");
    mKeys[0x0ce]=QString("Icircumflex");
    mKeys[0x0cf]=QString("Idiaeresis");
    mKeys[0x0d0]=QString("ETH");
    mKeys[0x0d1]=QString("Ntilde");
    mKeys[0x0d2]=QString("Ograve");
    mKeys[0x0d3]=QString("Oacute");
    mKeys[0x0d4]=QString("Ocircumflex");
    mKeys[0x0d5]=QString("Otilde");
    mKeys[0x0d6]=QString("Odiaeresis");
    mKeys[0x0d7]=QString("multiply");
    mKeys[0x0d8]=QString("Ooblique");
    mKeys[0x0d9]=QString("Ugrave");
    mKeys[0x0da]=QString("Uacute");
    mKeys[0x0db]=QString("Ucircumflex");
    mKeys[0x0dc]=QString("Udiaeresis");
    mKeys[0x0dd]=QString("Yacute");
    mKeys[0x0de]=QString("THORN");
    mKeys[0x0df]=QString("ssharp");
    mKeys[0x0f7]=QString("division");
    mKeys[0x0ff]=QString("ydiaeresis");
    mKeys[0x01001120]=QString("Multi_key");
    mKeys[0x01001137]=QString("Codeinput");
    mKeys[0x0100113c]=QString("SingleCandidate");
    mKeys[0x0100113d]=QString("MultipleCandidate");
    mKeys[0x0100113e]=QString("PreviousCandidate");
    mKeys[0x0100117e]=QString("Mode_switch");
    mKeys[0x01001121]=QString("Kanji");
    mKeys[0x01001122]=QString("Muhenkan");
    mKeys[0x01001123]=QString("Henkan");
    mKeys[0x01001124]=QString("Romaji");
    mKeys[0x01001125]=QString("Hiragana");
    mKeys[0x01001126]=QString("Katakana");
    mKeys[0x01001127]=QString("Hiragana_Katakana");
    mKeys[0x01001128]=QString("Zenkaku");
    mKeys[0x01001129]=QString("Hankaku");
    mKeys[0x0100112a]=QString("Zenkaku_Hankaku");
    mKeys[0x0100112b]=QString("Touroku");
    mKeys[0x0100112c]=QString("Massyo");
    mKeys[0x0100112d]=QString("Kana_Lock");
    mKeys[0x0100112e]=QString("Kana_Shift");
    mKeys[0x0100112f]=QString("Eisu_Shift");
    mKeys[0x01001130]=QString("Eisu_toggle");
    mKeys[0x01001131]=QString("Hangul");
    mKeys[0x01001132]=QString("Hangul_Start");
    mKeys[0x01001133]=QString("Hangul_End");
    mKeys[0x01001134]=QString("Hangul_Hanja");
    mKeys[0x01001135]=QString("Hangul_Jamo");
    mKeys[0x01001136]=QString("Hangul_Romaja");
    mKeys[0x01001138]=QString("Hangul_Jeonja");
    mKeys[0x01001139]=QString("Hangul_Banja");
    mKeys[0x0100113a]=QString("Hangul_PreHanja");
    mKeys[0x0100113b]=QString("Hangul_PostHanja");
    mKeys[0x0100113f]=QString("Hangul_Special");
    mKeys[0x01001250]=QString("Dead_Grave");
    mKeys[0x01001251]=QString("Dead_Acute");
    mKeys[0x01001252]=QString("Dead_Circumflex");
    mKeys[0x01001253]=QString("Dead_Tilde");
    mKeys[0x01001254]=QString("Dead_Macron");
    mKeys[0x01001255]=QString("Dead_Breve");
    mKeys[0x01001256]=QString("Dead_Abovedot");
    mKeys[0x01001257]=QString("Dead_Diaeresis");
    mKeys[0x01001258]=QString("Dead_Abovering");
    mKeys[0x01001259]=QString("Dead_Doubleacute");
    mKeys[0x0100125a]=QString("Dead_Caron");
    mKeys[0x0100125b]=QString("Dead_Cedilla");
    mKeys[0x0100125c]=QString("Dead_Ogonek");
    mKeys[0x0100125d]=QString("Dead_Iota");
    mKeys[0x0100125e]=QString("Dead_Voiced_Sound");
    mKeys[0x0100125f]=QString("Dead_Semivoiced_Sound");
    mKeys[0x01001260]=QString("Dead_Belowdot");
    mKeys[0x01001261]=QString("Dead_Hook");
    mKeys[0x01001262]=QString("Dead_Horn");
    mKeys[0x01000061]=QString("Back");
    mKeys[0x01000062]=QString("Forward");
    mKeys[0x01000063]=QString("Stop");
    mKeys[0x01000064]=QString("Refresh");
    mKeys[0x01000070]=QString("VolumeDown");
    mKeys[0x01000071]=QString("VolumeMute");
    mKeys[0x01000072]=QString("VolumeUp");
    mKeys[0x01000073]=QString("BassBoost");
    mKeys[0x01000074]=QString("BassUp");
    mKeys[0x01000075]=QString("BassDown");
    mKeys[0x01000076]=QString("TrebleUp");
    mKeys[0x01000077]=QString("TrebleDown");
    mKeys[0x01000080]=QString("MediaPlay");
    mKeys[0x01000081]=QString("MediaStop");
    mKeys[0x01000082]=QString("MediaPrevious");
    mKeys[0x01000083]=QString("MediaNext");
    mKeys[0x01000084]=QString("MediaRecord");
    mKeys[0x01000090]=QString("HomePage");
    mKeys[0x01000091]=QString("Favorites");
    mKeys[0x01000092]=QString("Search");
    mKeys[0x01000093]=QString("Standby");
    mKeys[0x01000094]=QString("OpenUrl");
    mKeys[0x010000a0]=QString("LaunchMail");
    mKeys[0x010000a1]=QString("LaunchMedia");
    mKeys[0x010000a2]=QString("Launch0");
    mKeys[0x010000a3]=QString("Launch1");
    mKeys[0x010000a4]=QString("Launch2");
    mKeys[0x010000a5]=QString("Launch3");
    mKeys[0x010000a6]=QString("Launch4");
    mKeys[0x010000a7]=QString("Launch5");
    mKeys[0x010000a8]=QString("Launch6");
    mKeys[0x010000a9]=QString("Launch7");
    mKeys[0x010000aa]=QString("Launch8");
    mKeys[0x010000ab]=QString("Launch9");
    mKeys[0x010000ac]=QString("LaunchA");
    mKeys[0x010000ad]=QString("LaunchB");
    mKeys[0x010000ae]=QString("LaunchC");
    mKeys[0x010000af]=QString("LaunchD");
    mKeys[0x010000b0]=QString("LaunchE");
    mKeys[0x010000b1]=QString("LaunchF");
    mKeys[0x0100ffff]=QString("MediaLast");
    mKeys[0x01ffffff]=QString("unknown");
    mKeys[0x01100004]=QString("Call");
    mKeys[0x01100000]=QString("Context1");
    mKeys[0x01100001]=QString("Context2");
    mKeys[0x01100002]=QString("Context3");
    mKeys[0x01100003]=QString("Context4");
    mKeys[0x01100006]=QString("Flip");
    mKeys[0x01100005]=QString("Hangup");
    mKeys[0x01010002]=QString("No");
    mKeys[0x01010000]=QString("Select");
    mKeys[0x01010001]=QString("Yes");
    mKeys[0x01020003]=QString("Execute");
    mKeys[0x01020002]=QString("Printer");
    mKeys[0x01020005]=QString("Play");
    mKeys[0x01020004]=QString("Sleep");
    mKeys[0x01020006]=QString("Zoom");
    mKeys[0x01020001]=QString("Cancel");
}


mudlet-2.1/src/dlgRoomExits.h0000644000175000017500000000363411624306130015540 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008-2009 by Heiko Koehn - KoehnHeiko@googlemail.com    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#ifndef DLGROOMEXITS_H
#define DLGROOMEXITS_H

#include 
#include "ui_room_exits.h"
#include "Host.h"

class Host;

class dlgRoomExits : public QDialog, public Ui::roomExits
{
    Q_OBJECT
public:
    explicit dlgRoomExits(Host *, QWidget *parent = 0);
    void init( int );
    Host * mpHost;
    int mRoomID;
    int mEditColumn;
    QTreeWidgetItem * mpEditItem;

signals:

public slots:
    void slot_editItem(QTreeWidgetItem * pI, int column );
    void save();
    void slot_addSpecialExit();
    //void cancel();

};

#endif // DLGROOMEXITS_H
mudlet-2.1/src/HostPool.h0000644000175000017500000000466111624306130014670 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn                                     *
 *   KoehnHeiko@googlemail.com                                             *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef _HOST_POOL_H_
#define _HOST_POOL_H_

#include 
#include 
#include 
#include 
#include "Host.h"

class mudlet;


class HostPool
{
    QMutex                mPoolLock;
    QMap mHostPool;

 public:

    Host *                getHost( QString hostname );
    Host *                getFirstHost();
    Host *                getNextHost( QString LastHost ); //get next host key by providing a LastHost
    QList        getHostNameList();
    QStringList           getHostList();
    bool                  addNewHost( QString hostname, QString port, QString login, QString pass );
    bool                  deleteHost( QString url );
    bool                  renameHost( QString url );
    bool                  serialize( QString path );
    void                  orderShutDown();
    Host *                getHostFromHostID( int id );
    void                  postIrcMessage( QString, QString, QString );

private:

    int createNewHostID();
};
#endif

mudlet-2.1/src/TSplitter.h0000644000175000017500000000055011513237311015045 0ustar  csmallcsmall#ifndef TSPLITTER_H
#define TSPLITTER_H

#include 
#include "TSplitterHandle.h"

class TSplitterHandle;

class TSplitter : public QSplitter
{
Q_OBJECT
 public:
     TSplitter( Qt::Orientation orientation, QWidget *parent = 0 );

 protected:
     QSplitterHandle * createHandle();

     TSplitterHandle * mpSplitterHandle;
};


#endif // TSPLITTER_H
mudlet-2.1/src/dlgProfilePreferences.h0000644000175000017500000000623612070466512017401 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008-2009 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef dlg_profile_preferences_area_h
#define dlg_profile_preferences_area_h

#include "ui_profile_preferences.h"
#include 
#include 
#include 

class Host;

class dlgProfilePreferences : public QDialog , public Ui::profile_preferences
{
    Q_OBJECT

public:

    dlgProfilePreferences( QWidget *, Host * );

    int mFontSize;

signals:


public slots:
    void setFontSize();
    void setColorBlack();
    void setColorLightBlack();
    void setColorRed();
    void setColorLightRed();
    void setColorBlue();
    void setColorLightBlue();
    void setColorGreen();
    void setColorLightGreen();
    void setColorYellow();
    void setColorLightYellow();
    void setColorCyan();
    void setColorLightCyan();
    void setColorMagenta();
    void setColorLightMagenta();
    void setColorWhite();
    void setColorLightWhite();
    void setDisplayFont();
    void setCommandLineFont();
    void setFgColor();
    void setBgColor();
    void setCommandLineBgColor();
    void setCommandLineFgColor();

    void setCommandFgColor();
    void setCommandBgColor();
    void setColorBlack2();
    void setColorLightBlack2();
    void setColorRed2();
    void setColorLightRed2();
    void setColorBlue2();
    void setColorLightBlue2();
    void setColorGreen2();
    void setColorLightGreen2();
    void setColorYellow2();
    void setColorLightYellow2();
    void setColorCyan2();
    void setColorLightCyan2();
    void setColorMagenta2();
    void setColorLightMagenta2();
    void setColorWhite2();
    void setColorLightWhite2();
    void setFgColor2();
    void setBgColor2();
    void resetColors();
    void downloadMap();
    void loadMap();
    void saveMap();
    void copyMap();
    void hideActionLabel();
    void slot_save_and_exit();

private:
    void setColors();
    Host * mpHost;
};
#endif
mudlet-2.1/src/dlgOptionsAreaScripts.cpp0000644000175000017500000000313011513237311017726 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "TScript.h"
#include 

#include 

#include "dlgOptionsAreaScripts.h"

dlgOptionsAreaScripts::dlgOptionsAreaScripts(QWidget * pF):QWidget(pF)
{
    // init generated dialog
    setupUi(this);
    
}


mudlet-2.1/src/Mudlet_splashscreen_main.png0000644000175000017500000023052412076170616020477 0ustar  csmallcsmallPNG


IHDRBi!i
/iCCPICC profileHǝwTTϽwz0z.0. QfMl@DEHb!(`HPb0dFJ|yyǽgs{.$O./ 'z8WGбx0Y驾A@$/7z	HeOOҬT_lN:K"N3"$F/JPrb[䥟}Qd[Sl1x{#bG\NoX3I[ql2$8xtrp/8pCfq.Knjm͠{r28?.)ɩL^6g,qm"[Z[Z~Q7%"
3R`̊j[~: w!$E}kyhyRm333:
}=#vʉe
tqX)I)B>==
<8Xȉ9yP:8p΍Lg	kk	Ѐ$t!0V87`ɀ2A.
@JPA#h'@8
.:	``a!2D!UH2 dA>P ECqB**Z:]B=h~L2
	5pN:|ó@
QC!H,G6 H9R ]H/rAw(Q(OTJCm@*QGQ-(j	MF+
6h/*t:].G7Зw7Xa<1:L1s3bXyeb~19 vGĩp+5qy^oó|=?'Htv`Ba3BDxHxE$Չ"XAP44077&9$An0;T2421t.54ld+s;#
V]=iY9FgM֚k&=%Ō:nc1gcbcfX.}lGv{c)LŖN퉛w/p+/<j$.$%&㒣OdxTԂԑ4i3|o~C:&S@L	u[Uo3C3OfIgwdO|;W-wsz
17jl8c͉̈́3+{%lKWr[$
llGmnacOkE&EEY׾2⫅;K,KhtiN=e²{^-_V^Oo§s]?TWީrjVQ=w}`嚢zԶiו8>k׍

E

[ly邟~_Y53rW򯎼^{7so}x>|쇊z>yz;lbKGD	pHYs

B(xtIME
8_ IDATxidu%vbɥ2kzA7@440I
I4CD)͌d2}>?H?AȌ66gd&hD赪*r~>EFҵEfݕk[˹_x}__ץo|qx=
P1~̔OO})"P_JPU#@%0U몊Ng	S;dT" fr @JP5	;CHv1#P@( @@|2<z?i(
FS]R 0/@|uĎK_CGM@
ߏi|ͥqY+dX;U=!\3߳!(QYt=+xXև?T?3vȗJS#F%pLzEq}a$y"1ARGgӟr^u1"4c3UM"Kd?gh)T=Bd뀙o:=!BKC	T Tm3>r<ꥵ2_yBu~/(SuyJ(h
ÚC~2ȑ|Ϲ:rlSF(~~ILɋ!pol-m;9@P8R`߼){Q

C5**+rJA7u)kS&˭b`
$m+mU81}6kǩHeMinۭo
Ephsj]Q&^/X "`6RY:0AS\m%
suf}`M<@ZKlL/?Z4'qB$A4"gAC&6#4tm#"Zblm7x{D3*ySHMPU8CTBC-h)@${	}6ٖh()&u?|Q@$A5?o			;	0BG>s5@]ۭ镵y^FH%D;tq#p@mA8lu)Bq&X	Pn~t]̡DO5bF
tǘvFhP
Jl%ZZEg%#{*6OvA1ƶ#:8\1s%C5U*1H
n!uzPE4A`-ud
7F#~͞1>Z@°x+
ֿݦ}dFߕNp_L
DS^&m/\kf]K?K$uO[Tͺ'9]'?C
њ=+W7G.j
?GC9T?4牭Sj\ѫTem8D\dedhj
Rj0kk&\5?ZJF-[RrΜ5i?[(M5|\j\g}ꥅ|Dz=ͳcV]K:@?=BKYLx
@C^ERC58C쏪^K1@uWX
?!*.V"KCKQj= )@ӕ@QQa9LIW>v3Zk3(<\Īеeb*CLJ>Oa@&oG>~`kDHd9B}RWD=h)&׳jdi5S]ǁC^Ab9M	t!?YU{[bb2z6;OuuHyM).Ơi᳙m[^oaE!Ȫku=M$ 	iUħxoH)>WWրKU7{;9ѽId:u_ɒ>,^,cܫ;DˑjB8ht%
5W7%!geH5AT&
/(aC).i_"ɴT#ukhͭO]ǽnϧI R܇ZcVEz6HF)W=>/xR&Ui(>@tKCcgmcJM Rz.Դ4mk0<8?){WO֦d~"8-V^_>
8chETp4RS_Բ790J@Q4:}Hy/pB[fC=,oŴSl$gms
j+qsR]RΰYR6'}\8lRwqqAJ@eN܄]uz}!|Z{ Z*żRHLDqqFScQ.}gk~yyT k@T]Z
@ɍ}c7I\SKKa
at8mf&SxH׳[)ӼQ8!jZ9NK_'1lNqdyM6=_OJX`1/f5_b#6xEYJ%⬢Q
U$ڽ3
ԧ@*[;<"AD9w۶&}Wt1x)j2OCSã`%ЀAd6K'[K*fLZjf;?ΐ O{.[l}21-IN~
M)$uvygQ$A5&8ond"sܶ[%gVĶ0M̞y׼c(+Аm@"p"E<]ٚ0zzM	#X%T)-K)HM(qUL^\hĭ(,BrU90Rχg1`֕V4DXM͟+)w?E2ZpP#4 (Z
;*6$≥_GUk ikpYHeIRpޫ"dCՀ5bAh¦Q QRf3	l-߈xے	R2MsrxL
:9AO+wIYGt<@8\`nl2gWy #ZKYΜCB{k~dӴo;@[AH b7K	CnHԠ
. "H2JAc{}AaMAg޽TiWzEM]Ƨu4E=3b,Zn,
`fTP,,jblLLz)'wͱuEqݿf^?l}:x֟]_)J*DmUFp(JՁHM{xdZ0lT_=	S  oDB:`^e	lD2yAF$󱎱}f[񸎮,w$I⛡Xyer]H\RRH=xQz9hl20[T\Pд泻a\zN@f^=D${Z	?X@(q
樈Ҙ>ؑagِWlJJS¢YR-b
4W.6SǛE90OT]3!"*o(RJp6Mh6n	l9T>cx419zw7%˟͏:wu2E
B/Շz>y),
$K~#<@RQ)ƀZQc7Rr }ʯ9r+R#0AV1!q nKťfr,-5X{򻔲Ki]RrY@4aKRv+`#gNV|w0j7жOB1D{U(V%“R[u
E\_0Q$Vg'QYlE *uкiMU%ڊ&_lZ%ZjA:th	m8x?Fۈ1ݑo,	հva6u2`׵ķ	%ET3pē=t'7!A*	xM00=PxW2	<*i<VIc?&ۈ$,;@h'
v9#{Xs8Kwy`T-8Bt$30UcUfP*T.L{I8Bm;Fck@tIp9vfj$+DBcI=q`8"Z$M>'t귰x55`|?Sg]*
>&oM\x7{װbÿ70|`$AI]Z@!IBqW*O6C!7+UZI!aE|LGr[}a
#ϗ\U
B5- <.x/-@)I&cs>BU`O! 
% Z@ՈL!Nn~M3ocl]|k!sz_eSiAB^H1zVdgvFy~|>+,G{`0phAԠVwDeȄ#Dc< 5,<*nRV1j=eDPZ1Q5k5L!@᱀cppY~2ϓZ39è}]nwX@
>TtcvGo,u.Y׼[ j;< BKЄN!|$`[^x
|0}5.vڒQRT)>'&%k@iʽq("T^r	yC^ևisu.-SFH+EKۤBrȫc0GIY٥@-c'.ūbk$ror`xr'U˗y"v/.(KV1:w
7o];`CLos*$@SgoZGw#)g9(SP-4u)bo{OGJ^7wv))'YB2DE[V?V'{t[Ӭ;AJY zj	Pg)D^kz[h{U<pگOxn&.2覞s4͡em
_)I!#m;?_e4/lL
ZE]h D#s:aSr3uD*Z}_ϒ|\8nEs~>G\7<!>FX~NW(*}XC:)u`"^Ҫ/nKRc0<Nш	}_bq"=x<3G?
E#;ױwgu~ ޾IørU IhǻH=$4FA):&^xůXw	XBJ
͊+r=[DĜ.Dh&f@I#Cr4$hPxU"VӤ6Yri|]gC^=N<&LcK`f4_x:nګװ˥|
ۻBSK&)2!4@
U\zC8hI
Q8D%O,MѺ*jt;VMfq99z`P
R	hsϼPkNG?Rf(Ie@(OFlb
] 9͐}Lii-,%"n0Y	QOŨ>	g3λhK_^C}ى9:4&&P;y?KW_D;j[3pnk۷n╫4[Z1(܎p˿?cL%l4VYH-84Ț;A-pcT#m9L	J?NG.RQQto5~DLjʆzϨVrB[DfLJ=k+!!%UEU?*Tz8:MWT9u2\+((elU߳k: ulomyRד;[O\Z6D 1hBn	&yw[z
J6Zg' IDATU&.$Ƣc geE"+##=mފՋ4EC"v3OU4.`&Q+xue~CS*>1QR2]"r8!h$t%i/
$U7Н@:fs0xw?.^U wɝKdrFUn+&W))Pq̚#ՎǧS4MU^ C"`EPB*[\|Ņ]t'ػ7%d%gM#Q)5PՔ`o
sXJb Wa2d9ݿIʽ@	*9xꘛo*TͿ`9&rC	IIs!4 n56n
rn8
WS@O,Uc/ |<
~1+
ƺꂋ1E
#1\P\v:\:=!|,jZRjYt|yi,>|w/xkxx/*ؾn;cx\T@ Ff?[ʣJWrg7.)wSxDϊkB—~*϶m\M\M!n}/x6Z'$OCBC&(1HrAR&)[_(gQ"PSnr6`<'S*"rǓ{>iI!D!e r VkQ9Q+Sj&NƟ,G?ef77abZ5;qAt\LwQM32gy%fAsQYJ2 W,R™6i{AR8Qk/ځT+GYN`OTD+9̬+6:kG}E3K$/)Ȅmg`ܸ(WsNk!k/_?E<M}ۗ8Vg*6[9&ͭF#k\+oCZ%Bm)S?(0>NfU|͊o
tf+Gگpg;f%^54qS7_Zqbp09!;X
qQ2U6:;og+bG[jBZ}QZ	k^>>twԢk'\5vywΜ8 PFnN(Eu'48_i-Y]eUY0jb+Rh!hJedufY&!O9)eG	6/}LTzXr՟Csm563Uρf˚Äm"*I
 VOX@wenIDMâÀ
q韢~
Wm;e@OzLfn<,eTe/r_*	x1ȖahڝR
ʔ+3KO-
2דɥ}N':vVvi=XIJ)uϥ>%]ɾMg' z
IF!3,Hk8Bl=2ZTpu@%F/כy:nTWd#9WDO-"4PB
,>FcL6wp?xR_=Z8ma~CC3,1RݩHM%3'%	6z&zc,ֵ><٪Rb7˪2*q^0I1پo??8E{
^tv@sN"1Bkb;jRSKP5N\4N%4jgNNnu9a9M\TFNeg%f"A$}$fn+`jHRcjgDxJfW
AdS^r(30ugGd4:)E~Q9".|,n.j)yWknOW&9!&@ c:xvm%2YCIrNտ*D<DV`F#PhW)6vܻ<çHMWD[Wpr	*OhCZ	G9%5a𵂂4leC6\Oօ`jfDeXpR}x"^yq!;89[h&3 %9z
`Ӡ
sALӺI%{& &U@sDRbTvǛRݫR-Bqk7 [0Є4ڰ2)_QAjts$RuMmƀ{d_ۼ~BW50,Xj?BdqӟF.[ȶ-w,"4Gw
fov_@6Z:oq?3*s0ܷ}]\`<jl$T1nlgH-@<9V׆_ʱxؿcɟ0:3c+Kj~YHݺES28(Y=ĢCA6z",
kk*|*̌ysNz0gG9Xu9bh1F01tku{BTP?K[}L@WiI 9HL]hݝC7qoc祯ItTqwFB{KФXau)6`$Aa|taq%'CW	YK@Xߣ災'H$l\Vծ..e%zkh4&6/{~<=T'b{l4v/4HU7~`d=siF~xvMW((\EA<D\FSrSv}箾n|ΛMA[%I,Ą(uzqsфq%!pOZ	%Y	|-LK_UaC	M5Z_If.RHLJ<)KqpPĘu; %%HLΟƣKdͱ!4p[/T6`GJ^1oќ-< (
揼FL`\VtǛ@(at-,Ax~{Rx]Ys8(>.L^}MzہҠ .![дoa~n0h6ul]w6JFOE=~f_bY`rÓ|"1}!lS D`ki{.
v7Lw,a@bVn ;&1 :sSj
04Xa5~O	
ųS$28-Ky6c{@/>) \n	#^Il X+H%|oؕErJ炝#6b⫸t3f{tRoV̚)N헠&kۑp8:3پۚ!olF#,p{/a`ngو'Txl~1h+Bѥyऋ,>/*@vRcuWٟcv/쾅f|lV4!j6@*6zɢNhLu̽VѠQRa0שfHEv1$[œA< fB?ϖ,7PҢvErSfhjCp%?_L.f1-Q}h>@"H]BD2JT~`("hPj9H"X !eI4F ]joA0IZyV#%Ew)ʗ[^yRR=pXwnU]Lmߠ1j7]M޺p$u~:F]IkXs-Gv!A) p us -0>mhx|V鉊UTvtc@H
$܎o`tC|h@{roxL@EUfu+Qg`8}$U50UE)$b
*3b+~, X{gT%ƘJ|Sƙ!%+UA)o8pOopO7}:RmnoF1PD~
LP\yAJ_EwOch
CSM['4`D&la箙o3Au.kVU}KY&)0vMlc`a,<Z&D{%IXwxb%js85Kf2DoZW#*soȱ5'7-4&63kቴ9D!$'k%,nsݼD]q̝IUG؄Mp2uG7I-hZkSQ)o[;Dt_p{
fM"&A	1
$KCQ C [Of71$l"&4iglA.cʓ>G"H[v^o[GBW9=
}#h00R|H=U")Uo]P2/|05I|Bl,/|6Lo΄+.MtHP4O]T^͗DY`8jUPuxiZ*ЈR\S8"p2`\)@Mzzۘs]	DfD }C6NW=mW^wF@L
)IΦ$:1_-LJ!>l3b7us#Jbxؼfa!/YlN CGmRn^`ɣ$҃abլC2blkM$@t<F ?MPn9v6=E!,
1[>Ƞgy8uq00u( 0	SH)pz
xf*` :e'B98Szaef32L4ٍͮg3OsVɑgkGVCEz	JH6-Q[`תU$@"pȦXEDhPӌ&l=6'\nxh^$
kz"<]&"=J`8={(ZBl0J@% H$1M7ʦ!PZ'EV}=
R'KR@xw19- IDATlҹ\VBLYX$t`$p7eňMvY1@]v/O3@0ں$V`a[S"p~HrϬ>:3 &KYzݝѝhzKph0F;2#ub;&&p`Puޭ/!u
}*@*(Ͽx뇈Ky9	RгĴoufn@hؼf vd_[CzⅇS>i2OHd\,l@!Og(&D 5q@g!TRppCgK,n2G'v+:hX%"bt%v9Q%''|R@CRZ R갈%D ڡm7  fg uǮ!wr_e+Q(_q{;?tC>0rR,11!E	~@:d0
tbԄ"v=`bf!7똞\HI!{2{N)rCV\j@
B;fhG;7m 1bF@PZEL%c:AREh0Wūjd.[j׹F{
`nOn{"40>k붣-4Ew%Ȩ/x!5[(F[NуQO[
hڿYUqt)sVъ@[lv1uhw
#v+_B%pD48wPkdIa[~RA׼.0MpΘXLоM4o|_}荆KKh_:߱Mw,>]: h'	x2)m,9  G#l\›h6."!Ha58Ks風U㔔؃t3xZ&_-_Zg
4ۯi|Li1k b~{Ayİ<2˂y
Uglp
OY6@+!I4,9#	.T#г3A%ݻscPi[0~_;a<:jvM	V}zfIKHK-)!K
.d}q. pksFlV^90?JWE)J$tAG=yEq/!Mkۮ}E4_?ÿ߃zݏ'slL e`t
AaɅݹj|BѰ"B3V,`
7KL&aѿJ7~x"	;oCpgG\V #	n;+ͨwhZ({O$4RD&&M±D;Q@09fGpxAJ3("FրgZ[zJH!BKͶ`"dqvJp=9}bJehr%;Nwrq}Εa2_p{;.дmYKr(1y$
&ē=̮)c3ޟp8[`Aa?о‹^xw~|mo_5,a{.cnz]/GRE#ဠA!*]ܿvXJޛG?3.\i1%?3vzHYmeY =ZH{R0껪ΡzO3	l y1/L?&HxyiJHUJ$'H:PԊL0x=f
`3m\tŢ1mħ/cgrBm
lVE6+!Bgr+(RشC:H6$0MG#8baft	,c_}&`mE{kMAUƁ	RqtIfH5qfl9"+X#yDG14BN5}ND͝k_DBh4V
q ED8A03B{/Sm/8>pg.T
b{2ɇ?y^x832tF*VhOc˿^AbQ(pQk)m!69Fb*~ori6.'.Dw6ղE	>/"dfzq;Ϩe:ގꁓUD[=	I6r0l'm|@]XM]MAPZ?cm9tA0KD|",6OW=qCEvL
ѱ27K H;Ps.U&^
~ƹk?~Gᘵ;?C'%{vs3Cz7+=JGk!D]2auqV6t~4)$D[|`CT;KXgA1ygGA=ISGK\"mS5z{.ND}@LLA35h8)}B@scf=w4ڬM3D;B
(al^0uJD/W%=`NSդ9h%jdpeqr˿㟊F2%x]Muڛ7k|g9?[kpq.ſý_|+NY){f/#2:,")4Р^5dqs||38g[/b&I}/D?A6Ds9\g4ηЍ#mGNu1/ͺ\"k-rlI(y"EYfim#\=^fS :d,z|&z]P`4"5u=KZ/bٿF1qY5]$/uӸVrm%y<.{/"}ji|i ܺjwi)Qn4C/IRNxXp|swZC}̮?j>>&1&(L	k"mQ-ES>{=kH[
=w23kY{ҶivBZ d8COL>AmšQZnPU;_Üڧw7ۻosbc&QE]d~O>t[{4s`XtFMY
1iQ&[~B=f_j{ \g>{/=}kxi.CA6އ޻jx/vxN0hse85
%M&+]%Ps&	ض\0T>t܀$*"Ӆ$B۷fBr~"7JJi
]zWQ!@x}'fŝ;_=)˵{]_62o6muf$}zK^GT xP }@E9f|n[~H"Vۄf7ݙd6q/e-UcDW3v^tR/ESs&O4_?xM22-^S1pRiGNl*gho&~a^Ӻh2VoIqsI$¸bqYAےV1t~TG(숲\27OzN&.Jh2įe8R_>1!c:DrXA&y~BܒIۣЊۘ^6ٶe=0)ڕք(.A{O7emxoINaDwfb\Eԟoz(_3Mi+O#iVZ8L}Ӧ5
4(̶Bީd3o.}jՠ-F	WycR{wpgo1|/
$Ǯs(kڭ};E`NN%~9fyfRc_/)
ј[_qX\Ǫ`\{6@h`·耴;~2;kl~ubvtf)L5{Y2I7C/]@aGbMݐյǣu$ßKW!ՍhtkͤEK$[{xv<K
׊]czIӳq!%:9/qRY!;(_!n>c{bk5ewBco3ظp5:?	X7oc42Z"TnV'HZEhWrў`8DMƛc4(WYoPaаdTa.Gɂ#IJ!%>"]+&4&u[l͞{f ̉6	IA%7sX]zDқ}rR﨟m $:z8}L9!P<5zO:1ކҕAiz?d-6{j&_\'4AZoswƘw4/Us_Xs6Mׯa\
0$)#"ĦE$CH>Fll
rgQڲDאӾ&SvQ[(\OrdŏtڌHv#6zHj'Y	*96IX̮y]?CWI,Y6+ďe~Q;VXK1g퐝H IDATe'Ulr/]oм	bhW`l{!zXABfpte
TQa:(5g)l<}[<VMTT
!/4nkWm6;4uERa4b29Pˇ߸0%>oZFӠNN<9[I-<BBucĶbM9 nrIA{;ߤy]\UU'k8}HưbYծ*w_c7z͘%Cե~ 1U4sRUwR=i9u2cΞ)M;7I~	k7!j*^?\9%0q	)1"KѰ,I֦5kDL\G0{'~X&)/
z⾠d	|[UF<Ϋ~ psaُ3i:n\}g?kv*85?z`ԗ,M"}!%bM}&c%Y6#on*
ɪ"$
Tz2eutQd&tHq,+:w:<:%l_6稇t֬hSv_hӛFՖ
JjAm{M^*fo0e89jV:˘-r?fU}Cz_aa/&`wcϞfbed"-$kbVTNGC
>*P#]y-~c"(P7pMf\Yu)eIPdhY`mX
K$i2~*5#TIfGG0ˆIup~riy<ʵ\kwK
T+̆^tY	a:p[8T3xmfz7laGW݃2¨4$A="S@u6/0M*:}HKAhiS3K?0~TA=7αܧ$Un]խ"ŔHKdcvb+%c$YRfh08+zKB"dxY/a2	r/c=+4{$$D<R@h
WPQCBhAdhMMfT.Uuډ9Ji#0^t}msE&x|x	xi"df5.<4mOzg6/Ef;oĞ]HS/\q4(1+4,f%AM[!Sx5r߬о0!XÚw|C4GV2ͨHh@@BDmBW>٢
M{h2API)o3=h|L#tB&SH"gxQBS1U*{viEi.+?Wy/xr8%/Aٽ'`mJ@L&-۵u8kZ\]Dՙb
a`PWsToG	;k*J%v[bΩ#4d!,4INSQ잃i;OcXy$.SHRK[\kmrÂ87eodldb?1{|$lRpXJ+W0
g)dh5䀚0|6^D1ټ$c:ƨyΠGaE|_1STnÙVi.Vg>9^_f &ۯ.[_@\Zx(l_dE荣
Aar{/
S"VBr>Π-6ދ5E\gpt^D)B`!CaBMz]<@fY=dL)pfSD1t(ELJE{
sIqmfu'NERXV	f(KpI%]z&#]16=L5#}\%~j~%$~~PKK?`.rS?u5K)ٍܾng_f09-& $ʹ;YV+3KsV4	yDO*42R~+;	D]1t"(%tո}cdǑME?-%g;O$)O'Uy+y]c|5Kc/5H;%AU*֗~	ܛ+*<{2?v;7ƙ@a!ID'
5j$1nyѿ\HyS#Jr3&
&;wjv]eq{I T{o9mB%Xl$I!Uj]*MM#4Tm0At1lT.uuXY `0ԋ۩e
6x[^wk#$ Oc\-62RBTɽGQ)qoX-I.Wq*874Q8E`Inuj.R?%Ijqk4v9M`<#?s
~^~g7X1se7YB'l+F8R8so_Ӿ5Mកq8w$VWP%2E9-h$NJe5m߮3+R^&>X7xW,WA}+EOLi{QmJbj{oĀg7߻ʓ4M|5>Ph}	q|V	<(S2F]YJ,xz})>~woyv\S>HRwѠ1>Y>EzkOS7I8R3AŸ#冘o5i:}g}֦+TgmD9|XNX)h$"\E$t6M{ 0*1.Gh*ƊJT8:qS5%r
ηBPi|f11Z7*f&6US҃^I@1l΅'խˀrܹETKygØ=@!q//ozj2b
>x:s})f2?x`U
-*GxjGRZA}9"]0%T	SVϣb[]3iNgI`iWۇJد#}ɱ^ȉ78
}CIefyEfs)ƟY? ;~kx;f8+^%3E.n
aR6*}Uya8bOƓ/+Lƣ=8q?UP<&t"R̪TF#{7ogknE1in_gBժ\UX&1IhA_FeRHù|;\19{T{;ܹ;o_GUF[O1l"d$s'Ij!{z1TZ?~O?_ߘGt.:XMUPgx.Y:t*2b
R`RW1I)F%zM<_c0L!IDE<KT)ʊ5)\`y&(@vY Pf^6KiЦuScLa}Ɠ
bЋ]7&N׸'[p7o|F[}JlӤH4;uu)nD-jO^h5ʲȥRa*ϡH1Y^[fqeb@90<7Tpr*Z|]#8
FZz2i0T=9RUCx!m8;J{aVFE=c“Iw{eTPVgy_c]"AKK7.I({s|>rtOY8gʯs~kM43ђoS{w*0Y%i=;߳z۩'9(lCKOb&[i$]&E1HeuR\G'6z&`YLzLmHܽ5
7dc>?455uU1(bBXٸ8w]ojl]zKQ/پ{le0ZL1U{ *jzμCuuc?W~9eIBo>~_GX`gξWL:^Í(SYt
ĀUػ-LY]p&CTpOk۝I4r@]Q"z/Bӽ[M%0RbQrݯ@%Ƭ1vɜIi7(pˢYv*u"0ppV
z`Wf3/k~ɥw͵ne^Rj`8eVΤ%KOk[Qaٱ6m&DܟvɁВ"~(1{
2N[;[1zxo;=`hl?\}n
eڽ(WX[BYb	b"*PZmbI@P3<4=/	IOU%s#SLW\\=GƷ=wlmxF>~z=z,½7ny6'C֧p(I*sMºv+vjRw9 S:+#6ǚ2B/ZaWȲy}BA/g\+]ZKh1vKЙG,=u3=xhkT,xtC"bTնݪC$E9?"FqgFYXFkŔS6ӝ~z=|߇xi;;L%n3LysW>+F-=f!ar@l9`1X18A`	1on x5嘲Q&YatK$dw՜#&Nt_b Db ԃ
]pSF/*]J3	Ei<*/ML8m>:, iZGmxƔ[a:)Kvf5ߙr	>S]:ޭo?pni<\8cRИ[l{AkQ@/s1M3aL)6&AhOl&tNާO5TnEE:	o[X7L4gE,>bBlʌ/"rL<r糗bQ
k+CpXW1Y‹?_lw%+FTheSk3?sOB=PLwo&$
n28Ό`h&qq爽
"
û^9{!ֵ¦hr!ւ薅K~).ޅAFHX0n
hߗ[v7E(F٢-)?c08O兮8
nif1mdE_
W	ۯlՌff~ntWkB鹞ȋ-I@𐌔̯w[#$a8JqGe,
X78JD|D/rn+I6nf Nw5gr x$xU]/-J={ey;P-)cBldD#BnK&[G7s>u
Nt^~4M,SʕlH) IDAT{oJ.lc43:fF0Xԋ+P
ѹ(u=~~D x}B=zq	:{W󭆠=	/~&AjnT6BN	`XFZN
[Og:eٽ
6zԸ)4RZٹ
hMZI"M2Ffm>sΕ¥oGx74GL^&Xw%ͦLS]&DRFl15s_JyRn#,gsx=UZlz*Nzx>άXNO6WJ.+2ӆD	rNA ٢.!ؼ4I.r-Z:l	onv?qEuXR$	>IHnΥm<{g7D9K󷒻f_dd*-zkK\UuY+X;(
,44
f٢^^3fBX^{(a.ppyGɋ6	2`>{#J9sJ[*+eLۖڊG9b5a"	J`]BeJ ɳ%L%|&NKV,mwo6g,yD~v%
#Mm%i66#_gegRRZ3K%TiPSs;N9mkAw`p%WѣUkDhO04
>#!BpnpLsdp9ew|6ռaxn`1܁!=A<*{Mc{z0Zǘ{rGvB)*	=}fbES{PC|Zk*RӤR׷X<n8{ly_!u3cDmu6$=vn_yPLfIt/FܣMbIHg)[A
֍ߞ.-xb˯X`βU[#%e`Hti6G}st|HY @ԂDdj)7˙rfP	RuJSLz=U6+dZ*_Qi_h H!/P$٫-v<=a
f7
lp^^Xg}L"m^%ȴ6z#XwIX{;zEh*ۆ1nsoWFh\2N͑FavqGy#ն0(8x*KWq㠁:ȶ,%B;M샒]ehc:hmbh;v^C/s\1ywB,Vr/M$IKyzv'ɧ1iqh	Ԭ*SKPt)4Xӹ}E9y@RRŒ&Jo"A~qmD(6ĸƁX̓,ggU7[HŎǒKeU(g3sB
U\p(,r3kUef,[|̨BO@ @eEnvQգQm"KQaFI7pz/`ؗ!XiFb~
m6;C|iKBGY:2
yN"}ً*8ew5ĩ([1V8Fq:HSZ„ź3jVe{Qŝ>F={\Ь
!fQSiij
eZ^8ޞxikvNŵ eIF6s$kTFMjb
@[{ZC3EcKw\Z6[l[bھFvKUMХ"r}ӵSfyj?;EX!	apPғȷ&9}i%Bʺ@Ja"HwFi-qC7|),&ζF%?)pPKI	D n
do֗Eic9{s$Ya`lpA%PFi%@\p1OjmP=߶`+;{٣J-43
"7@8<\z@SoQ5X*!-<葘Z&iCP+1'0#+hԠ5Y+`?8"
	jfMj" ki5&IMp1Nh<
7cEu`;J-Tl`$$p
\|M	Cp.8CFy0МQq}s=F_`S/QkT9
AAk^xC[wb"wrhum{-jcu~)a=r=:CK>Z(%d!n2b,4gSZ!=&EJ#@]w1iDN#U! ]
5Y`%ΤYNoV?D	|LU}ni HcIdh5y$*O>
mE-u_%*AIװvF\<=KSuZ=f㳾!	e.KTu^(;2I^`\T
m9T-yoæ~cB{ۿɅI0XaD|M"sL:Rׇg!Q,лu;[h<XgHRb
o3StvzJXgj": AɃ*	PB%Ȇ55N`.mz	B#I	9
X#
KiY!0ry~M{iŞ^c'_pk*6m"$߄Fl42>EuTr{: |4rhHFidv0V
?y(eD!ݖ # 4֌dY`E\y u
wzA	G5f	(c_cё-F#i
a^c_%ߠkZBV5*=8=]}Ǧ`[줆CUsZC!uM2#3n:BS{,tMRP[w=v^!LnT٠}1֗q]|5֫f3qؔnCt]$.Љ$':LӮ-`pDAk)"X+)Yj I3ܪ^
ܵ-48dml
ZTuAq [NDtC.62\igrH8#2֍-Փat(zф.|@inPsTtF
=N-6=6](hCf}7e"KI
ʢi\_e'o2`O!S&F c!1w˱M,wbTDmt)_f. *ܮ<_t)X f͚b6쭵$i7SVxx𰆹r ,
:>Jd[`
wclŅR9DڢhU/i0zx'+9>5!m'ZbG2[.Y˴Ue``x ua1[,A!nVx#W`
[9B<#tpMo5<(lGS.PdiqYX8-lqJ[PlCyoR-v}995elm}^19',>zpX$RaEa\
nx@\@ OMY? C2 $LT$i	
ߏ.؃O um89
"9ԝY#|!qd.pӞق!aAc>EA&aXKdn@ u*CaLd-94aqN/'
" :~~p5N&/GbB61TG94^4ZbXlQ\b9vB_3Co
22Rw8K'7:Q%ñM^*0UG{NCHP3NDdl<d$@SXqM4rsp-|:ћ&wEȶi֠o؂LLu
&f IDAT4*n+G	/sPWGPiuDUp*f5qh\
j 3xp,cPE:,4D
c~t?r1`&_z-bV~ه
{85 ca]De‰ߐ)!֗3C%6c7:4^*5
Tnn@T
P?(l.
9:?*G}HE
5'H=(XMlf)SDF;}@aOC/nR>miF6-jX`5
zjmb]z8ZSl̷Hk*~N*GۗWa9SQPꔅ'H\bO3H98򰯸oF;8B>kc?nH
:
5f&+΢V7k汿V8%OGCpXt<R=q9{<;PsaD)a\Գ;imA4ͷxϖDaK*ل'1>:XkfR4tx$VCIuP_2%+LC"X')KKEaqmHOS|(픁[Ti̖&'fe}XnXUW(xJ=3Hd)8kLw	Β7s☶H=8poh`
8BA
^,vDp U[-ESp.2>=T[PnMI}F	QA(kfHgĤ+O~h@:^ݤ{	*&(3Ď#r·iJIiɣ4BE\A؛w&Tg]#.vG<ߖ؆XF}jұKp;b	lf#7-<
Y#f#ػCl᠈^A	~OCnB,r	e[zM2G9d9U>ON4^8wI@ռh/A{Ħ6:aqJn6dr04>4
z#	UL&%zk;:]S
M}{(jRH2^.clri=تeSoeYkLlI0^4F;TgPC̈́r4F0"T>P3$Abl5P.xIGq2E=smq9r](hzژ(f@CV8av\XB8o–.p,64:1aCpEg´9_GddڷfϠ30Aϗi|4#;$pPXيՙq0dA%
r
CҰݚͩ
2Z`Vna^"4pHQڔhfFP|~4`m[45n'He&2]
ƞmx%F1\&?8c~!͙d7mRǧب@GN>C>X` d`Ha_]s<3
xAB	~B$Rji#p9Ǝp*c!zpc?éd8%t:"Phepiu`bjŤE՞znQg0 3[AIGwe|s1crte&b
b}VJzr=ԙM$F>훝qM&~'9V|f{ms)tΜUOX{1DgNMcK04N?6D4]tȔlo?$,12
.\t?,du
@1jw@q*ђeeĎ۰8/'ڂW=ZJJrvㄴ\s&"TQ;QEWk? iՅlQM'+jI]wMV.AS}G9Vz:΢qѳBQg~.h0zWUD22&y7
y>Ɠ	h,<㵆}֘vS
J:zfG@1OtM"(gf#bxGeS7( uFGGm8%,`Y(W絼fnr_[l /ޥJJQʀr(M!DVJq_k`؏đgM:3Gx[`/ɴE	U0x^pm[r%2&]fBYྫPv08'#WJzw>(]y:0l=?B85tyjɬS)uUvw3t!\pKcB,آ׸m-pN6Lݛi-E!P2F	+یaϬX{1E"LT>㼍n&
mk,z'eʻxniJg&ՇAL855}>V8f+>	`CqXC0MAqLS̋y`Am݆gia˾W[Mp$}a@XX)P*pW@b*I1h9%2ٵį+NkG&^!:HJ
`9i985(8",oFOGM~SKǐ~b|!pց5~&".ڱ::%bA'8>z	mq>(5<,:ŖTdemi
m/qWkpIdQcE%MK[bMPoCmcC/'Pԁ0~NYw1WgѼ	5\(N?Avd;89kVJVi\(FQrh
#t
Enm-$bեa^\KM8YMpc!7{3{ñSaW_^|Ob\&0x^~@N~=0'r_[A1GBe	ިqTeJ3`NRAS5`
K6Xl00K\56fZ\ AΤԯY|jP@B}PDl0dTH>JOOԉԣA[HDBY-Μ>v9N/lPS%73X]n
sy=sןau뫛dOiSz5;
Snk|_}G0h
lQ{Եԟ-`yy2B]4c]"gEҠpMg&Xr.41,[k`T\
[ldh05DdVO,7eQ]p{(0t~y?'*H"AzrK왬YC/y.[pN,A2 rXէ`
ۏ!M}??~/?onq{;		-+u@Qŧ%觛TQ"c
Chjbp<ubw
*Xqk.pę@JX
UcP_M-4p8/}4_p7~[nkŪij}tC| XzH
u!$A2,Lэ(\]ǟǟN>׿'ϿB
lʳ˩:vPWc_XCٟw#[4[c8>g )ݞqD;L1e
	,ĸT`1#0%KZ!U>BQ@&wCp
{ݢzN%Fab5:t"{:fi^8LRH}K|OgnlikNx.q;~}%ĶgFr
	M,PT/N;p"pM~a(v7o~|l׍Rc)
Q4Շ$Р.>8(k$;[::t"P\BUм9\)J֨7_%Nsŵ(\+7;`cTêHeQ4n,xe߽m<{yT[4H5`ݰU~
{ (`MS`s,/+MѸ$hcK|q{}2wl~Lr08Ga=NY:uTI{ܖ‰7J3L!T+؋"6b"PW0)4{K+:TefL\KcPȲi/M7{-Ed`[DXb?{aAф"zWxnV*2(d[?FXajF
QD7ud4/&臏IĴ["8
gGcH}sD;)IkC@`mEkX^~rcZs\Ip0s7˿@Q]_5=H
÷
&Q'$Qp"nxVJƇ#8h+(EY%d6x,lnuf΃2k[-pcVX(&`lAh'X 
6/'}X?I>"\b!d~
[[1ڑ0;>lVy3{Fw.-߹0\*'΃P;w(z$-TdI\3{ΤɎȩƇ#qAG;:z?mDhpcfy_>K%Y7
/
Ii
6sA!"Xlq&*gG ԊꓷU!&~4DU#ѹNlffZ?_Cݖ?Zܾwq32:33fK5O>	e@}y,1fe~)*
1K*pi+Wf_A'mtqH030eK丽Z:.2ϳBI*	vJ
c
G\LzxUKFH
r@0wsK'+W8-%GfIxPȀ%7=p4\1S|
!<
Q,_r@99pkNJ&G8`<BDzDtg)lϴdKkTbexa/WXEEEhJf.
-x24(zHf{(g@9`ك|@k >4'x"['btt IDATh峴
b,K\
/K^`i
dab4qpȇDv91%D}Zχ~]9'f9cɠ8>?Kb7l
|m7*XŒ+\nTba
e06@\?+MOAk?~MadzɔCp2fS4g/78}qi`[Bš?]p7 !8ke-Sbm`(XҔk\aA*ca`B_nLztwIW(=*eiO|W2g:;:anO釗<2&s(7n	|yw@(҄9Z]h
'5uTO9@Xb.#rJNyXłJQWxa/qiVDI%,{h/(WK!N$M,;HQv8ՆgV}FힱPcN,>$jWY8x0SP|j
T,+kss%U(Ȣ4L&XVgM#+mL^O?Y⣓+aP`IV\K,
%(LC:a{@ʉM;Q"0&
f#W@.CJ6`Z;hKqF>dC+hϪ8pBynu@]jvg* >[VkYZeGgć͜JTX,T+\׸*|IL?CFuvsjHSIvSc<੏}BR`y
L`k@a5fw/R}@rd@NY	aaAiXS^C/W_bt|9YĢD;YF֕"W"I=oCІw8'
;kh@{
\~_޽5+S': %?}qOgsf\_
JX-qc/AqKPPK >1=vK@v*|;YJ9F	}1}9ޮif1~-Lq\56<S\CZ'>;Ap(K7ϏxȞgfԁa`E	Ƃ+\Rk‡Td[6]PޜKJ&ɸPHmfC%Hrvg3>H͋ md͘aB[ Ѯ#W
2˜^7X%Pmh8-]a	UuBQ\cGPs[BK`kI	̵`!iG8>	0DzfFb@+p%+|T(D!uY>tS5"i]:#cub!TF漝[]ьPy2-ÜyϩyĻI
bj5p@eL]oO|s {sW\-T5oA\&G"oů;l|	
㕯C%ȾfttJs1xP9tOba
ygGs<7Xp,>BS>-RWAJ=r(Š=;҆ʣFazX1jF3buocJ0az'q cN.w!~`s9vo<3Tq{"jp-(xz)oR@%&*ޫ
pUf7.}.63e!ǯAqRS<:6SRK%*6XWć>7XqJc`yO[չp'I-a5?oіL'Rul^R:zkgrck4U9ăpIF
du-@;x
Z달ɀȂ!0a~ɓ%KcWO+jRxj''^(}(>6t>
)k^'<3kTxcBQX6>FZGۚBn"T;6T kC哿=X8YR?YC 0BPt{wo͗B	
Y(	:}swZ.ҨԎ+}8Lŧ8
XX,-p7`A*0dR3z!RkmR{**t߁DE(Y0hL2=`1;Rt cw~ʣAT@nJ)%%(ȇ8q:\nO$#hɛR%ٺNE.5
e@25N/˔r&kISo@B
?^ԏUD_0Ik0jvPAY8@o9mn!=#q(
O`bf(0׼~X}-`6ἧ3]8up,TN,2âtÙ'{0h&"{~\`쯆Z(Tvp-m=r+Wٛl66SRÅW~{tqfY^{s{4ܓGI8{b:G
xea*cC8JyD6ғ
%tUa7T>E7N
ߎp2әvFL%.o~6T07u̷@ݷcJ`%ƾKb@#$2q5ٿXV\#R0cSC@7Ocȁ2Ě1Qn%*.`k%-s~'ogaj{(ʧ)TtpmY[	O'^/hlt60v٠060‹OɣM[P֟Gl}נ.
k;@mݠfe!-c-PPp+|T>'%J(``xa7ISHT?⺤	ݐˌUn<2,WbdK#;_<}½6݊'rIji=*ݏYl|V/Z;i0
#3=(0 /2X
3sT㹹BImxgP͢^E6FDl)0<BG2ʁQ;<yB-.6G;۞2ke<%W=SOfmOwV1ǏO04Pa4 Rd(xk|`oX_C`	+PC-aQB]0`(g`8l{o42Sȏ)<ɱG
F̘&Wm~Wa~fV=v|'O
uGASb(Ƞ
KSڬ>d8<>9	BC@ͺvS`8DQ(q`Grn=Y$LNɠ	ʝhw
[~Qi߉S=pғ"qڬe gxƗxiP0ַR*\l0\KPq"M
B=vx7A(fD
XPK~x	oF	
,R _ENÌr1]
6uJ90u0TYcU0aqwҊ_ZA|dPBT17^>X,@TkK.%ƧKd},BBxNI6]MgMK(}Y.0xi0l0NϼX}әdD!dC?}4֡SLJub1,(>`@$
(Wl	~P~
,qMl8ĸ0+[0ȏtC]0L;÷|d.x= 
Ta$0.潮squl,[98'[f
S:,z/
68y?H0lu34=#0y<@O-y3W39(903H`d.l`P?@ϾfO=-N;KKpaVxa^S/oixe%Pcߎ:G'(]SاiA}иM-{]ނaP<*c^Q~\k~)	Iܣx0-yaޑ:3vv65ﷻ50UpAҾD.xC[>czA+^ʮ{Ha0M84̈́ΩI:%Y\k7B:Oa7ܿ\:p	m~89$ gm֘MG$c@S74\Ϫ_`lkK읓ZNGb"¼Uq?[}W(MdNTW^s6?*|܁#ʁQyҗ-)aMCs
y'MDQo7,2\|F
Luي=KV>:n`&)M!:\\b+(/?Mq	X8V+i>qߗաOϯ㺬hL
JbGv`	`c4
S4N
43Rh5"FzZzDFdd2;Oːڵې{3M]UE6US/$>^IrpA{&Lc֙8OD_f(tpƫ%b,‡Au3XSݓs!\Ok.״ŦaPHɔl#[R{!frʴ##.ŠKY*Idˁg.//c vU4nqf'[vPl<ĈB"
G#yz
'
IT(v
>?~4Ū-KU}L9
6/AIK^ಸ⏗$|fN8(ΌBt/{',woahߋp(w{{0!X5%%wf&؁Ė@扷{plh4DXkqoL 4ϱ_t554;{nu}ϮlS ~sc^P!p t*ЌkA-!iĿoәPx?:ɬ%)l9Q[P	&l9*HQ(;_ޑ}P/‰@Сz/pvt'x2Jk.
?~ͧBs08bCYS*_?G{,"$-,Q
߅Y~72XÐҬø=&8,.w?`e%	4>{W㓏>:a~B@YRzGi
ppsulYDaG繕{-:5KtLFЈQԶ'-,Q4N!"P	ϿۍBJO֢2]`i-pٟ	D"1W72ɀTCe[jvIZ,T}M7v'K]w7:<;JDQK)?5[Lb%K,!E&EP{}zuw~l{w}{{̙s9z
#.<4&0")*r,?цNQRp`]xip(#1h5R^S}s(*Ԑ*O.Gށ]vyC5nTUW#=+i*8DU[㌭ӺQNm|̪GE)rBk8ኈ4a0Tr	/FØa6KJ43J8ݨV4AUZ[)r
^(
 Hha)&.!5yup}9x\"& 3=[VRUΫ[:"I5046+89
 }=G
2y
. /B@]M
zqMDSEXj2<)5+~F|"X	=>/0)Q8ꊁˌ(Ͱp8's$:rdW4Ŭ
rLN⩾kjDʹ$~QQ$6c(E
08TT#JvTp{<2s(7751JѦtHpq*:@(̂@ByPXhQHY6A 
MTy6DB#Ⱥ„1reQiCbV$i/|%ݑA;a'hR*dab, F4&<9vqUn<)*E6*;TC{ʛ& 1Ft)M	nₗ'l"H$Osi!&=}!N
5Ax*¯Rq!:&I=fHB%-ޔ6ʺ/n,1DVO*nhw \KHRŽct`AX`wA@t=̱`	{Jq7&mbzyao0|<@H^6Y}z<vc,orVx6yb	2&'DHd5OaLN
]z.2T3dd6owLHfli2ؖaBTpU0ҩ	3bDPJ긓RR=HAGwi\M2QfIbv{&jSq~{7E\p#h`Ѥvv>y-)P
PJdaބ<:b"iuE@+X6p
"@
%g$4`טeBV[,TR! !.D64گE4F4y&OJUcFGyڤ#-bQBd	DPQр>"3'UO׍~%Uh6c	K!ޤM8Q=\Zic#Ԯ13h(q
U S
۩\٦ӖRq(U0!ͰB$cRm\Z4HIik[KpD%,0HOu'[^b3pؾ98R&Z+ZJiIr]b#ө*`FvxqxTlcsd
ǹC^^NF3^
tBIi-n9Jt
J$XԿ5Q)\r8A[%T9/nШ1#b_QFF̹*O5Z[,?]\URs̊ qH	,@q9 MIY^
%'P|)D
Dt-#:IJ9TRv<00SHN:0!:Aq,TёgJ_^/O#a <JyPʉ0x^JOyN2rBqg<@#bqVppRhTP8
($w|-+Oِ*Y
uii=iiU~ZL"K57Wc"UDe.	F

ԕrkbJ`k8!G@a8y#;+P!T=UofBO@!$I)"'Hp@{umpD;B)^MLne)*!8(cǮCd`مI|l)\.=r1vto,}N:dV\ΥAn+Qe̋OJ x?Ov1|xvmC2:9!f=ʳ.c	TX;0ԉѵsN;ڴM攒ƀ~Q^{0npPgL7٨F56t&|>K8S;TVy"0kjku|>x*lb>MTPǎñ<~4e6Y45u*
ѯ_odf?54(/b%{K$F}C(`exC59]йSX`7p#òHN$!]&Jv5eWT+T@ Ac{#3'6Xn]21~\olNqXz+*  +D${:#|f| ZTPS'|M)E?ݻ(-	#sBpJ㡯(12aā
(CEFшKNb8`*rOc'm8X'NY/肮ґ
}mJ!u~
Fx
U_0ѝbp9Ab*3
;pxF3`6ydf˕\&"&Z@(w!\15%0#[H p."UM'pN9bS)LD@$G*+Dٸ1;I)
xatH\KI^7ޖ{>'A]i*7m.dS5!`ZSVoR*g"򳤙H@)	)0
8Ob)NC4
˶fhM_=d$D4",!3+(2
O(/0FRFCEFXJVh7ygmjA#bcE/"Rŕ>Q(ɔ%H|L;Θ%B1#$!!0YFaV&6Y^"E"!A*
*NOZyh4Ud*.r3k?i_
()㪑(4tVS>)(aL[lIãrw1Ddz>;x*RzyI&8c
J̢
!©/F}	16{UeFۄ3FeA4d8"OʐdklT]yI,bD0xШ'_#J,F#Rnػѧ5I|QXPPڠCd5ZKFaDT9qf.̙ːZUDeI0
fTTTC2N/QHT-uJϗR9	ڦS(51HIbp9U(U'Ue6- m8>.fb)m;:rl`Q@s^5Ćl"05)h:ܖ8jUb#y3>J@Wl0@1L6G;R:=Ku11ڄ
c@opؗD1@cC$1jBR<:GgO|TgQV@B	eQ)c\h"8F+~VJ"D-eŦ3Ү,%&PF࣋P1darIcmH?Mi
LT”WED`
t@Z$9K?hYWWė>b=E	)&54_B&[5>m@҈*\,IjEcq2d*LTϸr:31gQi)K׈SFD˜Ԟ:"EAjUϢJAbl%31H:#=SQ*0ձ騖1(K!73^9/u*73llw jwK1u:mjm~;FuTAIEWz(7V-d`7]Jn`/nPoa6&MjlS_U`m
HrTJJogI,G00E=&%ЮѵߡpUWV_Q*빘Mdw:_N6|9u(0Nݡ6Ԕo>f䯨ߢhl5TIQ0m
:
z%)*¾EK˅CrFZΖಕ2z$z$;x#tꈮcF+l]NlոR=-t^سY
|r_{YgD֟,Ƕw-Kf%kxkyt͕;XK.#bUQdjئV'承d!^ #*ҿ'Ǫ
<KW`BEb+s{0f-DžX!ۮ_)r
a#Ǿ߉cDހ?CױeC|0Ӧ"w:w{Acy@yYw݊H0ꃇPc',X#:j_KFJ̅}#q`(v~=1m+ynappŦX$DJ^B2
n7rGxl]=~wB#)!JnǤG'3yްϜ/˥О#m;#
mYCRʬX8|"pyXL0~> SNVggt?wfsx="!r._J;o;5͞c6&?S~#SX0ϣXs7%B]dn7CwDݲ;ONO DrƁa9gjaѰ]4[\5ݢT}6C1{{ܖa'wފcoDCic&ONO/ {sR^#T7͕{a`cFb峬=uKNNcn[>}ӲI*r
ɬ!еt3rwPXng\ġO\İϜ&@ȅ˹R|7VPݧCKWpt3V9e9=m]S&>q33x76\K:3ئÞ-6kP>@,?0uX?Oi0MO9ްϜ^30[umljlNkjh@uG϶ǁe8H	Cʞ6?[^7>tXEɴuf IDAT1Y*ի1.sym>U%8%3ly@h	[|^}P?ڳ:d(#z:=$B0^9Gm57"8Y)lK+Pǿd(8݉I5YCJM5
_a3]}i1nD'|#g`#tynxm7t.p\41|t',

|s9TKn.Y81}p0[r7
y@XZmf@%–эMyNLL,q7t 1ȦDU_f
$i./R}Aop-7nj,f@h>R@&ȣq3.(=~'7o;#t2BZg#zZ_j@<ovY{tx2-?x({T9
JyPu9yt7yP	G# X__@è=z'Ou:yL!%'=ƟngpA0DӶjl9Jџ*:mEjYz0pv20g;v>W:
OFF\){>_7T폮ف{,':v0|`MVy"U@u
6
K
8<@sFawkdi3Uc+YNo0%c6$h2f:!u
7DLTp;QjNqWTGjD}_긩fPB@d͟nՇ+-I$\	%[٭h(h P8SR7~j2?phҴJaf:Db;ֶj|J7;SgƓ (Th.gJj̳ƢoN;mCcyD|3X*<g]NP%[vQԸ3r\w\s/Y3R_.e{NbG_`6B4K5&qCa& %*Ɇ;v^ Of:R;^_}:Yи!cզ@ۿᳪ2,޵K6k'Aok((HaP?~"0@Ma}@#;#1aDѱɲ:
U!q&!8B7n~R}&(o@_qes\Tc݋9h

`Xrari=ĭ;\[o\
xT-I*T.&	ofn3W/^[`2=:9i_m֛i>\U68J[՜+w@!k([~,?l^s ߰l	ft@1r<[fNj
1Ŵ>1šzrl} ]c-+߰\fuqkTzMxo6}.):Z7KZP",4UCOn݅]I&q";%w#9}L$#e)t5X`Ymt:v6/Xk"fea~.ٶ>=FnA@uqW1hPOݙZJ"TR`)nGê=;倳G&@гJP|'_xVaHM-BNlچ™[`Y(۵9v2HPnٌ-k0~(ER2)YNӶq7B_Nn[
\a]@NpŁغ-&/;˰.n>0/#{JP&|Vs-$mPnIK/'y^H
ZR5>~ƿ,4|NcE%gaz:;ԕ#d8ˉ[1l>F;udƞ+.3䖝8i+Xnj@qQ8s*zOOf]9uT'lGh/7V$#]}|yy11,_UT'ѵf+߽ƍ>ygqGuAV/nJ{
.lZ4m^2Z9@w H)
`䷧ܵ9q`,Zn	j=6®cLln4Ί["ӺNx2ӌLO;,H{oQ͟x<_ĭ~~o8/xJu s#o`w:>*\\\n߲2àgMyϣsۑ:3BղW<؆ex!Ӻݰ,-Cι}[% ?MryWJ
W@bq)ރ+֡X:8}](پO.xP0qaƒoykbUL;#0mv(|TUt^w+hZ;s@]iyiLUoKChO]څC{xkjyu->*pA`48fbdUO%nnXd[zƢBY0bCTdz"a|PWn=Qy|vce'r<o~Rd(.yQ
w@M?iŨ矋xZXܴ@N1Gr)1gbuz[ȟnDI@y؎,Am~+V_?g$RLkPy(:t0j9Jſy7滺[{Vwq'"[LoAVQg?Jw7Q[ӫrzpdu&A]I)G`Q-hV>V>	܀طl~o!n<Y8e{D0,f8޺64h@uǂu(Z{_<9}COPqH'A&#_==} Kc'1;1eϗ+-ԝ@XI]Ye]/gě|_.znnٲ,pz^܎@uBL}9.~zޥ?|,]BDžɈوo}Y=ϓ EW]Gn0L#i:SW@j𣡼ru0i5NJJMAFNmZwɧ
)YIV#9z (dm"{a2S1A9J@hdEh3[bA3C|6&x0ԓ
X^<ɖO+uGɈƵC%PB|D,F
@h
\:$$a[͘0lj#0TiY*(٪!,Z
W`CcӡI뀢a[ə	ĺ
ҼT^@h5GuQ=?ƛzjDK)&&:hI<h4DǣIѼ
&aUĚfsjgɒ|0mMg_yx-3-p}/`됑3={E܋e+76cDk;
#~@nlAs;&~03Ͼs'݌]g"%s*:ts&`0x,)(l݋{.WlTLJP]?c~	_2~93d]ik6^p'}a)2'>gߥA.H/cvE`Ɋ6	mܽ0z
_$\
w3;jd<=Q];g噷T@˰b&t_.z%Ǿ/;aM"-еK,(={D}xn8ST~-?=rkP[L񔢺ǎDgSxs;"]潅TVաTK'|E}ݺuĊTuǃ96~tD(,5ͻֽx1oype-J0B8D}C	\kV~EMm:C00jL"P8[%Bh	{
U
ؾf̼՘;pW$EP^l*[5>eA)Ԑ^֭/Q|JB̳ŹoB^̛)nEkXEpUϋG߬7]>}rgxo>\W6L?^}<-w_
!HK%BB'ϋsR=cqx|^ztD8QV$q!77XUx%ի]%5Ջx<zx\p:7+cM1h`/zpp/)w?CA^Ы?,t%&bY^ol2q	\x=(K/|E*}I?Wˑ=}f㦛DQQnۗ|][t͟1|xO4q6[]*L]G	 l?1UVbwbC~;~2!
)w)
1LvV͛dg5XsJ)'5غu!9q'ʼnr{*|l=mɼgFQOv'EyEuK+w`Wcͪѣq{}A\|QU]܏믛sOQQ	Ɵwsl}o/%R}Uef_;{[pt7Kڈ+װs!tO(:'—Dž3Qm}XJ\'v.WSS<p8U;$PTMsyEҽ:d"{P+MTDҞ"23SI;gIk[b] ''Cݾ8a$]y^4q@{i鏏'Jq`׶wQSG}ݍ?~*JP|YgQ͊ z5WTcX?Qq+[/ӓY~KgU9.zuB]mTZ59ȁ{gjld[iYXW%Uժ&>ybDžP*	""8acJqcٳ{F]m^Æ^B/]r_x,__/]k&_{0lX_.>s;̺x<23SG?Cc@sc,<
{
3^זCTU6	tQJQZ&1_{ =<ˆD8y/&L;vB>=p<7W_-`w7ńb΃/_}:tPGI}͡tL<};%KK5ϩǭ޽G_]O^*k#ʫg1a(uvA;mEEuB5-Iv氎q9C4*WRKC*T&nMA\_1+3yp!*|.'K+1ap|tA%<V)XNa.ݶ(RI/O7m]%"â/Ŵw2+nb	)ۧ$UZX;OTle~9Dqql>diػO
@,n=CD8\wxMžG3cLo
FD!OpO:ׯlD&cK&n$.UUuXv\sêl.U(y.^ys!chlkO!'',mnWd*_k߮݊zpO_{xkm]
<({
`"CawwM	%QcιCf~pej_hҔ-GQ_߈um$³nqμBN|ïdžz7oً_zN)3%_yس&;-[b}gU'BW_u>z?x
7=U3U[+ M$6	^4R,]=w<;k窌V~]1Ʋ
p}oŴ6RR4֬5rh,\v9ז|\=!6ocͅxrs:eeYtƜk[A3fMV֗ԺgrHzayAQQ	>dΟؿt̚};cw8OM6%Z>a{iU)_	)%̛MztX_ͶA&ΐH`]JmX&ljbN6dә-
%yjm;Xa3l]4v״=D̢6M6feNRZfۯ\5f Uebng/l&9&TG+`IENDB`mudlet-2.1/src/dlgOptionsAreaAlias.cpp0000644000175000017500000000312111513237311017330 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "TAlias.h"
#include 

#include 

#include "dlgOptionsAreaAlias.h"

dlgOptionsAreaAlias::dlgOptionsAreaAlias(QWidget * pF):QWidget(pF)
{
    // init generated dialog
    setupUi(this);
    
}


mudlet-2.1/src/TTrigger.h0000644000175000017500000002153712070466512014660 0ustar  csmallcsmall
#ifndef _TRIGGER_H_
#define _TRIGGER_H_

/***************************************************************************
 *   Copyright (C) 2008-2009 by Heiko Koehn                                     *
 *   KoehnHeiko@googlemail.com                                             *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/



#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "Tree.h"
#include 
#include "Host.h"
#include 
#include "TMatchState.h"
#include 
#include 

#define REGEX_SUBSTRING 0
#define REGEX_PERL 1
#define REGEX_BEGIN_OF_LINE_SUBSTRING 2
#define REGEX_EXACT_MATCH 3
#define REGEX_LUA_CODE 4
#define REGEX_LINE_SPACER 5
#define REGEX_COLOR_PATTERN 6

#define OVECCOUNT 30    // should be a multiple of 3

struct TColorTable
{
    int ansiFg;
    int ansiBg;
    int fgR;
    int fgG;
    int fgB;
    int bgR;
    int bgG;
    int bgB;
};

class TTrigger : public Tree
{

    friend class XMLexport;
    friend class XMLimport;

public:


                      //TTrigger(const TTrigger &);
    virtual          ~TTrigger();
                     TTrigger( TTrigger * parent, Host * pHost );
                     TTrigger( QString name, QStringList regexList, QList regexPorpertyList, bool isMultiline, Host * pHost ); //throws exeption ExObjNoCreate
                     TTrigger & clone( const TTrigger & );
                      //TTrigger & TTrigger( const TTrigger & ); //assignment operator not needed by now
                      //TTrigger( const TTrigger & ); //copyconstructor not needed so far all members have copyconstructors
    QString          getCommand()                    { return mCommand; }
    void             compileAll();
    void             setCommand( QString b )         { mCommand = b; }
    QString          getName()                       { return mName; }
    void             setName( QString name );
    QStringList &    getRegexCodeList()              { return mRegexCodeList; }
    QList       getRegexCodePropertyList()      { return mRegexCodePropertyList; }
    QColor           getFgColor()                    { return mFgColor; }
    QColor           getBgColor()                    { return mBgColor; }
    void             setFgColor( QColor & c )        { mFgColor = c; }
    void             setBgColor( QColor & c )        { mBgColor = c; }
    bool             isColorizerTrigger()            { return mIsColorizerTrigger; }
    void             setIsColorizerTrigger( bool b ) { mIsColorizerTrigger = b; }
    void             compile();
    void             execute();
    bool             isFilterChain();
    bool             setRegexCodeList( QStringList regex, QList regexPorpertyList );
    QString          getScript()                     { return mScript; }
    bool             setScript( QString & script );
    bool             compileScript();
    bool             match( char *, QString &, int line, int posOffset = 0 );

    bool             isFolder()                      { return mIsFolder; }
    bool             isMultiline()                   { return mIsMultiline; }
    int              getTriggerType()                { return mTriggerType; }
    bool             isTempTrigger()                 { return mIsTempTrigger; }
    bool             isLineTrigger()                 { return mIsLineTrigger; }
    void             setIsLineTrigger( bool b )      { mIsLineTrigger = b; }
    void             setStartOfLineDelta( int b )    { mStartOfLineDelta = b; }
    void             setLineDelta( int b )           { mLineDelta = b; }
    void             setTriggerType( int b )         { mTriggerType = b; }
    void             setIsTempTrigger( bool b )      { mIsTempTrigger = b; }
    void             setIsMultiline( bool b )        { mIsMultiline = b; }
    void             setIsFolder( bool b )           { mIsFolder = b; }
    void             enableTrigger( QString & );
    void             disableTrigger( QString & );
    TTrigger *       killTrigger( QString & );
    bool             match_substring( QString &, QString &, int, int posOffset = 0 );
    bool             match_perl( char *, QString &, int, int posOffset = 0 );
    bool             match_wildcard( QString &, int );
    bool             match_exact_match( QString &, QString &, int, int posOffset = 0 );
    bool             match_begin_of_line_substring( QString & toMatch, QString & regex, int regexNumber, int posOffset = 0 );
    bool             match_lua_code( int );
    bool             match_line_spacer( int regexNumber );
    bool             match_color_pattern( int, int );
    void             setConditionLineDelta( int delta )  { mConditionLineDelta = delta; }
    int              getConditionLineDelta() { return mConditionLineDelta; }
    bool             registerTrigger();
    void             setSound( QString file ){ mSoundFile = file; }
    bool             serialize( QDataStream & );
    bool             restore( QDataStream & fs, bool );
    bool             setupColorTrigger( int, int );
    bool             setupTmpColorTrigger( int ansiFg, int ansiBg );
    TColorTable*     createColorPattern(int, int);
    bool             mTriggerContainsPerlRegex;
    bool             mPerlSlashGOption;
    bool             mFilterTrigger;
    bool             mSoundTrigger;
    QString          mSoundFile;
    int              mStayOpen;
    bool             mColorTrigger;
    QList mColorPatternList;
    bool             mColorTriggerFg;
    bool             mColorTriggerBg;
    QColor           mColorTriggerFgColor;
    QColor           mColorTriggerBgColor;
    int              mColorTriggerFgAnsi;
    int              mColorTriggerBgAnsi;
    int              mKeepFiring;
    bool             isClone( TTrigger & ) const;
    Host *           mpHost;
    QString                                mName;
    bool                                   mIsTempTrigger;
    QStringList                            mRegexCodeList;
    bool             exportItem;
private:

                                           TTrigger(){};
    void                                   updateMultistates( int regexNumber,
                                                              std::list & captureList,
                                                              std::list & posList );
    void                                   filter( std::string &, int & );


    QList                             mRegexCodePropertyList;
    QMap                      mRegexMap;

    QString                                mScript;

    bool                                   mIsFolder;
    bool                                   mNeedsToBeCompiled;
    int                                    mTriggerType;

    bool                                   mIsLineTrigger;
    int                                    mStartOfLineDelta;
    int                                    mLineDelta;
    bool                                   mIsMultiline;
    int                                    mConditionLineDelta;
    QString                                mCommand;
    std::map   mConditionMap;
    std::list< std::list >    mMultiCaptureGroupList;
    std::list< std::list >            mMultiCaptureGroupPosList;
    TLuaInterpreter *                      mpLua;
    std::map             mLuaConditionMap;
    QString                                mFuncName;
    QColor                                 mFgColor;
    QColor                                 mBgColor;
    bool                                   mIsColorizerTrigger;
    bool                  mModuleMember;
    bool            mModuleMasterFolder;

};

#endif

mudlet-2.1/src/mudlet_manual.txt0000755000175000017500000017436111513237311016351 0ustar  csmallcsmallMudlet Manual
=============

== Table of Content
<>

<>
<>
<>
<>
<>
<>
<>
<>


== Introduction
Welcome to *Mudlet*, a modern MUD client for GNU/Linux that offers all the tools to get the most out of your gaming experience. 
Throughout this document we hope to familiarize you with the basic aspects of Mudlet, from the interface to its _very_ powerful and feature rich scripting backend. 
The main focus in the development of Mudlet has been efficiency and performance, but we also try to make it as easily accessible 
as possible. However, keep in mind that this is a complex piece of software with a large set of tools that do require some understanding of the underlying principle. 
To use Mudlet in any meaningful way, you have to take a closer look at the technical section in this manual. If you are not familiar with using modern MUD clients in general you should also take a look 
at the general introduction to MUD clients section in this manual. 
You are welcome to ask questions on the forum of our website. If you find a bug, please let us know.


=== Quick Start

To connect to the MUD of your choice, click on `Connections` → `Connection Profiles`. 

* Create a new profile by clicking on `Add New Profile`.
* Specify the `host` and the `port` of the MUD (This information is usually found on the MUD's homepage).
* Now just click `Connect` to play!


[[heading1]]
== 1. General Introduction to Modern MUD Clients
=== 1.1 Mudlet's automation features
Mudlet offers a vast array of standard features to automate or otherwise improve your gaming experience. These include, but are not limited to:

- *Aliases* – user-defined text input, which is converted into a different, usually longer input before being sent to the MUD, e.g. +gg+ → +get gold from ground;put gold in 2.bag+.
- *Keybindings* – also known as hotkeys, allow executing certain user-defined commands by simultaneously pressing a specific combination of keys, e.g. +CTRL+H+ → +send say Hello Miyuki!+ to the MUD or +plays La Marseillaise+
- *Triggers* – execute user-defined commands upon receiving specific out from the MUD, e.g. MUD sends +You see Elyssa standing here.+ → send +poke Elyssa+ to the MUD.
- *Timers* – delay the execution of a command or execute it after a specified period of time, e.g. +throw gauntlet to Eric+-+wait 3 seconds+-+exclaim Let us end this here!+
- *Variables* – allow the user to store text or numbers for easier use inside scripts.
- *Events* – allow the user to make triggers for specific events like when Mudlet has connected to the MUD, or even user-defined events to use in complex system making.

Scripting allows the user to create automation utilities (triggers, aliases) with the Lua scripting language. The possibilities of what can be achieved by using this technique are, practically speaking, endless - ranging from teaching the client how to heal your character in combat for you to creating a fully automated robot (known as `bot`s) that will completely take over the control for your character (especially useful for completing repetitive, rudimentary tasks).

=== 1.2 Automation and MUD rules

Effectively speaking, it is possible to create an AI (Artificial Intelligence) that does everything you can do in a MUD. Even more so, the program will be able outperform you in almost every routine operation. The difficulty of creating such a program depends on the task it has to perform: gathering loot being very easy, walking through a dungeon and leveling you character being moderately easy and socially interacting with other real people being outrageously difficult (see http://alice.pandorabots.com/[A.L.I.C.E.]). In the end of the day, you're teaching your client to process information and act the way you consider best suited.
Because scripting is so powerful, it can give you a competitive advantage that some people consider it unfair or even cheating. As of the moment of this writing (2 November 2008), this sort of automation can be best observed in commercial massively-multiplayer online role-playing games (MMORPG), known as gold-farming or power-leveling. The basic idea is creating a system that will raise your character to the maximum level and gather in-game currency in the process, both of which can be effectively exchanged for real-world currency. The spread of the above aspects can have much more far reaching consequences than just being unfair, such as inflation, loss of balance in terms of game-mechanics or, ultimately, a complete crash of in-game economy. For more information see the paper http://papers.ssrn.com/sol3/papers.cfm?abstract_id=1235602["Simple Economics of Real-Money Trading in Online Games"] by Jun-Sok Huhh of the Seoul National University.
For these, and various other, reasons the administrators and owners of the corresponding virtual worlds can forbid the usage of automation tools. A failure to comply can result in suspension or deletion of the user's character or account for future denial of service.
By including scripting support in Mudlet, we effectively give you the ability to create and utilise AI tool-kits, however, we do not endorse or promote the usage of these systems if it's prohibited in your MUD. Keep in mind that by cheating you can lessen the quality of gameplay for both, your fellow players and yourself.

=== 1.3 Basic scripting
The following part of the guide is written for new beginners in scripting. If you're coming over from zMud or cMud, you may move on to section two. 

==== 1.4 Variables - basics
Variables are containers for data. In Lua, they can store numbers or words. You can use variables to store important information like how much gold do you have, or have them remember things for you.

The syntax for making a variable remember a number is the following:

---------
variable = number
---------

Or to make it remember some text:

-----
variable = "some text"
----

For example, here we'll set the `myhealth` variable to number `1345`, and the `myname` variable to `Anna`:

-----
myhealth = 1345
myname = "Anna"
-----

You can also do basic maths easily, for example:

-----
a = 2 + 2 --sets variable a to the value of 4
b = a - 1 --sets variable b to the value of 3
-----

To concatenate strings together, you can use the `..` expression:
------
first_name = "Joe"
last_name = "Plumber"
full_name = firstname .. " " .. last_name --sets the full_name variable to "Joe Plumber", with a space inbetween.
-----

==== 1.5 How to send text to the mud
To send a command to the MUD, you can use the `send()` function. Data inside the quotes is sent to the MUD.

For example, the following code sends the command to `eat bread`:

-----
send("eat bread")
-----

If you'd like to include variables in the send command, you need to prefix and suffix them with two dots outside the quotes, like this:

----
send("My name is " .. full_name .. ". What's yours?")
------

==== 1.6 How to echo text to yourself
To echo (show text to yourself) you can use the `echo()` or the `insertText()` function.
For example, the following code will display `Time to eat dinner!` on your screen:
-----
echo("Time to eat dinner")
------

If you'd like to include variables in your echo, you concatenate the value of your variable to the text:

---------
my_old = 5;
echo("I have " .. my_gold .. " pieces of gold!");
-----

==== 1.7 Aliases
The aliases are the most basic way of automating the gameplay - you can use aliases to shorten the amount of typing you do. For example:

.Example - Brew'o'Matic 6000
__________________________
You're walking around the epic dungeon of the Unholy Firedragon of Westersand, gathering roots in order to brew a potion and thus restore the growth of hair on Farmer Benedict's bald head. Once you see a root, you need to:

..........................
open the bag of tools
get the sickle of damnation from the bag of tools
cut the root of hair-growth
clean the sickle of damnation of deadly root acid
put the sickle of damnation in the bag of tools
close the bag of tools
open the magical bag of storing
take the root
put the root into the magical bag of storing
close the magical of storing
..........................

and once you're done, do the exact same thing nine more times... trice a day.
__________________________

Alternatively, you just create an alias that would do this all with a single command - for example, `quest`. 

===== 1.8 Making a simple alias
To get started, go click on the `Aliases` button in Mudlet, and then on the `Add` one. This will make a blank alias for you, which we'll now fill in.

The `Alias name` field is optional - it's mainly used for the alias listing that you see on the left as an easy way to distintuish all of the aliases. 
You can just name our alias `test` for now. 
The `Regex` field is where you'd put in the alias command, i. e. the command that is being sent to the MUD instead of the alias. In other words, the alias is a front for a real command. We call this substitution process alias expansion.
Mudlet uses Perl regular expression aliases. Regexes are a special way of matching patterns of words. For the beginners it is enough to think of them as a general way to specify the words itself and their placement within the line. 
For basic alias it is enough to know that the character ^ symbolizes the beginning of the line and the charachter $ symbolizes the end of the line.
If you want to make an alias "tw" that sends the command "take weapon", you don't have to care about placement or pattern matching in general. 
All you need to do is fill "tw" in the field called "Regex" and type "take weapon" in the field called "substitution". Then you need to save the new alias by clicking on the "Save" icon in the top middle.
The symbol for unsaved items disappears and makes way for a little blue checkbox. If this box is checked the alias is active. If the blue box is empty, the alias is deactived and will not work unless you press the "activate" toggle padlock icon.
Now you are ready to go. Type "tw" in the command line and press the enter key. Mudlet will send "take weapon" to the MUD.
Alias as basically, a feature to save you a bit of typing - much like buttons which will be described in detail in section two of the manual.
To learn more about more complex aliases have a look at section 2 of the manual.

==== 1.9 Simple Triggers
Triggers are an automation feature offered in many modern MUD clients. They allow you quicker response to a parcticular situation or greater convenience since you need to do less manual work.
The way a trigger works is simple: You define some text that you want to trigger some action. When the trigger sees this text in the MUD output, it'll run the commands you've told it to.
Example: Whenever you see a bunny you want to attack it. You type "bunny" in the field titled "Add to List" and then either press the enter key or click on the little + icon next to the input line to add this word to the list of texts this trigger fires on.
Now you type "kill bunny" in the field called command. Then click on the save icon to save the trigger and make sure the trigger is actually active (= blue checkbox icon is checked). When the trigger is active each time the word "bunny" will appear in the MUD output, your trigger will issue the command "kill bunny".
If you want to stop hunting bunnies, you can simply select the bunny trigger and then click on the padlock icon to deactivate the trigger.
The trigger will stop to fire until you re-enable it again via the padlock icon.

===== 1.10 Matching one unknown
You can also set up a trigger to gather the scimitars, gold or whatever the skeletons could carry around with them. Since we do not know what the loot is, we will need to set up a trigger to match the line and take whatever was dropped. Examples:
----
The skeleton drops ring.
The skeleton drops gold.
The skeleton drops scimitar.
----
+The skeleton drops_+ is the generic segment of the line, the loot itself varies. Thus, we need to tell the client to +take_+ whatever the skeleton dropped. We do this by setting up a so-called +regular expression+:

----
Perl Style Regular Expression: The skeleton drops (.*?)\.
Script: send("take " .. matches[2]);
----
The expression +(.*?)+ matches any characters that the client receives between +The skeleton drops_+ (NB: notice the blank at the end) and the full-stop. 
+matches[2]+ simply transfers _the first matched text fitting the search criterea_ into the output (matches[1] contains the entire matched text, matches[2] contains the first capture group. More on this in section two of the manual).

===== 1.11 Matching multiple unknowns
Now, let's try making a trigger that would gather the loot from anybody:
----
Perl Style Regular Expression: (.*?) drops (.*?).
Script:
send("take " .. matches[3])
----
In this case, any time somebody, or something, drops something else, or someone else, the client will pick it up. Note that we used +matches[3]+ instead of +matches[2]+ this time, in order to pick up the second match. If we used +matches[2]+, we'd end up picking up the skeleton's corpse.

===== 1.12 Matching known variants
If you're playing a MUD in English, you'll notice that these triggers probably won't work due to English syntax. Compare:
----
The skeleton drops apple.
The skeleton drops an apple.
----
Chances are that you'll see the later a little more often. If we used our old RegEx, the output would look something like this.
----
INPUT: The skeleton drops an apple.
OUTPUT: take an apple
----
Most MUDs can't handle determiners, such as articles (i.e. +a+, +an+, +the+) or quantifiers (e.g. +five+, +some+, +each+), in user-input. To match this line we could either create multiple triggers matching every possible article or a regular expression filtering out these words:
----
Perl Style Regular Expression: (.*?) drops (a|an|the|some|a couple of|a few|) (.*?).
Script: 
send("take " .. matches[4])
----
Once again, note that we're using the third match (+matches[4]+) this time.
NOTE: Certain other languages, with a morphology richer than that of English, might require a somewhat different approach. If you're stuck, and your MUD-adminitrators don't prohibit the use of triggers, try asking on the corresponding world's forums.

For more information, see the chapter Regular Expressions.

==== 1.13 explain basic regex characters (^, $, (\w+), (\d+) and .*) and how to use them properly.

==== Retrieving wildcards from triggers
Wildcards from triggers are stored in the _matches[]_ table. The first wildcard goes into _matches[1]_, second into _matches[2]_, and so on, for however many wildcards do you have in your trigger.

For example, you'd like to say outloud how much gold did you pick up from a slain monster. The message that you get when you pick up the gold is the following:
----
You pick up 16 gold.
----
A trigger that matches this pattern could be the following:
----
Perl Style Regular Expression: You pick up (\d+) gold
----
And in your code, the variables +matches[2]+ will contain the amount of gold you picked up (in this case, _16_). So now to say outloud how much gold did you loot, you can do the following:
----
Script: echo("I got " .. matches[2] " gold!")
----

===== More advanced example
Here's an example by Heiko, which makes you talk like Yoda:
----
Perl Style Regular Expression: say (\w+).*(\w*).*(.*)
Script:  command = "say "..matches[4].." "..matches[2].." "..matches[3]
----
What it does here is save the +first word+, the +second word+ and then the +rest of the text+ into wildcards. It then says +rest of the text+ first, then the +first word+ and then the +second word+.

==== 1.14 How to highlight words

To highlight something in Mudlet, you first use the `selectString()` function to select what you'd like to highlight, and then either the `fg` function to color the letters or `bg` to highlight the background of the letters. For example, the following code would highlight the word `pond` in a bluebackground and red letters:
The first parameter to selectString() is the text you want to select and the second parameter tells the function which occurence of the word in the current line you want to select i.e. the first, the second, the third etc.
-----
selectString( "pond", 1 )
fg( "red " )
bg( "blue" )
------
==== 1.15 Keybindings

Keybindings, or hotkeys, are in many respects very similar to aliases, however, instead of typing in what you want to be done, you simply hit a key (or combination of keys) and let the Mudlet do the work.

.Example - You don't drink tea, you sip it!
****
You're participating in an in-game tea sipping contest. The winner is the first person to sip an Earl Grey, should the quiz-master make a vague reference to a series of tubes, or a Ceylon Mint, if he begins talking about the specific theory of relativity. In order to give us a competitive advantage, we will define two keybindings:
****
----
HOTKEY: F1
EXPAND TO: sip earl grey

HOTKEY: F2
EXPAND TO: sip ceylon mint
----
Now you just have to listen, or rather read, carefully and hit either F1 or F2 to claim that prize.

Another practical use for keybindings would be creating a so-called "targeting system", which is especially useful for grinding down armies of pumpkin-men in MUDs without auto-attack. See the Variables chapter for further details.

==== 1.16 Timers

Timers, as the name suggests, can be used to execute a specific command at a certain time, after a certain time or once every so often.

.Example - Don't miss the training!
****
Your character can train in his attributes once every three hours. You could either try tracking this manually or add a trigger starting timer after each training. Once the three hours have passed, your character will conveniently say to himself that it is time to do a couple of push-ups.
****

== Multi Session Gameing
Mudlet lets you play several simultaneous MUD sessions. However, currently we have the restriction that you cannot use the same profile twice. Consequently, if you want to play three characters on the same MUD at the same time, you need to make 3 profiles with 3 different names e.g. ernie@avalon.de, bert@avalon.de etc.
Split Screen

Mudlet has a split screen. If you scroll up in the old text, the screen will split in two parts. The lower part will follow the MUD output while the upper part will stay focused on your scrolling. This way you can read easier through old passages without missing what is going on at the moment.

Split screen can be activated via the page up / page down keys or with the mouse wheel. Scrolling back to the end will close the split screen automatically. A click on the middle mouse button will close the split screen immediately. The size of the 2 parts of the split screen can be modidfied when dragging the seperator bar with the mouse.

== Command Line Auto-Completion, Tab-Completion and History

The command line offers Tab Completion (TAB key) and Autocompletion (cursor up key).
1. Tab completion searches the MUD output buffer for words matching the word that you are currently typing. This is useful if you have to type complicated long names. You only have to type the first letters and then press the tab key until the proposal is what you want.
2. Autocompletion tries to match your current typing with your command history. Example: If you typed the same command a while ago, you only have to start typing the first couple of letters and then press the cursor up key until the proposal matches the command that you want to use.
3. If you haven't started to type anything yet, you can browse through your command history with the cursur up and cursor down keys. However, if you have started typing pressing cursor up will result in autocompletion.
4. To get out of autocompletion you can press the ESC key any time.
Logging Output to HTML Log Files

Press on the little button with the blue folder with the green arrow icon on the lower right side of the screen next to the command line.

When you press on it again logging stops. Log files can be found at the mudlet home directory in your profile directory. The path is /.config/mudlet/profiles//logs On Linux this would be: /home/username/.config/mudlet/profiles/profilename/logs

On Windows the path prefix depends on your windows version and your language settings: On my system it's c:\Dokumente und Einstellungen\heiko\.config\mudlet\profiles\\logs. Log files have a file name similar to the autosaved profiles: date#time.html


== Buttons and Custom User Toolbars

Buttons are co



== Mudlet's Trigger Engine

=== Simple Trigger Matching

Type your trigger in the input line below the trigger conditions list box and then press add to add it to the list. You can edit an expression in the list by clicking on it and then edit it on the input line below. After your edit you have to press the return key to accept the changes.
After editing is finished your changes will only become permanent if you press on the save icon on the upper left. This is the same throughout the entire program. If you forget to save your current changes or new additions, they will be lost once you select to edit some other item.
Select the trigger type from the listbox below the expression line edit. Normal substring matching will do for most people and it is the fastest matching type available. 
****
Example: You want to trigger on the word "pond" in a line such as: "The frog swims in the pond. Plop." All you need to do is enter "pond" in the trigger expression input line and add it to the expression list. Then enter the command you like to send to the MUD if the trigger matches e.g. "drink water" and then you are done. The more advanced trigger types are explained below.
****

=== Simple Highlighter Triggers

If you want to highlight the word "pond" in the above example you have to add the following little Lua script to the script editor on the lower right side of the Script Editor window:
----
selectString( "pond", 1 )
fg( "red " )
bg( "blue" )
----

=== "AND" and "OR" Condition Triggers

AND -Triggers execute their respective command or script only if all conditions in their respective conditions expression list are fullfilled.
OR-Triggers execute when *any* one of their conditions is true.
To make OR-Triggers you simply have to add a few conditions to the conditions list e.g. in our example: "pond", "frog", "Plop". The trigger will now also execute on lines like this: "A frog is green" or "You hear a loud Plop!" However, it will not execute on "With a loud plop the frog dived into the water." because "plop" in the line is in lower case letters and your condition specified a "P" in upper case.
The simplest form of AND-Triggers in Mudlet are Trigger Chains or Filter Chains, whatever you'd like to call it.


=== Trigger Chains - Filter Chains

Imagine the following scenario: You want to collect some berries. You know that the room contains some berries if the room description contains the words "You see several sorts of berries." You make a new substring trigger for this line, but instead of chosing a regular trigger, you chose to add a new trigger group. Now you add "You see several sorts of berries." to the expression list of the trigger group. When adding condions to a trigger group, the trigger group turns from an organizational unit into a filter unit. From now on this folder is a filter and will only let data through that matches it's condition.
In our case this is exactly what we want, because we don't want to collect all sorts of berries, but we only want 2 particular kinds, namely, strawberries and blackberries. Now you add two regular triggers to our berry filter - one containing the condition: "strawberries" and the other one "blackberries". Then we add the commands to pick the particular kind of berry to both triggers.
Now what happens is that as soon as a room description reads "You see several sorts of berries." the filter will let the line containing the room description pass through to our two berry triggers and they will issue commands to pick berries. However, in any other situation the words "strawberries" and "blackberries" will *NOT* trigger - only in the above scenario when the filter parent's condition is met. This is a very nice way to solve complicated problems with a few easy filter chains. This example is trivial, but using filter chains will rapidly show you how formerly complicated things that could only be solved with very complicated regular expressions can be solved easily now with a couple of filter chains.


=== Multi-Line Triggers and Multi-Condition Triggers

Multi Condition Triggers are the most advanced feature of Mudlet's trigger engine. Like trigger chains or filter chains they are a form of AND-Triggers.
All conditions in the list must have matched within the specified margin of lines (delta), in order to trigger the script.
Normal triggers fire and run the script as soon as one of the conditions in the regex list is met i.e. if one of the regex/string matches match - or the Lua function condition return true, the trigger script is run.
In multiline triggers, however, each single regex/string/Lua function condition in the list has to have matched within the specified margin of lines at least once to trigger the script. The sequence of the conditions is binding. This means if the 10th regex on the regex list would be matched on the eleventh line after the match of the first line happened, the trigger will *NOT* run unless the margin of lines is set to 11. If condition #3 is true but currently #2 is waiting to be true, condition #3 is ignored and must be true again after condidtion #2 has been true.
Conditions can also be Lua Functions that return a boolean truth value. You can mix all types of condtions.

Example: Let's go back to our pond & frog example. We have explained the difference between AND-triggers and OR-triggers. If you have a room description consisting of 3 lines:
----
1. You see a pond
2. You see a frog.
3. The frog sits on a stone.
----
Every single one of these 3 lines will be fed into the trigger engine one after another. If we define an OR-trigger with a condition list consisting of 3 condition patterns:

condition #1 pattern = pond
condition #2 pattern = frog
condition #3 pattern = stone

Wheather or not a condition is found to be true *also* depends on another property, i.e. the *type* of the condition.
The condition type can be among others:
====
1. substring matching  -> the condition is true if the condition pattern is a substring of the output line from the MUD. In other words: If the pattern "pond" is contained in any line of output, the condition is true.
2. begin of line matching -> the condition is only true if the conditon pattern can be found at the beginning of a line from the MUD.
3. Perl regular expression -> the condition is true if the Perl regex pattern is matched. You'll find more information on Perl regex below.
====
In our example we chose condition type "substring" for all three condtions.
Consequently, the trigger will fire the command or script 3 times i. e. the trigger will execute on each line it is matched against because in every line at least one condition evaluates to true because the pattern is a substring of the line.
....
in line #1 we get: pond = true. 
in line #2 we get frog = true and 
in line #3 two conditions are true i.e. frog=true and stone = true
....
Because an OR-trigger fires on the first condition that is true and ignores the rest the trigger will only execute 3 times on these 3 lines although 4 conditions are true.

CAUTION: The multiline condition switch must be turned off to get an OR-trigger! If the multiline condition switch is turned on the trigger becomes and AND trigger which means that the trigger only fires if all conditions are true and fullfilled in the correct sequence. With OR-triggers the sequence is irrelevant.

To complicate matters, however, you don't want your trigger to fire 3 commands, because you want to use this room description as a whole to fire your trigger e. g. this pond is the only kind of ponds in the entire world that doesn't have poisoned water. So you want to make sure that you only drink water from a pond of this kind and from no other pond. Your solution is to use Multi Conditon Triggers. If you check the MCT checkbox this trigger will fire only once from now on - and only if all conditions are met i e. you can guarantee that you only drink water from a good pond because your drinking trigger is matching on the entire room description.


Sadly, there are many unfriendly people in this world and somebody goes around and poisons your good ponds. Consequently, you would want to examine the frog and find out if it is poisoned before drinking water from the pond. This is difficult because the villain is a mean magician who used illusion spells to make everything look like the good pond. To solve the problem you can now resort to Lua function conditions in the trigger condition list that perform certain check ups to put the current room description into a wider context e. g. check if you have been here before etc. This adds yet another level of complexity to your problem but this is a very powerful means to use the full potential of Mudlet's MCTs.

You can combine all forms of conditions with trigger chains, filters and Lua functions. Mudlet gives you relatively easy to use tools that require no programming background. However, these tools can evolve into complex powerful problem solving mechanisms if they are combined with each other thus enabling non-programmer users to solve problems that would need a profound programming background in other MUD clients.




=== Temporary Triggers (scripting only)

Temporary triggers are lightweight triggers that are tailored for typical scripting needs. These are only available via Lua scripting. They are not stored in profiles, but stay in memory as long as the program runs or until they are deleted (killTimer()).


=== Line Triggers (scripting only)

Line triggers trigger on a specified line in the future - or a sequence of lines - irrespective of the content of the line. This type of triggers can be very handy in scripting if you know what is coming e.g. you want to parse a table from the MUD, maps etc.


== The Timer Engine

Mudlet supports 3 different sort of timers:

======
1. Timers that fire repeatedly in a certain interval specified by the user.
2. Offset Timers are child timers of a parent timer and fire a single shot after a specified timeout after their parent firied its respective timeout. This interval is an offset to the interval of its parent timer. Example: parent timer fires every 30 seconds and by doing so kicks off 3 offset timers with an offset of 5 seconds each. Consequently, the 3 children fire 5 seconds after each time the parent timer fired. Offset timers differ visually from regular timers and are represented with a + icon for offset. Offset timers can be turned on and off by the user just like any other timer.
3. Temporary Timers that very useful for scripting. They behave like regular timers, but they are one shot only timers. Temporary timers can not be accessed from the GUI and are not saved in profiles.
======
[[headingAlias]]
== Alias
Alias are triggers that operate on user input. Mudlet uses hierarchically ordered powerful Perl regex expression alias.
We have explicitly chosen not to offer multi condition alias or the same trigger types the trigger engine offers because this would be way over the top and is simply not needed for alias expansion - although it should be noted that the processes are closely related, except that alias, i.e. input triggers operates on a different data stream, namely the user input stream, whereas triggers operate on the MUD output data stream.
We are talking a bit about what is going on behind the scenes, in order to make clear that alias and triggers are essentially the same thing. In Mudlet triggers and alias are treated the same way, work the same way and only differ in terms of complexity and the amount of features.

Now, how does it all work? When you enter a command on the keyboard and press enter or return, the text that you have typed in the command line will be forwarded to the alias unit, i. e. the input trigger unit. The text will be matched against all active alias in the hierarchy unless access to a branch is locked by the user or by a script.
For an input trigger to match the command text the same rules as explained above in the trigger section apply. However, to simplify matters there is only one alias type. As alias are not performance critical we could reduce the amount of trigger types to just Perl regex as this type can do it all and performance is no issue with alias as the amount of data is much less. Even if you type like a madman you'll never get close to sending the same amount of text to the MUD than the amount of text the MUD sends back to you.

What does it mean that a regex is true or "matched"? A trigger or an alias fires - or executes its commands/script - when the text matches the pattern of the trigger or alias. In most cases this means that the text contains the trigger/alias pattern. If the regex pattern is "reen" then a text "The green house" will match because "reen" is contained in the text. More complex regex patterns can also hold information on where in the text a certain pattern must occur in order to match. "^tj" only matches when the letters "tj" occur at the beginning of the text. Consequently, a text like "go tj" would not match.
Regex patterns can also capture data like numbers, sequences of letters, words etc. at certain positions in the text. This is very useful for MUD related scripting and this is why it is explained below.

Let's get back to alias. We start with a simple example. 
=====
We want Mudlet to send "put weapon in bag" whenever we type "pwb". Consequently, the pattern is "pwb" and as the task is so simple it's enough to enter "put weapon in bag" in the send field. Then we click on save to save the changes and activate the alias by clicking on the padlock icon.
Then we leave the trigger editor and test our new alias. After typing "pwb" and pressing return Mudlet will send the command "put weapon in bag" to the MUD.
======
Let's move on to a more complicated example that is needed very often. 
======
We want our script to automatically put the weapon in the correct bag as we have many bags and many weapons. The pattern stays the same. "^pwb" (the ^ at the beginning of the line means that the command starts with pwd and no other letter in front of this. If we define our pattern more clearly, the pattern will match less often. Without the ^ the alias script will always be run whenever there is the sequence of letters "pwd" in your commands. This may not always be what you want. This is why it's usually a good idea to define the pattern as closely as needed.)
Back to our task: The pattern is "^pwb". In our scripts we have defined variables several variables. "weapon" is the weapon we use and the variale "bag" is the name of the bag.

=======

== Exporting and Importing Profiles or Packages


Mudlet stores your profiles as XML files in your home directory under .config/mudlet/profiles/your_profile_name/current (note the leading dot).

The file name consists of the date and time, the profile was written to disc.
You can export packages of a trigger branch, alias branch, function key, scripts etc. by clicking on a folder in the tree of the particular item in question and then click on the export icon. You'll be asked to give a filename for your package. You can export arbitrarily complex structures by moving them into a folder. You cannot mix items at the moment. Importing packages is straight forward and fully automatic.
You can also import entire profiles as they are basically packages.


== Quick Lua syntax overview

Lua variables can be either a string or a number. They are whatever there were initially initialized with.
=== string concatenation, variable substitution)

----
a = "Jim"
b = "Tom"
c = 350
d = 1
-----
Then you can write: 

-----
e = c + d and e will equal 351
e = a .. b and e will equal "JimTom" note that you cant use a+b to concatenate string values. For this you must use ..
e = a .. c and e will equal "Jim350"
-----
Lua tables can basically be considered multidimensional arrays and dictionaries at the same time.
If we have the table matches, matches[1] is the first element, matches[n] the n-th element.
-----
a = "Tom"
matches[1] = "Betty"
b = matches[1]
c = a .. b and e will equal "TomBetty"
-----
To output a table you can use a conveniance function printTable( name ). This function is defined in LuaGlobal.lua and can be found in your home directory under ./mudlet (note the leading dot ) Profiles and mudlet_documentation.html are stored in this directory as well.

== Lua interface functions to Mudlet - or how do I access triggers, timers etc. from Lua scripts
How to get data from regex capture groups?
Regular expression capture groups (e.g. „(\d+)“ ) are passed on to Lua scripts as a Lua table matches.
To make use of this information inside Lua scripts, you need to specify the number of the capture group within the regex.

Example: You have (\d+) weapons and they are (?:(\b\w+\W+)+)

This regex contains 3 capture groups, but only the 2 green colored ones contain data as the red capture group is a non-capturing group. Consequently, your Lua script gets passed only 2 instead of 3 capture groups and matches[3] is undefined.

In your Lua script you may write following program in order to print the number and status of your weapons on the screen:

****
You have (\d+) weapons and they are (?:(\b\w+\W+)+)
****
----
number_of_weapons = matches[1]
status_of_weapons = matches[2]
notice = number_of_weapons .. status_of_weapons
echo( notice )
send( „put weapons in backpack“ )

-- the following 2 lines color the first capture
-- group red and the second group blue
-- see below for details

selectCaptureGroup( 1 )
setFgColor( 255,0,0 )

selectCaptureGroup( 2 )
setFgColor( 0,0,255 )
----

The best way is to use selectCaptureGroup( number ) to select the proper capture group and then perform your actions on it e.g. replace(), colorize etc. Note: Both selectCaptureGroup() and matches[n] start with group 1.

How to select all occurrences of "Tom" and colorize them?

You add a functon like this to a script conataining you main function definitions. Note that script items differ from all other "scripts" in triggers, timers, actions etc. because they require you to put your code in proper functions that can be called by your other trigger-scripts, timer-scripts etc. via normal function calls. Trigger-scripts, timer-scripts etc. cannot contain any function definitions because they are automatically generated functions themself because this makes usage a lot easier.

To come back to our question how to select all occurrences of "Tom" and colorize them:

----
function setBgColorAll( word, r, g, b )
    i = 0
    word_count = 1
    while i > -1 do
        i = selectString(word, word_count)
        if i == -1 then
             return
        end
        word_count = word_count +1
        setBgColor( r, g, b )
    end
end
-----
Then you simply define a substring matching trigger on the word "Tom" and in the trigger script you call above function:
----
setBgColorAll("Tom", 255,50,50)
-----

=== Sending commands to the MUD or printing information messages on the screen

To print information messages on the session screen you can use the echo( message ) function, or insertText( text). Currently, it only takes one string as argument.

To send a command to the MUD, you can use the send( command ) function. Note: everything you send via send() will be processed by the alias processing unit.
In Alias scripts the command that is being sent to the MUD is contained in the variable command that you can change in the context of Alias scripts.
Alias take regular expressions, as well. As a result, you can use following regex and script to talk like Yoda:
Perl regex:
----
say (\w+).*(\w*).*(.*)
----
script:
----
send( "say " .. matches[3] .." " .. matches[1] .." ".. matches[2] )
-----

Note: The variable "command" contains what was entered in the command line or issued via the expandAlias( ) function. If you use expandAlias( command ) inside an alias script the command would be doubled. You have to use send( ) inside an alias script to prevent recursion. This will send the data directly and bypass the alias expansion.


==== Changing text from the MUD or reformatting text (colorize, make bold etc.)

When sending commands to the MUD - from now on referred to as output stream - alias scripts find the command that whas issued by the user stored in the variable "command".

By manipulating the value, the command can easily be changed before it is being sent to the MUD.

However, things get much more complicated with the data received from the MUD – from now on referred to as input stream. Before triggers can be run on the MUD data Mudlet has to strip all format codes from the text and store it in data structures associated with the text. Consequently, the text that is being passed on to the trigger processing unit is a small subset of the data received from the MUD. If you want to edit, replace, delete or reformat text from within your trigger scripts you have to keep this in mind if you don't want to lose all text format information as colors etc.

As the text is linked with data structures containing the format of the text, the cursor position inside the line is important if data is being changed. You select a word or a sequence of characters from the line and then issue commands to do actions on the selected data.

Replacing the word "Tom" with "Betty" in the line: Jim, Tom and Lucy are learning a new spell. Could be done with following script:
----
selectString("Tom",1)
replace("Betty")
-----
Things get more complicated if there are two or more occurrences of "Tom" in the line e. g. Jim and Tom like magic. Jim, Tom and Lucy are learning a new spell.

The above example code would select the first occurrence of "Tom" in this line and ignore the second.
If you want to work on the the second occurrence of "Tom" you have to specify the occurrence number in the call to select().
-----
selectString( "Tom", 2 )
replace( "Betty" )
----

This code would change the second "Tom" and leave the first "Tom" alone. The function call

----
replaceAll( "Betty" )
-----

will replace all occurrences of "Tom" with "Betty" in the line if "Tom" has been selected before. ReplaceAll() is a conveniance function defined in LuaGlobal.lua.

Colorization example: You want to change to color of the words ugly monster to red on a white background.

You add a new trigger and define the regex: ugly monster
In the script you write:
-----
selectString("ugly monster", 1 )
setFgColor(255,0,0)
setBgColor(255,255,255)
-----

Another means to select text is to select a range of characters by specifying cursor positions.
If we have following line: Jim and Tom like magic. Jim, Tom and Lucy are learning a new spell.
----
selectSection( 28, 3 )
----
This example would select the second Tom. The first argument to selectSection is the cursor position within the line and the second argument is the length of the selection.
----
selectCaptureGroup( number )
----

=== Deleting Text - Gagging

This function selects the captureGroup number if you use Perl regular expressions containing capture groups. The first capture group starts with index 1.
----
deleteLine()
-----

This function deletes the current line - or any line where the cursor is currently placed. You can use repeated calls to this function to effectively erase the entire text buffer.
If you want to delete or gag certain words only, you can select the text that you want to delete and then replace it with an empty string e.g:

If you get this line form the MUD: "Mary and Tom walk to the diner."

-----
selectString( "Tom", 1 )
replace( "" );
-----
Then the output will be changed to: "Mary and walk to the diner."

=== Cursor Movement and Cursor Placement


moveCursor( windowName, x, y )
This will move the user cursor of window windowName to the absolute (x/y) coordinates in the text.

moveCursor( "main", 20, 3950 ) will move the cursor on the 20th character from the left on line number 3950.
To determine the current cursor position you can use getLineNumber() and getColumnNumber() as well as getLastLineNumber() to get the number of the last line in the text buffer. moveCursorEnd("main") will move the cursor of the main display to end of the buffer. This is always a new line of size 1 containing the character '\n'.

number_of_last_line_in_text = getLineCount()

returns the number of the last line of the text in the console buffer. This number will change as soon as a new '\n' is printed either by the user or

when a new line arrives from the MUD. All lines from the MUD are terminated with '\n' which is called line feed or the new line character. This control character ends the current line and move the cursor to the beginning of the next line, thus creating a new, empty line below the line that contains the '\n'.


line_number_of_the_current_cursor_position = getLineNumber()

column_number_of_the_current_cursor_position = getColumnNumber()

luaTable_containing_textlines = getLines( absolute_line_number_from, absolute_line_number_to )


this will return a Lua table containing all lines between the absolute positions from and to. NOTE: This function uses absolute line numbers, not relative ones like in moveCursor(). This little demo script shows you how to use cursor functions:

moveCursor() return true or false depending on wheather the move was possible.


User defined dockable windows


You may want to use dock windows to display information you gathered in your scripts, or you may want to use them as chat windows etc.
Adding a user defined window:


openUserWindow( string window_name )

echoUserWindow( string window_name, string text )

setWindowSize( int x, int y )

clearWindow( string window_name )


Dynamic Timers


tempTimer( double timout, string lua_code_to_execute, string/float/int timer_name )
disableTimer( name )
enableTimer( name )


== Dynamic Triggers


triggerID = tempTrigger( regex, code ) creates a fast substring matching trigger
triggerID = tempRegexTrigger( regex, code ) creates a regular expression matching trigger


== Registering Event Handlers and Raising Events


raiseEvent( string name, args )


== Handling Tables in Lua

Nick Gammon has written a very nice overview on how to deal with Lua tables. You can find it here: http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=6036.

[[example1]]
.How to use multilinematches[n][m]
(The following example can be tested on the MUD batmud.bat.org)

In the case of a multiline trigger with these 2 Perl regex as conditions:
----
^You have (\w+) (\w+) (\w+) (\w+)
^You are (\w+).*(\w+).*
----
The command "score" generates the following output on batMUD:
-----
You have an almost non-existent ability for avoiding hits.
You are irreproachably kind.
You have not completed any quests.
You are refreshed, hungry, very young and brave.
Conquer leads the human race.
Hp:295/295 Sp:132/132 Ep:182/181 Exp:269 >
----
If you add this script to the trigger:
----
showMultimatches();
----
The script, i.e. the call to the function showMultimatches() generates this output:
----
 -------------------------------------------------------
 The table multimatches[n][m] contains:
 -------------------------------------------------------
 regex 1 captured: (multimatches[1][1-n])
           key=1 value=You have not completed any quests
           key=2 value=not
           key=3 value=completed
           key=4 value=any
           key=5 value=quests
 regex 2 captured: (multimatches[2][1-n])
           key=1 value=You are refreshed, hungry, very young and brave
           key=2 value=refreshed
           key=3 value=young
           key=4 value=and
           key=5 value=brave
 -------------------------------------------------------
----
The function showMultimatches() prints out the content of the table multimatches[n][m].
You can now see what the table multimatches[][] contains in this case. The first trigger condition (=regex 1) got as the first full match "You have not completed any quests". This is stored in multimatches[1][1] as the value of key=1 in the sub-table matches[1] which, in turn, is the value of key=1 of the table multimatches[n][m].

The structure of the table multimatches: 

----
multimatches { 
                1 = {  
                       matches[1] of regex 1 
                       matches[2] of regex 1 
                       matches[3] of regex 1 
                              ...
                       matches[n] of regex 1 }, 
                2 = {  
                       matches[1] of regex 2 
                       matches[2] of regex 2
                             ...
                       matches[n] of regex 2 },
                 ...         ...
                n = { 
                       matches[1] of regex n
                       matches[2] of regex n
                             ...
                       matches[n] of regex n }
}
-----
The sub-table matches[n] is the same table matches[n] you get when you have a standard non-multiline trigger.
The value of the first key, i. e. matches[1], holds the first complete match of the regex. Subsequent keys hold the respective capture groups.
For example: 
Let regex = "You have (\d+) gold and (\d+) silver" and the text from the MUD = "You have 5 gold and 7 silver coins in your bag."
Then matches[1] contains "You have 5 gold and 7 silver", matches[2] = "5" and matches[3] = "7".
In your script you could do:
----
myGold = myGold + tonumber( matches[2] )
mySilver = mySilver + tonumber( matches[3] )
----
However, if you'd like to use this script in the context of a multiline trigger, matches[] would not be defined as there are more than one regex. 
You need to use multimatches[n][m] in multiline triggers. Above script would look like this if above regex would be the first regex in the multiline trigger:
----
myGold = myGold + tonumber( multimatches[1][2] );
mySilver = mySilver + tonumber( multimatches[1][3] );
----
What makes multiline triggers really shine is the ability to react to MUD output that is spread over multiple lines and only fire the action (=run the script) if all conditions have been fulfilled in the specified amount of lines. 







[[heading4]]
== Lua API
Mudlet defines several global Lua variables that are accessible from anywhere.

.Lua Variables
[width="100%",frame="topbot",options="header"]
|===================================================
|Variable Name|Description
|command|This variable holds the current user command. This is typically used in alias scripts.
|line|This variable holds the content of the current line as being processed by the trigger engine. The engine runs all triggers on each line as it arrives from the MUD.
|matches[n]|This Lua table is being used by Mudlet in the context of triggers that use Perl regular expressions. matches[1] holds the entire match, matches[2] holds the first capture group, matches[n] holds the n-th capture group. 

If the trigger uses the Perl style /g switch to evaluate *all* possible matches of the given regex within the current line, matches[n+1] will hold the second entire match, matches[n+2] the first capture group of the second match and matches[n+m] the m-th capture group of the second match.
|multimatches[n][m]|This table is being used by Mudlet in the context of multiline triggers that use Perl regular expression. It holds the table matches[n] as described above for each Perl regular expression based condition of the multiline trigger. multimatches[5][4] may hold the 4th capture group of the 5th regex in the multiline trigger. This way you can examine and process all relevant data within a single script. Have a look at this <>.
|===================================================

.Lua API
[width="100%",frame="topbot",options="header"]
|===================================================
|Function|Description
|clearUserWindow( window_name )|Clears the user window with the name given as argument.
|copy()|Copies the current selection to the clipboard. This function operates on rich text, i. e. the selected text including all its format codes like colors, fonts etc.
|cut()|Cuts the current selection and stores it in the clipboard. This text remains available in the clipboard until it gets overwritten by another cut or copy operation. This function works on rich text ( see copy() )
|deleteLine()|deletes the current Line under the user cursor. 
|*deselect()*|deselects the last selected text
|disableTimer( name )|Use timer name or the id returned by tempTimer() to identify the timer that you want to disable.
|disableTrigger( name )|Use trigger name or the id returned by tempTrigger() to identify the timer that you want to disable. 
|disableKey( name )|Uses trigger name as id or the id returned by tempTrigger()
|echo( text )|prints text to the main window
|echoUserWindow( window_name, text )|prints text to user dock window name
|enableTimer( name )|enables or activates a timer that was previously disabled. The parameter "name" expects the timer ID that was returned by tempTimer() on creation of the timer or the name of the timer in case of a GUI timer
|enableTrigger( name )|enables a Trigger. see enableTimer() for more details.
|enableKey( name )|enable key or key group "name"
|expandAlias( command )|like send(), but without bypassing alias expansion. This function may lead to infinite recursion if you are not careful. This function can be used to make recursive alias expansion.
|lineNumber = getLineNumber()|to get the absolute line number of the current user cursor
|number = getColumnNumber()|To get the absolute column number of the current user cursor
|number = getLineCount()|To get the absolute amount of lines in the current console buffer
|lua_table[relative_linenumber, content] = getLines( from_line_number, to_line_number )|Returns a section of the content of the screen text buffer. Absolute line numbers are used
|number_of_last_line = getLineCount()|number of the last line in the buffer
|insertText( string )|Insertion takes place at the current position of the user cursor or replaces the current selection. Use deselect() to unselect unwanted selections to prevent overwriting.
|killTimer( name )|Deletes a tempTimer. Use the Timer ID returned by tempTimer() as name parameter.
|killTrigger( name )|See killTimer()
|boolean = moveCursor( windowName, x, y )|Moves the user cursor of the window windowName to the absolute point (x,y). This function returns false if such a move is impossible e.g. the coordinates don't exist. To determine tha correct coordinates use getLineNumber(), getColumnNumber() and getLastLineNumber(). The trigger engine will always place the user cursor at the beginning of the current line before the script is run. Use "main" for the main window and the name you called your user window otherwise.
|moveCursorEnd( windowName )|Moves the cursor to the end of the buffer. "main" is the name of the main window, otherwise use the name of your user window.
|openUserWindow( name )|Opens a user dockable console window for user output e.g. statistics, chat etc. If a window of such a name already exists, nothing happens. You can move these windows, dock them, make them into notebook tabs or float them.
|paste()|pastes the previously copied or cut text including all format codes like color, font etc. at the current user cursor position. The copy(), cut() and paste() functions can be used to copy formated text from the main window to a user window without losing colors e. g. for chat windows, map windows etc.
|pasteWindow( name )|pastes the previously copied or cut rich text (including text formats like color etc.) into user window (dock window) name.
selectString( line, 1 )
cut()
pasteWindow( "chat" )
|raiseEvent( event_name, arg-1, ... arg-n )|Raises the event event_name. The event system will call the main function (the one that is called exactly like 
the script name) of all such scripts that have registered event handlers. If an event is raised, but no event handler scripts have been registered with 
the event system, the event is ignored and nothing happens. This is convenient as you can raise events in your triggers, timers, scripts etc. without 
having to care if the actual event handling has been implemented yet - or more specifically how it is implemented. Your triggers raise an event to 
tell the system that they have detected a certain condition to be true or that a certain event has happened. How - and if - the system is going 
to respond to this event is up to the system and your trigger scripts don't have to care about such details. 
For small systems it will be more convienient to use regular function calls instead of events, however, the more complicated your system will get, 
the more important events will become because they help reduce complexity very much.

The corresponding event handlers that listen to the events raised with raiseEvent() need to use the script name as function name and take the correct 
number of arguments. NOTE: If you raise an event with 5 arguments but your event handlers functions only take 2,10 or 0 arguments, the functions 
will not be called. For exmaple: raiseEvent("fight") a correct event handler function would be: myScript( event_name ). In this example raiseEvent 
uses minimal arguments, name the event name. There can only be one event handler function per script, but a script can still handle multiple events 
as the first argument is always the event name. So you can call your own special handlers for individual events. The reason behind this is that you 
should rather use many individual scripts instead of one huge script that has all your function code etc. Scripts can be organized very well in trees 
and thus help reduce complexity on large systems.
|replace( with )|replaces the selected text with "with". To delete text use replace("")
|replaceAll( what, with )|replaces all occurrences of what in the current line with with 
|int pos_begin_of_match_in_line = selectString( text, number_of_match ) or -1 on error|Selects a substring from the line where the user cursor is currently 
positioned. You can move the user cursor with moveCursor(). When a new line arrives from the MUD, the user cursor is positioned at the beginning of 
the line. However, if one of your trigger scripts moves the cursor around you need to take care of the cursor position yourself and make sure that 
the cursor is in the correct line if you want to call one of the select functions. 
NOTE: to prevent selection of random data use the error return if not found like this: "if selectString( "big monster", 1 ) > -1 then setFgColor( 255,0,0) end"
|boolean = selectSection( from, length_of_string )|Absolute column number for start of selection and length of selection
|selectCaptureGroup( groupNumber ) with first group = 0|Selects the content of the capture group number in your perl regular expression e.g. "you have (\d+) Euro". If you want to color the amount of money you have green you do: selectCaptureGroup(1); setFgColor(0,255,0)
|send( command )|This sends data directly to the socket layer, bypassing the alias expansion unit. If you want your command to be expanded by the alias unit, call expandAlias() instead.
|setBgColor( r,g,b )|Values are RGB: red, green, blue ranging from 0-255 e.g. for red: setFgColor(255,0,0)
|setFgColor( r, g, b )|Values are RGB: red, green, blue ranging from 0-255 e.g. for blue: setBgColor(0,0,255)
|timer_id = tempTimer( seconds, lua_code )|Creates a temporary single shot timer. You can use 2.3 seconds or 0.45 etc. After it has fired, the timer will be deactivated and killed.
|trigger_id = tempTrigger( string, lua_code )|creates a temporary trigger using substring matching. Contrary to tempTimers, tempTriggers live throughout the entire session unless they are explicitely disabled or killed. Disabled tempTimers can be reenabled with enableTrigger(). This is much faster than killing the trigger and creating a new one.
|trigger_id = tempLineTrigger( from, howMany, LuaCode )|Temporary trigger that will fire on n consecutive lines following the current line. This is useful 
to parse output that is known to arrive in a certain line margin or to delete unwanted output from the MUD. Example: tempLineTrigger( 1, 3, [[send("shout Help")]] ) will fire 3 times starting with the line from the MUD.
tempLineTrigger( 20, 2, [[send("shout Help")]] )
will fire 20 lines after the current line and fire twice on 2 consecutive lines.
|trigger_id = tempRegexTrigger( regex, lua_code )|temorary trigger using perl regex pattern matching
|userWindowLineWrap( window, boolean )|turns line wrap mode on or off in user dock windows
userWindowLineWrap( "chat", true ) turns on line wrap for window "chat"
|printTable( table_name )|Lua debug function that prints the content of a Lua table on the screen, split up in keys and values. Useful if you want to see what the capture groups contain i. e. the lua table "matches".
This function is defined in luaglobal.lua.
|showCaptureGroups()|Lua debug function that highlights all capture groups in your trigger regex on the screen. This is very handy if you make complex regex and want to see what really matches in the text. example: make a trigger with the regex (\w) and call this function in the trigger script. All words in the text will be highlighted in random colors. This function is defined in luaglobal.lua
|fg( "red" )|Sets the current foreground color to red. Check the luaglobal.lua file for the defined color names ( about 255) e.g. fg("green") will set the foreground color to green.
|bg( "blue" )|same as fg( color_name ) just for the background color.
|table.load( file, table )|restores a Lua table from a data file that has been saved with table.save()
|table.save( file, table )|saves the given table into the given file
|showCaptureGroups()|a debug function for building triggers: this function highlights all capture groups in random colors in the MUD output text online on the screen. You get more precise debug information on what captured what and when if you look at the debug console (->trigger editor->bug symbol)
|printTable( table )|another debug function that prints the content of a Lua table on the screen split in key and value.
|sendAll( what )|sends a list of commands to the MUD
|suffix( what )|prints "what" at the end of the line when used in a trigger script
|prefix( what )|prints "what" at the beginning of a line when used in a trigger script
|debug( arg1 ... argn )|prints out debug information to the user debug console
|function replaceWildcard(what, replacement)|Replaces the given wildcard (as a number) with the given text.

Example: replaceWildcard(1, "hello") on a trigger of `^You wave (goodbye)\.$`
|resetFormat() |resets the user character format to the default.
| |
|===================================================


mudlet-2.1/src/run-lua-code-v4.xml0000644000175000017500000000104412070466513016314 0ustar  csmallcsmall


    
        
            run lua code
            
            
            
            ^lua (.*)$
        
    

mudlet-2.1/src/dlgSourceEditorArea.cpp0000644000175000017500000000332611513237311017341 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

//#include 
//#include 

#include 

#include "dlgSourceEditorArea.h"
#include "THighlighter.h"

dlgSourceEditorArea::dlgSourceEditorArea(QWidget * pF) : QWidget(pF)
{
    // init generated dialog
    setupUi(this);
    highlighter = new THighlighter(editor->document());
    editor->setTabStopWidth(25);

}


mudlet-2.1/src/dlgOptionsAreaAction.cpp0000644000175000017500000000324111513237311017517 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn                                     *
 *   KoehnHeiko@googlemail.com                                             *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "TAction.h"
#include 

#include 

#include "dlgOptionsAreaAction.h"

dlgOptionsAreaAction::dlgOptionsAreaAction(QWidget * pF):QWidget(pF)
{
    // init generated dialog
    setupUi(this);
    
}


mudlet-2.1/src/ReadMe0000755000175000017500000000052611513237311014030 0ustar  csmallcsmallREAD THIS IN ORDER TO COMPILE THE Qt4 TEMPLATE
----------------------------------------------

Before compiling, check the Qt Options, go to 
Project->Project Options->C++ Support and open the Qt Options tab.

Check that the Qt installation directory is correct for the Qt version you've chosen.

------------------
Andreas Pakulat
July 2006
mudlet-2.1/src/EAction.h0000644000175000017500000000354011513237311014437 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef _eaction_h
#define _eaction_h
#include "mudlet.h"
#include "Host.h"
#include "TFlipButton.h"
#include 

class EAction : public QAction
{
Q_OBJECT
      
public:
        
                    EAction(QIcon &, QString &, mudlet * );
    QWidget *       createWidget( QWidget * );
    
    int             mID;
    Host *          mpHost;
    
public slots:

    void            slot_execute( bool checked );

signals:

    void            triggered( QAction * );
    
    
};

#endif

mudlet-2.1/src/dlgAboutDialog.cpp0000644000175000017500000000275211513237311016335 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008-2009 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "dlgAboutDialog.h"

dlgAboutDialog::dlgAboutDialog(QWidget * parent) : QDialog(parent)
{
    setupUi(this);
}

mudlet-2.1/src/TTreeWidget.h0000644000175000017500000000520211513237311015301 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008-2009 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef TTREE_WIDGET_H
#define TTREE_WIDGET_H

#include 
#include 

class Host;

class TTreeWidget : public QTreeWidget
{
Q_OBJECT
        
public:
        TTreeWidget( QWidget * pW );
    Qt::DropActions supportedDropActions() const;
    void dragEnterEvent( QDragEnterEvent * event );
    void dragMoveEvent( QDragMoveEvent * event );
    void dropEvent( QDropEvent * event );
    void startDrag( Qt::DropActions supportedActions ); 
    bool dropMimeData( QTreeWidgetItem * parent, int index, const QMimeData * data, Qt::DropAction action );
    void rowsAboutToBeRemoved ( const QModelIndex & parent, int start, int end );   
    void rowsInserted( const QModelIndex & parent, int start, int end );
    void setHost( Host * pH );
    void setIsScriptTree();
    void setIsTimerTree();
    void setIsTriggerTree();
    void setIsAliasTree();
    void setIsActionTree();
    void setIsKeyTree();
    void beginInsertRows ( const QModelIndex & parent, int first, int last );
    
private:
    
    bool mIsDropAction;
    Host * mpHost;
    int  mOldParentID;
    int  mChildID;
    bool mIsTriggerTree;
    bool mIsAliasTree;
    bool mIsScriptTree;
    bool mIsTimerTree;
    bool mIsKeyTree;
    bool mIsActionTree;
    
    
signals:
    
public slots:
    
};

#endif

mudlet-2.1/src/dlgColorTrigger.h0000644000175000017500000000437211513237311016212 0ustar  csmallcsmall#ifndef DLGCOLORTRIGGER_H
#define DLGCOLORTRIGGER_H
/***************************************************************************
 *   Copyright (C) 2008-2009 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include "ui_color_trigger.h"
#include 
#include "TTrigger.h"

class Host;
class TTrigger;

class dlgColorTrigger : public QDialog , public Ui::color_trigger_dlg
{
    Q_OBJECT

public:

    dlgColorTrigger( QWidget *, TTrigger *, int );
signals:


public slots:

    void setColorBlack();
    void setColorLightBlack();
    void setColorRed();
    void setColorLightRed();
    void setColorBlue();
    void setColorLightBlue();
    void setColorGreen();
    void setColorLightGreen();
    void setColorYellow();
    void setColorLightYellow();
    void setColorCyan();
    void setColorLightCyan();
    void setColorMagenta();
    void setColorLightMagenta();
    void setColorWhite();
    void setColorLightWhite();

    void slot_save_and_exit();

private:

    TTrigger * mpTrigger;
    int        mMode;

};

#endif // DLGCOLORTRIGGER_H
mudlet-2.1/src/HostManager.cpp0000644000175000017500000000571411624306130015664 0ustar  csmallcsmall#ifndef _HOSTMANAGER_CPP_
#define _HOSTMANAGER_CPP_

/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn                                     *
 *   KoehnHeiko@googlemail.com                                             *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include 
#include 
#include 
#include "HostManager.h"
#include "Host.h"
#include "HostPool.h"

HostManager * HostManager::_self = 0;

HostManager * HostManager::self()
{
    if( ! _self )
    {
        _self = new HostManager;
        _self->init();
    }
    return _self;
}

void HostManager::init()
{
    mpActiveHost = 0;
}

Host * HostManager::getHost( QString hostname )
{
    return mHostPool.getHost( hostname );
}

void HostManager::postIrcMessage( QString a, QString b, QString c )
{
    mHostPool.postIrcMessage( a, b, c );
}

bool HostManager::addHost( QString url, QString port, QString login, QString pass )
{
    bool ret = mHostPool.addNewHost( url, port, login, pass );
    //FIXME nur provisorisch bis ich multi host support fertig habe
    mpActiveHost = getFirstHost();
    return ret;
}


bool HostManager::deleteHost( QString url )
{
    return mHostPool.deleteHost( url );
}

bool HostManager::renameHost( QString url )
{
    return mHostPool.renameHost( url );
}

bool HostManager::serialize()
{
    QString directory = QDir::homePath()+"/.config/mudlet/profiles/";
    QDir dir;
    if( ! dir.exists( directory ) )
    {
        dir.mkpath( directory );
    }

    std::cout << "Mudlet is exiting now." << std::endl << "ordering all Hosts to shut down" << std::endl;

    mHostPool.orderShutDown();
    mHostPool.serialize( directory );

    std::cout << "mudlet: DONE" << std::endl << "Have a nice day :-)" << std::endl;
    return true;
}


#endif

mudlet-2.1/src/dlgKeysMainArea.h0000644000175000017500000000325011513237311016113 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef dlg_keys_main_area_h
#define dlg_keys_main_area_h

#include "ui_keybindings_main_area.h"
#include 


class dlgKeysMainArea : public QWidget , public Ui::keys_main_area
{
Q_OBJECT
        
public:
    
     dlgKeysMainArea( QWidget * );
    
signals:
    
    
public slots:
    
    
};

#endif



mudlet-2.1/src/XMLimport.h0000644000175000017500000000677012070466512015026 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008 by Heiko Koehn  ( KoehnHeiko@googlemail.com )      *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#ifndef XMLIMPORT_H
#define XMLIMPORT_H

#include 

#include "Host.h"

class Host;
class TTrigger;
class TTimer;
class TAlias;
class TAction;
class TScript;
class TKey;



class XMLimport : public QXmlStreamReader
{

public:
              XMLimport( Host * );

    bool      importPackage( QIODevice *device, QString packageName="", int module=0);

private:

    void      readPackage();
    void      readUnknownPackage();

    void      readHostPackage();
    void      readTriggerPackage();
    void      readTimerPackage();
    void      readAliasPackage();
    void      readActionPackage();
    void      readScriptPackage();
    void      readRooms();
    void      readKeyPackage();
    void      readUnknownMapElement();
    void      readMap();
    void      readRoom();
    void      readEnvColor();
    void      readEnvColors();
    void      readAreaNames();
    void      readAreas();
    void      readHelpPackage();

    void      readUnknownHostElement();
    void      readUnknownRoomElement();
    void      readUnknownTriggerElement();
    void      readUnknownTimerElement();
    void      readUnknownAliasElement();
    void      readUnknownActionElement();
    void      readUnknownScriptElement();
    void      readUnknownKeyElement();

    void      readHostPackage( Host * );
    void      readTriggerGroup( TTrigger * pParent );
    void      readTimerGroup( TTimer * pParent );
    void      readAliasGroup( TAlias * pParent );
    void      readActionGroup( TAction * pParent );
    void      readScriptGroup( TScript * pParent );
    void      readKeyGroup( TKey * pParent );


    void      readStringList( QStringList & );
    void      readIntegerList( QList & );
    void      readMapList( QMap & );
    //void      readMapList( QMap &);

    Host *    mpHost;
    QString   mPackageName;

    TTrigger * mpTrigger;
    TTimer * mpTimer;
    TAlias * mpAlias;
    TKey *   mpKey;
    TAction * mpAction;
    TScript * mpScript;

    bool gotTrigger;
    bool gotTimer;
    bool gotAlias;
    bool gotKey;
    bool gotAction;
    bool gotScript;
    int  module;
};

#endif // XMLIMPORT_H
mudlet-2.1/src/TLabel.cpp0000644000175000017500000000470211647202526014624 0ustar  csmallcsmall
/***************************************************************************
 *   Copyright (C) 2008-2009 by Heiko Koehn   *
 *   KoehnHeiko@googlemail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include "TLabel.h"
#include 

TLabel::TLabel( QWidget * pW )
: QLabel( pW )
, mpHost( 0 )
{
    setMouseTracking( true );
}

QString nothing = "";

void TLabel::mousePressEvent( QMouseEvent * event )
{
    if( event->button() == Qt::LeftButton )
    {
        if( mpHost )
        {
            mpHost->getLuaInterpreter()->callEventHandler( mScript, mpParameters );
        }
        event->accept();
        return;
    }

    QWidget::mousePressEvent( event );
}
/*
void TLabel::mouseMoveEvent( QMouseEvent * event )
{
    if (event->)
}*/

void TLabel::leaveEvent( QEvent * event )
{
    if (mLeave != ""){
        if( mpHost )
        {
            mpHost->getLuaInterpreter()->callEventHandler( mLeave, mLeaveParams );
        }
        event->accept();
        return;
    }
    QWidget::leaveEvent( event );
}

void TLabel::enterEvent( QEvent * event )
{
    if (mEnter != ""){
        if( mpHost )
        {
            mpHost->getLuaInterpreter()->callEventHandler( mEnter, mEnterParams );
        }
        event->accept();
        return;
    }
    QWidget::enterEvent( event );
}
mudlet-2.1/src/Host.h0000644000175000017500000003206012070466512014037 0ustar  csmallcsmall/***************************************************************************
 *   Copyright (C) 2008-2011 by Heiko Koehn (KoehnHeiko@googlemail.com)    *
 *                                                                         *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/



#ifndef _HOST_H_
#define _HOST_H_

class mudlet;
class TLuaInterpreter;


#include 
#include 
#include 
#include 
#include 
#include "ctelnet.h"
#include "TriggerUnit.h"
#include "TimerUnit.h"
#include "ScriptUnit.h"
#include "AliasUnit.h"
#include "ActionUnit.h"
#include "TLuaInterpreter.h"
#include 
#include 
#include 
#include "dlgTriggerEditor.h"
#include "TEvent.h"
#include "TKey.h"
#include "KeyUnit.h"
#include 
#include "TArea.h"
#include "TRoom.h"
#include "TMap.h"
#include 

class dlgTriggerEditor;
class TConsole;
class dlgNotepad;






class Host  : public QObject
{
    friend class XMLexport;
    friend class XMLimport;

public:

                       Host( int port, QString mHostName, QString login, QString pass, int host_id );

                       ~Host();
    QString            getName()                        { QMutexLocker locker(& mLock); return mHostName; }
    void               setName( QString s )             { QMutexLocker locker(& mLock); mHostName = s; }
    QString            getUrl()                         { QMutexLocker locker(& mLock); return mUrl; }
    void               setUrl( QString s )              { QMutexLocker locker(& mLock); mUrl = s; }
    QString            getUserDefinedName()             { QMutexLocker locker(& mLock); return mUserDefinedName; }
    void               setUserDefinedName( QString s )  { QMutexLocker locker(& mLock); mUserDefinedName = s; }
    int                getPort()                        { QMutexLocker locker(& mLock); return mPort; }
    void               setPort( int p )                 { QMutexLocker locker(& mLock); mPort = p; }
    QString &          getLogin()                       { QMutexLocker locker(& mLock); return mLogin; }
    void               setLogin( QString s )            { QMutexLocker locker(& mLock); mLogin = s; }
    QString &          getPass()                        { QMutexLocker locker(& mLock); return mPass; }
    void               setPass( QString s )             { QMutexLocker locker(& mLock); mPass = s; }
    int                getRetries()                     { QMutexLocker locker(& mLock); return mRetries;}
    void               setRetries( int c )              { QMutexLocker locker(& mLock); mRetries=c; }
    int                getTimeout()                     { QMutexLocker locker(& mLock); return mTimeout; }
    void               setTimeout( int seconds )        { QMutexLocker locker(& mLock); mTimeout=seconds; }
    bool               closingDown();
    void               assemblePath();
    int                check_for_mappingscript();
    void               orderShutDown();
    TriggerUnit *      getTriggerUnit()                 { return & mTriggerUnit; }
    TimerUnit *        getTimerUnit()                   { return & mTimerUnit; }
    AliasUnit *        getAliasUnit()                   { return & mAliasUnit; }
    ActionUnit *       getActionUnit()                  { return & mActionUnit; }
    KeyUnit *          getKeyUnit()                     { return & mKeyUnit; }
    ScriptUnit *       getScriptUnit()                  { return & mScriptUnit; }
    void               connectToServer();
    void               send( QString cmd, bool wantPrint = true, bool dontExpandAliases = false );
    void               sendRaw( QString s );
    int                getHostID() { QMutexLocker locker(& mLock); return mHostID; }
    void               setHostID( int id ) { QMutexLocker locker(& mLock); mHostID = id; }
    TLuaInterpreter *  getLuaInterpreter() { return & mLuaInterpreter; }
    void               incomingStreamProcessor( QString & paragraph, int line );
    void               postIrcMessage( QString, QString, QString );
    void               enableTimer( QString & );
    void               disableTimer( QString & );
    void               enableTrigger( QString & );
    void               disableTrigger( QString & );
    void               enableKey( QString & );
    void               disableKey( QString & );
    bool               killTimer( QString & );
    bool               killTrigger( QString & );
    double             stopStopWatch( int );
    bool               resetStopWatch( int );
    bool               startStopWatch( int );
    double             getStopWatchTime( int );
    int                createStopWatch();
    void               startSpeedWalk();
    //QStringList        getBufferTable( int, int );
    //QString            getBufferLine( int );
    bool               serialize();
    void               saveModules(int);
    void               reloadModule(QString moduleName);
    bool               blockScripts() { return mBlockScriptCompile; }

    void               setIsAutologin( bool b ){ mIsAutologin = b; }
    bool               isAutologin(){ return mIsAutologin; }
    void               setReplacementCommand( QString );
    void               registerEventHandler( QString, TScript * );
    void               registerAnonymousEventHandler( QString name, QString fun );
    void               unregisterEventHandler( QString, TScript * );
    void               raiseEvent( TEvent * event );
    void               resetProfile();
    void               callEventHandlers();
    void               stopAllTriggers();
    void               reenableAllTriggers();
    void               set_USE_IRE_DRIVER_BUGFIX( bool b ){ mUSE_IRE_DRIVER_BUGFIX = b; mTelnet.set_USE_IRE_DRIVER_BUGFIX( b ); }
    void               set_LF_ON_GA( bool b ){ mLF_ON_GA = b; mTelnet.set_LF_ON_GA( b ); }
    void               adjustNAWS();
    class              Exception_NoLogin{};
    class              Exception_NoConnectionAvailable{};

    bool               installPackage( QString, int module);
    bool               uninstallPackage( QString, int module);
    bool               removeDir( const QString dirName, QString originalPath);
    void               readPackageConfig( QString, QString & );

    cTelnet            mTelnet;
    TConsole *         mpConsole;
    TLuaInterpreter    mLuaInterpreter;
    TriggerUnit        mTriggerUnit;
    TimerUnit          mTimerUnit;
    ScriptUnit         mScriptUnit;
    AliasUnit          mAliasUnit;
    ActionUnit         mActionUnit;
    KeyUnit            mKeyUnit;

    int                commandLineMinimumHeight;
    bool               mAlertOnNewData;
    bool               mAllowToSendCommand;
    bool               mAutoClearCommandLineAfterSend;
    bool               mBlockScriptCompile;
    int                mBorderBottomHeight;
    int                mBorderLeftWidth;
    int                mBorderRightWidth;
    int                mBorderTopHeight;
    QString            mBufferIncomingData;
    bool               mCodeCompletion;
    QFont              mCommandLineFont;
    QString            mCommandSeparator;
    QString            mCommandSeperator;
    bool               mDisableAutoCompletion;
    QFont              mDisplayFont;
    bool               mEnableGMCP;
    int                mEncoding;
    QTextStream        mErrorLogStream;
    QFile              mErrorLogFile;
    QMap > mEventHandlerMap;
    QMap mEventMap;
    bool               mFORCE_GA_OFF;
    bool               mFORCE_NO_COMPRESSION;
    bool               mFORCE_SAVE_ON_EXIT;
    int                mHostID;
    QString            mHostName;
    bool               mInsertedMissingLF;
    bool               mIsAutologin;
    bool               mIsGoingDown;
    bool               mIsProfileLoadingSequence;

    bool               mIsClosingDown;
    bool               mLF_ON_GA;
    QString            mLine;
    QMutex             mLock;
    QString            mLogin;
    int                mMainIconSize;
    QString            mMudOutputBuffer;
    int                mMXPMode;
    bool               mNoAntiAlias;

    QString            mPass;
    dlgTriggerEditor * mpEditorDialog;
    TMap *             mpMap;
    dlgNotepad *       mpNotePad;
    QStringList        mParagraphList;

    int                mPort;
    bool               mPrintCommand;
    QString            mPrompt;
    bool               mRawStreamDump;
    QString            mReplacementCommand;
    QString            mRest;
    bool               mResetProfile;
    int                mRetries;
    bool               mSaveProfileOnExit;
    int                mScreenHeight;
    int                mScreenWidth;
    bool               mShowToolbar;
    int                mTEFolderIconSize;
    QStringList        mTextBufferList;

    int                mTimeout;

    QString            mUrl;

    bool               mUSE_FORCE_LF_AFTER_PROMPT;
    bool               mUSE_IRE_DRIVER_BUGFIX;
    bool               mUSE_UNIX_EOL;
    QString            mUserDefinedName;
    int                mWrapAt;
    int                mWrapIndentCount;

    QColor             mBlack;
    QColor             mLightBlack;
    QColor             mRed;
    QColor             mLightRed;
    QColor             mLightGreen;
    QColor             mGreen;
    QColor             mLightBlue;
    QColor             mBlue;
    QColor             mLightYellow;
    QColor             mYellow;
    QColor             mLightCyan;
    QColor             mCyan;
    QColor             mLightMagenta;
    QColor             mMagenta;
    QColor             mLightWhite;
    QColor             mWhite;
    QColor             mFgColor;
    QColor             mBgColor;
    QColor             mCommandBgColor;
    QColor             mCommandFgColor;

    QMap    mStopWatchMap;

    QColor             mBlack_2;
    QColor             mLightBlack_2;
    QColor             mRed_2;
    QColor             mLightRed_2;
    QColor             mLightGreen_2;
    QColor             mGreen_2;
    QColor             mLightBlue_2;
    QColor             mBlue_2;
    QColor             mLightYellow_2;
    QColor             mYellow_2;
    QColor             mLightCyan_2;
    QColor             mCyan_2;
    QColor             mLightMagenta_2;
    QColor             mMagenta_2;
    QColor             mLightWhite_2;
    QColor             mWhite_2;
    QColor             mFgColor_2;
    QColor             mBgColor_2;
    bool               mMapStrongHighlight;
    QStringList        mGMCP_merge_table_keys;
    QMap mAnonymousEventHandlerFunctions;
    QString            mSpellDic;
    bool               mLogStatus;
    bool               mEnableSpellCheck;
    QString            mIRCNick;
    QStringList        mInstalledPackages;
    QMap mInstalledModules;
    QMap mModulePriorities;
    QMap modulesToWrite;
    QMap > moduleHelp;
    QStringList        mActiveModules;
    bool               mModuleSaveBlock;

    void               showUnpackingProgress( QString  txt );
    QDialog *          mpUnzipDialog;
    QPushButton *      uninstallButton;
    QListWidget *      packageList;
    QListWidget *                 moduleList;
    QPushButton *                 moduleUninstallButton;
    QPushButton *                 moduleInstallButton;
    double             mLineSize;
    double             mRoomSize;
    bool               mShowInfo;
    bool               mBubbleMode;
    bool               mShowRoomID;
    bool               mShowPanel;
    int                mServerGUI_Package_version;
    QString            mServerGUI_Package_name;
    bool               mAcceptServerGUI;
    QColor             mCommandLineFgColor;
    QColor             mCommandLineBgColor;
    bool               mMapperUseAntiAlias;
    bool               mFORCE_MXP_NEGOTIATION_OFF;
    bool               mHaveMapperScript;

private:
    Host();




};
#endif


mudlet-2.1/src/vyzor.mpackage0000644000175000017500000141366512070466513015654 0ustar  csmallcsmallPK
W@base/PKB~A@4VHbase/frame.lua]D9VAUc
R9bv.ۙݝ];v(_y%=3uS?~zT=Bjv-86:ߨ,@:-Bm(WZ={R%<1'v[I6(*zTƹ%;L_

 K|SYZ4Ixx1}8lR0O@v`4f1G )[!aHwqAӃHdڍX72S3`(?lq1᧸c@T	_"R~19c] a]h3<4S5SFD};%,9atPnCϮ_]*JC|;OiyމL$:l2`vjjG1szmϖ}8BY(Pǧs

oȇ1LBYSg9X̜!<LǶ>%hQaIm}դlvs2&c<_`*=0»̢
sn$`Q楲f:qV	t(pz('mRn;+Jлtѹ4>y8R8z%J>Vz+"j$t[TǾkrx)]VJHq&[
y!*M3v5$iRUދ,IÐ|árxO
.i/*lgb49?YNтZR}Sb|su)!]8U1sP-2r.I45aH%Q@bh[R(8.!6b@νʐVEtaNtΨOR/
FT\6}k)xV:sһ=B_kΌh}'& %|ߎTs[:JAj\#NNy1ygX-=7hTT)yǞlBš!E͸RQ5(~GQC!6>E$+Ʈ&@A$J<(L^0.Q0 vd+S>vP*N#J\+}|%A0&3xoɽ]R4&hk
tm3Vc D",00->w.aJ	k_ҿ,;	*BWTh!pB3ي,J{hI(ۧt0`>:Ns?8#sSr,e7N#
${\f^O
$r:DljC(x0ƒ1'gA=#֨$TǚJ&0Ow|֞ICқZ{@9cu@$,ugrabO*'7N1vWw
4Ը?2HΦGPr>s]F%&ͬ"'c!J( I>ed:$SvJfcLV9z^{*8CEj%jcRF*mvQ7ev)AµiI9ze>sj.(3D%*V?$!)ԀVs-5
\ư0M1m716_IHTJ*S	WgcֻOsbǸRj~8*uİ;=,O6J
z]dh-e[6:lwWZrl9@Z;<6q3)n骄A7k!d>&";JiWnYf9$h; 745v>Q̎dѝ"&[)Պ?zd27mgқES`k.;T&0⸮]T'`U	Lؓ\cS/  
DȻ2fsmv߽Cx~]y`s{Aϝ{vy9ĺ2-w∗=g)e&l~n,e(\ct0]_$n\.dIvm0z!+wK཮`ny\CO]B
\` 	6J,4;؟>1}
6~8D-O#U.7:cOޣYta6#LJȦ1 h5^ccL\f*x~9b"}%[1+򆏴0mnq%le.9W2Qi/7H9[e\B|J}Mf`I
}Xkj8n~ϾZTq!:U,k]L
wNc|s]YǼ|5iĕY
ާ:gPVcQg<6#%k>ru`;y[bx`rѶ̂oyU=]J]{u-:A4\;̡d_:7y'Wb[Br30G_l	%GD㰑Xկt	bS,}v
%f_jɲ-PݜUX0`aB@_UV&a?{eѥ0
dظθP%@pmTNT{@y Z5-%F$K_WLq\lhWր2ZB_+&m>F.FO&IEy{>׸-}'
ȽȦ.yQWTUBxtY)L]8P}>+3Y[9d:^5v'i+Ag0Vx4T9dA#ψy&v#뎪0,s=ugP2P_qri՟gY2d:q1XfvD~@PKА~A`*f	base/hud.luaYY0~f/G"q%n9ۚM8-og9ڥ=瞱sxaxXq4i@)P3$;=	3CL~]Ew8:q6ǝq4UJ[lE,^Rs7,nL҃ZrVkN|@AS6ت
-\ThXs;^X9ۙ4gt
N+NyKtZ2L00ChXMmYi68
OقфJ@E05L;\oV+Skx_OBO	)~MDn7xn+'m["Ub.L+((ޥ#2DĊA@G9$,Y$a	!#8LS	~s8a+ĉMp)9'pQpg`7mPxg"v^|%5ɿ;	+Bڙ°hKIO&?jFX76r['j-+~Գ3ԑ^EP{!=}P=ޜ_8Nfb7qڗWx	4VGQEPyvh4%cBMzi	JB.wtɢH̎.{{:SǞjd>[q+Vl4mB8<#ƢbS#RэWY$ɚ]IJ{^vl5Q7µ?A4%PKe@eZbase/options.luaXYo1~JDlQ$nJ*l6T~;㱽WR]s}+99/_R%=MTpV7Gx\t]xx>rc#Ę皧P)
03g/!s>̘ejՓKܑTӇ~lGGŎQ;XS{S((dT16}8_!sr&4w>6`"7:0/$h0ZiJuR>aEfbT*rdd 2I~o[p7eXE8x$'!0p9א5W"yӜ.hOu ~\%t	^mM'
QKB/,k"8+(f,؎D?%m5fʑK"bv_[m;TZYadܶ^3vVNWX%f9q{
	䄲IhSJCvhҔ3qE|r;ݖ=[:AMu{kXS*o`U>*,qCUDf9e>\/=\:t5eWR[IIBŋa9N}#MH	7^:
	ނn5yLI;o'
yh'eǶ'
'
>WXZu`^	ei],Jf61N󫾽NSr#(i,C,X_\N|LcCM[4Ob!X_xk9H@>ƦJ-opZqENg#;lLPyz
{v-[ۅh6˘L;{%R3ۏ+{]Y;%
tԑYwMMTeoEl,Aۚ^k7]F-p÷qPj^&S`|i.ӏwM`uY~+F*
>{Q7	iZh,e#P붟wC`x	TEۿkg{2o*s r?nM͝gB0ڎq|ePT5l޶i=*	jģUl8e
ܺb'0PK
a@
component/PKGe@Rɇcomponent/background.luaWmo0J"D*J0^T7Cim$FAwl'vҕubƾ=wt0&oxrPN?Cfcmk:*J)*#k)Э"M2xHAp`!m4Ǎkg_+5ey9!3>>%
=t~/8)c$^D[IHu,r{78dc9t\*Q1욶H6L1!csfi+V0Hztu05&w+	7G%E)HLrX'UC*c&6ҧT%rsgӿT"l~ɥ=!X)O$b޵Pq8lXPe|E"	{J4;"5>(6wN-:}sТzE%r:~ɃY~{$E-=KbEsj+NjY_wo9ӑyT{!rʢZ1Hź\3fyͥAYDpB^qԹ*&
VX^٪L/JcaK-Yj]|&M{aB*vL%QAjan,$7G/#\>g=M'|YW/*_>Us-	tj
Ey_`:	jX/C2j| 9M-3^
g?tZ1-8^OA_}׵/Bqֺ-kSwf
/e4TmnB4wbzCGnܽdSƻ	Vw%	()aB	}/vݱP64di)Ghg}**fmW[)s'|DXPv|]wϚPn݉7eMYBywٽSB7Zv;OWD42g3?M~z$%"
]iޅnZ"Cuf#|zPK
@1Xcomponent/border.luaXYo@~NU9TD9*rMuJ@ۙ|$i }H׻3||Y"&ߐT@9V/#r`UIy˦4'u'ReB*s*ZLiw@Ӭ 2I`0xB^3AR{L`8bdؔ/*^R%-8Д~`O7Pg"):+]䱕לhwvLCN@Sj
lpKB!͌xPSoO}ׁ|Sd)-o8;4-5kI6]VC`NEl.kE
؃K*NlOV))cl_"4R%P6k!4UEp_Av:>u`]@De+p2SKrx8>qZ6Ôtuk}֛&d0VpIsSڔHB7"S0d0!SrSc۽F6yFdU0V\4?x}Og;\zubbb-g.DgT?b4B8!nFuQoQ%3h8O6/2g_-g%aUƄ/i L#`aV.CK9{eSacs*My_dYْ3@|/3̭}Qޞ4Z,m+5=+Wu^6Mͷ̊Z-V
t_AA2ǟ
R\7JC0Izh(m~çb33^^;WC\axVZA1g'?bm!3F|LM]'7znLYx#]?V%Qs~oO#JVX[sk6I[\{i 6{?.a,ُJ
p7\'oUBf|VA_jGlޣ?Zax+m138;GV;{\9
?;஝bcoJEbmͩzs.w];䵙{Xk6oQbcZ 34OVPKC@r̖>Fcomponent/border_side.luaWmo0bM}ƦUڗCU!Cx
1vlΉ]:>@b=soJ13͕f$jrl0gO>cob_Ҡ9	˳Rg,m೴vDj
3*3)8z^7U3WtLbпvj)L􇥙zj7)X7lE)LG=	ʩ3r/.z<20y#28jVl^^zi>>qXϬ1č>]5Su{sdP+jM͙)AE*yf>P l
iLTYVwC;6-Gum6g3+UɈsKro!!蜺r"fj0H,RD^$I1KJн@E	m"CeEQ @g1f&i,su3W6re,*Ԉʧ*q4PǕ;UO
bfcDkSC8wiTabÌk5&D8u5lY\~[4 mBX4
ΖҰFa0^Vʭɨlw~,_'܊Œv9f0b

@e.6A*R?94D,o߼(CCUKв
2uNJďY믏946"\!¹on?j=#Fރ2-`5NuEG(Y㓞)[4B;wPSTB< 8+zn7޳O@&z+Ej0B|/%P5K龳lOO(Z8/'I	&Jyl'ݗv\Dp}7]
t6^S$?Bx+\kE/W7
s૖h:o^	c5[ᵤƸSy7d@R.7NE%Q4䖵RoO%{*%?e{zrQyga/.C.AnjguoGoJl5p
¶K[c;q7}#myZa +1[p~T}[uRKc[n;`g:O]PKe@x(component/brush.luaTMo@=ےÈKmɘ6G+UQ!1twJ,$m`f{fp6L^QLHu:
	p!V
qwGA{FB@/Wиpn1YhGzeD++̄:QYFa#B!ApLb#7+)3yװhFȱP2b$N٥,j\X9@L}wES(ùlՂ~q8*(\d-WSmIN	j0'$+-JǵIׅ,Q3\S-ɄQ11u@;nIR{{NTu+>3^wJ3-0i
{rBWtcfç˜vq{hj.񮁠sV6-~BW-k͚/v+~V\Kzf_]E#%j8^2䄫xz"LW7zӠZ Zd;j+XK^{3#=+WZƐש}POJŮk}~4~WJȶ^ͶBe?LE1ptr'IBsAjbE9.b.F3Ι5;=`7w%
m6
];yH.Z ZC8h:65$PKe@PRcomponent/color.luaWYo@~vQ‘\
Dm%(DKU[{[8] #s}\ۃQ>sQT07i!pgUT<3&c8z^+|M,L)S`2	o?Aa̘zrxx{{W5jF%2YCtJDυ'&W2
Q1CEΫT¦,E-؋\^Y!XxjQW,M<L=@C"@5F5JyKP/21X2}5lK%&9T%g&(SxsHSrT8вJP"<>xTy/FoX873L?1
BLȑx][NAC#b*H|*0&aˆqLqμ.D_6yUZ4ϨeGfM/W'1WpA°rۀ(GDH8yL>cT|!T^,Qu<:aUp*hRH\y:Y͛Hy=Z6l3qE&UŊi$(^>F,.DGN4WRNDQg&$) OǬßr+\߳J+whۍ@
۞dhն)fee+[1X6V%+l|,Τ4V)eoUe)Qt7u.:nzW6	rYh{ɱ^A{ی`Uc@!xw?,68@H3G='܋	xDCkW[)E۔mHجR>)db5Tk;}PpUHmL.
x	ץ
w,FJ~I#v~Ǟ)B۫{[\de90O~uJktu=mr݉>vi,7\G{J[k{-]4f\пx"K*dz
C~}K@KMyd񜈎涳BhB]pშ8^նhCƾU;|Uwv+6_5aqh0Ek߸PK@2component/font.luaVێ0}!U
mH/RZoEYG q[BZfļT>	|co!9q3*%}E!s`O_0--LHP؂A\զV-Pt$qe a)|Xs&EA4tLV]$bݫmstK9ccK&Cn}T8 !ǝ1g(qHsP[KJ|]Σ@z&s_kݹ{_rZ*NURq4ragvrx'u5\s@7+RQ)AY"Z^l"((\Q\5 hndM(uR7	yb"Qvyd%ŸӧX	KS䄓;{1ܿ;^J$2::3n$!Ճ0}SS7=?AL?}'+v<@UjPfD}jM͖cq5rߢ5N$/UYdj*֍09cɇ=>J]a9xvԴI/;y"6pŊec^y-3]ʪ΂[!M*ҳUel%QcuMpG3	~;FHaWm]Rٗ(wG3lDĸ"Ĥ~i$/
[b4VnMS}Uk^
ǫَٛ:^1\&4lڳ yg?PK֩@	Nwcomponent/gradient.luaX0ݕFC(bϪZIxwf9mmߌ=u>W3ç38XJ
Ly'³,Z,#w&Sxx'UU^HFP1:+	g!qu6ol6AHVH^ޮ5m4;>:>JH$T	Z(-p8r^JXԞg1˴XZiF-6&\Gg0&lݠd\.T*
VXYwlN	/lN|8iflCH"(sY,b&bX`=cՊU,B5"% ٚFz-n-]lAXK
ˉ~)^NydT@8,mbF|xƏmBiS{9E%F|ƇEߪ%"8*"]&>Ir!H
ZJlnLNp#0	dC1n+@.u1b-R:2v1H
&"Ŧ&L9bp1GJnbQ%XQ1<7cxA-JN @][Š>Hm`"rԡ~/mS	zuQx340>g3aG3aprN-Ik
?H?0O,0@9&@X|lkZ%.٬AD%7bdDkQm9tH`aO=pM\p-l
˚BضD>p+^V|[ؼ :?xb"tė}nN$#2Ra\ŵɌf' @fECuIoQJ잦rDFۋv5a&ewG"|"Y-Y$kus.b]D߽a`WCbASj.?IXg8Qܲ(yA.U۽PKj@component/hover.luaWY0~nQm8Ҳ˵KmM`;-ΌKyhxo!|]&ٌ+
.4FX+1%}xcx5|mUފKS(e̜śϐ9qluSV(/p%/U£\xMuڝv',gLs8ſB^wIFvVGNu1cx/s>k`N	,\riNk'IRw]օ-'FUh)+c!'!
C8&|
AnrpHrim}aD.YY)t.([2V7n}l]Rhkz$N19[
'E^j>l]%9C5Xrͽ=}JS
->zXRlCH7`ն5''lJipu${a2F%OL(܁5W27F貜uvc83/
C4ai
iY`{0thiH-GeuR1:`k
:k?9BJ#2VD	9Auscq
^qR0xZ)\
uѷ6F{m>_@$OuÓk6աa0a"$#_Ke
n޳5]|
k6!֨VcN#[h-*"
V5'&%0#F^ÊSFLY=J:p&kwTMF^g_6gAǰwS8vn>eűeOa8|,ηUHc=."ߥ} ``Z: H?0?<)}~%py@`Er?
u-kIkFl3}=m~{#uEF.W5%oݠZrw[
؀Z3^Mi'ޏes0;K
c]ܚ,v>hD'tyiͅ
p^j+~\c}nS۪鿝@~td~ş`dF kLU]kR}:'Ev$pc+286t԰>m\57c\ޘcah^#\cwGh!W%+/~,YVZNXRPoͦU
>C:|bNUjTȯ9})q|oPK;(@<K
component/image.luaVm@BP[Hsx-|
"RͶ]Mwj3I/^9dv^gf6|46Sx)XK+ceؔ{ܻZ
Hcj)9T:G~#tEgevqRS≩RƮ/jMwfn[(p:1XRVM٦<ðѻ*Zop*uMEFϽnq!`ŲD2,}[viK>SzU'糓(F;o76-wty#J/(re,3BR,߀Y1UbOȅBub3!wxFi\>\&~
+G\Q<'}eu'PJ/2+dAZ?/Pb16+7ilqr±Kk;5ޝ6)3xdȵ6ʵbyS5;=%=W5տ~\JtSrwBi"Ӵ%:x:ʦ#S ؘC:3I=c!fBu޳nRx.c]+UVaVGt< S[&]lM]mTwxC`ƬɁ4%Ϟ C=,_bM W),)pC(h-G9ZVb3m$j"Z 
PϨ~<
Ώ{cMéd(!JFV&K`+r	UD7VamwbwOAp=<8z76tkDA6)ae
0cgM<WOx.B#qCҺK%G:ZZaupbSI9@f&kMXCxTdumxoNW ?7=a>nY4VpR!F[&4	0="i]_׭1lYDl}ô>MXqBPKˆ@e5component/map.luaX[0~ޤ681$ qۄԭ(IIsVI6
#9vd׮ww!gS7\5SP؏G4Vj3-TFfS'3zafLj+-rN80SWRM3:AΨ1pl	㱦W.,{ҥ=Lu(>135|&(2Y͈}}s;63\\9y(.1z:뜥㘀,C߰ -f'5TgjŐydrA'DJc>'L,I(ncB$ mTËByZhk%\ӕCVXA	StYvb%4VPn`19YÒQZVJlnsƍKjvnNJ	֭lWRV֌GڱU7c}50nǠ?'.sڄ
khtRjC匈}NAqaΚ
\E̬'|X}AXeĂZi6<-Y}ŞkWUiffޖv?غPK-(@Acomponent/margin.luaVmkA|! &ph
#X߾PIxٍ{;;4(~hnfvg^cvuM
_PbI5+{dR\,=xx9i,PYAf-N}2sg:L.//3&L6I:{.D	/Ex
Tppf$Ȋ{RX}ޓW8
-(VkPߛNZq0h)r[@ZYgiKJ>
#VcgYcxN[zZfTN(%+jƎ?
^{?G3TVl9m=
$}nPxE-ҰSMyFvd3]'䅉0¿
/:!= ڭS	xq9kv;u'm:Y[tm(-i'dH=`7PK@-
-component/mini_console.luaZ0.`!!Z(eHlXb#*4&qh9Î34e?/ޔ?R='2T'E+sIRGWF|eqOG_seL(PIBQ$!0+%%&@r?|8ybt'y~]>
h[lPKe:q=D%"XotL@*"6"EXDE-YYU#"ՋY .Uu8}[i,݉QT`X#dK
mɩW0VM؊;E#x
Jɿ. V(g6G6G/):d-aFm
f05thV҈uVE_2Zb|#rzaaИ`ijO_T`{LjmK(J)r(٬T"d1)XxZ?)_wχTt ꦴsY̓mF-[{r0C].먇mɔ]\gd2Ml/x&0@K-Gh}}-3X`&bwHON%r+Asܗ,-Eu|fRv̢}]=⸖ENL8mٲ૓}&3p0?GKBD	Vc~#<$lTvr.,q|*̩W$ФUKyjPZS
DV!8с;ZWV9Vv4{su84^?s1IvnMqqvs䑯b^~Nl儨U^-%_=JPK
z.As7o>.C=Z΍/*\ K7W|AzUBG5o,<[,Zκzğ:X+/Mjd\$	gp+Fjl
S$%7@V+>mx^\TR RⓁN3XGSd<-$n^(X';;- ;UEPi;IWoV1,ӿ׊pDv3RWc1ߋ0]<QS?3ʑʹ5Aooa(Jj7Ma?[
&ZT*k㈑PWk7D͒wyQnb#l{
UMcߵGA/ƶiҋ%Qs~M/TK'jJ]VC[qxQKTFW@M%*p/˳e
*ؠ`r-Ɓr
7ظc5msLvZmK~<-EjggU/v;F/w,0ݠ赹˼!8a
mռ5Σ#ӇQ_6:;@q߯=*w-6C\EW9	WRwU'Sp@x~|~#$5NXe
%m+8t>
l"7Wȋ|C5ln;
nඵv^]PA셪Wv#Ou]F*~Y:ٟR+DS|h|1s4=zI/{;)
Rq9hC(A8ݢ=b+d}`t0(A^ÂN	t92U>k`(e%Vr&jaTtPJh	7{
g
@5U<Vqd,gҎOƒy<
ަqB3@~.`EߤUR|1an	
1"9NJ/@d0;gЯ\JcQ@Ŋ]Ig2$sl^dpc5vb=>R$@d2VIb; ˬ;t=Fq7*Vă^^6MOr_!Soa^MD$%aQ7\m9zX`Oh$AXH޷I}\1壏8նqŝ?;#fp
W6PS:)
!jҎc*:_]\םfurvcudfiDgA ko~lPK;(@0/ncomponent/padding.luaVj@}0Jm6-DZB[Bo/4E]uw7)ή.v-q"9s]F|0W>i%תbiaxK8Ck3&JD^
d^#UF:H$X	u{\%"W <?LF3dE^{\ÙHL.HyLqD*1*Di^w:
9
_G>l)i.tN9ZТ6#E%eXPsjF:H1LvN"YK^Pf/hK-=K|GlR&6SM# VC:|uQKsi:ߖiBz;w.Q8hgh׈OP¬"dﯔ.3L^F4H觍Dill(Rى9%'jfqp
\E]¬TBr!YF5R	OKJSS4T͂
u
D&	tLf*g9d\x
SOEu]<{]zվ2EpJ/jD4`LAiaz,U`/v3?q?d9:b)#AM#C~b;ap{]QUFS)|
[[.sgyv:la5cl[a0t.5s-#WLLڍ|G#N6,
)
LmfF

D3ZfwUr1G8¨UHr|Wu$+DY<^X|Wm*fJ%3~dІw<2ƮJ}$ѽaxc#A_>\MU>Ѷ7܅C^wΠ}<>J8%^h5htSYpTt+T3br<188*>A@SV)j8q^7익3$n6
6(GlJ!'KwPPK@?%-	component/position.luaY0]$?f!!UJ jqۈ4K7 ޝm96q>όt8dB؇eR$.\Hr\_dXj[c}e֙"ȋlS.RP|fxD,.GǛ&%<k9㱐cT v+%9{(z	:NdK5B_pD{`=eZ2-LcSbbϊLOνIVNy|H'6yGl] zD9Ԛ3n$QNI$y?W>
l)^OfɵfQ
M뀺6
bK-jL`LR{K^Ģs#39'f$~F(H_Мi1⋭2Y7P<4YR`ۥ1uNĂ%m2vbDDUo}NΒ|ьN	IHxq|K᳹[.tF__j?|Èg@ntVC+7VS
h[B+\0~O:j`!0Z:0[fyJ'U[ ._c@m
~qGWōIc5k
\ߢK;.ah7i@콎tWGv($Qިgu/4Pú
g:vLAo4C6m;wD4AYnD䬺B@
:wEv5n[ӰB}M@js(P?	o
~sXV26BIнWgA|[⺑i+TLիmi4~qscsbG0/r=lN{PRk,w7d_29p>Yw@C}RhpwR48 >_H@vy:Y?X?dSO^#a!aCpKgcKEoѐ˥f]_;t_Zl%5m
;]ڗh],10YQ㗗qt21=6J?\}械/jsC\{1>8/
S؄kmym_acPgM_7-(0 ,`ek8PK@	bcomponent/size.luaYY1~0	&!Lơsý=wӍ~刼{B%(t)
 3{y"儼a)q*1?UAT)W3ֵ"Tt<7o9\J('

^&er-`db
1هi.Rhqf;O
Չ⦣W^
GkR,	!.*(4k %e}QT1p4M؈{|<`3't6Nm-sČh"3yZ /=m|\κk gKi(NM
MѐaQ*˜z
0aY7!U;s)JY2;TOGtukZɥT7s=h!$N|d$Px,3k?gvK]L3P`@$M$L[a[҄hZȺx+%ޜe4&[[%(͠`oh_
ɐΐU]} &B~FkWX9,laoN6o>!'L[pLh.i\3~

Q8 JKfq(`a5LI}8-$^LMʩk
	gE'zo :}+$l+'yrqNGoӜ$Ǯ4͖A]^W
"	f:eꕮ4h)Lw3ҭ:ܽv[c5놰ݤ鲹^
|so~?uȷۍV|/OnWٕm#[=l9؆p&l~0k6Va-y2FmCk5ݰEVJtH/*3Kb8]Kr%%(U5%:[6Հ5kxg\(֯ECq]Ȱ7&~I
r;(3ѓswuS7R02b aM;~+JuѩNbO:Oϩ8Ffj5lM7ĘvGarmA#+nW!T29h'W15b4j:CZ+B5TtߑQ820mᄇN%z{Cq52 [>)!-e-kGƢ9{ I6g/Mw )emǶJH>9+~uV]ivx#ok~SǿRpcc>СU;~zDԗ
	__R<þ_,rv'/ʤsIv;Ǽ|Fa9V)݃I
tn>>zŽ|$Y{
~wz")ܬu&n>OkJ4l	-JZ1w~y^'Ծ*QU,B-l4RzDi~-N6?4_0~[_Wz\s"\43	zD<0nc#/~O8Ёe Xͤ{rxW{ƹ_&~8yP4f=qd0FGJPoiؒߍ0/Wm`gÔbkc'	n'q3e/jdf~VCL(x|c3$',K0#-~b`ƛqfPK
@	compound/PK]@HRfcompound/box.luaWmo0IJJ˷JC$MS6nkH`;
sw@Cwsw/n6#^R,6PF-Y
wo߹OosʲK59en)ՋP1te]̴Y4
=<V`pF~ͦ8?L[)}J(%'zMdz;Z){GvL2x,窔Rkƈrg()]S#Vf{''?9%0|Wh
G0ą!L:SϜ6c(-
t1@'(6_*͈2籨^	E-~F8tBw7#	U*~PEH	0.6Qy*fh0kSicʒQcd0c4UXLi!a\ո""x3Bd2( a.)%^c[dj`*UU(tL%%4h9xil9b葄pLrV8K+j;ʭ!fO'SHDg?4nc|*CUe86af"z>~9ҍn;yifo*2@'i_f2r(xռG֕LɅCrE
WJ5ؾZ9s]>unef39l6
vhlmMs|z.݇۽-&-M9cT\ jwU*=lP	W@~5btZ9&~=$U<&sqBF4ſ1`Wٸn1C8w&瀻%moD
O#?qS5sƖ6UvTl.@XOECjsa'H	/7[i\[eu<(OjO>١?k6[F|-~	mhG>	_QU5j&q	oiӬTs@%|\$ijˍCE
aVբ+i֬XP
a-yC7PKk@f
?=compound/chat.lua]o66Άˀ4l}C蘋,y߾ǑnPaޖ}xNq8`(ICNc4V_38Lt25^\0͙{8I4OZNux:]\<~;:go=ܕMI' /j?@%sZ84Z:zHH	uf?gxʃrEy,rWw1xT(dT'CIs#;Z]q-!_+)QQ6*O4U@z"9#0jU2e(2!WVPr)"1w0;dHPķK>"qxCh<s̙GRd3_GYqt	T?3HHq	7ʤ(![?H]`ЉdD>;.=/Ȱip5Rx}_Xkz.2b;DS&󂌠JUʯ 
¹0U=7
Qdnk	(Ģ1{dM4$iFIvLc11mǼY7;ɲS3s6?d8 4ڋJ	ȀDcAƾʚRDY{0Qej@߾=r	<
5mw4$LZ)
9NGx53p^@F*5E]ZBw.[-ת"L빓W?zRcM<;eVVjjP&qX6,LGDD2S*+ҖX4IXK9X~s{ihI+&q|7'GTmFgD'XFo<=GmF~B@:usY)KY'XمTBMxkgoy\OKKS)'roWb?RoVñx 
y
BR˷BZkRȲsŘ@z3}L#q!ӜZP;yC^
85)C%,zNR>"X@V}/7J%{eyBߍOCCLRnAd̀6N&*,,_Bz	.t gEfKEqYkE7PV=wWY1TBq$c@UVN'_hQ7U_zI,%\h?%sbd|%\
8\;=aiagT:;
O'WvY%0Ǡ%CëYc-;i^T@PT]zP35evvHi#18S>>J~ɱz|Bn	^Jh?{1D)=UP)a2Z}#ޫ/r6TtiEADYjPzbr?w^Aޤ5Y:1BS3m}XMRwye-upPA&;dإMG
Z2Z,)ggBkGuh)[\(ntTv^lLѰP pdE>!l/FḩZ?	ew?}%l;k#ǧ]<8')ߦ`1M('0B +%J.!CK['wb5V43k@MWY,ܭ*Y$"#-L5<2	IvѕQ-ζe*X(+gGÿ]i
Z<=!C#ThS;ۉ)"U	0msp-.30HbL={O~kCL^C0G<,|dvۍ5fԲ a(;QmAUp&Kٹ*P߇r5S6QÔs
=
L^WJ~V3Hc'ĽE5 ۫7q-H3&KƙnѸuܸ;25qu5gw|T훦Kݩ٧KIډmA#XeHTaIgNҶ)4*c"%ڭ%/t{Z:Ԓfsn]Wkg#ypbw[u(9L<*CDS-$$_Xtq2Ҥ?݁#vv0	]~aF-Ao>0eLN`UtkȬsr,^$sM**A]*
-
PP/VKJls33ayL9FQPPw	6gno{KD51Ax,}Gsqci"aaj{샰;tδ%Q4RgDmh<].r;J]̉j6e'wz\w.&^wy4xH3$}|
.+TQ~v%pH4"F.}U1siLĝ!HefǦ?"j޴Ğ傸U`En[ɕ%y;`	2ݖq6;XŝSwҊ83qt4ӳ4)}_ku[&?p
><5;t	:l=Zv|[ my'*z''{^+h,蝇ݞНW::q&A3|GqRĖ\H. 讣2^/~EmLāw݆6&JlZwB{ub!vZ~Q^0|3GsCP(1U?Lb16
]qַvf|(z
x6«?b7^qM]2ҝ6U
q-7C^`.%U)*%}Fm$lLۿԖM40/q{h3g0וȼ6f/PK	@,	%compound/gauge.luai@sPSX\e/eY´iR'Ikケr"hn:{&^n*bo<3شPif:ˍyɐݸv'BT,	䉜)Ts>~2<"̫j9zu^vZMD\UY^Οˊ	>4S
kD+8el, a	r{9 d	a8OTlCy@h_zSn?LAfm9X)/+L^fȊ&UFh
V/S^	Ƴlņiă:TG:	
"Y*UansӘQBp12gK.U@f	Ws=QeIU#H+5d$(ZA&RIOS%҂ ڡRr_^*e`Z>u{(0P^ɯ(%9aųs0WB*MLDZt51E=4;t (F)ŸYUVOĴzuˌLz!@lC+@J֠);͊ϣF(YDȚ7bsf5@fy`pAFUѓP01256Xsl\Tmx6Dm<0譕g4͸t&E^q5ۄYk+tzM-QҌY|]1%эfE3P`JqA%}vKnW:ݒ{.В#d׈PG]lRT6	vӠggpعnrYa,,#4%̠cL["}}	lɩOzj
(
PPcɈ%MrXaOONAEp=:u%f{mhfCrb2/hPp״C
@*hA4D\?!c@s^ǽ;]o5:)LpJx]	nR{^Y
zIZ-&r3ܶy\P
ևJ| ]}@Ϻ
I85&(o],UvyhWDAzM2KdLdե	6t
oH
[Z+MͩY':wl؉b4A9#S(?ni5XB̯hTY񥀦)Lł#CQTMJxhbmt:6ej险Eu;={4$Y}Q51ԅPct[hP\EfS:9Yeh5m׸[Wcɴ;sd9S/CHMGG2{k9^hPfqkQZwxzD&7E[_IbS_V^k1@kOnKm8NQUgzo}[M-!g"@+afPv	f7pS`B[2q"&O枯fpTw\og{\f|SҨ͊+3{k;fJ$aFJ|4Cd9tFg?i̭͛یyƈZXԚA֥zsV{l}\+͕!%5*+t0§3`.H/4^{2\yOM9޷$D7.**4o9*5a%&lN^|D$*WK'wJap8twh4/ྋ]ܱ~CPQ?4?rY'MW_C7@jS4~;k06K`~k4?PK
(vF@doc/PK
'vF@	doc/Data/PKk~Aȉdoc/Data/ClassHierarchy.ndN0h
s+e(#(JHԐؑp{zc9Φjnߟs?xwE[	}ڛIGdT߼bFFdO	Nʽ}JRL|yw9	xN#~w&IΨXInŒRd+Fz+B1SxVeLO#1״">AS2OfC3!1ݣ$E1wߍz|(]>GX6KBJWhJ;;1KQ&SRZJ
%qu_}FeYQϪl9R8F\
֑ 9R`d}mpXh{@E
,ω,G^+ou#yx"h"v06XcE
$ԈpNxQ PK
k~Aldoc/Data/ConfigFileInfo.nd4P^P^P^P^P^PKk~A5@doc/Data/FileInfo.ndN0 }'tC@EH#'1I0!CN=
=F(<}eje'U38caHb
M_϶"B'ϮAtdcDZfo7<"W| ]†݄d҅۶{[QPU2M+NC7AxFM;>
i֌"}м+2}x+JV;wAFPh8!U.,\֡%QF_;(xuUG3]9OosմjNӀA,,}EiB25t20-R05x	_@~m<[jL @?̚C`f{]U/"	(Rpݾ \'tH+z&I<}ެlv91bi?E/߾!k^7X?+慄=4Qvxp4a6)np&!YUsչ61|p;9ttgD"iVC=M<\%:sЅ(}EͅI
XQEtsbM4t3-[B$T)<S)[υ$`,WRbzp$.rT1q-Bs
SEcӄoo]Dާf~sXwg~6Ib)N@bh/(
;Qx+<;Kwpi2
Da[ì0vfM">rs+}4Ut8BtI/M&2$F3o/
X*C:tm~B#F\TVp !ݦ,GFd'ۯh#He;>HyvPKk~A*hcdoc/Data/PreviousSettings.nd;
0D7 +VBB$Ed!20KE	[%hV8"yx"YGŀ]K.D.@E~PKk~AoL5Xdoc/Data/SymbolTable.ndrUT	!K
B^MH@HLgƬ jvW.+<¿=swWva`x휽8|պuG^t)<+aZnoZ_ͧeR߬GpCYq\Sy7%YU~sȿKzpp.y׿zpNlO^YAqeɞUBR%j땍2G{i5.$Q/Els]k!:_1;v"V$Ԍɵ.Tɗw\㤨Ε\Žjpˋ~b}&EkY(+ۭ<;{
kQ|;Z/|Zf*c֍L0lxDd;͒~=.Mä!,~ԅK
Nϳjun&Xvy`~tBÅ"[u܋~P\;&>e64 I*=DW3he$ۈQ܂{XNRP)x(`əgrXl)C
ԕvzџ_U?ĘO`OƓ*Ju|rLl'Y|4
#Wd؇qMK&QO[׵w"ng>g7wÂ@@pwBAQKqjN~t!t1kL);CrƋ hh\Z'?#$]:&Jo{juAMFg0	/YP4C^@-%E`hu96,DR1&,рqYxsKVid+Ndnt8!WH14i&]!Gnh 	[K6Ʃ:a}yh>[$֙bרe|"Ldq\ϳ#KRu҃W;[[]X&q`7F+pep]IF 3?I.p~GGG޶lu;B
rcA怉dXE<c(w"s9^Hɬ#xX񔡏II9>A6oDz{s6c0U"Εh[*LhUW@zh-ož98Pw%O%!MJZ$\J6	Ky5q#K\o
n	/wd2Orw5KJIL9UA,Io?W)&@Ϛm_36p	@)0gM2lNd2􈂀эqP:iDr^8\}m6pc~s26f_WdFK7qݲ?ǷY
?	Z܃}6I/Dj^tzp1qbj\GZ(
PR" 
[n!=qF\WQ_(/o!XS
m>S]ɖtHSUW[x>yJ	tb"ʺ`{[Ixk>iĮ|BZo2]8
LG7hh4Xh'
uӑ
g'w]
${*,l!l9pu[_T+	H>cT9"*%ٮ"~|.»pЌf>WWUDn̙i3ZBSE
	P#
d_:u"+qޠ~/=}"-iT4|7_ȮN`'F?v鯂pܭJDv QoR qD)ܦ*닀dCWu݆Aki'唯cI.4_@q)[Y̩0$jlLmn򕰥8娛4e8ʁ.?l0F'Oh"0ܠp^ͣ.z|?7G"$H(=_D@X\Nã_EȄA
'+lx</k%/`5$Nkv̭5y0N<ĝ d2	`u	XDNQCܭ4pG?%!:~747KRVWۂt4#>燀=ULހT2;	5"LyMњ'8bo@݅\b^}xrkKeB.egN;@8mVu)*xpM9+5&M><,gNSXRsZq0niCET٢ĥ@Ap6˳}VG	f<Ҧx3Qlm;TГ1X(\1*x)΄WN-ӴC`[sYϦQ\-X >(ԠAkri2|6ET9G3XT(I
\NP8@Y3'dE>1u6.`L@Y^	1^g˳k4"(cdG`tsOk=.7f%LL	jg~5hEnXQ2V)4Z8Ci.1GrC&Rs2-a"5Uo/JcF$'N;L;üH 	lE*||G+JrHA[!@
0f:ߊj"an$1MZV[,4PXjRHf$UƵV4*;x\ s~U֦ڂYDoRh} 67򓝺ű>?5qmćhLI6
vCoy\vS_Y]D\]d2_]Soks3:z
AorPT٩V`@	 }fx&A}!mO]z˲J0ثN(	^}R'tЋClBM[h"L'"vxzTjz1@$@+:qT~qWQ7+S6ڀJܗfuzȪbaYNoѰTdF]9t-4n]2O|Lϡ\nz-r)qtJ>nCbOsq%O.AJWT[lMxE҃Qf:sDj$vaڃ8j1
MjҁiG^CdXgҖ[T9e'q?Iz\p[

MNh.FQRw@ Аy5d6@*7U*"|Haa<YRΗӓ{tؗ,հ\C~hF
-HK=UZ"DЦ5y`CVYsVYGKo?k|E+Ѷ7H}O:&[$?;UE]Vx.ҳ2 ZeN HΚUs6IՓi8D}rG$xN>0s,\2rTw񆤿	}DnM^qЎ).	yۦEirb8d)ƳevpR-|o'r,3J<~eٴ4DZPC3$p$\*KC22tVPǴRL'%A خbAK{D\vv@dȊH"&ڇDb"17c~eEXi5K_]_]RzRd$FwӺ˕	\qw.j榄d5y)\ȇ}p"Q12WA &^U'[F#ˆU
xXFDŦab	ˬ2E}-22nkf~ku\+:y7/8$X^G?Xd@A0F664xwSEjl6GurV݆hWE{=[4lQz.N|W?_@PP`ds",/e;8,fUPޚr+#[Сux93YH"q
Eg$Xb{+.J@W2;Q_I`0xk;d[f!>|^}@UE)|[15k	}HONfkVw-8MIyETcM5WTcJ].è
šD~D3Ŵ'x&JRHc]pJQQSWהe`QReMR."]<39p?"悿&J{=(fOwHu>ޏk"턬'e6s[ZHªY.xi6ڠTFEJ&
:A<|X^K1>bIKjG@I1	Txb=Qʄi{ؘ6vǫ:ZuV37{d&3w{H`Tw0Fnu;mQBrG6UH7Qr]zfNf.撪+5ySA|
)lrtVlUuXgݤ5FV^C'SZN
YKCx%}qC5ӡ-p4W}K
ʦωvy땑2lKX]zGWR۵7@Peڊr$
Y$’29,Pt| C0A
]Is@K01i2
Z̴_oQ&F+/N8c)/$/?&nԲEv&PFNNE5ǎC1Ç!ӆ1U3ߪ{f$AZFgї.׺ 0Y i1-\wM1ܵ)l`N <\ObWd`7+HREC:q(E?#um]lٳE]4[EDÉfPe(У@[|3*"e
+<a23?.zXhihc|>I<Mscߊ
,LrHCh~;{'`=Fm?r-踰.KHV3REJ3L< JJހAq'M_j_εT0Xlo2x|pl,!]*}PmdPQk=6H6/	sku08bAP'"[kyCeҁiZ%3J_:3$q"5{JѼo5QUbe[IK"IX7\{ZCSAbCY?}
*.=St{1Q,q*2쵙Z75T;!R=In"'͘^`Qoi(+)թ+,y{@Z_&ֈ-E+e'8@thn\QiDzTL`ۿڏ3ȉp2D oQXHɐ)$A=VaG+VNZiiVqc݊&4W?3Uy.3މ_yև|>gf}-ЎG+B!!zI,UJUW ZZ
RJQ[dP8Nbq~h7?s(b6`122hG;*u6{*'Hhc
z+^2-:]Bcxg>Jz:d6m#Vl0aE5sjnRɭ"PI*?ѓk7&LA5'794_^SMM;H0\22%WO7⿑Gc\uo%R(GyT2|R4cALrj<3Ni	p/Q\!Q]KOl' Idۥ޲r6؉4	hiF181APM6B2ZY<	|G2CDJQwudh?=e#ȰV]UA˒8'7]s:f+Xsۅ-#~EgWM.'Z.#Ѱj@Tl,dOBQ0	EZۡbn,BXJCQjbEAN&{BV:L†Tx;Unaw)jǥGT#OBn |LONTV*z*p$irn
6!E5Nc1M
gx
cGY@c׳g\fWAwr|&DxƦ־9&zn䪯F45\uL(ZP(|tm#4{k󽕅4.EEe~3N[F<u&Gg^Dz#g@@vJ܏G/0;!Cvf>7#p>TAnǏXGu*\qjHĚy@,%MT7,sib7o7Z\Ȯڼ6y4[K+*#hNKtmwF7>뤥XVFeԴΡHʧ4}s'W&0WxcEJQ
eWKHw{UvƱG@
,zL	A-{Al`"#O]kZ1PBiOt=O--?zd`?O}4}A01"1}%ӧ\S CNr=tpܛ>yin}`ba5"tN
Cx:+qH祋?vKr1n@:8i!|v%)R;QƖd3
YM{Hnou؆qp嬷N@t/&?&ԯdLtՓ̆?vǔehp=ڀyp1އ}[U?5&Rd(Qʨ*PTqBsE7K)RR`&$"D0]p6[[SGjˈBb
3+-֩êZέ̘B/{oҘ/Y|/bv2&fOeaXnS:B!zʒCQ"5x..n
8p
~,':Bzm3	W2Ȧ19i{	yD;}cZw_)&QPv_ý(,3ɨPkё?CaHF4`3
'nAYWikEktZmTpn}xzPԣ2
M@
lI@i}sMw2'lcY|,pFz(x-Jne1M.iզD)MGVT
})nQ߃XB-EyLOyX4>83jrl<3^[b>(C\hѴzb_-q^IEFwсD!Q`Y6C{
ὢʉ-ImZև1$R~O=T }(4h:CQ&#,(9.4|p`Pɵ*Ht:`8
FgAXgȌtSJ-lZpR{^ 9?/\Nsx 5\ 0TG_|B^*,궊c7@&Л]Q!T乹zwL)35YVƢPS#+4p_G"56lsoCf.B:*cLn$nqܽufg&jꃉS98$q 'B'
'WgpwEb_{_>W8bzK&Eq
Slp 34n }ք%	O8xj87]y/Lσ	fqS'd<'llP3>Ohc,8b8B=+Ʀ՛"ح  woUZT	Vn&ѝǴRu0/IS FV?Ы1sҫUZ[Zuk
DE$}FP8I~ϛsk9X۵f-}<
mO S
\d_ƚL³Mp;u.8oᦖ29N<°g0`m,I^F=g%([gO%'LUSZ(D[
S\ZŬrU3+P$H+E]߶~x2Yg:/@	YusO_/AFt҈^|IFc;h|uGW=d|#[Xxo$I#Ɣ
(dۓFقخ5]	?4&;z}o,
G_[⻿W[XR4q.'v8;vl/Aj #ώ")+ IwKN*tI&dgLO'&9ݘ4^'1<5K44m_ߗs3d5ih!ycdzY0=
#7IyaoW{3',i6&dz';/guNX*>P.`ߞŒn@:ZgiD1%НwI
BnLtFOa4}I\x){(];m	}LC&5[SnAӷ7on./O9ME"49nAM thc=(2M%OSqހC4~+?fx1 Q_8h`eeDM8<3t})j)l~o..Zwb
n7\h݆̒q2E;̯{8n
xOwf׮CY[h.E"MȽ5Tw$jQL^^;k@!?MH\:R"D:B":kɱFل|Ly @pvXkWD$E@	'ICS$T̍Xܺ:uܺ9rcu^'0˞lܪT?͊:D%;x}:创Y/|̥
߈Q)	Qx=2Bj2
4RuJ=J=Q*"b0ԜC'H(CVg	:_	$10̻l?ӱL,mVg)uYO"&,T7l	(c`yRhGk0ꇨ2r8xqSA//rfuӌ'qӼ;gtd;c
3}vʹxS@g@9JK"0
	c{n}ʹM\v69%̵/7]lC?e`7#
	gˈxfŰC*~.EJ`yphWD$,Xn:Ry."$z|:{@(&q]	(UFERBgSJhێn;y-<ƪ
JѴV%*j2Vg#
pg90+ST)KjXl1R)>"WajHy%eR}?kE^@}(ׄB^
#a]`M`E!/W(:V͈F(j'
?/_0Ȁ@`͞Iza LUy_E@Ѡq-SjwuqOkj3$zER@R<c,dv~2f웤$Z}>s;~$buA*Rn!Ԟy1߷?#]!RZm=NZ3ضVaBTI3ezΚYBE,;&y=k>o.vJV]W^a*lݼ:Ӎ6|$y%fW2ڀ3xuJ87?'
56uضvu@~]WT:l[6p~]W:l[Bɯjј_m_WTKu=mHm_ӺY_mD~]QSx80>:S3Yɯi6̯öO-dRzZWȯ35zZm-ZZ]Q\V:VmNZn,Դƴ:l[:S-,6aۺt&u1n5\PVcZrZ]Q]f~4aۭՙ3Vwu1n3*3iuZ_vL3;zgmgVTYv.a-5d3Vww^H>[iuLfI[BT"$hy{p
*x8%zs۠.Q"ŴeifvPjQ
fUrf;x]ϳfwp#Zyq}mKR4hxa--f\q
Z,}[hբHW%@yۡL$*k MA$Ƅw>ɱu0BFnDb%)/KA^e7*^U+dhUrlvFD-(+];4[
%@rFf*w+QqIAd'w<'wm='KEKEߊƶMMQuI[')ʩ4%DF12y%7%5e1dHSӰG=z.9?E5e^ɝxКJXi}UcHLف՟zye&ƚ>S5q,n!5f(QgHZR&]֯Ĭ[VNlL>kj8!ѕ
E&47
Y5V)ҔGBRRy
rXiT9ا:`U!^VRXWex2#l](E@ IJY`|qwNjp=\9@x*2DU:{IXZ2.О: H%­g=coC9.Σt7yXF!Mܥ:ߐPğ:ťwQP5<%v/aMpM;^û	v&(%#sk}w
3{[E+3kjnca.-}S"P^Sa|>ƺA'ƴc
fC -'=mꥇ"J FQ$	WBx1qO,C:>3!^eٟŮ7yJx&7/aX,3L2ŀm&QsL]//w_ԯF`y)ݗrYua*#Zl+MuezIzY\Aޢqh0|yFjuf-λ@&n=2vy~G⊹	@TqDM92l+
[IferkUCIE"D	l/)O*R푐CHrz&R;ja6"P%f18I7pYMGc?9v&e7ihRq3K܈u6=D
X"|X
1V9qgSS,EbP.z˿z [!|}I:ø_o
tFu ~<^rƝb˻{w+dH=lqO?oyӷa`5IzY7LC6VLعyR-H0ּ;',3|7rRU͔rlARH8x
D(7ɓ+S6ݝG;bDm~ώة%Xi#&[x0؊qԣ#P0&39
9p85)HHg4%{4)4X4i%
Jn*VPhD_A2p6Q8*
\QWtɁ~a_
q
+4!wbߩsĞ*/iC8WXꄔ]
+,CEUQ`QucM
x٤T-6-l?ey/mbd4I*UAsQ?Xd%E%ߋ{_Ȳ5p
[Ą~J4rY%ʠ 
:"-0s(PBQNBDBG+ۇNx -i(Ս=x}}y*͈ݒAr):m=_ןRʻ\9xK j*͢wҞP.?7oaK9and̂k*:S
yh#
}Av*diAhrDXtҷ׶]3k۪G|4״m%_<e˒XN=Ys=r"ݧs6=p9(w]\_
x}v,5SWN[g7U:ˢSYꗦMխZ{&,,z@)a*K}Ĭּ֠|UG`Vg~
Y}VV
=6؄5`ȭK7]l"I[r
߀b}P^lp7u-pup\w1uMo]ט^
x4Z#/[rY#9C*rk_$Q
.i5I\+Us^Aj8Ԅ#eo4L{S)d^tO#Uvݪ|"1gwS4=Rkv]k2B!S7po0M@hv8n]%a.Nr.C_5+k+JR̋ 7/C
IATK*ƃyj~W"A](-&L铜0
Y2.S)Pyt9"$@ڪV245ZPKj~AQx;doc/files/base/hud-lua.htmlko6{N:mq[ah,j$ew$EX8HŻ7g׽7ܝ^!jvkgḹj72՚Qqkpۺ=5&rﷄԗ@^ڪ۞tS"1R:^ED1XC)uȖx	mK*C}sw?[=$xB.B"&HI"ЄQk6[1p)Q9%
q4Nt~37u_Pk M߿Tזy)h-A0'x	ShȂC,D@!]2twgigD4PZ7gtvj4wѿ)i9dktf%88~%4
Ǐj42*DcI4\wX&bEP]kL#
<#Φ(aggM_A'+d~=7`1U+0>]:Z7`)X>x2\᠀,ێ	>rBPq.xnj8k	n*BϥfRq|{+r
Zx	hCf z)Kѐ/w8,
U@T{"fÐ06hp"sEE4	,*LP)H8REL".{hHhB#Y ,Fb1",L/ ,јv+J\NV?x};wv߿z}{@?*e-
XbK}01A%i)AKb:rk\}e@*$U[HAQIKЄLM[\u
Vc:
b#+Ț\"|N}ÔmjOf%ڤWVQj
OOm >Kx( #pYSZ[`2)T1w1UdoMt"r D}:D06qrp5i9
ʬfCV͢L:G}T'[
mʿꩰNZ/h(`z-hu-Tiګ˴agI{7I&62g\=ԏR
X/:^./ƴ..3XBGr*]35n/|*\ "S2vڙ]ŧԋ—zfuOXS	$3HpUZO]6UMn%bNASi2#B;HpM?Yoˑt'!l8I=4P
N֌R|'"RXq'StcJaӥWƳpay;_"XPC6ڣ1	
s W`GG)̔OOl_bk
CҖy\*̗e%fJWl%+m>孤Ћ+DRlq;`ERU'Ys	pI9kCϩXmV%GD*@MCP&J
F9J<S
gn1@)K0‡tp9}nyH9|1AIZʏMtHFplh=fSØgXD;W8dhZޢ+qշ#jM/?)g+ˣޕOh8$Jĝ98,s\ bJ3Ԫɕ[=1'-O@ꓐ`1ꤩZOƓ]'>)7AҘVշdZC欲جc$^!ҧl!KBkZ거j$y>(ֆ{q@IOF6+6фz[(g7S;p\#fG.r]Q~UK{>%xʍTExOa*s}|%JSQU	Phᐎi__]_[r
*m=t>Pv=hI]
Y1:Ъ> >zti:
58jN+7LmƤ)vTe-n1ɘ܏hӮZ(sչ.$&UԭEIo{[67./mBK}\U	~JEbRbRd끳/ֳ
%n)CH}	Ґũj`\:Pɲ^mDc,*[f&y#]O"Ri6z?"ׅps3ޖG]1f5j(ݿHrc[{3̑yG$D95;!Oc).?^vLFBØi')S%a`:.]ּxݾ#yB=0G8]
sUHc0(_gȯw3m/Nr=L`1Y4da=пkq6w!e4`k306Ci;,
c
uQ^y$""8DGK)	ek<ؗ#=
L`GMPVVOs͟Z[M";شNԓ|h(|*
p!DM ]lxB/iP/@8~%s|)q#&z.2(iG>E	(bysX(b
	"_cM7V?y:tO^y54])u2CJÐj"acZ1}ʁȍz2;fq$487וPf=hoH/4FNw4@	ȝLY>Ŀ\2A23W
جOtSF޼S()ϨOX$RT]df/SFJ2.23Ύ́dN޹.p1kGWa0ex¹H_7HKK*>	MAm\~@Г$c*C?/
jTm"xӮC~
kXBz9ȜisRվU8]Lbըs^A9Vs9|gRN[t}(? jKL!~iRRk	%peÔ4.էe8&xJU0嗎0_!FcR%o~:[\yJb4-A+rҲ\G'<%<#c:핣ʱycutqOޓy}x=up81Vz?;;??!Ei.°̓
%g25IP$$[v@_uj䦏0m	b=UmlQ/JbʮK.o
×PKj~Aikg~Fdoc/files/base/options-lua.html\yo6@mV
4vd˅Y1C@KU5
{$Ec[hj;~xwo}sϮȪm7MUpXݵ[Y}Ï=*e=`?7*}>w3UVׯNE~O[?P!ްf5hI+qH,TE1=/*)Ow!h
u7e>+bįY$-āzBԉ"֬jՆ?U`/B!p8ŸGj?!n9ݟjYF^w.`]%[YC1r|EhpM[nwikD4g^!5W^muE	n\`R1-?	!eխƯ&u5￶*}&aua5!a8ګֺjB}HUK*FxdPƪ'Zbd!-3Ѧ7|2}loRzF"xQ?
!8	2d+qu)SzjmxsJŤ݊ƙ,%bRrjCI20ԑ.rG!vB25!,Z@Ck	*d QRp0`]QgE1B2B}f4Q*p{yī'祢>]7#@}%n.A\űϟ\GO4pE1@rCAwF}:j{%kݶ&c/=PIg,ӵZ gAg9,/@Ջ(	x`pbuWrC	`80,Aճ,:|B.>\p֢[[m(&yU]}>24Ge,懵IF}d)ዿa_1=I\2Ԏ5jPehi?YHPФO^Ozwwe9-L9hWPBytTȋQ.l`~&5&`"Űxw`r}E Rѐ0NJڏWsRHu[8p
V]7_
-?,s-?,pKQVz!Hpܤӿ>ԧeoHF2nDhhMetU3sa?XTW]Z	0/%
;>u|
a݄S.}&ԶC(:}Vh

<])7
B2^lLppA؈]L7Ώ^%3[yZcK^DϙfLRkr/!o%c97
@CsR>
:g18)fCgM9FuE\tR|-CYA޼K“q@}]#dr!\}\3BX,zHP:HDoNNM]-W\ʙŒKy`R@=beNҥVR9PUV.h?kU\Bx&"W]YLv#eq'	Īq9s<#P'(o`vA^&y)x(kDwvOb1f骫5xN7Do}sO]ysOT#81ə'hwo3+(q7u)?I81tř/"tHv$OvcsT˦)5f!AlZFy%fv++tS9I4Q5[a)sI_LP+~⼑}/ئO[oU5edGDrJie*	x
QLq+W\WL=1ŮE9Op?}xc )4T!{P1㫎fcw4$8s!2
v"aܵ,ˈQd!ҥQwOM/:,w1{$KcHgU">f|Kt!o{\A<Р})eFya[&VABy %.˽)<1,TVyAIAy<j`cl$!Ko{4е'ϷYʢ.Iz")CfEbzzrCttjʂ:j+uMi$9/"nqUɗ
4E{kAFA;`8 0Σo>j@@#'i
W^X5|=l<M6/ͦw-B'1WRCjdR
&b):Zߜ!^r*ؚybk*594#F~XuLK#6[^L
jSzdv\\ȕ%

>Mު)wwz/۹ۇdm򍄾<+8Q .m;#,0`fB W 5&vB%i!l-izOm6Ce7&>*2I oc]I/ AF?k'uBfa\7Kj^Fbf3ݎ0)" / T/'$73/M şɖ$y~_%~{oEfsao\g*p2Rlϐ^hFx`xS&|{4Gcpr6MmxɉRa~6ͣrh~TJs?'MslodGh&b^wmD/Qgro  ۻx&v=yFtZd>mm: 俙XpN $9TJce3%fh=]?+ hq{~3|0\0:Q04sN11$QJ \%,3iHؑFvY2D/$w*JR*@#iuxqy9ґr)?(@qr"/z'{xu˿Nt>R(ڣq^5 {F]G{=- e!41;>ɤO[hDog7řLW9VЫQ__+삙*RGqEM՜Cw:C f}n3#zhMNr7,8VOzTYXfP`-Pe-Ǒp71F%Э0<-Y) h` `Mj!Sq"!A!۵JjVdQs}6sNY 8Q8')yU5c15jiEYi']a0:],/xCuV^n_4P/?$S@_|,erKqn!7B M(:64VSK2zxiS-민j:)Ӻs ϚuaHXBy @ wVbإyGE̴;e0XI[ҍƩ+O-4|F+{ :K_7 S`b9>ҬJ8fȊ8!@< ǥ%xޕ, K)༰>lMWa UF dbBdm$Jl'"1E⑊[nRah[d7H෤R4+_xn$m0'~m׏$RmM8tNDZEI߸Z޾҈|Cdz/Mˀ䲷3(L_9!O__#O$F_b#(˜AAR]!-¢~bM˵v>cg{*,8'Qkhope$܃Hv~wq3Lρl?.#dvF%ڗ'NVH+ `G8~ؑuT vZ,K_, `E-Ȣs,|Q^E, ~|\8[~,(-%seq h\D#LGv'ؔxOcY杁x!E 3ò c[l;zlQ;d/ʏ}76 ٣?PKj~AO?aLfc#doc/files/component/border-lua.htmliOF{+Jp{-HSUUho9v;{y׹|r@oN;_nЇ;AF4SްUl4ή dpCXl=6n:q8q6Aۃna~_zpLeNHP#DÑܐa4%ґ/a<@1k{yڡCϷj?=k|A`LHh 0'#^o?ט`ۭC#L |{"яwy]ߡcCO> _g= 6^x:2NƷJ8#S}=Dk}{ Oteyh};$kơe?H %44??3+!n4PSb{B't:z ~`{.jַ[t XПJ>D?ءMP;GkXLj#&NdC cPfʵ#O@PiBq@ x' <%C%  x8lLBw{Ƿ/M&JTqDaZ|&mw& x`#Qbb0}ɬ.e5r,[ cBKrJ8~MQkAfd;V|p9 KʂK *UԎ6&\zQ@A3{5@7л0l/ݺw|-BB'fb0_yW (۪E!2c E5'u#}{Nz0,k%YZ2fY?"I )ƾM.(vrx>pyp _;m N6N#k9b(#YdFLV[̭d6.@.č& n~<%|T*w 4hdfZ^a̾4mKm`m3 <`<}S9[vĴѾ#iYA;m3T_@:l%QF$ywɴSi>F%{;H%s:u4${+m ݨ?rT-x*Wb?}I JhC/{jpU1?M-XL[fmXhy2/1(UHiK>DRmBBQJ*,*>XB53Y?Ywvuddm"eMư2lm [.VWq{ki!fj>\;3yH HLEL6xfJ7pGOMCi6F<*2 Ĩbvx|ʠ1= +ǝ fn/|%Tx[yWB΅#quJT$GAXQ 6vDX?>> |txCQSTW r!#'=CW0{Fʄ&T@$`UD4RTҘj7LͶ4Ua9*:cֆNc9-.A&5alȴW!ò?l&YV6ĸQx٫@vDC8!4w*yLUx؋oT(mbE9S/tcE~YRT w[c\uMc -Że-v3[KL373ݜyuRN R[Ϙ-|$lҞH{34ӥ,f4; rvg'C;e^|/_!Qx5ZW?)R3ׯPG!~g&2_p 8GIe얌2^fyW8.;RTRAapĢf„BaBV!( Q7$шYzh>oDS]cw/#~*/Y0-bp"\烈*xOQHO'9fIצdhV wrȁWvVTA9pE l[Q;t9xQ1ڣXJzk!+Rj~]q\:Лp6WS,~L.P\,P;uY u꣘p&jm?Vqb$szL=o4r%q&Tf`N=Qyi'}Y '{*<, 쇻*z̴k^?sLW`A؊咀V.xy2Ǖ @ņr6R<*N8ϏsZ$!#ܥwӹ?k.~I{@܀/IkƤA䒬Loό8rC)VL$RehLg`,W7C|NN!+*H(SrWݓJ #кfК dЗq·7+Ja{ qjU] kkHJ1ƞā#؉$918Q_Z־a9'S{?`hY[/ ]"eSz|5xR i)8D2dƎp* Al:-t{i/P\W{_/>/Uח / c9µ_[m|d4k&<]__>tY{0@Ɵ.ҧ:Fɚ[?NjCіJ+**%ޛ hЇwn#p٦k'z,(ҹrZ*+olB=e34ہUv%[e#_xK3N}4 ͗͞pS1[AR܂Z V>u3s^ ToI@zQ);@ a ca"I:-Ìu6Jj ңHH:aMυB?PKj~AL=Iu 1X(doc/files/component/border_side-lua.htmlko4; 6=`km0؋ !Tۆ&!q[c;Ni6ݫ5v9I>|~yBnMiZ]S].ōfuVא6VfYxZtթj|:ڟ~'g}6&hMňA?s:MM+K4VKHc'ܻh3jR/ ^4:YM9L=|:?&j!\54ȰU5/&شput)= ~S}yC)ΦD0\Pj )^TB8XC}`_>S3m 4΄?T>|1 G&Hu晔hg9룯2ZZ[=U`L `VCJD=E!Bx ttM盎6[NQ ϴa@Os&(nd1WDF+I[%a9 w|fV k`F`ŀ@- 3}IM|bmg:6Y"Οz~JE &]Y $n"h[}](l0x+fDOXÜ!\ٔaC` 6QCzI*d/w{c0u`lM[.q8@ =1b4:;'X ;)C_RZ~/whp{ v `ek$a࿍7Q-b6 -}IrEʁ$` )^BLu(= (n0%1EF g>4nʽFn5 pO/Ϙl=9 fPzCӋ>g" φgs ? tEYR-Rx_=E9)/B480ަp MF/EmGϫt3(CI p|WP|&,-}uF%b`%՗Pc0Td/ؼLW\=l 8KGRk|Ą!gԋ/"(ɢXR|cFHĉcb r@O}Ͳb n|m5 . ,H}F@'L@\<+5NՅ8K=%5/nVR/ 䔄b#<=2`At!.XJH3Q@%+]OJv.vF`bȳ{a/\oZ4>XU}2Q=3!q*<*'`IܺXg\o`U({HfD[(Ym$dɪY=hnV6BѪY|>|#eBYQg#j^^֫ꙅH2GobU/ZH{a WRRSHv"-s^f]4+e<^I_~|ns4y *co@W94ʔ˫ʈGBF2EFn~A .?v <6R/1uF*[TVߌy,x76}4EY|` MB aa+;.l(l>HaRn5W~ұ7g^31=~Xd?XaRv"߲o\;%y`2c;BStGW=Wk_LLpiؼDAo1 ) +H1Z;Mm1\|Ga@x K,k`dGP 3{z 3~뛞3Y ΣH3_bI*JVH(V-FjCڥ2:ܢ}艀 ,y mT4lPunׅ+L I³:x%,%FQTX8Z1@ݱP&8H(U6F, iB;M4Y|dVb]vL[; =C݊0;R?:ɼ Utm S@` ҠBQRhaٓU-rm&vLH,9FI|X^CYйxY+$B,dee;E t$24.mm3VN2)_aFX ;YYp0"iYv:½U[Jy%Xe(IֹSmsS̵͢LUIz- u[ N[KY`ѩݚ-iL>Td=E ?xÎ ia&bDOj(b b9,.J~ y8o[BI] ك\Bvȡ$-!y B]կJ_bo=bX_Y=;r[CXO?Q?HD׍A&S_vU2$!*-ekRQ>x~zU +2G?f<8Z{Dvv'XIAE}( xDn1zb zbD2Wd:#6v(Y^Uʓ|e<&8 %ؑ¹e]t׃‡:4/:%^E=jꭿ[XPKj~A9zݰ :"doc/files/component/brush-lua.html[yo0`CfƽVn`mi ;v8=@=?vrtU=흟7ϞuQ3w<ˆi40>0tZ:2{'1Zn3h_to91aq |F|VBb KZ#_>DiDXMvh1yƑj[@LYygD2"6H ;@%ÖQ_3Eݐ!H9஬}ZSćFH cp-ND03ݒcS߼sc`9VrV&m}ku^p' `aUZF> [ʀـ24rhA+Ga ]D#i^`>5_o~_@xR%.wr3 N,RR fЃ5?A3߆>|Oc"(}rj"D }gyGX:{duyvc?umB'jsھdWK Ϩr>Pp 9gǴRBVŸ#/ `SɭInM%񶶠'QlPq$Y&skmmEKHWS67 \(rF$#qn㡒9vi^=Tۨ6.wPQ SMHe.!j U2?⷟cIμc&qTDf+\WMٯ^rym>OQ$"IуsZ*D(IŔh/qH ŀ`|v5&E{L%$ =:2`Jq!rR9 o^]O0|y{R u'k 8bh@'wQрp{h@W- dj&%ۏ,q~b~PsJ]pCz*4~m(6@(6.WDق/̦%l>*MtcvllܧgШf e3ZK*/%ҋ6$ӪX V]RNPM )V-Zi$pȦ16 d7'SP(UJm*V" FUaq3|5/XhGN-۷Q k{F`#ƻڎ46es7Y-Rf1wYL=K,dW]c&k/gYi9C\30,%Q-uO6ጺ#k<>D}eP3QMƮmaR<à\oBӉ3o_2zK-78Ή~.֫@yαG5#0#L>JB(L Is^R 3A~ F#)]"[8"RœUvnZn~a$H=N`9h L9Ҁ_ɚ\-A WR,5>`oVn#WzuX^QpA# ]׮[B|] L-Wd)˺<T(nU &U~L[dwG>r8q'*#:0TwDVO\ BlD.:JM@ďǥAB!@Ğ;y|$4KE@Lv.L6N2*u?9?8et.+t\%l`g'j*Y͞5?0 |I?=|ӐlsU| k2u0NXjcO]hd gQKg=Fc"N{1{HvAfo5#we7:U f= uؓWؓRH/HNp LDPHkRĶW(T+9j5b_<1x ݹpە4܋*Wz.=xp7ˀ77_J4-E*/:jnyz7-LK}ؒ iwT`bvqʾv[.q|7ގ/`\{Mc;BȐHRyP\H٨:^y87ˌImvnlO7G|PKj~A~ sD"doc/files/component/color-lua.htmlo6I?xtGBZJom i$ I8P6߳' лmDP}|{txq󾅌it2v-j#Ӽ51b,4iezR=ڑ2Xb3hu߬1aq e{LFX7 ,j<3OՔ=[(avLdJ}{,a{@l ߻0nw[L4ǠJ31/W_8TSy}+ʔ:L}5Ҁe43 BsXir9^!w#3b bQ좶ohBh:Vl5EwON;>`1`'v@1(U,B(n6iBZz~X|BO4`'r5`1xX+\6 lzlA4 Gگrw{m?u;eU71e$7H݄OmBa]KP_G"ra mVπTi˵C@.=ƹJ)=`P m"}2Ss31'Ҏ6 Iv&Y8ɂb͙)`eu\0iYRYEy+*o{)peS,zʂ[_TP}:wknuTQ/Q1?T3G-@aI:mJhC)/+[DlWPj5m~ljν'NӇV|a=jHƍ"Km}^OiY#Պ Ľ gL"?&g쪪g R[>®Wϼg!K֐u6KdXd򋵾b\6>%-VC(ezJ9!4mU M∑ic48 "ٲUnf\)xi0pk K|D2QcǶ}v7o0J-Bs'Glďo gɩ^Wk1+p=I1QG7qKF}9up(=DKU}Lϕ8xK„! s;F3}4FF>p8!gW ՓUT>P (o9?L^A{/G~l/I!= r-/"nN y@}l}ltW)hyG SquoױwA{|^G!!H9A wk7#?d=wvCF;dA]#I8+˞cUvC@!\I!IU]g荳\,8ds1fnΕRģJy^$/KBC}Q$ZO6|*,mm1J)%7g2s$~{YC q]};Wз *iqݗKQ8ºx^EG1:s|nUZvuDauV51VfAǵC]Щ}_ o iդ?;e ftJ(F B~vJZ=b(5 J>x6{o)MZUлZuG>F@6 &PQA`OFMZѯ6ŖSFQdcg1i~pWP jEO176&j|B5 ST m@sbiv i~[:D_T*fwg:wџ; 0Iu[$G_!3{a#~f+_jRV(D q)1`n1 }l; uPz`1u |wBn7wc?Δe6#t&m=׳l /ǭb5`)X>[*0_4` 9DkurH s&ӚU=~JEG)*AJrZDć56A^j!CG%&/l L=˅C58Z_r9HBM{s#$ > ~ncBz* (~Njr@{bSᐙ:7 'C)_]#~kN۱-}#ٷd֏(.ϔ v6Sv4Ŏ6J(`Ic-fLyK%SXXӍ4M74Z 7^^{ ՌfdvsAσ |ޞшR_'FЫ1+v, 鏰DodX>1w&C) cm-^ pR~Y<"&JzƢk2ʗ^(W oryFuI!h9=5%[h,qi<(rLvNFO,PH٭Dz[d8^ (f$}vP1@{}Ĥa^G.MKF06MһkhUnCCi_o fjnœ0[?cI[V@PkD6$C 7rwa2yMODn"N&~AHb<=G!SD]4&A3Yq^À8;> ۲| (YOO4D+C+Ly2[baVC'7u}aITmqr W忓ƪ-)&mϘ~5楤d-ʚ~KsȊF y_=t(f=_Eۧ8~;!ͼ멧DZܻzƨ ]U [ų&9ߓt/Q-ouˉ-dO)-Z6gD 3"-{RLAsQ D_쀌"+;ZP1P*z}(ZJWJiБڋTHђ]G#0ynZ1dI"ihg74/(}0; rJF[N~_ TWynuSϤ 3c%ΣLBۄzw9ntԜ~XJkuO7Yr1@<ی`ԩ|M{YDQS\ߏac+Uĕ:,ȹpVAK],d[? &:*+g %6d[֞lÅ+MT,;qj~>Ӳ5c]WP.)4ǖBC4Mt`nBGI|/j Ŝ* Iv 犟r87\;.pj?w>1s-㏵<υ 4;  B?A@ R/& x(, [*Rڶԭwn*эJl?dY26ڦ#=6ſ7PKj~A-ҿ :G%doc/files/component/gradient-lua.htmlko6{NZIGb$ 0DZeI(;ް;R(?bVm"y;wCsMήĨ?޹l871F6=y޻_#>v!l,nׯ^:ɈQu2fPeGi=3W{3Ĕccbh2|]V1Z'ke(gxI]֟8i!9,1 } C6hZKn DhωCaD=Ю S j%v˚ p̶2#r:.Y3b:4 bxGqs~+*;ǂ]`J4Z}J?! pHwȟgFc R6gIJ'>hP2ZαGF zTCB33g(9pLXڞKkG 쭺h& th7&Q4+{{w;;˾ʶt!m6vm;tD&~*g%.@&y:[l`,$$}A8bc9ZquLd*n9CK , }(5'iøS1RXR .Gnh"t\ `s1T\Z򼎷UwAblj˦Z}/ -@==ۯ ᅤ/vH#pl!,a[ Юg&Q e0-3GHg3Y1oQ(p<#ʉPdkyH  C=oh{1pD}DQ3i323fm ubׄ)pdwȩHDu(Z KEN=R*|l*M0C5( bAf%Q^+#UfvTʶYmTaSma#1X2y6E!)£LpOeS\Wz{D.Ll `Ds%Gb9Wdjd ɔ!)g?(klN1iPY󰈯Ql|-)75%Ӷn1nnJNrEד({Up[-:P]&]KoEN.U@=#%B1b@߲llb^Yg]+?=\9j,Zɛ:ƺya7C̈q?Q:gXLRH${ƣ${{&b<ˆQAym{B"+`_I6z+ Ne(C xmeO-m> !uY`}6A8:a/]DlG$3v# 4C}lհP;dvu|b+{M2tP[I;YR/1XeVh e@ BN*S;fY}*6ڋb)EgWJ%wQ+%w^HWզȚVIwr]T#?@ܗ$"?Ten,\WNGYmL}__տ瞅ß s-!D.-".$/dL3͕b/?:'DM-)%~oPKj~AAL YV"doc/files/component/hover-lua.htmlio6{Nȱ%68ɚ-bg0 -ѶY$*7%ʗ$۹cR##oN[nNѧ;8o!Z~9m]?Ґ6Aˏέ~{* Ȯo-Mjj޿;d!fpD(F BZ :8{DCh54J>SM<@Yi_kRڤ} >*_.:m˹G>Z@6 P Q4@CCZ1Na)CQdcgip[! b'%`x>WCS<I6X7XCsb]\oo9Z$Tz꣍>gDIѷ(MAG!e0yAX }Tf(DGSb]aF'l!rT)Tl9EwGL0a<3|$E`;Bo76'g2N*}Yp a<Œ cU4 [ F½Zs&C:nwn;ݫnRIG#S]ɡOR]$>x5x bہ D-&oŀ K9,X0S2jp A ) ":;X > >}7P1aL%Y S߳[N3yԘ%Y8p'w>v,o<-GG~!#L `[BcW\ !2#x9}|d̖oXS^pڤYªJaU=kr,#C`шM(1vL4cD#U (4ȶ*g$W'|D>J>yJZNdU[C%Ϧ] VppLӹ[v{,Ji˪$YC;&}'7m)dRJ HsG{Mr~$6Sb 0P[HLza cnߚԇYlNUQúT', s$$.Jď/xlr2,sBvtƒ`ʅ?8;@\z n KH ^ǬDoW>9~Lwj9Ϊ >!:*FbыQؽU`q #m`:?3$lol3 :d^FK:k"q)\9%hfL#a_YZb-V?y}kžuO(d%(d;OYAĈ G$7!6jvҳ)-߈Jn@ܦ :y/He*s,b!l!z ^?4T׎2?ߠ~H[03 +,iUeoMG`2"7}<~xQ׹c{$d.$ %Ǜt؝#>?;mj4[ɤ~ӹߴIkå.C)7y <_մʹww jH¢3 ~&B褋qqw|_/YS;AfŅ\B)eɰvnG{_^Ťhvk웹dS6DxKЦXC4&M*5jn@R!Gq:1LL3% xG_2vQ_/PKj~Aiu} F"doc/files/component/image-lua.htmln6@U9v'MӢ(hK]YR)*^wHK=Z lsWw/m?]_U۶}= ]۾2}g>ޯthw쇋ve#`׎0j}ŗ_։K:P#$sj#u'P_#iLX{Y{mN|Һ!A5ϐزwil%Yd?-R2hZ =^PF1`wd]LjP+{ʱ󡶬YFD c`.`w$[:qk` uu{~'M{ J8V oz4DŽF9a?zlY'oJV>6`DhiWA@mۨVӳb)D Ō87A%<; W?lj!@.HvK;h8B [ŃX'&9tMZ$mmuny}>O`V0 $_. Xn3I:'/ 10?#ȝCxssKfB$\$&m9%|RPָ.ߏ#aZ㈒G@Q].ƩZr)6` sD 2naAs0P*p^1!$sT1Ț[ WA[\Mp&1pp- 0wK^—rҝo=Љjs[2~Rk Ϩzv]/0Fn;+ǥ/z^qaj }opQ č%KZxNt  0BGQşb.R/ɑ.AƊ"V+V/aoki腼dZIx JmP?HI"l3Ekq`ZV<1bjezQ Z!*+WjRqOÈP 5 tdUO9&Y0 @Sx/9E5e'y_yK9\l wr*XJ| 0:z=?fd˂`! 5FC;#{L!wD<@V)Z@18{`nh/w2@vh+~`cO| ?"l s% o +H\TYJ؂^OtqjYӴ]x>0ss~JbŮS.&g yRkdCdNMO##z1 "cb*d.yQo/e[lˡ-GKl!-0+/^#yp3!G5 X}Z6He(j-:/,qtݧ}fL6慺%A+LSIC~6$yʆ$!IYlNHu_Ws?pHRr0* #oQH>Eeio@mB>hRU K!ȬOU,b֪Xbŏu@BR/G+Rκ2e.<ִ`rIzKgr=UfhX^v]Eٗ4,f$ QgIC[y\ϬrUN7/aRt`^ >CͶfa3ۑe4A8 ZaNHOmYRO 0(DMNDo#}IǁԻŁ R9.^Z9X( !3]7?Z+LkX~ّ!&wA(/0=ZӴ,?$}4U]TשrFꪸ3.\e+Wӄ 6Mgv;GLzos{cM QhOY8iӦK3;IO<^ S4qd&WQB2s50<-%s˃ d>Sz)' aSN=QUƓ J'e~#1}<P(|'k4p_dx$J:|Rƙ):9kV&kBuC?̦ϗӯ6n:h7j=n[*.C|!}j2F82QujL`t&:@\TUOp8krWkk/-%|J׶3|7Ԯޚs!Ĥ3T JW.qZT_I (sSW25+򄹕%DF)1<`wv *oNf+bJ3*I+Hq5ufBlw1E6=Db'ٲfkY+|TFNUB|3 檮 k $%Sj,%v&i/ڷMH -=~,@&ђh!=yi/i."0QsFDAJ!LG I;Q̵2#@kEN^Ƌy^I?/mяY_[r@wyFkt}C/F^po^p6pvlՃceP|,aN%ZyV%oh~ AZޏ3OEwCOSx? AYlef2)h=;cߔ@b~gp1x]1 Sf܀t>iʡGjesfe:bobg@ԃ#?ޱ |PKj~A#Ei ^ doc/files/component/map-lua.html\yo6[vH [,iHee9IN^:jw?^9=:FVn4Ǣ`h\ZQ|hL&dFqsҮhD4tnSj}ŗ_`?&#P#=J+y^G!5O3 Wڗ_8wh̚Oc R%k־K;Uղ4Hh u%FjJzC8.:+tO=Ԭlֲh`C}HTK*F`B=X]XP}ؤ n3` .xWSހS+`e#~:&wG"DGǁ17nNۻj:P'q8d >d&!gw ׍uZ[($D4T7EҽҽY +kAP:V'Kb+VvXm =pT?teFo-oS9d7Yr_5_;|O=e4a-] z5%Kl,Ϣ&@]EQhGD.!ZXhY? qwgA6LR 3(RޡX/ x}^teHǦ3\;hWd|'|(GwѶt3[˸DƎs'R!rAiif`Bք-m$0FKXw}`- 7YoM6ظ9glLf0>6aC%HȌfGR4KQ2 S473Na;)a-%`%E*}E9zGKüD0 q_0붙D0bd&6, [*_Lt̺D0Z \r'Q7JgP.hƕ*^bXˤABV]Z{ *Dq Ya$ҠX)ڸVԦVtBm*jS|i ޟ>es9ӛ>}ФK4c*xn|d/ 9~\Ú/p%C79*6E%erNۉM͍qi ŒssHN1áKkߊj=#+S'۪l}PP-'ðwlpq%`nW&ҀD m[),%|> gWU*`e8A"rǮ[0F:*KW6w``7A 0e%@Y`G}g}5;+KXwq!,<.´1t3sA܃cP-lh)5BoU †SQ x0ʘ=l8 -<|ƹ+Ϧ9rӟΝ~E\g@g*1YNm/;KyN'1#"wXfCG\9!^- _!QB I ]<:l:2: $!3V"!&R'=M]c;iΚ[>#.E!|/o5$d0q*Tk{F؍ɁȁSTtV|1w8,}HTLoadm}Mm uvW10/'ϯ'RH/#HZb0GDU@> ;qn]z[[0Ӻ _ N<](kl |,GA8Xyug6|n3sYݣ jVdQeS /DZ]x/\w;f֡e\CfmL/7|FG8Mz[&b5D3wJ2(Kn_ [t#t}oݴ4Cy*뛍f7 ǿ/KR Ir/v=Lإ~ [ + 3@x0oۮ y@WniP1xvײUE嶢3oPKj~AH R#doc/files/component/margin-lua.htmlo4w$$ĵY Vں;KkBUn$$zَ8m+i_}v ޠmdTLöi^v/EQ4 d( 3dRVphvǫveDсбhզ?kVcDj ňA?bi}VӀAGjg0"ԽuKZ8:a >M#SD#B(O`ZQdQHMZ5gUDVxH?guQhqC)Άf AH(uMD@2=E(6nwio4}Bid_T* ^?' B_oc@R%{Fv%~ R:Chg H JMU*)}O<bJlԟ;Lҷ7虄{V=rb`CfHtK:FBmOc?Δc7T&mku8p 0ji yx /& L0ZE.H0JfX0NۻunoTTHx<4W%IZ&/&!lw RYu[7LJm^J000qE–]<ʨɤ2JA,V\a6` 0G޳OMuY WDEt-F.Ku$CG&(`=ì#u= @ߠ)} ?F9c:]n+ #^O( =vGNىH%P8I7>9a6UW5+ N_H|u) 8 .W':l0k^ZwX$C)cm-("O !1Me]VCg8)GEIfV0ZpYv H"%+gm-Ĩ5e%L'E,HOVZa̫*<3 -[)+$Z)t-9n_ vO+ā ^og^E88]Jph+g*UJS|}trfߧ0 aYXw#NO6(f-Ls<̅)\śds2f!ԉ8:\Sv] -!E,U9#w32$ۣ2)sDT "mToR9ra8νxD<U6Ѣ>\x /e @\_2%O\7/cBW+tdx'Gy_y(8CG07QChq# wS}̛PtF!IL'CVzW-lUV"ȧfW8rSoAq\k Ƥry*Eo fje5P;@)}|Vj;J٭dglq* ]')Ӈ; (Zam*rAZs\` jyT$@0ݖYI9 n:^4/m#YȮkgB W%5( u-H+Xx1㏟^"\a`qd׸Lg//%t,?,ƽQ]7"z5 3?Sv` k`+rǀuT:F;ES:A*ٳ˝XtS ( .fk !LNfIC{&R0'%ѵt 旅)Bim7C|0;EveX'aF4V? 7h]6`u6Aqpn_yf`GsN͔PU{(o1p8(ϺqZƗoςuwJTyF&Alԏ4PM2OSف'X{y& .̕ZvKq { &v7Os^,{K&nf\c697[3<Q|t`s0,ad6M,?Kް)C5c&13(~f[CIoฮk d+4nˤB UlEH 8kSp&Rj>*++–tS(hcIg{tg!c/"JlLq[Ru\@ c;Wn*O騴wMAR+ya{婏/Ð% YE % ,d_(ɌHC$=&J-P)~#ͽ)/\K/a s׽ޯޠdh=(_aɽѽBƟˠ(E#2P}j\j]*/+ X#dGUQ;̣bVeQ::7;ujjxֺuQ`Z@MWti~Z[ܺҺrHes7?" 6?\3/03lP!`, U״ɡtesblcć6=/?PKj~A\A_)doc/files/component/mini_console-lua.htmlkO6/6.pP0؀!{hPڸ4iAcy;in[Wsl߯OMZfVuxNvrmwh45vwS9io SF`h?C,on4 Bآӑvإ#-A _< 48;ZXui&;%[?wXUi'4?[Ph$"=#m{vnP =tbc?ң'^Oݿ/)hp|{B1Ƥg kı/8Ү:?_ gOY 6!Pz!Cա}Ӧ> M ]Fy\&ۻ㛻[[ip{L/9AM{3w.{:!=jYL1zru`O1`|^n?: =_CсY~CF(1ކ?^<'tm@*nۿ螉e[l 6y視P=XhwC.Ч?%A/gtg zxCk7矙ŶZ)2 nYi{P=ZLNCXL2MG,2Y4,9-GZ_C0cr l Izئ94{﹡X zN"$֌L3B39u» 6QC!GƤH搎u-+*vA>=h>u `j"JoCc~'k\: kl,Aњ6gÇ2-?p9.f<6*"l9>n0;=CP?[ Yֵ͑2]ȩwn1 2ob 6>T)xb,w#I˙|wVܩ5vӓ![6GX1L]"ȼ/#t_C(ֵnQ/w2 Pu-[]A<N0BlXxʏB|ƨ[< o*[\:ֱ:g'qv9v]j {=y=VЫNa ^QۂSN7}d-. 5F,̸lgXƀ _8d*r7, Rd4"1Ӕ'f!KѤÇf~ǢiSv{? ZN=Z"O;pL IG@Ciɥ1qK%WU$\ \Ѵ|% I赎#3%) `4RpW@@ȀL 7BŨ,xx Ҹ2H#APqTnևF<[2uܜL2_5FxFuV n#RC:ਲ1I]z&+t" O%.4Xa]NeE|п/i>_Ɍ0b"8cmJtq9:S2KY_]= B-Xr=}VVtHEI&b3)U9=OT)٣uch=1ft*|ИOg f_V"0_/|7hM2_,7ݘgD&-֐Ưb4!_ԕIf^!}%r$\V/&T|CߏI}d|91f i ]L۷KW&ߐGx夕I7zLۻ%+tlJ<ۮQ:<ϲKg<۾t|1Uhg!tt*oR|ĤyfĄ, ZxE\ӆPUHsUvNޱEv,|qwg7ZKahwv.ؖAe Tץcv^g$tCR*乗BD8@;ށD8CAG*g@7SK7s*a+Ud&X,+9 5>0tA tz˶HUE e3DJa,nᄕs ~|R-[׆s -[ETV(˛1}{yw2gx|WE8~N_0.[7qIluIJmbgQw8OF0/9A#01ԎO_J;w>,UJgU1m\ɺYuff!amDO!j#[T~/ qw}cd׽ll;S+AW#+t=g8$n] J)u+oUaI=0ɍ>Kϴimݗ-϶.g0s2JU:;ԮȕS!ܸg@ozj,sk'VeQ.6%N̕U#27\bszg a&/_je?{@OcB|3ߓkIiNp=^`3Z 67 ̗?櫵~Xɘ i_raN߆]^sN.u>Œ(q'o)95^&_ƋhP/okc\$;LIݝhQ$qkތ {=FȞ[EiBYy _O5_%{vߩ~ ϼ$[gwZJ.B'մEp,4Y |44ҭ4T|^ UQVQD{`E3 `E8O9O iqBn ܥ.̃R+(-hIb`̢N k^R8ʋJ)d`ᰐmF =t|Y;fe ڟ@`lpP %6Y+'*PVI izpJuw׷>p,}ťE܇ `I銢_-YUA#;Y>}P5_5LnKdݻk@+Va0AnaŋU(~\aoU߷+76ͺIY/"PJk>]Tx|q]ˣ$βJ2W⮖K]E=%Q6_(_ *g]8v!;/TBU{]tXI4^P?--rPJ:;Y5,-TJk3"`iAUiOO*ݖ;SgK)TVc NgY#{WdsI۶ Q4MSV7]ⶌM]ab=jFjՄ9ƎWFZ3bo!iqWօ;jʚ5`aL7X#3<ɔS{,a"{l ]Slۋ;*hǠL21/*?shIH}Mh HadhγAZg(mcT oDJ½0DN!B(.V= tjգ:h6福dc cnk~| 뤭3_CX| (%r6`1X~<[9`5u j`߾ #!b#4бO= ]w{gۋ/8f$MqKӄL9 l}(E\7T%h0%. wr1N gJ (0[tAM FŸ C|}ЧVUY_%y-Ʈ+| v!B<21uqZpC #:9yo׌վ}#؄N `F̀ߒSV(퍜0%hF*Y78$ Uq#\+՗WhJ< ֕+$ g6:Md՟py-O=iyjx9ӉaO0OvJv+dk ΟT.,GE\A 38KmP6VpY ,ߨ 㥵ݧq"< ) okKeE G~a]2H~bxӼ pKkƼғ<<U2xB@/$ #!Jl~^'&m9ȉ v^y Om˱2Xٷ}[6uN꓀9bYVuxt}C2d)ED.WdB5EIIʋWEl>!GpXbk>:a~a v(jL h@1Ad-o ãmrrK*πJ@17$RVƜ  &FWΨ`.vt(#xI4NȔ k1Y&}!݋} Hf9|2- ( ?URgFsv0[ E\_24%W6{FX qD"(PO؄OPo)!٢,wZ%!US쪍_ؾEfzGbXhO*1 aS I?hgU(4Tb*`n^+yMky-w/0\gZnQ"fukQ ۇW?6B\|,0/W伖Qv_rR3;.gfmXȋm俖/ ~\ !XsբeFQyI_,D*wm.>HO/BAFy!. T8rYFK.w5 O ѯeI5OgIGyEq/-Ty)U O;051p OT|XkDJh< KaFETAeuaڇ"-Ikw(CY~pUݨIZ:z LRUH ߧY*=YHnO%+8{BqC?)ACݢ\_nw^cIy5瓤`mK{'(}J;{š;ԟd+ OQ/qرmN5])SywxF\׷7d_U7Ks9I6渻!^uūzu7˖{x'pDK.U}L͕0sZ8f !sʋ+Y 3}]YZvJ7X`Jae:qdG卟AgX'm3E6R\B IK[C>qc,^>> agO*7\tYEspm(Pyyui>W[md@l&\ ߋsFfJwx=7o,:OTlD QMtK,XURDJOC<ڈolj PW^MR^`bz<uNB v"l)-y"Ӭcof9qmAZu m,_lb'2]".Dæs3+5֌I`̠WneZ q4$OuŏW^AV0+v[&`]Pb+B 6gm #^ǵ;7T`]K)(++Nl(5ʨ3Xq x5C:Yv7u,Ⅴ>2הMI0.qߢXʲr(3,WrcU DS6+ $ĥA` (l:RUy{xBUlQB~bBl*Hs??2H~{E-D73f 2Y7R6W/>LEAf{t (&Sr '؍HK-ꝧ{,R=w #>+doD:["L{/휒'/﯑'F_#(ҙ AAR]cGxe䜎^Yz\W?K֮%i_SJ@Ηߗg{_뿽A3_zI}b%NH+ڳԅ .z@oixY5 ߧP+O%)BzTVQ1tYtjZlߪ6KZ"iv;n{/}0^"d[> ,|5 owW ߏ+k/s=,M, ^*Կ@ϐ\ DU~@Hȃ̰y@@0QԎKCA2D6&1SQWo-m{.3PKj~Av.~ 5[%doc/files/component/position-lua.htmlko6NNuI v [,iw$EK#i7 "݉W'Wǃק];FFwn NčV}zi cLC=N[^ FM9g{6iˢ/g1VB(F BُƱR`u`PDl28 =57Ԧ_{MmEMO/o}v?8FHg DŽPQC5@<V~Ÿn n l"ߊ00ߡWsgSۢ ? pBsla 5C056{:0.OFc4lBkdb_5_~a?aMC06_gF@Қ6%ƾe?J; 7{ I Jml&sKd"$Xh8CFvЉg!Nkf)ɻb#1,GxVwz+8Su뤯2y|jmM XdX x/ ,0NF%!(YgOӛ4o7˓ۻÛͦ 6Lp0t ;m} `CАI'ic0)[&1,9ԥ E&dD-u Vnkfß C˛|tε`LGY"<%] >KL fk̻vS\xQH`7y[J;?>ۆ - v`˱Z/^Q/4Ur3CS J!I!t"bgi9R~|ITQ6U ?"o 4hZ=Yeυ-M9q-9Y6AY"]WH9\˛M%Èy=cuGj ; {+* 1)DP[Yg 5os"Jy'])kŐǨ ؅`1+bcK+fls] =T5Nn] 2&jpA6 Y’m <:<ɤ?Vxl9rcCK"X] l1q:)%%7B=V4$"P\cf{D5g d4~(AzM m0g@%@`fb' 酁pP ۵Smf@  `RpYj~mio fO]Ĵ$$1!Hns$)MonePqSO!;z9$~cÞes90sGJ䳂glX{ONh飙DzD'̮&.4:u`o>@ +^#+% rW QW(ut):mTɜ[cw֨|k2ˊ^^UKZ_ҫ270  p'#P eK nws )S;ZL1m4r< r ,q;LdLjȓGQ3;jF',x%P JSDթb1@ɭ29b9FԩVd*],t;uןgI[I7J*]W3K͊Z`7*Hovs3턱n1UG5trXv{E偙H=dS(V@:,_$((e"#. : C~}ێ~׭7Jhkвp`Ys65צU\ 'R{ť> jBYn2/iM)(}z;Le C||P67KC/^ҦV)u;%,yfC; +)t{ǫ]ubJWA/:C b}ciCRc7JصP.+ ڏ9i37MKvxW }\٭FjR>{!9=93NEd9f[NH-xQVq$t7*r! +.J %7L7rJ)|_o{B؉0Ѳ}}YIO/iEjV_U2cQ&M}2?:|Ye+!Cpy#X +ȴf3g=S {N#f/qĶ,sRt3$ۢcϥH&Clr@K'[7ʷS ]7R 7Kh(ܽC !XTY62=g6PCvJ) Q)&,^:cJae1dg卅=Ybq9єsj⧓*DO\[] XA*dBq]KYE"S gUɶAU]9^>SSmd>*F#oxW5c1c5y}`7RaOl]&`UP7!AFzm ,ǽ;o˸Bz s;YSQ `sQ$has]y7]@yvn+&qCҤOTd=E3 @S!ɡC̰6l#7gt\8[? a nU%pި< v}QBlGK؈?$>)v]mڳa(MdJqʛIpzb#_TF2&%J'֕7hȉ _3;" 4/"0M_:8%O_=^!OB_#H™ABCcGxUĚQ1$yrzz ^9Z9E\cBbh|={;tnm6C|.|xePzSPE"/'oVr7kg_ f$21 L"vBzzYtr׿nVϜZ͜]}<\O۟pCiY|(tYO ωKfv8bs6FԂ+ys3K*{^ˑ̣-j!ȟ^ՏD|c_ 6o$:s17mP!`,Mz`؁3!\EgL\jWc*~BmblfcFZX;7 U @74͞wl_[&}mݖd~+x> HgKD 4rwڡ^WEoj,5՚[Fۺl&h;`mU\CNЭ[TO 'x1&5 bkeѱ%BG lrWM&؁-m."m*m%˪)2C 0qr[|6E͌>B>R7~{p bcsIRTYO?"8͞55oY!]cUYRewXyT Wgskc1&gφk6Go;5C+\n.1z4J-(BrTS }+72](&ݼxS} kC 2YEs$ҠM5RdeeqkoUr8i :n< ՗v$pkDP#nesT,4iJ.6bB'1M %&ۮ3ܛM4Hq;!nȺ?fy eZʔQ\/WeX=lYMYk>T>–> YhdC#kC2 2ma1E f Y5x6 C*؉ =ۦ–ihnpŝ$6i Y&#ԙZ>w3 Xs-m{!`61=;2]Us?a毑Oe4)V_C=PKv)ƃ+ٿFf 扯R@bQ(^v063 *c 7䲳jɿr!bBf?ݎWcH5ݦ[Cfr'WqZ2FsҧW)E;EV{-V&xYARӔp>SLvr6{M5/:O.X3yk=3IWDGF>{(e'A[Qf샶^6crAGy3;pc e)n"jfLxԾlƢ zǩ`iez&lXD&0 (N{R*'/ Йoe 20QVEGe8;1(/SکƮήƭ8lGl3¸ mNهQi-*C Z}3q;SoG-`W( R5<jg:sDEIԩ2(Lmu_ށNd))JL6 M 9mړ\o7\}[lo x3"R. hZP7>ac+Е2XZSqց}B5`"C" vSvyF,kpQ@cUNYӭ>}BNǖ#c@9@C-(%~5Em W@ fҞ Xj/Kk]:4m),-`ؙC1Ad37@V&YdСB4i߹Ŭs2)>ln5CBVX5 LlaKXnʸaDiJ&6ÜEOKSX^myWPW fiu-K|a]&(HqY^mTmSӒBff'mq R7lLRf%|Yke:.Xp e@JWG"`ҚQ\u Z"heFl! ؖ XQ44u(Byō^˛!>2S) SJ^qDd3GhmoZ%5MjFu#,y#|S/7 _mс'3_U4LC5XOڃ#g⇘=w/^-:c\٣_|.R&%KKlcA\%;!HkdbH7uǍ}}1[>zqf!u,}G/IGA]m񙵧ﱸ6Pvi$7 Ҕ,Sw V6LK43=Pd ;3AqF;!Z(_]s˟Ԗ x >E q"p5b km0ֲ•e!|{)QU~QJ+n8}x0R߯D\Fle@[rp$xg/kb9PX 0ya ܄ܥI-*ZVr Zq'PK @doc/files/compound/PKj~A*0f Fdoc/files/compound/box-lua.htmlio6Nݑ@$M8 g0 mѶVY(*7%ʊ-)VlnxG_\wzܜ^_^tհ:};Q m>5<޶gYsפllnNc§ry~ū/D}hB> DCP7zXhJ-Gnh8,$u;k|k=>~Iّ<ZV 'p q&ZViϞboB#@ 8?~NՅljğׅsVPgD7BԿiYW'icP4aϡL21/W_#1`t&r0挹lXG񣯑JV<4`DXiWC@mۨHF((D= Ü8h0GWG {-@XR4vh=İv_ p0{C`GNQļXO2:X'mNG|[f]Gw(tdNҪfF>LŔC@:h2r}"9 s3Ȑ :c8lف]muҿvh(yJQВi>! f:x d]8#` һN]N}.J)`w'Dڐ`"x24g4 ݅wkEsOc5]bSHOf8cw_tik5uBg=7 q | |ɞo6s~u D[>9+VR}Ef}\xB%Np&|9P}'/[>c?a izx5 ЄLC3-2]m+@"~z}9T(I'/k%Y/HbH+bzO3ix. kYGDØVR?H}/ILx/}_󾿂w^QJe=G#Y\MH8emHZ+ &"ePγ1D[ft}a4 By<~<_$GDEe")өӫL2O9frD)l½iaj2A4-}Z'D| $|::X'-bh*P1QFn0q(+#dtpa)1sxCBP (J#!2!:}>6`*xƾ"em'S5N,, eiH[tC4_J$L襓"f"k8tyXQ;SW hydhi!<ტs? ^Ixqs7ɝJbRU%aWRu! 1@;K ۩daoQe +.,þAea߼eX5%/]}.þ}q˰RW5<]}}bW_j,rDf],]W8xR<}n1Rq+^0 *RZ ʨn=) WU?$Ų\>B 0JjXJkODT"iC%XՃVZԺ\&h<_T3[v$GUW On yEI܆" -&1a 7Tv&G9#Jloh`c*YnU5Q!**NBQrH\g]4((D6YNM)uWff>s1&k=fpE2˪qLCƆC&N4 (g7S82 \VBENzY[,rj@CWxxO`);(~x"0N4R(٫6 v?m0ivM\ߥkcc]e I]22:wȐ2L4RȆ&j+5Mm$1̈X-YT2-8<33CÕ=c{]&H@)[QQ`݇E˸3x} RCtGĽ R R:T"uT׎9{`E]u@I?r ST]5?T䁰8}d'H+*mwiIO*ga+J$ĥڠw \ꃭA4x]CWQ%%(t̾2WԈ̐zC-y.ٰfk YURTޫ/A6Suc_TA1%33x0l5}l,"Ʊ#셪d~ߙ sJMrśL{/휒/o͐A_#hZʙ,AC]cGxeԜ^Y~\NOPV D0\>H5&m<?`> %ݏ ݩGۡ'Yr\\8~:x4B@<9lBM$\u >;!8ߦw.=c$zCc&S%IYfWm~Jr9~G8$o|TUtl;W gU4Zv 0.@j,|:PC&\㘾Y` z WI _mZY1,?0b[hu)|-DNnR%ё10P1u ?%)0Plšg߃TKM6[d’a & 19CL(049zM! BKjnQ&}p!3jW)W[*W{ra]'^E\X&gXZ!!BLLA戃Hء>n<** 4T6lʚvE zhImZy5X]P#4b O,bT;C>ÄFD2ۭR]p :**>RX/s0ȓ! v2/]Ao{?80Gڬ&h?$W`rB' L3fKROx0.f⿲y xe`hol*ȾA '_tb^yyGG\7'L޸l5_ ,|qUG qy#@q7 I>!o|XmI*W9)KlA얁jF)E>@@:G#AאidOX RdΧUhe3f{WvpU>LJ2):O=x$EBXFV<4UBqP2 xJ w(.1( ppwqB'YJ+0\](O턂,镍!1!"bX~0h#( H Ilen Y]>3ВLjR 8W6`SqVUNវ?PY'͞|dJV}>$yj/s^/~I։giyU37s0'4ZXV掙ϿqyI$6쨳m&^b/-c{rciitؾ>zrCMjC1paa/q,QVcg פtL`1#O3{uƜ-bozl[]o.ųʕhPl/wN=g'7bgl ۳қ=UL#ޙOw-݌O2d;?eD)#r[M>LiUbs4b(٧M1tH2v S!:Yq.Ņy$YqzfAZSDŦzbjCf-q-kЕ̧dT]ͫG{,ꊹ^e+,IiNQ2] \r'yL~e0m1ʅc[+h[G$Ȓk(M?VmH#Nٶ% ŠSSd{ɉ׏4R.?Aqb=9%9bH\6'_~ʓ,I&3iÊO4x xX&Pj g1Ssq)z1kyQEH9Pҡ3a\-bF<~d/`O X?O5&gw(wR*䡣6vϘK* rgx,y8Kb")Ĝ'Ͻmw: Ӆ Wn y{ށr_HS}1b$9Z/{qvw!s k~i9K.3a(=uOKG3b1(zԁ<.}Zԕ){_PoNw yt;HXbzh^BS d@"gXOZwc'CM؂؂]mйV7~m ^7B(Bȡԃ !uB] T,o5s%K TC^T8޸K6,"sb)*̓?o;sP$-ɔ!q*b=c·w7Gg3To}=H1&9QeŢO}=|ҍM xVE$C0o_8GO ?F;̵1)ABMSCYyĜNVJ V}((Z dyۦ@ix f5/K' No{[d-r$s\!\+y5/gޝ9ȍN(Kf j`gY`?=@AomZM:\].gdoMxwpa `]*D/׀"{Ht {9^^ݱDD^>ô'tz?fH|J`SQZbmb}&<%OZ䱕gVdE$2^>刕Jw4v ,|b~t#ȲD5|h y9˚?qnDxI+. E$ C ;vwk_ԫ Mvgz1#eaU xO|&JJ,tU:!Aw`ӈf(ߞK0[.}jXg7+.6p!#NluscN'b[ֱ<*;U+imhc1 (k5k%$G汀F&)8.93Ȃ=R=l= &+HƁ{8^xVJ9ld-.>p/㻢7P!X>+h Tt0zkyzBB^-8Ǟ{\&8{h_^]ӹ4(q nЩieïNHn8]˫m~'@tP`*^P8D"[ 3X><"o</;8B[=7`gCF,hNYhO8a4!>mG|EoWøc3 ^S#)Z GQD>l貄UU\.6PKzL9}5 % Jl'"{RLspQ 1c< K0{M {\qTk6i!-?& ?#c="C}q8&Sڝ.g41P Q 0alyql`mfEsQkC3i~4?\9kJ5ּ`wh}?>Cph xqy$u>KM5_$!g!00X<,^yT+EAAOIy ɋ%fE9,D%SH R.@6^Rr x)FT֥0ºv4 :62I|ڽ<{W~3C]wD`L'!c nH5>ߥO|N=^%\ɀy$F"Q0TFзYB;]o ,sͦb,Dq/NҨ`5h}#DE5_lvJ${(}]8̵]c\7~vw bCLU3EAg]|f[ux~iTǂ }ra2l>gN8r4$8b9T;xv:_q`?ȡ.QE $ׅŀ,sfL,'b@δ q h~ ;/A ?x 6'_Vɣ8/q^_M<ȫYej=W+gCW8b%BLaSkQK*FQDR̶.ɨ`qIS5٘Ҡ1U2\A<[Bm.4jUP "TqzT+$Dk"by$#A7-" HYܨ腉 UБQ*HɰYln%x*T#'3O gsbpObWh&LCt\\o_r/[3{,a- +Χ 70'|(*}\㎑u4J넣W(CkW(2=ㄸ wq;@PW؍BlK֋0g/[wv ;<kNpD{q*d_ǡY_dn3vcjgy)>Mz3؇=_K2 %ɕ$>|ҌEizn%XذDc_hfP(MO5ZTc#7s'Ȣdc#7"FSnlfY^P466X0f^ &&M`^±կld± &df$ yƢ<0Xb#?ѲfMG\]E'N/mԄ뫋EӶ^^l"(^\xu)\SdI1+PnBj4*rYUnR'׎kv/͔>i&U ("@YtF* LPB .܀"-hQ(x,k☚iXf-l|Ƣ#jY Z`F lD=`FzrŠ\iՒdݢReyvF6-юKzO4׹O 3N9[*1.d/sv3([(B2+Nn/'XKtيe|"RFM>zzbE*8\^W BYV ryWR,)Ɏ\tAM%ҥ@+iXbWS"^&RX],UIS]fd8SӗV9bq;j5g %KoR'G HΖ0z?Bs"84'3- Tn6_^ (jFkeh  >]9`uR]uM 0-[_p}w+ys>1Q՚"Tٱ,mϭm<8zm Î ^'mT.VL@> }@~U/|}"TJs,1x`fcG# % [Tܜsn=m!6㹒 -e$߯^L/n^[|+؃]{r/ бm?z%//)8b̲Pu>pى*)QYdqzj۬4LuoTQ^9%l*3&Aϰ +<\U"9_ 9 {۫2ՁÂJ@{Y뗲 Fg~D@0ԤGURMi =sYXW~].Nq93D N!R4蚹H)T< QW 00ha J2瘫UEuUTTWq)Bd;fM\VJؒ?[_9[1'%[vzF,)+7|B-86QڦxRTT{8ED@~n(-Zږua]}f}am@\5[bYiu_?WJ8Chz%Û{~?]ؘ-fޔtNG鰦dKwt{Ag2R-ֿ_Yǚ_edi)BdNWP F=`bz67@bG瑋j|<*\䜰 7Gx5@Ppm&}5=j{}o7=jvD};|| 4PK @doc/files/enum/PKj~Ar{ ^*!doc/files/enum/alignment-lua.htmlZ{1PD1 ws)vm v]n0N3Σi{~8hng1]3םA;8wϏBrɆ/}uk:Db[LgMBIBY," ϴ$ߥ>GsAdbpR%i8/0WIt\DLzB8hɨ4.>wi؀N!bR9ԜCR.崜;-庨^f]QiK%pas=4#\Ptr~dFg;lb4k?|rg`36ӓ~3Y=vx4slj{"!=p?݀8{x(S,bK<-P?b/:^z)ɈLz])t1!ACjG aa׭ X<5H_MYe?e9'}3/'aҷvve^ݧ>xAK_>@<(=T*@j{;TC_QKm`Gyʆ {,'l>Q-9oq2+ L_5ѐ$'1Mh8ʖAdm5P[Z?"Q" iiBUp $rS :̧wB]4M](i9XD2Ifa)k5yy[K\M[Ày_L-ҌsƙdjV[ Bq'ȀJECvxJ %h-wR!Ie]Ȱ j .U/"$Yp;.ɍ >59OJr`ۆE |3P/~8R-e1)t3z?.G?x9㩸ERBWUz9ˉwlFCi?Q럔ڧ6e|zf+A3~<4=Q˵{18jn_PkRYbP/5#Xi^R;y??8 jۆ,ٲaa69VI8܆ 8A# ;5 <} EgIZ۟mgi<:y/f*{w4r.mP1ĿToEH%bbP{,`,w6]؄ްH&QƄ >BtǶf# ="1 mpM>K" -mMݟbKʙOTex[!` Շ?'PO&R)9(1m=O.oJR>Yr )biH=[qwEu@.] > rgGsh9QOKq5\h%QOrRW]]` 犰1%`]8&&!;n *eG&C"ŅtQX&%kOv[0Z{\VtPڥPwb*Jg-r.u&g=BX"SEt M5^ImAD" i Xoັ?8)|ޟ843OJأ#LD.¸}&wb' 2(g8$jQ?۹u-M'~;ɑӳl !5A0UX}f8IP.Z4uM Wrp [6C ǤvGݵQ[b[]uGf9Gir\=#~=yم,$5cR1)Rʚ$,#31Z,4(]˛Xok³9k,`Ľ)uEŲzzr%=uiwg,jQӾh?^7n]^ꜵUmmqT}l'Bm{6Ug*#e_*c1ۡUWV۷%y<&mOH"TȷNVҟBn5,A [|1!i<Txq{UƏmuQ+kXDŽ ;ah1'ÆU ~:AJpaiSӴ;ɸ/@՜z9֔0N8!X$[€sx8 ` 1ð۰J%֪T*o!:p6 tM@HuƩ ֱK|вփ{·eۨRIW(5D5 ǂh0GXD{͜Rꓚ 1\4[)9{ǏkO&(65iFzeR[}PGDaګ#ON 8!Q 뿼ߜoz˫׋&9ГR!wZ!ء(nuU+#` O&'͖9MXN|!qx5mFy1́pm\EN<'5gQzg sV{̩7ݤ&5]ɍdKz̊]l֧#t_8?R2 Lo6Rf#c!{ ,d@(6;{[/ ҅YJ9l04uTWeZ1l%mZZ5 .bk!ZnB`hVIzd}f%?TPHvr嶤+T9kpz+RoT5^XZL^Z`Vcodl]r&[8G[zPh3]<"#Y8JlyCTyJ=ĤþagJf\D+Qa=D3\˄ a3"et8OdQ1-r<~ +[ `ף3Gd3:n{hfyh xB3qJR2cy`W5=+.d-ϙ ɇdaJ(Ghz}i]X [&-ʒ]Lꇐ)kۣ'[װSiQ½ Rr@SiQO l`h,=~@LJ5tWt)3{ ^{B7;8:pCc1Yd@#ܮ~+yڌ%뺰I1=X3^4=g}85aΪ9J%3ԧ"uK oB=#ă-^C#8ޱ1ɏ*j$ Rg!,cBqoeД, nWYBP+juP9R➓*ĩ`Hmgv#낆 cSl0b^Ѽ}b&4Kqx#9׊T1| BtGA

C7C`@L)@n)jyR.5< ,2Û"4 szDn8CERR/d6ȟJFLjt ׅeU }_TUb%9ޱ'7.q~](-mձod)`c̣gD><-@7hDnz(@ 9.?. +Ik2N}&vb?HGv[B)2RlHLϬ8d~ fB+O^pْ8H;t uVw`JJt.{!zA3$K;b\xF:#a, n~"p(4͍>i'^ NOB(qQvWVV|kh9.O<@>^F9n4ԝp-Ozg iks3ÚL!~DRScz^u44ZO^R0U^?<"hC셚_k!#r@^˒VS]yje̙zZj~C=}҅ $\K'<5NiFXŧc:\ihfQ7,V_Hf/[\/=U$>Ϗ/eܲBreO_0O-Obyq`,967Y9X-YĐ(=3D^xBʻ"aq6NQ F`>4-[3<xH4SMVب|tR)@_]k)YRWPKj~A6/)%doc/files/enum/bounding_mode-lua.htmlZo1(Ʀ1n8crWz\϶/=;f ׯ'wZzQ~8ln2G}={ g,eugYuvXe|߹ΚGzKiܾu։7N ) iiPPV83#w骎c._+OƉ2 S> GTA??qMI@ï9"$E 1'úSoڹL*TqIpS345`DHI8`},ka9,D6]v umB{pew9 %VY&SܾEhoL3/SINS!Ci8-o mSJ%^{$$K28@-GhJ,D5;b}h:^?2͒Ov<מB<_N8DFd iHb#{ -}@L+telxC{[ۙ$| 5So FW,;ҕ U5M=WE'l7W:޵u]Kǻvx⢕@I&KB$W:O]޶ %?u,BL&/ ?h^,m<6 ü9.'Ab& L2VQʋ-s irY4< R]^2 iZAѦB*emt=CkP#Dn7ō'9&#AlB6C k8GeM%ld)aS aAڰZox2O#;GF#|HwFq }أdќX{&⁩|:8)U^:(0l?!9|sH9f}}gQ@{M33fy 9XF<^bẝ~vM虨 8-ؗ]I_X۟[$dPj*l W vX9:y(–!J@R^bң~YXm3t̶RkЇ.vlBqg# cRI;1fӂd<;h|DC\vSŕI䦦HF5qH6 Cڝv'׻0]^o5n6( ${|.79kăUiaϱ- [qwXFwq"(\X(+xf(XG9 `yFi"rGjHh9\[E8 NJ1mGણPAv5#"av~Rp]y>-MDK'%B%M"-orRa~ ;ow\;Q>QSЗJ@5Bz7n8u0% #P':kzm)`|=p,$Qͳq:PT1:{<$/~pq[W$kzR-B2jzϟb5$@X!qǤpҤq_j9/zo)QHE0 KH!(`X!u9ΉUotZ )hL^yPm(\g \PEjAHg|t9Z޽}=W ^ϭ75Dh@oJf͈GQ q">Bס,[( `GOQ"XΓ{۱ٟ1tNZ> h4Cz~Y(QiY@H<*!Blz>._?NXHV\sCOH^f]ŧ%a[Y]S&52jȲZ_%\kTpf@Op˳K]:2`Q(t} eF$Xk:ګ{0WJْwwmȾЊ1m@Í.)8tĀcˑ 9qC'rЄ)u)=> 7 AGH[C8㮗ڜU; \܄ְT(cgzg[ !:c7x^A{{q3űŘF.!l"gĕ䶡nIۑrj)ۓ%aIs?\G֓]XO̾R[l8mi97«\-6!,m:Χ\΂a|'͞A*跼\O ^SCp^)_A,T}{²{ㅚT<] 9L; 4}D.ۓڱ>ݓt?r\aս/KgX {s}#PEd9;vo~ YkKW9A(NRUXsbf%i)pev 7Ӳ8~_S"!%RfҲ!~(јys,8_\gůwԳ]ѯN2z,!ei!+:>inSҵEF~Z-Y6_𒅾}ajvГ{Ko<zp^5(NNW}_ yp \l?ŭީ [L9 slivGX ZX?nF$2jfe>œuyXs8Z}fmׯԯ y/7PKj~A04)"doc/files/enum/color_mode-lua.htmlZ{1PD1rj$s).۵¡;ma4w:љiwۣ[r~t<=pݓwr)g;Nk#Brɚ/}yG< Gc"1RU=b$g1qgZ G+骁ϑ`.l\OO摤2$ 2*0k:B}C GYHD@tA'ÆSo1Q :A8% q4J4 ^6+P U u e )p+ {%Cr ?C^bQak׿*kfgFZ<ߪVoޠCTp69~K 6TsI&G3s﹅kCo~r]TPT"DcI|4wX&`1~1*$p@Kz2{wESjYdD=G. ƃn5 GQڊVF@9LVXN"ij.E=Mt(>K^rĨ:a^st 5lx&h+ Q2vTdj2AC|p}W@])ޅ/y3'P_Q(^`R}}'dH#"M|j;,VVsKo[9|8ģC @櫒1@05iN il릹Ms}4>c2ED1gCp ɻv\d]ŧ.w¦\ֲJvy+fjaf7X;!}O$[:3ɤ"1qVc 2`*t؊kS2<,yERyJI+>–*dfP1tX_h `}q}\iqx=އkj /:.P@jC0c,ףY N.Ć#]_*Zaڢ\Xܛ ^[VE⿲J^{8r[Nd}fy{ʠRqgx9?xXG'~CgI܉"~3 wlB4n][wK  uV5ᡟ^mr/ר#xz滉i{3D9a c1ׇV`l4 2rװI6c,̖*1)Gmj$ 4R7ϰCkB{/A[.MWw ⶘|]&Q75(}Td{8'B2aÔZ).QDzymƦugMh {aLJ/5i26)+6cmdkh/n88#2ׄRqAQd!sRLdI93I` o09LzڒFKFf㐎q9_hڎis}ڰXlҦrEJZUPătHZigcs 8\#/3xsK[w[ZF qD=>ATĝ"x0WDE<NjBlq. |Nbm+N΀Wzm>FढRA|mUoT$mdZR).TrQū66a6 yA[3iv!+a*ʦ[c\hjzFX2"KvdijT@zOHgY{"&\=aJdrY:/+L7; v̑q# Jű.ji:Bed-^GdK8IUUZcJھa(;Z}d ѯhÄPdvBH垺6i2 kW0-̻.dWdt'sSLAȐ2ִa4rYdR"NJ|["|,x]/׸DV>G_Г{ a]`)> A͘#ݙ;>-JreuxeBz+Sj8b_o7WΉHB)>BeS(A53 }Acn"ha0k2AJ![i3/QCvcJ#BЫKs2PKj~An('doc/files/enum/font_decoration-lua.htmlZ0D1 SNQ 4ƘK uvv_:0}}/}ں;N>NpFǃW]dmQ׶{xظo'ןX'>p8ޭ3޲uo˧ĉ߶"I",$@HD`~1md\TyP?HQ:<;8]χo?&8^,0_HZxӲ}̸K8d4MU}9;4'jer kxYܔ$R$ і!\GTn'?xA _.Ճ?9ZG :}5Tp q Ņr%EVCG b=аFzmRXs %u&/Gf4 b8>m6WtPnΨlr"d(aǸ!K%Jp]NunST>e-8L'25TTWiW*aY/V(rYzffwga)k9yyky[I.S9_L+?kę`Bdc: nzLE23G`x$Ar.8^E#a WBٲCJH)3JzD&g;Re5IVG]ꆇ+G{䣫pE9}w;>;]9{r3ԼN8FQ%Lij9@+*C:^L ~;8]ٹflY7hNPz4x{_!i8]ӫ(J/4yXZ|Ho9ftsHk5dU;ƑޤX&⨲MAB@-}qH`{k<4IDLS2p󳄸+LݴLfYj8Η9@w3bE'rÔ! %SR*1u!Ǒg탡;g/[wK^=$t@nU-BtffC{"9 LpE8>,ES z8'%NM:"t`=R_/2t,Y\*}Rթv=j17MFł>d) *ZQASNҘāMZ9\1`m yE{IsŌJbhUGJ[58 6V*9'.YFхWjt-T}|Xx,$Rl( zPū&U0ZEFW^˶t8:ӊ6pD.SR>^!/!Gh &?D[iMZxwMHHZC?Gj)jl 'CܓG&"msNռ\\Xb( +4)5!K:DK _3gy@z`%/ 8QUjjU01ik A6Uk u@{R#?C vG޸S]ySb9̹zZn~C=}̅ $uF)Rʚ"9N,5,ɛXo;8f?s^[{@gs?E==γ, \!;$h/HoY $|Skʼ>YZX.Y(T6~:{FezK{leHb[R̯46m;3c>HAwiXJ!ς}Th[(#ni\mP2_ ȸKBz-A<c[* cbAټo0hg#+?RI;1fӂf ÇʃbKrKSwgd'`I0I` o0LzPZzdڰbԿԴ->Iz|;ԦjŠEB& }[T=7h b[Z86pj̞oaiNkăE,QۧN~Pĭ6o IC(,4[^?.`mLxU=MDj[)%ZYk#1o~PKj~AtvV'#doc/files/enum/font_weight-lua.htmlZ{1PD1 $pc )ev v]0N̴ѭyw;󺅜~8hn6k]ADsߝ9eԓ5_N捛7y4!oMH!TɷN_Ai5IKW wiPNy1c<&7x{ /ӌF(t'"XxKIr<(;s>׿*N A uIoU7o GDI~܋ 6TsY*G3sxOĵ!7E@~.V3u,* zI"$>. =@3""FCU#Ö0Fx#(Qyfl~#mdG< 96!Ԑ.n@=zM>`)~2*&B !z:{wxZztŢ@2B#z \D@!#h[#E!h0NZ!}ʀ(RѪ )I 68IۖŨ`.H&:Lui/C{07 @l{;Tp+Tt]Pdw9 iX!3}J.|iλ9bDklj HnFh硶O@He|m5tP[Z/$%lEDC)ړEFd[ ԭk׭u+\3iyJDnCf C?Q::+PN0CtgJ}äD: #tgd:$ܟwNsnV9 7Ϙb]=]&|8Sލ}FU{N'4yt8F:rAynj(+w d9ƑX&⨲ AB@#} ] {ľ경ФJX熒۟%m1BT*eϫ{_=Έ;:9cVf["L*w AK-Bqm/8+[w45< {,`SF /5i2&|VW|S<57SZ]Yi`kaxP9# 4uNJ6閔 CٟQUm?E4zvz^j)9(e6ftLYBvLz.6U)/. w[0*]Qڠq] {A4ef;vM8-#~Љ#xȒ?jn1 F1{ATS/GNZ HHal,Gw?JR5q)ҐHq0k.^IaZ&֑̆;g+.?vpGH.SLE)Ep=Q꿗'4ш*k[XZac;+C1%OqZ >}I§II3=z(!DUp_6ȃI.gX sEPdz9X70;tvvg!k 9A UX}ޏfŤa(pz WQVvX"EL1FfaKPh1So ̓zs`9ǵ˙sz Y5I\:bR5)YEXgr:\YjY7ϱOkLҍ̧4㏻;[[G uf?9dW_:`^[Zk%{\߯ PKj~A|&"doc/files/enum/gauge_fill-lua.htmlZm1nkU4|s).۵hN}-`4w:>O;vmuF'ŨCrQT69S],A;:wO:@zKi_vZS̀`ݜB/ $d}.@=kM<`~1%p@Jz2g7E}n eId(Ӛ 5c}!8$hK#a(bhbАg!lg*'Tih,Ƌb]]DWש^zYȇyy[ַSWXC柉(]j;3T6|g gň52{趔n×ּ}ɕ/O.(vݘ*X N2UҞB5nIØxtB=4ah-rӍC;#MYUH)chSE"6au78=YZ&CX5zR%alDgmnMcX-sN8`A(;f|AblRj[tcyQ 5쑉<@l?,Bf Ç҃Bb3R` d LPm #ڟfjz7ɕJ!Fr?Ӳ>M8z=n>7My匕Tg-cu뮨zmи Įȥq]2s筕+v 8QGshQT+p A6$!qxRt0[i+/z'1ϕ`qp2p DGٽTaVQ_)IVZR2C9)bU JS v0z [3(@хtLڣRDWa*IG-r.ug=CO4biO5.aagAo:J - D]dະ?$n|VDŽK'BBNrXaվ/I#sa> Q EdX=!;HB2-^FdK8Izj՗ hÄnNB\5"K_$O;G QMo!FSRP+]uƕW(3.dduL2Y#!CTDgMz&ިfu+mF/Y&^n ~lj}8?ChQszáJ7z9 Y͘{l MPqNDJ[@6'B> +ց 8 R3֟yMgY3(>ƪk^p/OPKj~AZ8)%doc/files/enum/gradient_mode-lua.htmlZ{o0`C:@JnZV!48NKA|wvNnZbΎc~ong1]𝃜@|'Z zKi]vځHB|KY$I$kELVӑtg 0D6OG'N@RK} =TC??pMAH "EpPɸ.>wiTN#:Ϥ7j8 մA?}%SRs*ɞsY&E3s癅!7C@~.ru4* zI"±$>-;,Caf "FgCU#Ö2 <1gSw~6tNZ$hSCz~ 5QvҨ4xP~Qt0|~2<{9zO>j6 N1_HFpsBO>x4ҭ}01h4I[1}ʁ3 ,a$68M%ђ }{xpQ}ꃗ$,ũ eǜ*_Mj6<@`:J  Q2=nvTA!8`! @R> _'gN,>QZ91@L73왨oCZ+o[+:B-nvM|4f&\'ml#rӔYi$T:cu 0 JU|X*:/xk*^s)_,,c&H#hku2뷄Irj9L\+jjvZ ַBV$$]cp̘W+ZG+Ӷ2Klʻ&ӺʈrHQFhP/efxl\Pd`$ `aN @pcU}&Y"瘛Rh௘Q#_"rՃm*wgW;P%790j(Io0GCG$DM9=v!G]fTK _/ yDza/$UUij/D i ]ѴUGߓmq/@{ƥ΋vzWGOȩvqvu; l6jKAIx+$wZ/\PV# o5&DbSBM"I"Yc ϴ$&>@^ Xʐd !>"N¦#<$" D:Ht ᠀Qө\3 Q :^x8'xLO Mp/fAMu 1'R|[A0K?G^5 b~yyU=ksIhLZxPeLy }LImƩ$i]G`h9- 5guQKPG$"K=28DhJ,Bjwjv6rLa{d숳 JxجܼY{md37~3IVߎMkYL=5 Χ`^ ExBEAp>jĭш$ttpcm^yg{>|ZazdD2H{. Ðn5o"GqڊVfD騧r 9Z NVJ5Aҷws8?,QIn]C0Qd6H?Y  Јq6ަjY]<qHܾugb_J׉٘B5K>t`>u~9x)e ʩ1ˆ{dX:/ N =S~hFYx2㧄Irs&R&(ٜm@ȐcA !%Ֆ9q`PCG˂l]A0P 2GAD2TZ}K`:\[v(Ƀۙ;<&XY3Qy{sfHV\Q!3G:de-v(%aE`RZNFT6BSrP:WBu+J2,f> xW}Mu+;[vc:-Xykw油M_R:cئt@@稦 Ea1){jCІ4zf6 801ӗ, <"$6 WR )wze*) p"qZ6d,$82< #;qgzZm9]Ty8!H{eB}i ^ž:\ۻ)elJ&Coh'xyZuvE!cI.Ĕ)&CKsqjҦ/QNba# SM0V+?;fqw(+W0cdP{ ͩ* R)T6k) hn&ɰ#,Ch8H| .@Ӭd0܀9m6Y<^}Tdkw?'n䂏I6E0l喘 Zx"j c!fyC#%GC|1Ѕmyv;Dc;|("l]l.@nk,.dž;LPm; VT\eRذGr?Դ->M}r>|nMy`"wvc>/CUX ·m#!`=eT]cU64 A#ψzZ~['c20"m+䴸X.`[!/a+ec"}$R/HmR퍄W"B~(mj{Ad`;ړx벶.'#:Rz$*? SQ6}=sQΥ?oYw֬D#D?9v S9`<S*D q}3;p.iC Ɯqc"k¸}îpb'6{i8"!joRqnrԅCNWi:b `B2ҖHO" 6B(NҥZs) }s4xsD^ZEd_ _;zCa?#W)!FcRݩ \u]ng^_1Xaz(Z_#Y;ɔdG B MAV31Q[ʱE.yc]/gB> DV@@w=XXv a]$,xqr7n,b*˴GDew/4yo`O4|E`)!dK"P75`3틹l -Aca2`͵K;dCyY2=>-w*|M}s\._m)KwPKj~ALޔ>'doc/files/enum/repeat-lua.htmlZ{o0`E[+vnxMvZ spZZZ;;ntGy{/O^Wm;cqN=䍕l6kv\kQ>VwߗJ@5Bz׮_;u0! #P'_:mzm)z|=pc,$Q͋q:PT1zMb7o\zh šTsF!)f Ƃ ^ÿ'F 24VhiSܳ4)l'ZN;[0bA8`Co'`9 29{G'Msf~F Z<ߨׯ_CT>D ` ľM8M%C 3e}}yd=>FQ@1h4J[1Cʁ(2WQ68Mꛩ(7*tt Rӧ?DI3^D!Ń`AD濯&5 A`Lµ (\z:t|$g<>kd m܆/y3'PxӐh^`}w6uȐFD"n @v;Nvybxb!]pKObL4jG]d1a4Yzt)hU|R#*#iS;VWěX5`<%\x+z҅3]by-D˯U$^ 18`/39Z1%,~ݻ!m'NT5y d;2,ј %ؼ"WuJѠw% ,A8 +=sYJ1tX꿔NuK֡A:/o3VdmAeWxCEU\sNjx.hЭ~vБѹޅ[@ք!WiK.Pʹ) g~=8_AVoͩga5cɺ.'];9%x80&!#;@rLOS4n5sHf\G#FۖNݥbi'VIl4MWRrp+LfTpCyPÜ 9vwehBŔ-- 7 AGH[C8㮗ڜU;kЇ.nnBsk#[?RfH[1R =-7{ .&==j9eԓ _NuDbkBgMCIBY." ϔ$ߤ#/"&y6wi؀J{F1NҨFfzݖmќ89s%&U*SiHb$&h̅.i[]ƷcITlAPA("ͧOBzAh:vJUOJGA9d goM^; ˅e>ie-q5|M$#/R-\XI3R0}hxDU#&<{Ie+K?@]LkDiS]yxB%+}hH۠%(wC.%V<"7zJ'.3NLbȢwx+ ڣ7>2MZ+>kCDc PU^s[m-[G?xj GqnMs8,"Wz ȿ32qO]8֯[52nQcEC=3\zgԜB=~CLK|FmUjg(6}PLV=:~=Ʉba3lN86KĤSnUUH(+hVbرpp -ؗg]|b(9 n_JكD+M%{ƌNi9kږas}5v>7MyM#m۶znиĶȥqm4sҌQGsh9Q{%[Op2!cӤ"m+t5:o"D9U 3΀0e([n"]A̐Jq!/SBu] ieulEiԁQ1o2T r.ug=MO4bIEREtepX/dPyt q* - H0eະ;$'|Vޝx!inC '|W]; dqHjѠڹu~^J8X~>T_YHFUaLf4V[}bf%i(pTp qZ$u}MCr1 8.DNH펺4ºW_\tψ_ouϼBVLIf\$I[EҭIw? @]gL]R69%qd2$C/͝'Bn KVގ61)([3qGwN уn&x艮/|k;X ;S&(Ag=gĂŢ3!*./Ls콕WwJf<\1O3!?˧@=`Ύi~rXPrΝkCF ~.tKC ybƩ`>*rN#x=rx&1>޺۱<:9Qb`F'Sq֣;;O*{=ۃ ױ$ =pn' 06V5(] tHYAQH)3"%4#A$H"?#4H"[J;?:zSc )"WEˎ -݄㈑,EQR/'E)/K%0\[qPkX67 ǔ?a*s)}˵~<foyL?s~7P〃9m7!%y\ 9;{GJ޾9P/gݚ#1A2MѲe LSۢA+>RJZZ[ڵZWKDŽU^/c^6m= [g< fƂdaWQ|^%&_.\%JWJ&듉e)*2j(Fy)Wqx߾`+,A1OD"ƺ/zJɪ uwfO+.sKֱOb XyfBl>b6b\~#k&A]Z90EkI0)ץD<(/kXcAgQaGknxV4x<&R:dJrəvC IxYPTrZOX:<(ל*<.$Qa:SQÀFUpUEa9c!8DWH˫^SE$Xkc%D."i_)+J)V;J cj1ZzU&y/R^&W'J1/qF7C,,+]ͫGNbm>|(Req9i)ڜXczWrw,ea_)ܶA;L<ˍUEMS&.x ı2- 5g@; `ǐSpuw"}T- W_P]oR6׳ .&7;.A`B:[\>%[7>c܋n,}JnMCOӢxH3AާF}_$9%o]k:fs2!xg/ܥ›d17#-<QzU'qU^2$Tj`ew"֊>LT|2J&6n+1uK&.R^5Fb oe崋φyiTeG rĔsimDΝϽ\+pLݛ4dhpevrFmY&IZ>g`"r;h גmN99v'/^"3c0ؖÄ32גLij1,ldY8DO% k6I,ĸm㫪씅?l xKʄbaјT̘sˠ-fәzN(4 &P\_- ~ymḩ\jmL\nN2g1?:o}s'3&>|+_[q .3n]ַ %sWv's BF ,՘]KT/ܱAҸʟ/ګc+ Ǘca8^G(XkMћfE}<%e%<0hl]n R)",+2L-uNB9qY8~F9Qi"#1;'CSX=*8~}>Y0j1[q4Ӽմ,rS5ppg=[ؒL3܍rTFfӿC('l~AB[]ESuhJGToڪ9+=riX7KHdaEJ!Z˄\!P,¥n@㳔Q =EI_.Šo MB~?PK F@doc/files/lib/PKj~A) 8doc/files/lib/init-lua.html[{o6@mv0,Ilybh,jwGAqd':lES'$;AQGc~p~F7g=4Z{Vhpd5[ 8Rw}~)5j][UMOyNׯmz)J~ODXYVQAp>q}*c:7ƷN XI4CvtɂYb1)%uf?5'fTGCj7#n@8W|"3Asqt2 Z4h~Gdc(}$&n2&{pfW"u6-\h3_i4k#D LR<2 Ir$xLN]M=4U)tk!bDجf4H(0'r6{#/QqJMyI)d*-fZ}BK8Ͱەva%HT(|$h2aqL`+~e{̽; c*=ez{B8-Ы4q$"b1a#9qq&z0(yUf 14XСE+cQ)eCŧ]ܳx<# 3yڞh=bf݁{FwR(dgmcN'NnnbǶ*8QM8}r{ <_xJO O"`k#¯()SM9f9)= xHY oY1!kXeނ TT0LbqBq/iԝV /G")Do+7| kx,R~@b[0` sF@_G|[u\:9XRd3Lzq]1; |Rc{FÅMr",`,&ӡE$T"*"&,I2qx@Ҭ3I)LOq5<&؄ʱ~ZDQM0gn! 9YG,qg &~N=gDP}F#dZ^GLYӆt-`u4DOx1$ !U=m+0Az6aS1^2Z^!}ma8VԽÿҔc`\uFb^55sRtNsC jOHC$ "蕕rQzLb.HWOEhv薯OD4|+ƅ?.99NZL 6hMi6Lj 1e![PZSb<՝03ɳՀ} )9! 00ek՞su/#pP M|_(,n8`čl;+JDu6qFk ڵg9Th-Kӓ۟k{.1D,`wŻP{7aB%|L¶y`ǚ.Uk-F2}kCwE l-Dny}b&4kK8Fl轘hB|BǶB>>QrC\wԇEl.ӽ))=[\>faSXu OO0J]6-q8){{#,Ҏf/KND9ʼn$.tC4|"ChXLOsHœ 6pl-4;b !ƞs{]&%YĨ+EI} WS6/Oe} -kEw*M`)Gj7vo\m,|θ_M5 wXwYzPgس3k4#,xXˆD#?;[^'B?g_]Aڪ  P2pݨ;{eg8 8'QC?Qf2gW1jWFS*iCE]@:p}O v; BQWvAh~sh!ՖNC {2TTԚ{YY;hТfr #ĆG6&b̲Re+W-̕+b1L &sq dHi򈰌tKZϥ.ش-/+_c-A&j㗝_7sU:T;<xˁL5{;-W?uP^seT9eQ`?T]U( 37wb1`=/P.F!4-GB( b$],OEUGV.d`ĵt诅C ~ ~ PKj~A͛!doc/files/license-txt.htmlZ{0P^#01z!)#ƘV:v"$==w=t\h[ۑ~FBVն_?hvo뉇 ,dEBOm{ZVjmlV5];j\vڥ7.#$B|nX"H":% n ER "3"S}b5.1ih@*zɗ1M>!N⺕uLa!he8խZLӤ38xN/{@ }fӂ)Ag@2yX=[G}5 beB,1֭A{>]~ Z8MQ^Fgb*#\m-dA%\X!]d0jXk-ﶍՍ*=' XMhEq,*hIxFYݗҥ_;lc;lr/޽aa-[)hX/֤a:H 2ˤ|@!*fVF ^@5")qo rq6TUE}9v8aLĥJKל#n}p dg߈TXi" }18V V 6Su='$ <a$HNLfb9,jEDBQ(gt!"n= \ o+! |%ZQ\@P-LU)LtA6-I<#es-XHg(|,Ji.QIEdC3LN'_K]El+>y* OiI>cqVl!eO%aOْ\ `CHYr*080%E@9>qiC& (,@ʸT҈a;h<|嶝vMźVk'>qsEjޢ]AΛ<4#?A7i Cܾ@y :;V+o+&5ǾۚcEǣ6Ag Z3k7i>0W@B^) 0VVcyGaW=G*TzM_AfQRC@]G&|w8g~aX_F9 Kg<xJ)7p 82Xx9[[NX0E9Ojs)݆aLT悆!ϊagMPxH&~1%~-|Mjpd'޺ɻ>IrGU_${ThۨRN"zҡ 9/Kkf=st }Py<&ҿ[X{n[+,'eٕ:ʱ);i9 t( }2"KU5PA6_ ~_.x-RUAÞp3W)50n*# 24x4<) -<"_irza  !%;\ "ɘ.[+aTqa|,Y\|NYC T䖢)6)WCHS2nkҙѯf|<-"$_;<8g6,P촽Pg/gVۂ̧SdL|I: yjԂ*&VyRGZOO9*_l:{~ޢϒ@Kx!f~x+>,e8><*AB6ݞrJ\7Ab*qu>ɻ㮮N{VN^-GbIDy;dIH8`BK6TRl}}":1zKN@/Fvug:.Gm7Q) +)r7G:9ͻmZ]soF8!1\XƴUAwi{ͱ! XB$ ;l8DK礮)pEׁnU&<'U?rpid=I3&P\yw-_۷eޚ7[ȰotD*YߴC|z>ȵmqV׶ʦlL^[G@_v<Wxw}=l~u{-wbS<C> #osq^Ҙdy, F p rUn<~5/w53Z1ȎzHC)zݴ©??߅KKԯ1~PK @ doc/index/PKk~APUZdoc/index.html%A w{%V\Ш\{TQJ6*A،*@%CA&zn3T;-to#PKk~A vddoc/index/Classes.html]{S63i)b'@z-9"qϱS?i߽+ɖ!;Ԗd~#_] G]9lNmXFo{9T2 b^h۞?>v>tзp -E/8 ~0áH [~8Tb7-XA&;TBvȃo95F'[~ڡc:s-?谬v?#;J.L1b34a:3v!DoC$2&Gaio҇$V=yRV`7+tƞD&|PP<3C^m)kz\W[[_~aߣ-AZ@ r`8=J;EW޼MqU@٤`"7Bl]a:`=`?=u*y:y$e.{8+ f(ÍuM ʶ+SAJd]{׿+̶,/|v杸<0b;?zQPчټbNJ~\Vʼn}Pey~ZwgټOEO+yYm~QweyW~UwټǢ'n&H\~*zVoO".c - ;N07L۝wsò?+1Sl j'qr8B'h"Ou=؏t;oY c7 Q{xZӛ=Egl'֖)Dq]u^Pr3#{M]vђ߽QxS¤,"yYLXF;k)ġ2hjM)J@f)ldVNˣcr^ ]YyihOUrY24G/O+=FE=Ϲі`BKn9]n<^*qM& <徆pU'S^ UUEm)ޗOWb15luOPvʨv I\KZD4S SJjQܔNNp;Tћ@"Jw}| .xdNJ:W稨fLJײ`'F4I) R.pUHDgmX^\)@v5]^!ik U{HSr+&%]FBi|D5m u)Jt$JiS8ΘqaOm3#LȭPv9 u["=g ;y9xc')rf Wz* ..R{>gf̅.Еw9) ]bT<?:z/Jlw0Z&66c>|'pfCxi*ǩV,CxG8U"MVNZV@ iR.8^.,6P5@#Mʅ>گZ…ѣVa 3ФLH w@0W gP4M!mݫZB5Ǻi~nT7 xW5KdIpȃ*%d)p&'WƩb)78o8%)X߸ۍ?+~)S~ ~ i tW,JwFA~JC9y[K*ҳgpUz kk54^\3^V]KOzU x^Sn'2XWꯀ19afs! ?%}N"dRN`A6X?\,aM&&@7c⃻$8kDԕ)D}j=Lv3zKWg>,D a*1 Y w#ቭ(ts9e %jOc˧ߤ'5bmDZrY IMIѸG+I..ܸӖQtҲSV*_me;L:㼏?&}vD8l_80y 08f? zÏmwf|E Q8-eꗌx:+\]~4뿜\PKk~A{tS!doc/index/Events.htmlZ{1PWg|l@|\nbݝ - *1t:tirޮuYu:gG'5͝Z{u;q|#&p6gw\ ޫUVqz0JX /T4?Nʘ(i5qS|BQ5P (a!ATQT$jLA|E%zJh*)e i5j9"DHB82@#Aՠ\P8Ɣa d,DaOq͢Obv'.]HEO(Nxۆ:\ݥR:@}g{l ,U $tC7' ?t&UB# Qt֤IPNNQ&!)gVmzIf$ Y\P)>FH_߾خ]3NѤjAxGo=-+!H)ba]| ]$1:,=t's#;#Or#ێ8#_9Ȟ#Yy ^~D+!Gu;Gëp?%EBD$Mǔ 'i<#XO'ڤB] WY`6M%z%X՝<7QfgFWY_N[n])1@׌T>$eI)pYe^I@>w @g;75n]/#yzΠ> Ѳ V}<0qe.D`U%|?4y&ymv{O^OvwڪuUQqڡ, "150%K]KK4,3$IN)Fq6,-#'S8os7s]79WDD5> :)t51}x6juRTǼL|xBg455"Ρ!>@|J}"nE\d{ =S?;ucûaif6|v7ۙc ȟiINYOUˌ,?<8n}aJ׬}0A$kEHiu~^ub.O{{R˿8|wFo[t`Sf/ BGh,$>fXvr.aـҤD&G>qtnG_0,a(<5‘F|g4c<EO<_ )! h؄ch<%>k[tpc9EpIYV!oJaw;mRwsNS:d՞jfeÙ=C +c:|u-^}Z,ٝ U,ʻMNޫcO>Lf\.7աmyvos*cPГW7QSqwn_xg[{m)g]_sPgL8Wi_s2ܕ:)kupVō:M:Rxf {V?/%, &i#)#ёsismlX\u u௾SZ \(UFq I︂NOaѣ/;Cko<e9 wph@5}LOa xSȪUAٓfh=*5MG ekT?'dc0[M&1֜49w+/-s\syo dꡰl8N`{KJsgiS `A(q$^ii!`?B lX(q$)S N!cmv.gd-${kz~Y CIڙ3LIE6G GژbXy9yMpT !dMƸǾl#PL4Ⰵd`<,/]_][(g)H8zA͡t48hk l3}CqB 矹Э$ ]"8F!ik6cB uBcqB&0&<SS bI(Nwxgz `0b~ DyZYǶi;g0XhaBh%lt s0Y8g9IB8ŭwo[|oW0nY܄_B܄rdU 6 )Pk&˟L}?W cJ(q&ĔL9ԉL 8Pa`i˚KТI^Y}uQ I(qP&hN('mOāO9ct0Y4^B4B5gbX|w0Y@bB@ Q&0Bra|i%6*T|:|Ev8NРxxip$U{:,@5!- M5 c AP`LAZ%L^≯u䄡B#8KG[|5^Q^.ۄsfDP'Ba,JΣsfwV A'\Z][)%sM満%J0k45r} *82xBBgySIpO iH(q:H!tH1r!7yJ(ۼt0û2\9!B>8SRF̯@NSزP<2\d_,RC#ȕVC:?ono.n//ߞ]НC3mpN&:\n68RtĴGE}p\*2L vfozʹ&W60mZ 2,DmykR98^ɧX+ȴm٣nc{7 ]>yjYjpЕc%U<1@e?:|j#ABwuձVQhvt@rґx#XІC0\ b{[5ICAM.}K(sQekg[Wk|G!+Yp2++*+1ѧD#9ڭJ311=,3nL;Q $pף1*-Bc0#[sdg_zU8O-R@adh2xljb t@ :UpǬkf|zۨy:76.A3}$˨GGso*" X29 |kϐb J{#Wu/}Ϗ(Ocd/BOP.s{lm.2u0uH;TP5'd$l4gvnH:?:[&k4]Zd< KM?}\ 5iraJ6Β`=vy`Ymh5ؓ;϶#%<|}J2*T;YñFeGqĢ _H6*ɉ 20\ 'X(|gt>*k70uMDݫtTc{PxU޳\-[(8)=eP)s46qV沘'.j"Uumm.oj;y DX#RmskS+4r7selʲ*yjJ]uAuʈ0> Ӧ%Gwd .J7hxu,B!?/82σp`92d23ؔ,ss3t>Ek0t@gS$?&T KfPY+O- щ!Mɟ·;6 5^-NvUȗlnPv; fje9qWU:GjnѢ*3r H-|B$uskXaM (W$"*kͽ򤵵.%/3Ά1>E22CFkGph0lN}mezHN|gbd X7P/ ZG mJl/hrڑ\x\!c6<Ie3>+e7lM°q OLYzF(vv|iZG*πg.2y-@e$?U٣Ѣ+K?o̕VEFoSs.ՅI:eytkK'9\Vٽ-i6-ltY,VUe/'ONfTم}ȶ.:d-zuM3Lc[8&+Q|\8 ֵijsG~Еv4Re8d4I2Qq2cQ ۯo}ǑiO̟ɨJV־$ K%vag,a$X:)[dDmCu *b$eT:Φarz~%)Cϲ+(G.i0OJ26y}*8y'*C6;gaal:Ŵ!EMZ f6k?rG-4a!9I,aۤ8Lk`/'\3»HM^8\AL7TV`zlτt*Kg1#c/66πo{iڏhR0{w)#]PJUsMDFh"3z 9ʭ,ot,(E8w{7=apt) Xĺ yc4y'9u) ?|c[;~4l۔TJW]Ed`€g5lBVw<^zc1ل411,'60cM> Rh0׵,iz5wpgf;lHihg;omyضCN| GwR\Ee# %^Ѕ yٱW7 D3|B _[ Baw"5TRA>U6{a\l ]t [s_7$ܟU,0]ix3'ΝgCD6Q 7Yw"R d8Ք@^J}6xb9^JB,*IX<2Mfׅ,+QG dy/] l .*Yl [-*ś @[T*Wl*[m7us? |[v3ʗc(Q{r+rf ~J =og#|K*J@S?T7^||Ydk5Snv&*ŐG 傞UA]tvcwqA(o /ۉĠ3xP-ZhH3O,YĎ5֯Z~:^ǺkZmL6gc?;֞LL;W #jG|CBRXW",]znҶW9oqW8<)֏㐴Ym`I$rv2ƚ:KNfl9i1rbLSlYd3V3J3ۛ<$NBDWh.s$KvD&oepYO9 c{!,wVK1pYl .} .2h݋˷ `i(BfE״8r$iU n RmJeةHm6y 8MiRIPɀ5 y*q"Sў_=b`u"^dqjkYr¡]<6!q0aCD0[=`xD7Vn$`.-Al;C~AߡHKjx,J$~2GS0 jjq3-ӟ"1D'( \o׺:MPbbE1y1Fl=T{~)XR,`yh6 wBZΊ |r7aC'.8R-< sH}{ 30L6jO*J/`u^ w$}T'zL^# OjqXz='6{f(*MNI^ "+u?CSfKC;_z~?AW 𞂎9zzzWrko\z; $ Y))\pRpQUPU֎OBay`1`2P!Gicˢgw]]W{>5mR)8?UMAp@~4~Z:o)G&u v/_|neDVTJK̦U\㡤,gZU,W騁O7""zkb" ۈCO2fӯ^ϿqQqLo%`g$hPő4Q*1@`{QHAˎQrƄel"Q@aLLI"A@dOjc$DoI`c> HU^q011'~'j溩'pWJ˗ET(D}c0|y&{iJn!KZ7XtSRiX-j=!DRMd,H܋n)wwt喡OdňLv "}ps`36Ӌb~UZbSݏ/2 }m{=G'!xJ1Ƭ *3OxΐCZ bju!ӗgr V=㈞L;)膔߀o{&^PQO6eVeۨ'UJЭzv1+&kٹef$#F0lwv v%zœ#:㓚==흷罓^5.+%K-ۊ]7Q=%Si.T'J,uoٕ͕%·5gB0}( $Ql H\d[6|$I=d]jf`(F $IF$B}JC 2 sQ~tخxKYާ$l$tw]t(gԁ"w'M~Ej)~=xe]Eԁ-,ceu-ƶgMw9k >b?rtI~"aC=sIxa@Bn`3))#G]l}/p߁s GoՋOdAa@zl-ؘ mkBh"Ő6E܃jsE-4Z\#)GLU Ȉ6aľ٦BT{Rx"ub}9㩖4MZ2Yj͐<4Cc/P *Q UrYKT ^uQX`ged;QKrF]╰y]Dn'tJPNGljv/fQ|* xoQA2N\אỴaDKLd ށr=}4lFfbNG\))ФG<ԍicui@=8svDIgOa'THXj*վ&a6mos.c~ s6< i(GLn|a |0=%`ӂ1ˉ!O!X8yiZc> U#<ޏ'~v,F "&чyA=]Vº f[/SΦg[3gzȚ_̝&M) BdT1_륑ZEE͂* Y,uLlz4rmtm擥F~Gm8Q }>Utc(ҰU 5,+=xʺieW}f%.Yfsس5E`^Ycu$ovPKj~Aۋdoc/index/General.html]{s40 5i'mikOޕk0'VcJ%۱%9u{aڲjY}rh z=8Gώn;jlOȘvuk=|~wr1gَ-'v >h[{Sl; 6"6 v8 a 4fwF6yqvxtc۰b7u;m ½6K\bo߈GSc ;9"MC|oZm=]O@x4y<۟, ־XZKC^f)uDSǎ킘63(pسhߠ% v7ozD'ޠQE8$^G;x1{B7kƞަЗ( X" o*O66xa}}1vEh{8G-#7QW2OlIȾ7a0C_֫_fB>+S3RC{mxƾu'v ڳa6 <>dm[8A67včxXguXHcȰ2ֱV:g챌uF+kz̰)_?7s-=u!ho VƷV+a]3~|a ﳌWuqhXC V ?֏Z22lX?34y&cϋ'vzyCIkl4a' $0 z)@5 C$=',do\B {!8j}. ^<4%8̓ﴡ78->J.x<5Nv[~  2 | B }ǝ/ź3/:LYd^Kt~>w^bWh `. "oM0ܹv;ص=/jAnvv]ru?~K{C rIw$eqM7社Kߓl|Kn^ ]>6WB3aSe3)lD&TsJQx8QlWesT~ISbH{d|>aJ"p olb/Բqp@^Iz]^%s3Iѕ:'9[)yXOLJgCKCfL4|Ȧ?Գ$|Y9$\I\2a>Jbrڙ+Ia9J.!U? 4&o!URހ#ȐVPI PW2J`d`Vdg9^ϢCSUQIz; Meq֗TF $r#xIH' Ebٍee,f[5BT9 h%4;tGSB.*4CHeTH(R#H` !E5NFMe]E.&p%^=Qu))VI۠+x"IK,FCi'HVK9]d:[(QJRkrR W:/!ljM-AUZsX-}(IʚLE[ Ui-uK&J-{X,ۼ2NLGI+LP=id \g~D –JnrW[4CԱϩc:l/5"(u.rՠ1+Af`jM%32BӒZ2&d S>p%sxXiKv‰iZ R~-\I,UUO6ּ%Jq=9DSWᣪXFP R>'p%YhdQ&dY@y|>YsTkrL(xeD>,4JyoH0>uG\u) yYfA ByeeŊR>'p%ګJ J wd eQG,ܔy)2lMP 0%t8 س0-Mӧ𿜴`OWLK1v8p\(怓M8K9(\DSQv%kx{X^" Yy-F Tp%1@CSACˠk6*GTKI,@ !^6=$9Hjxnxz$MXc)5Q@@dT*1z-x5[5nkkVykGCWjD*laFkQYL8 Qt;[WnWCn t4tU$TC>MtI[NH$xPRAQ~BzPWNH %|ʮN LT^K`u/$2 aU!C݂.ȣ)x6=0^+WF) <@MH{PN$PZSwlW-͉ rP"(k7 ')| 0BeЈ)FqFi;JvŪL?Dm 5Pd]TG| :ANmK 9ċf N#4 ) =(=Zݶ]˪ܩ+k m_ ٗݸR$-{)N%I㟍u> u\Z X8uE2 b'@l@Q` uh뾄h|UC)ƁKdD6|@5_k4b hzґޗ0YGdNcFhJR=Q2ۦ avMzU' LfH,/Yf:#y>\h^9Y\}j8>1㧔&PF# 0Q,QF}[އ$)p̺Ż; g$d@&GO4{&v_4+ Mr̗kz)'R>Qy ze?@4?VGf Cڡa?S+Nbnb:0Z7sf&u掜Wʶrum逸>ٞ53ܱUځM4PdvMoۇ` \&Tƙbpr[ 71m}/#2gkxXvm7 !7#R;WJsP>=O!^;6gD`l2Ny 7@utbX*Hy=[ X LWگ69P#հIOHB1\&@I.e[-%+>{:T6dKDlWTP|hMV_ҕpKY;^_= { oOZd.B\),dU-5[}\H?0Lr2$+XR&$ߒ-WpzZToWn$g74(1ĩ' yd YP\Vt߬;Q-.Y=9.9v8TA'<kBp9az^Ib͈y ^'֠50[fͺ]ΚIhl0xv fEڣ$z3*!aV7W3EqVXHi(ⴡ̟H[h+zQ#1}J&)uVp>q=:4V $T"} TX'd]B2/Pa;[Qb䮞 T ytyb*2T;&<ɨ*0Bdrb K :&Gvv8^d >]%R֌c2^//i쉱GfF +^.gb=ן/fS{R`ZoL~|-*p-BeۋX$єLB``ppP*"6>YcgQ='8bqj\b{F.0 $q޼-7iUD{M2hTUm7l6@x` MKZ 9گW(b`w8jяts [ >eMeA(Xr˜z*d4E\R 6 ;XFrIkw5)p|ϒGHxPKj~A=doc/index/General2.html]R6ߙvZ.HB&qةN߽G-*ɎNY9t$}:eﳃ/ :xV:<z;k i0\|jmu=ֺ|zs8ޚ7No= O?=-n@8-믥}=7p~aihJk>l+{y5K?vM=B?{-;[ξ-+PyGYN@Csߺ׶[4QưmxS^1ҘY )yOZ4jeӹiF&khAC0g$Yzg[[~b_Dtyxovhmh{}C_DbD?Zr6oXa` r--Mk#\i Z~`{.jo;5cD4Y00n!k߻AKnLߍ!}RzǸ>.AY*k֞!=#2>ZRg7ρZM Q M_{/K}>qٳM?({vb]*Hӏ~*%|鯔kq:w<M?Qs=𵦿VJxgJ 5<;o48~d~R/J ?)%YVJNkԶCcXh8˜,0L>g]+HGrdAE^5n`vBq[ M&y.4 $X<9п|81u[҈,պ:QSq&eAvwSoXgv1.ņu c3U~iگ65| +۴pjHFK0:hf{-T FH0D"DyD"q], ,C,<,)M\/aK |FR|F Q'h,kfr[6T00A#x(%RqAZv+ tqR v%"J160 b!u-ʱCӑBatDt$% >!4chaJa2X"XyXbi RӲLaqzRz 90˷71[^9hc c;Y_YiikFanTOqxu{ m l{֗+cO2vbOݱX&*MʦMCHPil+jV耣f d!(baՙ_ZM) "6LS8 v\S#bhSdձFQyqR:dLuXTIƅjRz8l3"O70X48N\XD>QeBHP\{ThgZک.oZ72ǔ姡&ΉWGJѴ fT[6H|9XR%M=WKۃtw)_1 !< Wзzijp5hDR72U"U x\$zX3wyiDlc10o^\dy5׷T4*cR7bBTyTR"Q4l5DL9R>:b|B8w+ ER.80e"eK +] GCPp sl> K89r bZ󔬮)$ OՕ-Hm խN+ t2Huqd AHa)_$\PwYEK$ۢ+ri#^3f:/IH (e+#"Xe@Ef'qK$ 5/TTk3JpBK(Ж:~pK簓H±1x\J |$|TWdXoˉC8K/J[^o9h3AmAcZGiD /twT. @g9h3&A%L$7;ׯg$`6#$PreX$״o(IG Q*$J0%MW'jG $6mm (`EWJOH,'RmF (`DR6HNڌ0APѰרRFrjf BF!a#DݑS!|JBiLrߑTb|glc mZ )Xt \7IT+[Ar3^J\ױѮJrnaB uF.Sd/r$ƭ!(D_^<)R+CWTqμ䜻877nʺr{]<uq s΀Wӧ%˒^C ,جra,BKܖr}9`KiT3@6}`JpFr1ۦ5|r G+g]ΰB-`\"PP<$6Eȉuk iXz`#^ldZ ?H#']F!(D\g?⢣eq,X6@^U/7H&s.bU' nc4@92 A!V;-ڡi{`a!$Lr~eB 5.vG)nzW{GΓ'CPD:t[6E/%.7^tYFמ8.<}eg\Ǹ(wYqd&/ + "VrJ7{oBPU$"*J:'q%y|~RK;"zrnczix qFS91f A57 9u Yc(/'b=F (T~{(N\ 8tpбXz9:E.91A!\M&rGdd8!Dq4r~/wg&@4Q [ñgM/F$<UH ~߻:SgJԎ%`RN]͓I_[d9YRn}Jr߫h.g-I{54f$U裢8pſH3u(R*4I+iPI;h.gI͇+iNN)D8D \cB[UQںG*4WZXF(ѻ`[{0HݮoйVIwkIN= ٢YYT2G =Q:'Q yPQ{WXI㦺ZIU]m$Rꐡ&d]I R[*KZ<\Â/xO]]/\^><;;<>xe|y lFӓO4|d7~ *ķ2k ow[Fr 5.#zNC o"#'ynSä0H_{kkP|CnùPﰪM.t`Qe枃%B-d` j>R<-oI-jďcHM`g-O܄"GRC2p[$P(=h 5 _%,`/-) a B zwYw =m`LSY2y(3|eeL|Ijq ,A?a^պ؍= ׄVoMfmr閴7BcebpEa0S.W/-y视 Ab0O,$&A`uOMvc JKz 0`o_~czn gi5;5ǴἉɟMd[5 Y61 R`o/>;U4|MaЏ|CՄHWXƺnq78qZÏ. W]`;&Bcx`XYD!ͺBNc9k = Ga[DB#Q5:́(yN,7h&gZQnwU w6p_YX-*-*e8 O U C^|+tPgOXø4&qC#FW6J#p2MA|TY]ZxJElOؖ\V5`X cn$£~WnwgЀJ0&?(F=l>jٛ>|QzTa8\<7_s@744Yviwc8BqMmT@ٌϳ(׊ D|&u F^0HIVr^AWCAzUhL)WCVVE*Oe-F ZZtԇr`-AIf7݈DP778y-jS:QGe#˚i8l!æ:kKX,ßl'r/Z 2Mt1&^rkOͫs8#j@cQG"uޅ>-z!ͮ3ΰnjxjjmy UribJX`M,OY71YOh0.`no.Qxc!wS'ߊ}y7ِ*^}BZW:|K+3A֌!qCGn BXwճ>FZcDsjuNd{b0 Q }HlV+M_ws8!BDv"@#>U<3ۀpIfw|U}<;8ט@iܦEch\j[5]'㮉A171bz0JEn`aMk{Zq?cVl U(>-θ @f4žtGPTۏw-!fh4-Ĉ [znffȰ^Y|6h$'BO]9r{v۽G,Wɥ@F4ndA1k6Hq|.UB_{fM?~a?[ViE6d">9Uq̟7Q,#cdEN G+)K;d4sK=FX')rRb`T >RvrFc3֯/xF0Eͥ7Մ_dRC|ʰN}$x^D[JOLʮVJ5<' f<S[6u*]EWZ(:(JJѩea$E68F$Q)J l3ilF3wX$ Hũ[Ie y[ KC j\ܻM ѸxNB1nڶOBll<fI$i)[,>k&dӘxG 4.\.~>H!iW ̀:ܝ1#oBs7E^CCT|A^fe CTrR\bsg/Rr"v: .{lC<<.Xȳf.fy#-uguDOY *zP\.+[5tPyCU5VP5| {#.˭}cjĎnJdw}&$GօXS_;5{s^KjDѯjer$}kfE#V,}fƿU<3԰vk䧟;2tc6c^]_2mlmT\lhRQ._ᓯ#=wl1N}r2O}&ғg//M}m8Muv!H=;6657P2y exb_>ꡄ~#Q/:CM8k5ڲT=X7*JÚM2m"i,4\^8e[ n>oPwig?7V$0zeIO5  ?234%i)c x2HbrQphc{w&'C MvhmhTt'Gx=ݣPKj~AzzSbdoc/index/General3.html]ys41 MКk}rq18q0|wv%ےHr6/O+iwuxo.~:;0.NOvO sh_쳌V8xk$5www[w-?i\k;ۜDSlQq46{mL'S9R$,sϟEdm^<̉iӎ/~n&Nh绋́ioGnx6&Ʀß~`۞;cуG !iD@;&9 CӘzjBζ Gn ʹuYZKA+^ kB؉?#  h?;vk2crln{ml\]HD-]Fd ;SC( Om\= I@لߍV* JhoȌNDՃ։(|mܒ tZv򊠍3ʣZX\0tnuOEl4VٻRx6-T+v2:N`o;z[?L|?n8s9/i_Kr+/g{Upߴ ᲼7fYޑi-;6lWeo2j}*fUi*iU̴ϲUδɉwc3s}U;NVL?Z2ퟲ;m\yĸ1 vƈx^8wF&~;1}?Nq0nFqv3Gc|؟ Og { dzp9_n]>^bJW Jҕ)™JpAjĄsm)cWt_a3q X“_O _ד‡yW%tg 5rt}tt' G:Ncei/N%# ?PòFbJQ8 YʦQ"qrJ **5T9TjI+js9M܃P ր5E,,]g -| z{rXFZ!?,_Y۝;ujmǾľطa @ܛIɗC~Gxq[j[uKz9P_4r`jg񊷥/8jtSIr_@"y BT+Kj(v(vj0s-^ד]!g/cbM'hMjzv+> ®( mz=}i @Vnjo-iҧ7joJ(|e+!|(!IE$K$!@B  AyhߗPKƆ 32>7,l"QĿ>J| X ݾ䪄s1>J(r{JB rUM9v% WM-qgA, (ɖp/TQ>!e'rI ]^P*L8儂,1 6} 'ã|b1IATqP>Q$+! XDW鑼htGtP`TVʨ+2| +HX9>"m12 RJ~"8U#.FkV\P"ܟW9oXj\bQt5+j +쪾$sT#s0 g6NTU r^ꩶ([M^OE*ZB1yBGqmYPcj[؉1CuNkYuʟ `V۝-ܖl=>ڝNm\Tcݥ6/rCvVD]C9bkÛ+mS[m.'o;%6GDOSܰaj#: 3]_EҪMVK+3AAs岫mր>^b>ՖvGXN{w&mqiiK1g=.S&% C)l59>RS*1s_:Nqs~YIm?[-%T\JeSg'VE|Նeq|R|KKEVVԜ tzpIMmZ[W [ijr!{R!nj~U^LsP|dԢ#ڂz\KZ`V?ە/WSyBƯ5UJ\@iվ)F9~:jڢt\Z߰աSU&Vf2geWڧssRvKmI^r)a]g.Uۊ**݀xl[c\99YVceHem?霜j˭wwV;Ӡ8?x~廋˷|srq|v>l=`U0#i;Km_y?~D|C-c!~3וy@"\g)aj"9N$4n@E$-+t;[j{ߐ]hB<\8kmvq-߅EM?os>ᜌkwd9<"jC(FEcvGMs$+K/UҀ!koq6[N>vʞʳeh25%ХגPKϢݮ=k |#vVwIl/y%TxnO+ b'w6UGqa~ځ# u׊Ƞ5:1MbPTجn B[+J0R߉>z 9;ĈOY&7.c{+lpDG*Q_2PڝoI(WiSM|*~rKp 8s  C:9g Fr)C/#dĔ[_^*!^7.[[F؍ ΜSݢƁU~w1U%s;ظkOH@} 1"@^.}nBFlc taĵ穾=5c8tA?4Z%[+ kwù<2 wF#^ԉ"@JW--qh.明ccR#X\x%U?Ċ̠\l˨8?èJbX*Lt_N}!^*ׯkԕ _[ԒcU7MiX&n&fA˯c qOs:3} kqIyq\)h zZnؒˌ]S]ai×,1Fz0: /2Kl~i ^v ?Sd@b@uI~Kڲ\Ic.y &knւM܇h..Qhn7VEeIп `$//t¥+* HUve_ܪ1+v/Մ+P>Y8`Pwz ܇xnQa 2C H^zu֙Pla5xVS{LH]_Zmj> YJ1t3v*1sE\'l}Dz)񔖴| Qa{6+0N:j_Z s 1Utf}9NIV符^;Ǹnuέҵ/Ezn`Ц~mL|ҟ!3#i1c`1ucgF:vݱq$?(Ӳ<:MG$ˈ6ƫ0T0Ƿ`nHۼjK^9!|c#VM A*#/č? g=jl)[ lQvWA|7= f<{:JvqXVnnxCf؎En7. CzX=eY/!.+Pn;|h| >i#r(_=lnYyS=s.'na6]y-\so"x=̦<t@msa'& CڪnjL\WKnf`V&TggW6l[!f_N+z;2C~X`eQ*lJ@/"h *ơ{n. X8a0^Vx kR~y篍:nFBKLH*9=v[kC6c("Ο^GXKL%QǾL!fV]bKV } sN7 G;>on<h'2bIuCKsx\Lƙ &j_]IWB忤iu &2=ԤWu0O}}wbʘR5~eplmuPsį Wn+˒0(~Q^Ĕ㨦&dG>^MM&:XƽwL &;I5Y33PbE>vrIύ;R?򮸴,T-NmIJ @xrN➂DžEK{ya8gޑ'?.#ݨvLӠ r [Ftb5eCaL2Zƿ|+˽66.=@|e%Hju0Nf]??8<PKj~A$;doc/index/General4.html]{s41 5'z8>h{<8ژs`;Mwg8$N/@Yj]di/oO^}sh{j>hUji8|UfʬY »epoVš;+N}>.Gv1mSCL0c{ 2!u`!_ÑF(>xw}3؍=d`? *-\"⹇Bi@FiBt{`V*UZ:]Ox4 Ilx7}EˢpH^h5*-)J Bv89vlT37E&hF l<;:'Ag>#,B! cwe11~*/2w_ 4~@6 `wj%# kЎc ƙOC3a¸GaQ+5c4h5V1mijn?D(9 M` "q r ϖ*vh^W ?m] Fmdʴ^T^kyxhZZLHi+6i:Ѫi}UFz\[wߚ[->uS3:{vnZy.LbY.MRѴ*^ֵVwNVMG?OZ6+ºslM|-WYD9\N8Nd*X쐤rAnԹ2G$dN4C܈3%0 ]gEmJEmd9nJ/%+)UNKےJ̖|*y.=₷OnРv¶}ب| ËNڕܨ)pARuLrI{RIْbR"AVu8qYRY{ٲbl²x~ϥ쩣Xml)1M H@ :ָq-)pܘJ~1aSlH 0#QVumpYRYs&rfYTY=R9ꈩvDL)LO\RR&].lO*lNDy>:P5˄-S\:꒠ՖT1O 2cdfWBK^N|Ÿ:F]dv'c^!UAN9J_8vN7o~XvLpE\q素Bs. )i 0dD= a<퍑@u,#,-3/^f2:5I$+Ցg3V&=w;rMA\ukqqRq3OkU,TeukstzɈQsugeE4S#+`o<]<ꀷZJ7rAȻX+60R.o~WC^K>F/DV` 5L4#LLYSO+zdZjKM_tyI x_sn.p݂"ԓ~+!UD$ao`uU}y(uDopE59o.(YMTO)''0duoqɈJ!Vñ6Kuos]vl 힁Uq;kWSx<\Y؄h'T|[]ca ‚ٖ"{*KZ~{Ԥ÷)%k}a .&ٛ$]k#^fD٬U3A(a:>WX$=6G|[^ӀXwʳO5F5q]鲩;ϥc}lqFٴl9h^FUш Vrl4vArlMwފ'v\[C3YJ7WЫqGߗDzD:LiGI>Ֆj"cSD gWxK{.(]Mwъd,׽7/G1R !w{sH2x&FQ>rxS6=J 'TS{"rhC4ʃ̜9M/}k@}ۈ]F#,۠{mD~gqr,Xx1ٯQ1t x4n6䗕i[Lf4Cb1bdasbEGna0#>>dh1|h3쪥IT*d`Bߺ DNMjWcl=E09,6udf#gp - J>V#93D}FuF#8"CPGkkbݏjD#&|֠PK U?ء'M'Bl.NpS}q>)bzOؚ)WNҷ; aC8C!@ ҙv>Uɔ@ U6;Nd:աxJj/%Ŝ X,\Fz}iT)3"wg٫C# ?ftd ,!m3/ 食c\| Cعwm]_߂m:rGwԋ,^2f#:{ if1GH/-˲=A+Ѱ U]h?u-+0֖?0 2 #rsgH!`ȍ~ddM&9ڇ2^D8nT,_Ӭ>XjPr ħ%-$jwq^S'$F8N9MJO_6x |ׅNIGm{ilF/7a i;)TOtG'1+W/R_[8sjR-k7aΓL$qR;'جf xQqbOq;b'ݬgSp^9OxV:I"Іeԟ, YJAsB!ɺrB#1NZD*nFoJVZONj%_s7%3۠1lJ# H߁ۨ]l N_ŝ<DŽwRM0Z{EhPKj~A@"^doc/index/General5.html]{s41 m~Zp(BRs:N67Ӵ0|wV/IN6,iJZdwG.(_ϔ˫gGh\kGq<ƛ UQq<јsm?߿9lDq QUva0= {{z8s T[}JWy5(h({{Ke ֝#e\8,t|8F_(nyDimTzQ )0,-9Pm+?i6nyaRvV&OQ{A4Y*Å91@G&q~|AñO(_)ͽ.Q\+ {گ$jIeMgjI9Ws~FdP TTKվLgNX{{+{W~ٳ+վ*{jPZ˞?=IJ?9駱3]e#7yA=H F : zh8۸ ?st7'(iէ"lh@,r=q*z;L_(ű|$?Uf0\dt4 *X."0uO dwF{LXbbT!Ro݀w Oȃ t)EГ\T:R 9Kl[&)}fRQ _-!_&UX DU@m1E"mӁ2^oS|ͲY"b(m4M&Ҥsi4;t TC UP .TގAjEjwzNڂڠ02 n{.,Y V/byסLABi^;7iwo7> |J`"=HρLoqLKqxXaNmbr1[Bhߐ}tb$73 ^ɘMti E,c{A1yf@-!SlEQ!3LA~4v62läluly|Dc,}r,نcǃCK bP-.ߝ<)3a` 2}>âtXy~XIO $Ֆdv`:Vݖ47VkP7ss^ 3>l]SךM ך~- /EblQ\[}(zξS~m)<'=#}V#M2s)Aʝ3ˮߢ}m;1Cد6uJfA+'YzεiPzL.=5q06+K/VLmLsc4fjv(f|"k*SlYӢlulYl'd%L%4fiR̥XMֱ?ȇ%:-CC`p%[_EK.K')r,v&;mʱ$^za_ ,^|4v$uXv4JΥd6!AC{B7Ka@gj/Aefgr36>TbcR-:\-}xϘ __'\v:TsyAh3%|3 x 3x?%Fv,JLKLAL*ڭyqYeEQb]$7 qT{VPђJpPE[ ;wV"׸KFQ\p4MN50:Á/v\,7M`+IwV;VpEr ]IhIɟkћ“wKHW:>*CIy+Hv 7mA1]|a{L mIp(xMl CxףۡdX\2 Z,egu9-{*]Spb!q-rrk |$ M`KIś4In.4D`5>R;0FZ_*4en.tg\먇L' ^VoI}.ů7҄3, (i[< ^ۂO\TWTd ]Lp)bX,v >1nrrIG 8t |C`סKBV/;-թue [R].~KH国ϳ*G?mP#[B&\_ ~黉$zAqW>/4j5i:]$j(6wKf}V׸DjžZK\ҵ [9[챵t7m,p2(p XLcrawgZQ?|1J'&$ .{%9 bdI=*#]ΤNC77U6L^%"Pig }:~cW! a=Co.`}QS@H BIZ9 t2FȶfZ3)28iA«HЮElea =AˡVw&H"җ| D"P|Jp3> 4=3?묥u>B'0XS.]<~LFJ3VtF列7t2Hy\Bb = v}ip=}D߲'ƀt7eUvYUN1+)LլFۊct6/sCb3>K|-Myԙk}k~9nZ|k9umm5x]>) Oף*ʓ5i*'kR]5q i8y@Mֵq#[.]Rp|ʋ.Ԩ0gҬ(PCJT!ת$Qvޭ(]bm4+?dE*eeWNY[W A2|$A;XSb")+6w`= q<ǃ!zy[Hxc /q(m$HsbeAS\UG9Tφ#e>v'xmhqn V`5a!Fحi}+Zp%V3oF +1  6J0 Yˢa3l#|vPy,1% ,[,\Wa.W/3{u漡O:f%:xŽ>X٨̶`tz 0Bvwut[|B )XdnuLxP&3w8394yeH܆n`C%Oح7qə(ټ񩏇7M~phV߶oۥg]Ar+eY=+_Uɗ,^TeQQ;KŝEa?؁ٮp*)Z C{e~'[ q0%Ǵط8KG)x zfxG2 ڣn_r!o1hFIu^r!d%' =.(X,+#XcgH~R{S̅av=ĬOY/JKm{:UH ȳ",/$D-0 "]l?*Ҵl*-xCy-2o]-teWwk[Z$R"Ax}C۔"*zw/` kdg:ގ7e ^!l}R'w xhEV떼ƀ&#jɮHeIK|Yiiԯ :V?M$!i$TqVxYWiIw0e>G Ypո&.8'p2vd\\zka>|}f7[}19[!$$<"]WPQYCQx{\YSk ( {  P6ǟΓLDk e4;Ç來'?ZQar_S^ұ+ ?Qp,(ԔZɺe4iish?}U zJoʝ+(bB,"j y!$'&^otԺHoHֳ%_eudK9;ƻʣ3턛]?-78?BpkdˏezcI*i$GWJ _~z(0x7'Bc# Mkh@WT\xuqOl4>;  SO{A*})*Giw7wɷdɓS Q4=qK-no]->+~ gߝ'4.Rt3-{G_+DJeB$K!MIdWU.w%oz *{}UgoQP`mdKeW=j$ZJB U @swQAw2w!kVBFڗgrWTjNEnf^8*~m[軣T~Ċ uK),\Y7mʊ-'9 "IuS1Rzf* To"Jk_ᴺ܅9#~Bs7{%AMS@ze[STrR,1*\ :vj񌰚 c ZkFfHQN7Q%׏S1ߣicߏe0oX/V%hX4QV0]|[8)74f:ڳuPd3oP>>ŏfR5~ph$F\WX#3HTOa\D}555>=7eh]4/Tʧ}gmؼ @iIOAwd|g/PXӧ~4יG?+Q8FO?4<PKk~Au%doc/index/Properties.html]{s41 4kܵWZ苶 qc1v>`$[SZ;N ssb)ڟ֫凳wvᮦo?v=omNtMvkym}nws9v,lO?㏶2asi軞Znytmƾ_kVrsOC;t-,?|]z66vlͷ=+[Vk!}fGoڬPΰ`ۋPs viZ;{3+~;]=ZA`lnvO1`G->:us,@tw"}/QYm,DӲ3}zع>=/B^Eb[AETܧ[>}.#g?ӟ$~֧?c~Чe$>4K|w8˜mma&e}o2Hgу)p;!(I~ ؇s(*L>~^׬wn?Mk:ehmIfk_,#`&C̻[x. l7xb=\EO[q:KhcoXIb=\ڋ *J" ;_ZW:/Q6-R <|j1Y`t`e_<خ l7ە%$ P*aw^XZςjK_RL9]iu{WrFZ J{2=TߖHꇵH0-$ ?&+-΀cȰKRTge(Xfaf[cǭOʉ+Έ$k(?dGtÎcߺ^Y,Z4VYep0Uþ3n3]<*B4:z"C]bUM3:2Ā{ʭ2[fzfsOEY[gF odJ,j{Bmo_$&IJFw#/{t3UºJ+˭+ɁV}>CJzXS}ukr,R_*osv_rhOxeC;,VRT0h9;1v$; "bIzς?JeMHI)rC 4=FB4]i4&Y fAOދ5—yφy\rBPC<2$] eAYk ,) F) !7!%aTɭ)}ׯk @ ߐp&ԋ*u"^!|}*ɣ[=*Ct )`NT+ac˰#X+ўoe8 p?5'0ݫsS֧I5LF:R`V3'oHV FL?q2ßf_LO ߲`O>w=F'w Y{Y 9z@ }`cew ~te)Pk8H+3W4TCBJɚW*d~RLս,b8pNcͪS@}PZM0;|8~X* ~PWE5ʎ)]w!%.<}C/*AJ0GƎ ) s ݇B]`;qR̙EGj,0 ϔ.ԐfԛGLOӧgyud6$H(wb!%y7UەoU:#q$Lڶ+јWc&5d9/2Ѷ1+(Q*쏬AD6A]KrlGڗ!oQQ8 `EE9d'5 Q& +12 %zթ2Tz95^(.X.s) ͒iJpEFJ}ZԘժ1r"7 EiMa)5` 2TT%SɘI6ɰsfwDi4O )$LHDdY.˾=Kq%C6Ri1Gx`XBG8 J*$75p@}!`\ɨ'kPDXxklqotUa<;Z PL+; O`SavbF<Ux{/Koh3lߚUyEx}"k@ dN5x6-N` ѻ$'p t"RJ98D'c6(~U6jDb辁09ڏOAjN "s@UxTc#,&وba5bb*`Bqbv+MRpcTZѕ)#HDEkr5 b X]"5E[MNaqF0F8}W{ 7 ;vYUeW1Zc4 j`oEnCgR=T9E4hߗ]"3'j]Ө=v \sjIOF #%=:FPKr` RjZ_ ^kDj4'x`"v&[2X)•t5U_}gBF6oTlUDzAFw^b„P7V/LOa|#&Y;Jr{p:Wou *T$Hv*Q5 t*QۭHe5$ʝ^Eht"i66CfS]tlS N߭Yt+O)31}σt?'kڙv.j٦酯ddR-ݵE+*18C5݆cz:Sl lEcȵrI_!E3` .)LNF%/L= ?3Sg ~|P5n̷ח- vS%% &UͪvVqr/D:{RO$g5KkJѭǂd0<qIA ѣJr7P ʢXN<+ۈJwS+*T;rZX\!Z}K.ש ˱f s+V#]1a&UdiE[ȚNk`zg3\rx'4nrW?hs<5/(~meLv߶"aO@}o vZn<EϏ{,}e Xﭧ IyPJ{ M((J#_^>>ѧ5݊wLg55K\\.Q-+%yeUVZmeی0;*YSo2u+mu%E_OGk8?ѝ 4jlG5_;[tYg,pTIJʮȃ!SpQok{}D,_i'hѦg$=vhmҬr 'C_PKk~A]- Ddoc/index/Properties2.html\mS6~3TsSC(g@B8"qة,,ےb;u:liJzq^:WGs~nN[HΡW7uBCڀO\}6kUS}FZ޿kr1 2C0*72Jg2"ꉻ 7'yiW>if!F :u-*6tQpl/D|6q? iHPԪU]ClUGCvxoDO{CBɟEɲ |io`a肷gMP_N yvqx^/2=R]ֺ{ 崯- 3Y=ЏH;_-dc W]GJ[P̈tY@Ƅ碭v??+@'bǠzCPYY_x6/lm5W`*M<33:$/cm8ЇmYG=yF mWyf~n, zE[*(ziѣO5]X3 hIAS-APԦg* ]9VR1DMl輲e+峲'Ydeo.+"m2Rی FvAJ}fU;0=:Laf+-V&3[HlrB cGHKПbnn,"u1ئ)=˪U!OfMY 3%J1nlb#bCZldZl̷XYEWpzuis=|#`ntvd`D]MWɥa;mv&۳]ewZ0*"Ǹ]!Ǹt+fyʋQ'xGI,/ؔ?(|'[R'ϝ6Tg7]In&Ż lsg[l'ԫp גd.3#l~A#7(^%E͘Z>Ð$f%|vD??3.3\ K{W%8s~Y<+'Fle&o<کvpFe;%k6_MD)3##Ɍ2ǸxozBz~ e$)\f鍽\;?{2 .3{k/W 'QuDճ(]p9=}|<^>v./:W7b_NzYyqpX3x<&Gص/؀ 'ZGFSx>Jw,^RWo { L&=aб}w8׭((X,hŐ[bˆV?MF׶ ? (,Hzb aa1 L3 JI(>J/++&:ZoCV@au$=޾Hpb*\Ib3F81{kw EވՒ⽣'D ޒI'|Q|ăV,j\b- R|\SD ~H˘, Zl)Ϸ)dъm`@+F6RiCi5 r{` G}XY^v)YS[^;QS z9T||z9+a׋q^d#I\T*=jф>r6j+˜틙drh&svdxiƦ.1v 8,>\ IlhLΉ䟋xQP"=Ea.My!l>ѩ6)&lf$5˃?u~!kXtbb#OBSpvsU`/,O~XT{#>=$P.SԸS$RQ[e S>!V$),= vQĆJrrT?P}=TZh!6e_ےUI 8,*iS~vKw3qBbqپŗp%,aA( ĒY]ٴǫ$VZS6N+DQ67~HeHuåZ ر0=f|48L2l`<4 \C/sFe:De#G<\LEð-I.yW;d n~G e%DYl\dDJ5/(6zw$=7KKը!+=ZCAI2ITxu^a%k%ˮz¥n;ǒbˉ L<8K)^7Rb*ZWpC҃@S~li ]'!0/,#J\\}D=KD.?)K4Z@BGߩ@'뚊ѼTѩ14LٶMK+7E h7~Sz*a 8͕~Ž/!Q< nOVL,2PJO Kby<dFvw~/4Ěhҥ<_.Q]$%y eedZ$-NmTY]0 :Kg>;A~@?6Էr~8̿S#3j,~OACM} 7S*XcnTQ=x>I,,6_5 o*,:C8M 'yPKk~AGdoc/index/Variables.html]r4 ` e8M'qhОÝ8;N$[cYSEy%}ZNO~9^]]j7o//N4}}lޝ AyFY->m6WUcnCg'hva81w}lk:<ۑ?~{Ew [&בOQ=6YAhGGo0r"~g5vm›Oھ~p$W]] lHggZB'ak?&9W@J8 E죯G떜 ~78En#k3e m+̦Vd$6q0<ұ7PޥoM7h"^*_SUD~8uq'Zf?K(&%hljX-HCM6~X2\ԟG;ZNIG?5r[|ch=B?ז{wp`?LMF9# )/xanztl8￧}8wS?L;V8lZC޵c}x\tD];ՇEYѵs}x^tK}eѵuѵ }x;ĥ>,*J^ev H`h4P>So[[]ַ O}S>>{GvSL@خ.=Ŀt?M*kBp}:w0O A7ϚCK  珦IE ˺}},rXq<$A]ğ/|ڳT[ݥE zcF7ن5Gu$u<-heh_?&_9={}EuzFMZּ!`yk(irMtj:Yln e* #AbQ%I0AJm7m]p5G{4&?FK[K;-%'R R:G䥇t ""8)&HGpX+DJ JH'h$֯Q|bH!=H)ѦַEַݯSQLך o721d Π t`Q6*V"^,6RhPGlylL.2tB"C'; ;hD̰TT8`avOj&qՠp8kFnO&SO )5(#>bFdkP!eep$RIUFwMI n\8q.)X0BL )mS GD8 W n:F뵥LM. 0 _e{A?uM+A)m6y.bQ7#pktζ;THむ$!?͙k.k>gAgzMRfݦìq;8טr+~܆ }laV2?-)oSGoN*eU'RyY9hƬvZY~m#ˁ 2( M: [lGʨ;QÑ `&JUsȚp\.徝ս%ҽ`BvZ7K`Ire8g4x9vTHvg1p)N˓&JR,R;aZ5N gS{x!K.p$Ⱦn<1Р"eN{kFv)#2bxb-wNX+]UH'˗]esoRvܥ8qrSW:)+RVG8Yu{RR!])]ﲅR•R^= DWѤK ; 0 +X7p} rr>BKA5z>XyH ]:V#IA /q\6@@eZK9|JZ*zDs)Ni>Xs\'֦bɽk0dWPYʭ Uƺ(nr476|M!Ҕ)y%TJ| SrrôDkXm Wu0jt)@ ꥜ 0MQ-$M;IDYkFDinCA WDyg`>q}i@zx}zA[\WGz}pbg=B|-O'g642NX `cHy@!1%k<+"Oמu-!BGT!+Ή(ƫ3bˑ~t9cVa)w¦HKf9q eZ @M [O@gRQ;sX2M`rډ9(NX( HP~("x ›/_i@Jq7t,G+r"ͥMG>ޢ}BdgXGsVߔ"'d'Pf6i? BY=$w}o4T"( b,`K+Eʳ=[U ub=/Aj! /{T\O745$:u@"Yt'A O"UCIFvF9k '%Qnm U,WLOI0.mN.'$}l蛞b iQ?s4˼f}PXjgͤHN'w /QDaZaJNưܕkJOlO?bI]d"FTB@ V&Fx9 αU f> d&4 r/P46}qerT[ʥjE⯍)4ſȴz?T6jw?z`}`Zt̙ǿٓHЗ+wFKPHji'bbhTԽ&'ȎVz#+PݺMro5;@ A\\- %!ylk@¥5Y#J Ԓc9𨍑CgHDԴ{6ڛ@vLFp!U/ajnʁ*oaľ#y5IP!2 K4:(ǗWn4ڹ3#pqI%'eE: ,|mע(ekeg6%Uɍ 瞃&ev-2vh>zw{ff]^9w_FFaI`0 7&:^y6w0T~cQSÆz l7Wp,ޙC@*6 khX@Sb,f`>A``cv 5`Ԟpz3 B-.̷A SR .%LdN=X˜e"8G-_+20~c#YujAKQh8ɝI9Njj [8VOPZ%d7SndePF eS(uW1,&jNFT9Vsc$!Fz@lu ٯP8IHv?1!#-˶2d8Rj0ޭ,QUhk=וu lr)^G[P!XviMʖCE]k6X& ~4s̱GTpaO{gBT6YSI"hW,HiHJ,e%}_ĘueƢJeƚLuf:ZMq %#fI%kD;1Pa^eЍj nV}0BOaUIbImflR$ !eѡ^%G ЯTyEo1 ڮ/J,աpʗZcjTc lkK_UqnVN}p1<~?1w 0~xuz: RV:~$Us5uHvL+C6 u ~0l*ê!Owu1(ttIX.$'ޒp)u"iooPs_8CQO-h֜wK3;Yt]'2T-Ucju`-t @9YEN38hYݠ0a\G?[Mr h;+\a,6ժr$lZ:~ސ)\F 29`?WwNxh4l$BfY$(xޗ1s}\N# c Vo֣Ng}z?@02t#r[=6îX++s)fsfDmK+,~qt?c<&[BNa s)06i''+|iIDj(% rQġ#iAw2p=%m2u~V,!IK=TbfcNcn{LɸUV;:D壈GZ>QVzjaaJVZN hZ9U5(r ?wSQOB-I736@,e\UC9t<ˢ]L6==U+NXzU %X]?)9,/$2c*v8,g37}NVX#82AʉY<{a[iE'* b#7ݝ5$,j;AZU4`⬢WZxqo] u3יr{?zљ \}샄K]WWHM:n kvzQgI;S"/+¯ ;jzrb#񫽵]{Aa"%i&s6G$}} & -n><-;.4%E\?wA*)zHb9Sq&XOfsv09.#r9'(WKݏE_9v{ _o}콏uw`BeL="z$cZ#1I_$r+Ӵ:Kjj\IbU{Y%bX>':2&A`r5}N =^F{?w_i__iǟ5ZY5P?{ !$dM09u 3=X{,_%ep~hgăioY$˹ƁC-?J\/U\NdD4'߅>PKk~AXD-qpdoc/index/Variables2.html]ys40 tmh˶^^4]a:N&laA#R_?`8yc:cB}pdXƋWq=MF@U݅L[(>m4xB6Na=0r5k^\"/p?OĻ#} Nav__̯M1\Kޏ~f֡Sl2ۡ矡/'jC;dF ׆n[džuİNz֩^3:ynXz=o ^ úHVKúԣteXWn `o 6}nwuW4DϰzEO{a/a}HANA:81i w ={JP)uu6Mzus~V.mHPpܻA|5fs6]2?:,ǽKaYnSUsEb/Y̎[w'w?3@^0Ӌ-u~dv>{t$T˪ O|\fQg`@dMRJT ?Oedϖ37F+pbORlrvI%By|n3%tynI \dhܻgˎ<3VC\򎛦EGBbLZxƬ8 $H VShږDضU:4.P-S`*"g/tAr Koڴyv%hBg/hVv)ףΧ[mO|:8{rux0Vƕ:nuĝޙ&:Seiq++e?ׯ¾Velu'/''G@ٺA\뿾_on.=^-pC3haagZY1J~ϒ :gԣ&a@BfXRcb'B'E]VfC1F~gA"Ķ Pl 0 _Epb v -%`9vt1;C n㮨7paVhba0v#.J&)H]f4Oc($yU&Ր@EVז,qPO֠ n`uw::>\qrN!)^qD-ur]eglGg4AdCmlbtJ7Ņ_-NtJ#y1{[B/Mt9؍նmH4AURʢ>ېiAxL2zi-ss))qT2Ӥk6dT:j3yE5+6d2 uu;3!}oqކp3!6t+* HmHVrEoE/{ld[ˌVgȊ ܚ$MGp"&c+~k7]zEoM.49k9%fGl2VvSC`Kx1AyHV ;}=s`K%^F7F; ;ϻ`nCRT-L(6>H?r[VMsˤRc!]Z]|Pw8N 15nڛ fFT=6duRrvbF˭ӞOδ6sPˤ6zEj^F!H8?m{167]` HVjPnUz - 7 ?&}.0L;kmC\Ց4/ֻmXEW 9g݊~`oLF63)r@>=1no< h'n_WlB7t B[/>sԡddLE*K6PŋxVEi) 3Y ث>y e̻ tEw@B{busT='cp@T,@M? ͈=d i9UH'ej.d;P!lDF:|};PoEު_"+WM,Ѻ;DX~wGL[V]?XC:TJzQp/_`'2^9G\(4>h3dK2 ;lx=29lTX|.DO֒G\J0P6#\ӣ"}[:B>-q}_dj7ԟߡco*{?^ĻMKG ]"EmDg'__b!?aԈcp_2|>B2ﺰ9K,56Ң^F$ N a2o#Efמw<#;?w^//Qū~K6>Aٲ1rbLJ˲Y>FnX5 ""Rlџ"~NU7J_PK 'vF@doc/javascript/PK%O<}iZ_ddoc/javascript/main.jsi43І# ft^B]Rx$fXf̌$إM,͡hf4-Bfa$Mx19cxJy@z l-MsxwS1gh^E`@JL*]T2f"l!f7g3J>ZMӐlpG,m]fl&SeLx^%7%߰ 4*K*a`S"xQW vl1 *(Xf և+>OXx>B|[ L1}m"tW0 9l!SQp[\+iѳ_I]yvp3`aoA:LޓkJ GDtI!pp\> z2 1rWSDƎY!,bƪh=V`3'au/)D?jM?A?.P%[O'brfxn+c.méN(w^{"[F^K{G;.U(Z!=K ͐O~S9a;Ep.[03yeŵV\WwP~4VT}|؅-vZUNWI"t#/}H L,yEfaqBXfJd߆lWQT^@1w㉜n[o1l`pX1 <qzNw+95x۫|?LއxLz"u|,Xs䒉 b51%[A|C J2L2 cqJ}ʝ%g]mL&gSS5+$ѽ.hQs3Mi_e[39G) ©n7/{k0r=5}.6'ӢPk$vdȀVjx z;*I$ۨk0ԥ3| y܌[ @60U) h <ԀY"> ٯvsvMlh8rWbL5-E$9Xl_9|zpx p vMTz4;rܖqzlpe2eԹAgRFY4$%ᑧ} > ql;#['wX/ EMV}t*,-ܢ𒎧N09וw$:Rn7r"/,uksR |Q01O08n5y0;P/tLU)hu6# ; FE=m@خin#ædpG;N[F`\!C;MH?(2U ~5sy.6[xLZK)L[}$=t…*,Atu9Ryڰt>c: su D le W -8[XjĚ2_ɨCRXE 8$ۘF DvIpΘ[IbA]-JLi%7z&F]N@BیvEȌ3X R*b1y;#X&m6.dfT6WOgƾ}6\Ťj&q7mfqIݽHw*"}ٜ( ƣ\ې4ϰ 1~Ebc)/્zߜZS%Upn-ns7r}}sކ\ԎUphel(wSiR$?U grYլk(*銡K @ Ujl6>]4#A:Jbsc`ՇVE8XoY*v[AcFaGZz6= 0 _yпh_RIKsXZ+kתWS )ě4\WFt*nAQVQ&N(y,QKWUZSw-tR@噂1kҋpC?[-0(rb*@;B@ |&NqtJH<:8#+L12QBq#Wx@V3>CdFXQ+\R@ё bU!0x*QkOa5"GI*.BH0p2DR3\f6k5t<`o$0/U' mV <^m'aZ﹍Sk afx7N/QSnr^!׍&'Jq*W4XBC0 yg}h /? 0ɴ6q~P)"A^G5Ȅ-/ +)CKs`tl]v|e%m$A\|s uPSV׬dvmPr‡8P Zf-{Whf<̐V;R7c.S-vrðNi#]{ X]];wՈ͖* 9Ԍ;J-*WoOBhNb7hŎNAZkd˝߭'0-(Ǎ9\au}8 )Ѝm0d?Sȕ;5S!t6 ̩p3R' ;7D*iC*)n)qړJU[. lQj9HE~M[8uP2lkuЖ /_zÖUz"z\iܵU!=Y]wdwDx^) EJ hsNK1F ~"~?}GhWT>2Ǯ֕yC:m}ZwF[6AK5^bg6uptv9fjB灼+t[>ʻa3bfd}mPK =]ƅNdoc/javascript/prettify.js]{CB?Bz<\C ;l PbK%~~ffLH>-kwggggggggg::΂A:1r: A4Gg( (H/ߤ( NQǗw:\NuJ}&6}`xqdA8q8} 80 q͂I8 0MQf{$Y2ij/Q[e4MDIDPNf} dPQAULo"@hqpADa,Ja =o?5Nxnityj^yp5wdQ0P([ZbҡBn$x^(ӑOrۚ)òJZnltƄL\1μ )ڒ˻grbI@~8<yY4{ux~ vxD1)Z@hDhȴ;"s$ИDӒYxW)X9AI4Y&5Q[ޖW#Ʀ<c1PHgAh$M&(9t6@L/Z2#i%Nِ(G}G2ᇰi ^u38Q3xyQٙx7PπaH20s:ξ{mf}Eh:j`m|Dps= Qrbx6G<oIk{/Km:ˁXj#jq[ nmE(qG(S,R''.FGKZ"Vf a vNޢry$gwI8U/聚-cFh[Z]Y&2bh6& /Ďh\`@ n9{{2F[QRйP:<^}E4BsAAHܺ/[`O4MfqT@<>96#e]UbU90/^ aُ{"BL|8 PM J򌨆YE,QM'^iX0!-?MQvuEH ;\E9w:QCD-,Äg(FEcEØp60/5q;zD^*Fe}zX11O6b&Q賾4 d@$,YxI&9< 1 D6|F,+1**+$i+M0$y0EX!a9aЖǃpN8MsşQfRkVmsMQP mz5} f^WN#̥E9+Ԗr)سj,7nH~pebz'zwRZ!=KcW =6z(qy>J4viw> t%eTde-c8TRMDFZ7hq j Am-o kKW9F;CEpjҺ0/ Howgpa|8bjx=z~0'ȻִI0&C6Q, EYE]o23%)B,h$Rˋ9ᕛWjRN,j[K!xBF uк rٽqwJ(wYG/0YGx JW'~˻`0.(.ƣƉ4q7;#:Cq&54WU*FD-ѧ}^')M0BTE 'R\AR뮠W)L`YO+\bҚr j 0 I @"I-:"|a^s0)aD8<&੠ dpku B?/Q[ ևhLjaM?9=Oޞ@bI{\[~ǖ|SQt*W: M޶ `ZۜaMI_J!Pbn6ݦ))_~my͟~Ƿq}Cl<ˏc[9ߗA^tߙ{mֹM YoegY$)D#ɭh~Q^ÔKfpY,iLbի<ٺ 6i=z#X]-*`k-qh2»ީ_^kt[vX5tKepn7[mfRsZU1`|44] `|m^FĘMչ<{PNc+chØqf)iv 8(bs*hv,9Kq ?jP߁Q >`ەא͑2Ɍ"Wl_?V10u&&H|WhuUʜDcپe[^]2BhlD@) Yx v"AD[Jcvf3%^U:d$穟'''C㪿X h,E#sa_rz齻w;l2^+ŋN<'d+6#-=B G Tco8`>FaĀ- |Q_UK9}oW*ne{heVsRLI n$ܡT}rUH y!:TiNģ3Hf"5ȊBq9yz:= uU%)fJdWS%i$)fnLq 5!+d^DJ>"bA)ysgS̲wBґ<;g%vh(ky -SYw%c`r:D;>%`&V:3WR&o5Xk4m=&R )$F>..My".BYltb%֞{ <}Jݼ0:> לZ[/VOҘvrFIN(4lIx]7BxLH3vm~J>,t -r/j&DJ߮JamyU0`(1!9EUyR*3!AfN԰i3E ʟ7|AtI0GÂPPlݐ4"1wѝv9kpF:śob`'!P! p1Z`!ؙJэDܙt6VBz!̀ )%䟐[nJFPm|VhiƓ&2c놔'AL6^r QPh40i(i : 0E]gFM2#ܯg,Hܳ?6:{\@y9JI35PrrVa )W=fJuJdQ]j[Ce<=z! :]۴wa_.#ҡP!1ՓX9EG$ܝݎP*kdʆW[*LeP2t@M 7u`\]}_{ PH3[FWidHtjytДrJJP{Ta@jayԙ2k&X0ev+lq a&^e6a[)l &"\W*nߋD܅ikϖ`2뷩(tlOl ioO2>ؿ^<$EԒ g!DxtE ?,4|qZ)1Xx(!tvrvdKmos3 h ~&uF{BN;xuغ۽5?ϋ7[q1hK ܂$C;]=3Xy='eMpDޓݳ(K^F2ؙnG~m]F!-i.%6mXLnꠘ:uSR鶶nA0Kxt,8ۦ~qЂ-@y}JWtՂ@$,m}ag{/|a6oz?>k.&9ʁnWުzyEzfWV(:`MTuL6^\< [2v`MR [ʊnEm朼(F|K2E`s5<ﯟ9ٔB`|HJ&%o >_cxA2e\\^3+?}M?}oz= -@elNۨ ?EF$|ZA_ "SOGu&7iwS#!2V8$JM޽FlTɷ]5csViz]j}S?4*}ZXҰ,•uK1Z~"xk%f5nM6T}M{T,:gzQxY2dt'HK1K+;PԳ Ow)F>Vqz827Nn7FkivrnOzap4.2~u֐-k*d^ך7C_ |ӈ~:B[q$ HGx@*Fڮ%'鋄aY7PG=OkZ&Y^ tم(8I%UE"CHHOu>7eۇ]PUs )1NS:!v@DhKֻݝ'[RPzt܍Hl!9Q24q!tH9,B)I#{@T$!60(ˋe0ߤ O\ؙj'e ʥXP?鑎Flri:@fS!!y`ISrJrmlQE-שN INϺ>`7:ͬhSn63H klmvWQ5=N,u]✭] "iՅWK,`bQ,\;-5zW?!E _zsˡZA,tÅ[tuK=(* Na+%B x"3[*a{Ђ2aZ#9ȿZ6JWL}-s-Rh}+ ,aP59ZoZ )̍LxCmd'JN嬍PfeY a*g@6,UAuuA77,DLzDtJ:\-i *9=jq|+h<]@81sF}4_&YDwz,pYĪ%s}9p캘9Sm*/3"{Ho%N/vm/cx7v[RQkBE@ 6vC4[P6І(+FV-i,5TrN+?g@yOJ;tF?p -A&Ld H5*Љ9iʝ2awJ)P::F5Qg xECǨx{FHDq'  "B¨FҼ@ 9RPk|L-8-n@$lzPd)Q)2gutH/5X~8]&ٶʎ}T^.zb 7^9GQ:~:F9!UD42eGKWY\+c5dB0<vvⷹ'ܐ'";*E{+ )!^+}cmJ&~nܫ eWk}ѧ(~-p|mwo39 t닅7Qq",_Q*X"ᥧB6vY*O6pαFw|ęu/:ia %u!׮/Am?|a~>Edn #~yMrFi!QJ8Z.֙k [\GK#ĭ`gZVv?bup*k,gʊ2ۭ)rJ(w|h0YB5,m6"'eřU s'%SѯAHL&;yn73b<8i emذ%U ii\$  [ӦO@ɐeF8G:-1!yJN!VRף}62 M1QU B"{dxM$ SDɜtr\C`;30'!Z5 x)]ʴ^~Fg&ҕJi1*5f$c|8)Q{*d/KSB\PK]|La's5[;ZUKB@ mbU6Gd3cNwe;b] q\8Cj[XbMvlj)lr\=#inT[ۢDh/ EiD|F6q}3-'e") ;±9Y1HW(ն`?Z܉qIqrcFh şSf+K}= WGe#ۏ кhz2ܻ8 _cTFd1_b":%TƀW8 {9@q)ؾH5 ;_5Tߞh]*OY{ڀu r.e.k\sm^6Ug}/+QH|D?b׻a-ۻߖY=XX=O_JE moqPGplDĮSs- G sORѣy%:TEJ&3<9 9(*G8wO.XG>m©dZ2l`3Zs3`Kp;|,xj^^ݷmnG등L/ zUn5\ +ğ$*sJ`B bW>^0tSy/Yb-ӃYSobDNzA֚:weֱnAeHW^^W OÁ)s Gha"z52LF):-.ѕ˚x#6f@Qwr`lJe1AU F1R߽zUX<3t#U:R I5KQ Rd?sG H A:h_sA&*@IX{z(uJa^Cɒq8s̶\g֤%5ء^%d#ӉgŴꬆti[flJw6:B["S{ i+G7Sҙ; =D G7]ػ8ElNYo.V8 tqKzJ~aD,@.BPQ3UrmL8wMDY) t=UEʴ*]:uHX+Jۀml/* yM*y}!:>Sv+׸K0}hb}f"Sy_^f[ n>o5pb,?a^Am4z{hh[lZ@icMr!{hk:XugE1.GlR K:ec-F,hP*N2lJR䁺0C4 hwE:UkQtk 汊+3Sr9NKV ` H%Kɋ }.`*fwM]H?^UjKNWG5y2΂|FW_j1ld!>:)W +j(>Yl H^5]/-3 u]z*; k#Ԅ3\_juXd;f٫ÒkDE[6U=5cN3h/&\\ :&8kHS"/L\.8k!7ƹLKu/l-n"K=d/υvvo)[0c62 }Ʒy>Xqn;n Żv9OlmsX|OWkMoF !_,`A%QN /Kg,H*DIjToBǍ Zp,[6(P6^~ (N%[C׊ m^탡ߋIbѩK9N",U+@0UL}f`,5Sr T;el2قXxdEP0J51;l]:~IX5bF mvQ(3ؕNd(R&.tPT~K>s +Ro-gֻQq s xmVbi4)dxRf 4fqLJI^M:z[i@57dfwP("#%P]:c1ٴޏ'fjv`wQ'|_{+:i7!4;r% ;3iᝐ~P*'djBaС#0ENe6eDm3FDc Sa!O ;WuP/NlfelJL.U*ze{XZO EM" z ZƝ٢N-E s)Fn J>c[rC35Qb?8Cjw( VL  _p) Jv*kqz[h:}Ev>[  W$~QNK/mb[MwRLCK6 lY~۷e29XjJ &c+aw>¸ujhKP5/1Et=," uRˮx4@oXв }nӴRcSf)5tkMrcN7#S2G 0/1ÔYa>ۊ1:957*%t䱱ؑnz!7+2} ɋT4$>8>^}X t!HH-?jvґ sIV\Btߞ,x eD;IAad=(ڪ8ycwXf;7f's2LZJQsՉ9sS^ D`wlX2Sћsquı%D}~G`_GD 4uk@ɷЩ +L8?=rQV]W1UL`<^ѽjշoP݇*y/Wۯ\oo 1IB(GB(`+Kݼ{E'O _Y4j(;P4iԱa_!%Z oivxEO僪XѠ镤0TLܹ<У L׬q^xWґ-JC텊źZ. PX55f ֜oXȆ6=5v6J須wY;e-(:nvj,Z bYWV}&YBG4MJ`Wh)Q/׵">;{~fFKn _0ܛŭsx")w J+x Yɶisf|MU*S,tVh ڪ˔o<ȡ}㦦 M0"S"|W XQf1Xa$+N,K ?=`t+{x/9𳩃JQ/=-zSA.w"h-~6EsIJ0:%7 %ŸF5YeQ2ڬeڬF$xm PS 7ֶ]d189.TtqIK }BB$(u1E_p%5S,1YWS7ߛy@yƜ|y-AP_tL.Œ2јkYT(׮hL]JP2fEEhU(F50 b$& k@ J 坰3# !gf_OSujk`f1l9>-++-h)(- eC'귽C OJ?h|9F5Z,;hach8c-xz !Ko\O:xxψ8N e\A[Q(l^.rxKh`̮'[v Dć08suL[aPz\dv>v_峎 {Dq|6b:qjVBTE`Ak>`2pND#ig=J@zKWnV&eF]3c +o\Ey#ҍ5"߹a ) ٖCou&ʈTCͲ ܩm]h³ 4WJҿ2  q[MEr2q.)O qD:TZkc 헢;-S׵vw4pԆ#W=Ybn8̀MF'؂lXުQu}}} ӛr0y=y©rQ(2?>|p 9;Yf~|glնu20cԝGt*,QSE;;9 K 8Qh )8RSr :c$]!v`DLQ |8$RhC*6V 9S#П6hUz| Of~d[UN!UYRڋ K|$U˼ +h*q0WqR/Ey[hdL} t'Eh圢P1^^w.3Qj<9!X]$sG=,;CiU2!THFT0/[G*f\aJcua6: o`cpOa"/^e!{tzIQj58 I~{!=R 'uU{];1JްD"./.ۈ-\W$/Kw4ݽuH"V_zgd~'wuA[XPP!Xޘs|to`hTv$Z hwmDٛ:궼_[$"x(q,3"ԷSVOX_x~z`' 97/~ӛcO}&ᶪP8;.JWS/BƍbБ|V@5*S'  p(pj LE ,NPkⓩc`ѺSgM/ vU}oVпѿ;8P3d]qk/abH{ Ӱ]z@XHtPY-Tq}v/x<; 1y84=kCHAp8b 3KWBi4>:[(DrqCY! UBp ;'TeQzrxǢ 3t.]-N8#mzP5T;&]NN<ׄ9',rO r@g H.pbYpx͌PI*7G%|5Ўa״XPY3 q_#qyyNyLπɟ_:Hy9js?עQ-aͭ! N_Mgho%' OE]oMNr<-I _wtgwʱkjl] 9XT~jwtB7KCS5Cd i7y 9&l|0\Đ3cvOy9ivP̓>ut0y4>'α&ѕND1%Iʀ(L3дmi^7^h#P]l1:|P;ze' ח_*^Q5o&~.3>}mm8O\ބJ$W=N?˧LS*D4 r^F=uOT8zRAUT,y4 ~o-=`eA* ꜰ_@T /宐z csOɞcp]\Ň|Hڑ&e=VΩ7Xɣ/HRlUT^w&[6+T׶TdOP]Q@7$Gh?ɜ4t Ff7QgR#eD(Іt%'7CvӜsc}]0Ҷ'2MB=vTL*b*{`5?>?<[T, vN=3q~֫KJTJuM5rF aQYvi\ TZN54rH[F֧^U)) 㨜SqR.ѐ9+o!\/S `#*pԆT,4a zGw}I˝+N)Zq.S/7Y)\铯t 4ʶY]o*;=$DZi 78/'muϻ||֏~a5(LG-uq8OC ; 5 j.A95 +iTш`!ʃ< Ͻ!Ep xb{Hj+8"]cNXUJseZbU:4̥m S(J٭חʰm?P ӣ0S,1<+,jViQN}  Dʮn\]Plj*q NF0Nu.=Rpa) ֌P΀չ7\?s x ODqtZareon[ uF8eGxˍ^8?Û ~t`SZa^lVi_ų7-qs}ՉHcz HZTQs[[ޣl,s3<y8WNQRc?N_te #n|-Q4Gyz)?N?"TJmMփ*yRxSdUg!;xȩ3_g?aWB{Ɨ~IxbE}v Gu(ƻe7,ݺ @ 2g0'Af?{|2_eQtouyH<ꧤ gzAkb~R񅢗@=|yc2L@=$yh̉x46@(L\"qBL"ހ8Us >d&ZѭH4oLv:G)24^ܦgEǨOB2x tNr<%|Ry!2؁,{aY  t+thڍ 7xvi)]HDY&vPvh [^bx! :JrF\M>%k5:2l^r0bx ^Ed iDz4!=*)Γlj[{ hdsI2|j? (R+ơW$Cbn؀\j`]%/($mhw+z䵣i0re oj,}_fGEzhUDKQ`0O*l T)**DM協=\I&dRJͮUgO\4R g!8DDE^]o]kscA 6a AnD`(t *t@Vb O BhHcF5\̀΋Ys:U.@)Fj5~V]q?M+&-E*[ D& 4D6W< G ~ D;^!DAn0"!ʞ16hHV>d"LջjeZX˸."Dt[8iGiWj4s$ok1߸v[[-&zj0;SfƧ[>o3# ,iO >0\ěowCHNSӧkI2gKgLKɬcV; NeC=}\M#qd`9:%'#7KV1`)NjC}.aEFW%!+fk?#;3+m"~XWnBބ)+ Fw44>հ{Z5_99;(xJǏBk %GbjXp-g /Rr2`ZS,gʯwB‡RQm4S _IK qMGg,"5|1yC=(p"zNH霄atl9ү|?괶pkJzs/&8KG, 极4U>z)IF@aK!eR8U4L{8ӷ`}N8%4ZflC0`YX7[,EQopZ[ƅ O>FU/2TZ\7u;(g&|1ɕy鼏.i4w|/5E3\=XTv|cupp09/o#K'{.>A_0B) p3PKk~A )R, doc/javascript/searchdata.jsJ0s{; ϟY:Y ]*I:ٽۯf"}BDۗ=L?ٗ`eIVkf5rb⢝Q󢧟 0mgoFo2%Qy 7h(?owׅe8Km`RP\\Jp&7<> G5iM!x;$VX%A-˖U\g3VWr@.D࣐3߹I!1St>SH=%q_c`OPKk~A0y doc/Menu.txtV_o0G;C6 :@l!6UNrM;sg;itUg'SmJNG|_JW |myN"p΅9XhuVc 12_:;}LJG[IˆKN ̄upUeanJr sȩ[id.]`|iar4JePzUDctX.D*|z B 39d ţ^Y6cLϠgJR0՝kJ6:M<\}x|x2RbT.=Dnx.ƿځPT4jg -$X8 RC#")͂.&|Ps8z*`#gύ|!AXC:ʭI}r8 2 I~-ZsM ccz8sm}Gt&t5Y/2,ϳޥ%S!+E9crs BY[U6B|A0~5\d^%HEĆSQ-lZ(֎J#T]-R A$7L&[d3 QJ߫tn^.jܒ٣6- \EJQԭDiWaH nmPK @ doc/search/PKk~A]doc/search/ClassesB.htmlV]o0}p罀ĬiMP`[VnSeb vf;|h(0!s8M=uӅoK;h0yƸ3踍Sq%Z1Nr=N[Xiڧ Q0B`4E: Q[p͸!,D43" EA', 󌩄1@~EBH"$1*i!#|T 5%h-3pg :8#JFEgD-SEՍF 4Du9j47xASŤKPc*S(dj`3Cj4~0.c2$ьp= I2XI ǖ;5x@`P}b Fu츋OyYT;b QM{)Edh2 L-YSrBi9[vWnO#) N렋.rdMXsͽem]'rdރH_Ȣ0$*_uNS1jI=̔QN-d%檜o@:t`tw seq5| ^A䊱8[m4Ì,T2˩9-J?p.oRPVU`'jX|ՂjU%}Y}Am_v**g<__jb4' {# 6%Qbl;v mv<ўkna|wy}``6pe1l6,jg<̬ykԄPEn>2Fh!1Ka0*ԏbdأxiFf&}ޡ$iSq3 c -A"Fa=H.B:Uya,ɒşɚLViMzS |-sI+H9:FcYŔfKnJ#Zඎ:C h_Q\ɍfK~R+3FuPD Z`;B ^40U'!vV a)0>5S:^oN{KiFxxg .\AxNv=wE4=&D rLo$2d̥L=H 4PZ[iEj¨*ȳ'$@$3Kǵ^&ji _ek+3Vs0I%}*nQF4c:Ihšssõ5y1̅fQ72.8b$`݊sDn  P eBOD W%ozPKk~APA#edoc/search/ClassesF.htmlT]O0}G?\V#qlFڲuReӞmgMqZM4EJ}9z7QL`t{q50~Ÿ79Ǚ?DZ0^rcwTJh8({G'uD$" @g02v fSrBiڕv)7ƾ45te'$c"3sCxA|[o-h"r" d5)әDU\DU!͈bxnpx*?>euCm=ebe(LECY=4=v9H3k^Bu!_M &* QfΟan#] 9 agZcwu4Z]vaIa ;ͧPKk~A(ydoc/search/ClassesG.htmlU]o0}p뽀ĬiMP`SKM{LlH`gqam5!ksN}?n>|^_jaqos3q%Z0^rcEݏ X*e",ޤحB٣ƖxqBb:|>(i$!RL%ikZDY|;^4MXNyA,Jd+҃r0G|836% Tʢ,d5FZi2Eh-n0<^1,.q0NL=^Bbgþ5a%KE''4 T QM"4ޢ*(čBƖxIF:[|ޡ(,)]q2J5m -Q A&2D }1*I*ɊɆݜIMz0S݌ \-H+H8Q*DSQŜd3JH#X4DmuhN,VQi ?Sk3V2M;(Hfox-uZ_g )y+Hs*)L.%0: ^o-{Gi&wୁ"#b a;=NvSp1j8͵!*U|}AF&1 R $ӌ P6hkYEyYGrc3/ ȕq}A9ȼZǂG`ݿUyVDL IFU4Є5afku j̻)cȩ QAv_2UpR(9EW`Wt!T n'; uAwMm5J;M` _PKk~Apdoc/search/ClassesM.htmlUn0}^@kbvӴ&y(=U&1$3ہFS}vJDNHk&8]wG}< i޴g~J?`^/Oxz^VZf QRDjV?lrM˜"(DklD*ÛG= ) %*T#І_bC؁d7#bዂ,h)W;3`xgy͘e&bF HE>D阪i52$ Ѱw]Ej#;<КIVT}iïD쌿-$jnx _g (y+Vr* J]H 'bu +*U&8ߞX wୁj"+#;b da9yOvͯZTx Q٤=/~ 2 41 3!*Ĕ1`QNJ#7&"y3;s-( [K3X,s)=V70͉4Ҥ\ "$jvOUc2,QS5~, zAeWїgnl=WW>nSG[ qJU4P5ݪfT[kgԆ iڼWO23RMBO0+] NװZhOjh-honV5? lG7PKk~A oHdoc/search/ClassesN.htmlˎ0H1VИ4Y)0ʈ!9Ki۩=u~4r5Fgޢ/^ሐم(GxN.^@%} ƣA=捛7& SFh3M0`+ Hz0ۖ ^X&))/!ɲ+͘Ji7X)R!bE$$PF-] ]ѩ)צ2kj|Fae.-3TDYSFe~`ʴ⭠I'V }k0y/Po.Z1i~&"r`-f=c 1'J#E6wJdy[kӥ?=ɛAI(a QQ6F?6P`iBQ`dzwjhMGʌnC\@pN{WT"u|fBT.;pK"lp37 lu# U9À9X7PKk~A!doc/search/ClassesO.htmlTn0}V,vB,C[Wɍ&Í;NP_\/ٷ>na|wy}O`6s#d8BRcl69R-lB&~8mT CQ0 N!?l M0 h#^@Rfw(EE)h U|!rl3V@'*+ /KgS?UR씇y?c_\ AXe1T%R=d~-)hp[G4/([@gFs ?LʕQl7؎P-/\n]q|9Wp FԔ D+^7|{xg .\ADNv=wEe,[%N'Sc%Ad2nXd:R1$\]bQAGȭo cm07ClE\9 ()v(XSSο/Vq uju7s(#yCMr$4aM9Z3|gK uP,ӅUrstnEk@"z P eu\~ޞNڷoiw'O}PKk~AN|%doc/search/ClassesP.htmlU]o0}p1/X Xj;Omiw8RP7@kE;6ç% o//Bt Mzw1{B5^`d2"~7X8mT CAp)%7B*B]`RAW2GVڷCi".QeDz*efBj@Yʦjn67r9"Q!quwRƦ_ݫi gTޗ"J.}&Yp$fE6h48{n.}y^^q5J0Ku.h̆=z tsl@_(i:f2j[i-w[;O'ޣƈ5贏 PKk~AJdoc/search/ClassesS.htmlTn0}3/X Xj;Omi;NP_\'70t|9қ|w1;B6 ޜcd:&~7XmT CQp)7B:B]`ZAG2GdI&ޢ8i Ҧ\/97״DkK˜xY46ct܀٢ }k:sZ%Ny'>836$+!Td^NUs]GV̮%en>Z$9fJn4Wn_ɤXٝB!KKhŨ}?KXV U^[!qE g0+aHML)ҩ~}[J7'0w\JDNM0sOUTʢAc(q2K."q"Й0qu B&SrX5ڗGnm|?Ifzό*>{r:K&r̞іbNu}Nl&j&E !qݻZ9]u\!PP,",uAwuwU9`-T;j91Ku.hns5Ud|{B{t rm2Z.K'`ƴ짺kPKk~A.doc/search/ClassesV.htmlTn0}V,qB,E[WOmki;NP_\G/z7Q>M`t{y5 0rŸ7y?D1l6,jc:>|-IbS"[Ǩ+a2gR?a;K43C%7PH3d 0_R,( Dh3V@* p"Y3Y*Hv<񰟱e&i )'Zh$"0=hػVjAp|͡5Srr҆TLQa-l7؎P ;Yb 18 >21¬!1"z2'fJgRͩco) O V5Y[ٹ+([anAc(q2K."aaL"CfL*T܁qsZL= h_]Cf~FIDM9Ϝ'3$tFY񬑉ZXDJLLD$Ղwj݇tsŇ(CyMLd:JÊs5z9̅倶PV]L眔1R0tnEk@7;bl{]B{t]om2\~ސN7oiw OuPKk~Agdoc/search/EventsV.htmlTQO0~G?ܼV#vlFn0Aharcӄvf;-aώӒN6M}\C8^^( QtǸGp YVxu5,Fe0),Pp Qf0\`ZAW2G<$JsL?PҦʹN977Dk˜xYL`:QYa b^9%xVIMz.#c L j,b©Jk豕F Ņ,BUmu6h :3%W+W.d2)2x2;(drox-]uOZ\ŮMq|+j8Y#jJEsD+IoC^SZ}#<22 @3B6 Ws]l,_؞jq31+L%6AEyFǹk᠒ w0{Oweh= @y{0֏~nq|PKk~A(=Tdoc/search/FunctionsC.htmlVM0#s^> Ɂ@j[@VN6R!;8‚Px?NGr5L={=pp> ф)0l>f|4JΘu-\A׮_|iWėZ'dEm-+!N|uB^rcK͟GIJ}#dBJaK![K4bJYE TղKk> s-NX ~<fp|t\rk2uS7yy.l#4^k^$d2|ێzSoDkz+?>|+tެdTNH\TpERz^+K v߿3Q6~/;Q@ w:w`-=QFBx@`5.^Acd;;_TU$cU運CFJ-M)"L ȴ)I Rښj^ױt9Jb0K}h34\T>'sU L~déOxA0VS%E rw̶L˴Čw ƽyڂSɘyLںs籪w%d1\y]et/Gޠy B}?Lzwk'rO.ƭϚSoT~s1 m~9_~_WȸlaRJ=SWoѸ+.y#Gro褏9h=o8ÑSs ҡ՜4]A8}_ߊPKk~A]Pdoc/search/FunctionsD.htmlV߯0~78!+ j|"V`Zv 1C{ѐl]sCe<0$`>cc|fT^a?Xڕ|c<4oߺ}+tq<ÕC W:"}UXQ`-EĊ9KH\as2/2"n0K!,C`<"2VԣNT }+C'jcvuL +C7:C,_ֆr/'Ϧ@t܊ -40PykM xH>r2w8FڹV+:ޣg`,(2#n8XgtySJCqhy"$JgBG=H)4_%ϲo9Rx6Kն_ qNZ-ag(~dũݑޣ fFs0+Fnv(>!1bg1RB2d'kԬ*2Zғyp)O2O(7s; S7Ž?/L өZ,k8uQn< TuIlh_)ߛX;ˊGj ڪ~74M)6"֍'5pO49p!.NHp(n8C%NusqԾ45foPKk~At4NI doc/search/FunctionsE.htmlVێ0}G@+H\BlvK- Vn&R!qn/J9$3xן~ _x~|ܧt04'~ɬ-_P\.c_N/ŰeOzXOlB۷n zd%QPp)xk/BWrif˿Y'gLnWs"_@scWsK"4i˥0K ɴb)߲4kF53.5h&JV fLHƪ g:.5c&bIHFw=Vݾϡ3jiv҅O_ | a 3ɖ@Z~<*ukfy40Py M$<>r5e+odCHX 4ls ;ޣg䆻AIx*- qr1H4^D.Ө}PDFe3atu؃ aJ#,IٮtQǗ8SӡzMn0 OU ޹j뒵dU̔j@َMs*JUɄ ._^qwrxqNv]Lcre,B,835++t| FHYxKGp|H"% Ğsk7o_ kܯ9C˴5x MA:oDXb~D5u8TijM;TC:g6θF aMVէH:<> _NiuGܔB"p5̫.b!Ho qH{ G¹#cRmlzŮhǬ3yp{{qOrKtB?|V d*! #Xt$@X; n#. -mB(e5-yxp |gzϚ"V;ިciLrk2EYLlqΎ45  .+uFEЙhB^S\еvH,Uox[`")mi|A*cEW '8E;0p XV{-eoTMjX|eo^Bid޼&Erާ[!N&mpBj6_Ji<2I6M҃ `PDCBFQ0B(zCfX_0m)^ ,fb9,Kn)xuJZ.m4VAf %xYN6<Fi, 4 2v+9㷴aLYtQYTjGft֐ GŠ_m!ԘMUUW3Nu_pS kNgMFQ(XBop҇Leu"7bVw{c %vQtyNB\rM-g„ZS#'JSg(X 4tdZPkgɁ{ Jg3}" J/8&Ɩ.ҌdT4svVQƚپtHv,W]XZMcz]dJIRto)p72 (RzeE6m˅i M@.wiN$t$c1i~xXm~]_7{\V~՝yO|V/BomA 'KM˃XK؋(x OuJC6M}{{юo1DSܤ%B@mHα~v{zYa*A .nՉsT^}Bo{=;zi!ݸthGM }_PKk~A doc/search/FunctionsI.htmlTn0}^@klvӴ&y(h=U&68@>;4Lb&$r{Ή OzQ>Ooatwu= z%7"@Kcl69ǙZ阌`iVCQib03 GGۏ%,WPp Qu3i49į"d!x ɒ*Mt7Gq(RҦ\/97״DkK˜xYTb:Qin@P(G_NVIEz[扏G |-uFY^NUs]GVA&3"4VQ}IshT\'˒be;7*5BQq?KXV U^];!'.30PT@/K)i& ~{[J7;@MVvJDN]0sES(q2K.."~bCbqhLpequ B&SrXڗWnm0TQe[SJ.IejQPj7}kkm9Ur5D\BBSi0JwUUG/:Df7$KauXvƐ;zo q5Θ:$G`Nt tst!i7-Aw^{Z%[_Iv~b~eϗ}T__PKk~A.<doc/search/FunctionsM.htmlUn0}b6CnZ ݴ$HgvhώCNՄD}9εoWG _п98o ~f3m1 Scc]R&lxͮ`jfŴQYbhjRn>8Ufen07pY ď"b0G(Gu|q,?Xݦ=\ܞ)jbmJ_b [?BhH%/^>+٭m Z |ʹċ ZS_`y%wvQzd:IÚٽ u7x@.Kjr4t!2"7rι-Bݿ& [Z65\b-|sҾL=ip6pM>oPKk~Al!R doc/search/FunctionsN.htmlW]07?z!DY3F.T"xleTvۀ*1$s紧pe6Fޢo'C{|~8$d>!)FxmLvlRd|{kgDc$&7o ?MA EǾ| [ Q\[!6lg |5Ue)ߐbYgL3ob1Z+ qDrE3@c 2*Ғ,|C7t^auWGj ,eGqFLe1gTL3H&!WN[|:K%)[.ȸ̡2Vq:x!70X8'){`@~zΫ+DLQܣ)5XC4?чoD6a P ЮQ?xҽ\>զxNDv@m'ApFoh`2ch)UTG12]0U$sȁWmXiSk=n ܩ)t`ϗ29 z^.SïXpdIoHzYI{n8CU W쪠 BʊN`g*H\^̚?_C]>ЏJ]1&˹l M޵n@zZӇZ O^L`y[X˚aI0sL˃ֻ!~)O!,fhR0}µ[Jԡ~ŵ^T3}*Im폵ܸWxx_xS8zpiqb~G ^@ -/-3$rTnQz4Ydk⤨=>5kUS9S& ĕܸ]iKVV4j2降LGSapԟ']HУZ݌3f/фA" ( ~.nBgʊΔuA=+ :v‘uKjK]ST5 T/JPKk~A{B# doc/search/FunctionsO.htmlTn0}^@klvӴ&y(RtӞ*pgv&M=/zٷq>n0B^t zUw{B-^T/lB&nky!jX,CIp)5Bbn,W6GTYh'^Ap>PJ2Bu`"B DT(2N$Zd$U˜.yn3:)InU#Վ Z)+ Ԙ,Ϧd5&֌4T S"4ݖQ} 8= hu5\'K|:ZXB!ݻ4nbԾjh|%vOO@+/ӟ#W\S Qk*& 6\*xߜ{ҘU V 8مNאk:䊻E  qdjq!ҹ0O5:@¥4M^eru(]]vgs6ZMؠ.>BєbN69~_7exStϨvWSy*&4$4>[P;ѐv_}UHfsQF ɊxB?{a4T~L]}}x] X շڸ4fdRs7Ti"P| n:俍2|៪KW=.0(пPKk~ARx͂doc/search/FunctionsP.htmlU]o0}p=fm7Mm:iO 3vf;P4ώCJlՄD}9H|йiex}6'mB:Np!48#dX VzBێv&N[Xg3P4rx-_e>OP[I˥˂#*A?ZM6&wOG"?As c)u`8A"3KHK~33w3xs(f|u6 [574qj ])!EϑWoK FKQ[j*2ssM$={E٨}A@CNv J-Fu_TΒKcv`xOD.'i!ґ0Rq BfS Xږ)wξSc+^1r]\gfbPM&7W"M,g#%j;&tK~PpǹL UJF\Hzk' ]t*u``wÑY.{F }Ե'9UU^WڕЋ>˵.JO]SMI{ j&tmuQݴ ͋%kPW.$š0h7wN5lU$ m͢ڂ#@~.@kxF+1øz1g{T?PKk~Atl5n% doc/search/FunctionsR.htmlVێ0}G@+H\B䁶"(U[@Nr5L={}6Qb&J$5|Bv}t1KM. 6*Dׯ](H9K 熁U*ۄd( -v%'^H j%>8eJs[<(Y!f'N97 Z5TUH|:YV8:VYi@b]5_ 1 ?Yu#p,eX0C2eU9Sq:FOQ,^Kd2z[z47|Od\3VeHd}l -0HDO[:Y{R+x ,w0aRLHlҙ,e)- jAٕ9TJޣ~7quRY RNڃȊuPDFaKa)UU8 K#,Iޱ;rrۀqa. Xʃe\ݺP'{._J񀲣jd_eK9])sOT̷woϟ!ajwd -ֽ`ub@ MQKyiNSmD`o_k.hPvw @ٓsLꃕiu~se Nge(w+O2 oXyz_ +OD K$Tqhvwi^.Da&N&fCphQHS/*&66Βirj'˹ I;Gyn)8r*PU9;@gg'Zm?}\]譴+STzlد?~PKk~A`Ƌdoc/search/FunctionsS.htmlU]o0}p= f$uj)*tӞ*\H:gES8ZMH\&|ֻ e|~ë.o=xG;HfLrIoT36dnxaڨ<145)B74h88U""]Y,L0^H 5 ɸhIġȋPDD@!Z5L4"2bsfNT^U|W#?URn씇y1?c_D+H:"CYVJKԕ0zh L4"E^~Z%ۗ6NeRХ HvDb>V; +ӽ!g,Pq)LV0R\@O&,P\kʖo OH-<jS%P):7ɞEitZxo8K."/fq󤔆"@H:4i=ڕGnm|=r;}/Z!o<'m:֋FEFD͆IS+x~;OF6U|8u'n:1{mٻu]re֣؂EO伔;R.q˧.`E~m[c3:66gɝ}hc}<&P Mi"IM._EFWOZdB^q_ ҶKluoN GPKk~A( doc/search/FunctionsSymbols.htmlU]07?kb ?cdۅQ$/񊔵/vn0vsg=}?LGbL>}5Jy@p>GhUOnx{k" r1$[=b1_vZ; !k@+ǕK滊#(*Cq$PXgcRO`̐u;mɹC<"( $5 {'Iժ+:{ ߊa1HFe ITWu5tvhJSMcurH%tFo-7.]tQ}e;(eb7܆`B98q>v߿IrypB\qCgP C]; .~x/Q|| amO{ij#NwQ<8b&)bK~b<ghP}bS#ѥԆqRڊ>]UfuJ[X* Cՠn(rf0" iו#%8\]&h~Yݳv륖-pkPJh~ROt!.%7%X '_3Oi"S%N87H‡Qj0Lkm>К- ^c%;j$ݘuP;˨LJ]V:y(_렓tPr'8ǑĒ:^uԴA~PKk~AgCdoc/search/FunctionsU.htmlXmo00x&k ROi +9N$MP9\ڿ74~Ӌh|u|p/OC;Pz6/N_QZ)2Kzy6-t=;J>v޹{onc2 =# DDc'k~FނIŵs5}{~&ߑ䑃^G\-8i0O)LJ4faB`'T%A|`K62% DVX_f_#/bJ9x,,p&%WY1G|Q {;ufR&.]^CdJwp!*)vqu3GSM)4o;p4lFLgEh(<-THcAo uXf!V(*ڹ1dtNN[;yr̤IDnKSt"fB\:'QRN2ϟ6@ ԇ-nV<4q*ħދ2F̚?wFD,,o&) dDZ>e#ԇN6\:d@̺YfDg[^ Ss_*',&&M 5jDžT,m2g-w=[61oTST<,낥F|DՔ8Lk)@k&af`'ژޢ[&4?bQČ)NsՐTx·ch[o%qlTܐqYiX 㻽Ԍyib[VNvX;tF%f;#l(5hp9{ 6 nkf]dDL`g j7\ B,X[6l^5a7s660U\dlE X-j]nܬN\:TU, Np[ 9þ(F>cd$.PLG`L\4?.%y/LP[;887ڏ]2*9(1ٲ+*Oj鴰(566PvwT'kPKk~A=doc/search/FunctionsV.htmlU]O0}G?y/FSH@۱NP*ZشaNK ST=7Iw}ԇ/# "Bқ"@skOV+z)9w]wb3e(݉~9eiW2_&FJזx>ds s\$Jp3"2c5L$Ȃ;0 YIglؽ Mop}4}l 1%h1BQc~f X~_poTBM6f)$h/̻m.9 `?xpcc(|zy0M6gi7PKj~A[3.doc/search/GeneralA.htmlYmo0>i> w$RKY۩eLB$lƦI p UwsK{p%}=hBui8BӅN> 4͌k1\N5q#\¬#vLvaMi%uEN(6qN{OqӡADCQ cCĭlP)$b: Wn|"odBj& 4pNDԕm=%+e\PI]ГJdbQӅ=,a6y/nZ;PQt.o3\1(-_ )jmõCpW4Duqv3o j绖Q}kpX](XpwN#4@h,б/ #)Q#3*G;F@h#Qwl{k>eڦdc&`.U,'+sV铚2$Py Rq4m$ơ<9i ~_LyCXv x%j9Q𸦬S{q9 əOGؗMR^\KIZڷoʴt>"&( Jl;? PgK% ̕ǂ7Lhǫ:ixṔs_.?<"~|GB7otߝS * R+.{%&3^++(.}$ ը%~y^~WiLє}8) @'KI]hrɔ?geIXVz2|#È-Re'Έh.'g 8 93IJ8$rp2QQ3E1bں u0(`(V/(ju̦$WehV gB G8yQ5nf$]?͑69)J83nPӎ%jMD 9K)UG\o^Sᦦ: T\]K dAO,c[RE\YaĬhMUP+jNAqm-߄CgTͶk{I>\CPԩ$zE? !ܕfѦ֪cӮh)W#7 ~d~;pH۳H;tVJIytγZԤ4S(T~0G#k;ٴA(i@GQx"_ s漪h4`_/ s7Y0+CRW_ e!8,&\!F$[l S< Fԛ2)`8C 2/`QZTU-H]WC#8VHӛgmmTt\[{\[jk,Qvg?NR"o jݫo:s:v !V!XY@֮9UN6)pyfhuu,+$'dX4IV[ 0GҬWվ@mD)ܞ*ֿ4n cN?aˢOKr-vJ)rʲu{\l t)F%2}vi\ǧUp\Wk@d0\0_jS8?Ex_T]o}qӿ 0iL=@\+,=$T6*ZxGCXe[>ƬJ'&$/@AʦB _]PKj~A!%sr4doc/search/GeneralC.html[mo00xd`Lt}kilw]AwvڮBb}\;NOŏtS9c=39!7cw|w&b?9`Q PN۷ߝS"0{]&$sHr-<8/o:ϝ~7_p "$@?S 8wЄ˞㺞8J\((xǤ_n,PJ?IişR-ph@A994Y0L,D=:8tNs¤_ߐ)xƝHFWmtUw_V0f 9PS0Ww[ hΰ1c0=t>ڹJe$Z!y99KFhѣgnOi~@"2Q2g]z < Q;Bcd_)CkZz8WU$lr\^FrX0'%S҉gؕ#&7r`b!Q\ԅ[Nrs%H +L fTP)2%!-0* %alrbcm[4[.:i#41WxMn0kXOO 5'%o%LNrBdS*!$$#.)ʸXfCcJfU%3_C[ 62lLz19a;toX} |0Moc:±4 Cu2R v+< M im|ai0L*-$u3lJ>D# nv b;x >UC[0bM61%X! V fv]3lV$pV_ДݳEuMJ[UurbA%b Rm^J# I+y!ș={>rQcie릚Ԡ87oM:zEVrl3%Ul HڊvꆴG}4 meJؔ C5"e6Īg\ۏj` 1O yMBTh0z1n8x Y.X&$Ovɯ{?Q6|,,=˱ W$PRzHKOFC(Q(&% 6+`mym*TjwU͔2h+Z%##;o Ȼl۫S[ulqCǩa8hG0 R ^vkzyh-hnRF>ձ1$5劍rh\1XIH,6 Q=+ET,`Ťj1jMXM6eԡ߸i#⮤< MnmjۦfcLI)zmyja-W3ȣ?+Dl|Mk2Mrxm/vtF6T7'DS ZCcEbSK,4xjn*^-9եf!2{Ì׏ke/s}LFOߟ1[wjj 4&4 *֨Z#c8;!L4V0O3tF˅w >I>:!?Ϯ7яX9(.3? )wNvƢ8Ob"/_/N';F<$P[4;ڬ{Z6JJv,8#8jrNC9S#Zصrl.QNPKj~Az8\doc/search/GeneralD.htmlX]0}w0J~m΂:>1 65 :wo-(Pfgܓ4sǿ?_ tyw)mxB(1‘ JY<&BN^Hɓ3MBb۷csR2 m] 9(5k]Sku9$ξ"+L8i/0$jA4eqFT \er)N_dae,% D> jhuB}(Prtnߊ'5b4F?CR-|7j`a_8>r٘+ӹQ^,!Box%Ӭ|˴\z+c0d(ӄx0Xcxul\jeUObHsC)1)u1l3 UQ 0لz?oJkӮVx[*] "qg%>ҵ `3ȁ"FPi(,䁀L:PDlko [a=DѣdI~SI$"MF,jl"7RKk +Ғqr ,U_/x#*]q[ↂםN;la~=悷 mr8ֈeaO͖Nm?S94SYF*WwFz'#N/Lq)EDK1kp iU¶kC8<"!'Kژ!kp +~)7P,o@7;5r9yo@D{#)h)p,wm7;{7wT{+/PY,l֟UV { 7W%naR'l by3s&ށ\nk5~ym Xx[4Ԯvbメ [6^`^\xP PKj~Ab}wAdoc/search/GeneralE.htmlXmo00x$h 2T8NtI;f1hꗻsg;ї>z;z?:;"!.!Q/x`J/YVŌ.EۙEH%@9 [9.H#t؏,ZzSQ<إ"Z% THםw(=,:frΘH~H\BdAāRb2:c;|L(}\,WH>ܗ (>i,V1j3ܾMQk"J2ץ~<2JDF 7*>n`|b6n߄Ns9a TMh@U&hz<В =t>J$B:P.VJة k< Q89/.0<–ˀa=q;HuxmcFԊ#bln#*(cv ] rM plfS'nKY c؆fF3"H,kiXS~u$*\͵K #R߈qofMIN!ЀhBiq48 @zl?E>r/-enZ^=M%bo?pl-tnĜ*Ly%PטVYeڧ2 LfgyddxUO1WӰ"n;y #t+.@[w[%e GcʦNj:/vکBCW~PKj~Av=.)doc/search/GeneralF.htmlZ_o0G;&h!hu!6&:@$y8̏޽sNۻ1Q=a%b?g4ciֺZNGB2vc*$:N[n;Dl09f,HZ(GƂ]w<P0qCPӌ$4u96)BVznmːGK&TʎwɧiQ?19K2y Nw Ǿjݽ_ x8g3vൣx^p" o^;|S„5ϟ ViN!!oYXDKrA P>"s&dS JܤZ!y rAI{-D9xZYn~;q"t@0adED1 Y) A&(Rozq fi4Xv&Bh|2lZɌ/b|xT`1 T\dȓn)hiBR)t (`oWYa)Wo\Bf8EׂNlR%n9W_)$wXn֜ž ʿQc+t?mS0"Ŋm5kVM&ȵ qD?_4|D3iW5uqϡHv 9l߰M#r f ;DKgATϮogۇgE}* >pfP<0\*p >ɓ$q=ǺÅh>Pτ ].Sb*cJ6+G+%wG/nkF}YUn+݊z ]%*oE Ou_g:8{p:KC,on窌;Ge_yȨl}%W@S(q;#ԏ#J`^ 7ƈW  >Ϸ.6h=&khd]{n\qYlsu((]GBZ+Иϫ;>w3Ϣ =^ ل:̂7CbC<ٺO`ө56cQVջגǜOѩ]&Q1 53FL1"-+26H,"KOdN `L-1"[rDIie-![NCy ɜs2M>TdQo\YH#>._eԍNtN-1BV7sZek-8k[lŽO!9rv8Yx'8M 7?FFN'BuA@,Nh :w&EVvI=7'int72`BO$nkvK}E7i :?-ղ1udMyC;k.T]v]^| lġny5Ah߱a΀Q|:%oVCHrU0!7/\h7v%P 7(:p>`k6%`kh]ʯUg\]5XjW4U6-̣PKj~A doc/search/GeneralH.htmlW[o0~G?@+=B䁶tځxmnlCwФ9\޽EF>՛M~yڤogv#t6S"՘/eوD<;ڨ$4$2޹{dz9o CVMFqBcjQ3o/q$>f.97PkbG>&:$%0:TIf`8gc`Ss6‚ L,: \,CQ(>,z0:FwA#~,quQj] (5w$#T*9\ټѯH2Cf*1(.|h O8+:Z 7XF^Ӯw<u%CM҉Lce/(+}:Bx@JfS)9A~ɋn.?O#3X w3@v"IAK( ϰh(UĕB.X)cQTuбn^Y KkEk[O(n2BN!O;TjRc4 ?etdƕIq;vUS8Q⤗w4 G|PO_n9W ]S|<nZ]EwrTwQ:3a ՑJU\Gu-G5\Xq%:l\h7wZG^G!z9ZN!\tFceƕ?-PKj~AsK?ydoc/search/GeneralI.htmlX]0}w0J~mPqi'mSDMR( tYӜܛLn{OA}?MHgqϼ3B}L![<[3&ΈҒGڋuûwMC?e"b? >p[de5Z =XkͨTLGoZ/q'<$K2ajƘHEJa4l`#DR3F@@E%4tʂtNOȒA97#XK%TD^CFe4`H4F" h~m5&PjkKPLui߱V[HY1ލ 0<7_oh\2Y[+!Z;43D-˘hD} IzL*.2{İW!I `%P9NHQ!qvEs7qW^PQAM<25' PĒD4L8O. ^ 1u3-Oˤo$ӄ5D4JbL" mOvin>i.2:J ]u r [*@+} &bLgWEi}*0Ro[mCtc_[o8?յl]k©bb:)(Q;wlCʦ(Lќ,bd"izm#1]YM[n?*tǒ:Ncf¥1cӘ8fBS)ͷ }cjxniM sԹB?x㇝~_kEΏw2X':zs3j :ʼnSdN8..i]XVk ݞ9x[pN޿<[cL\iM٪]Hu4+q_i :*7Z\vf^eq<gzFs*VmU 6"p 'Gkr-ۇg#Cתgh/c?PKj~Aq"M doc/search/GeneralL.htmlV]1}7?\?ctf5,5>LjiǶKv:,f{{mz>` (".!I/l<BChamzOs2 nKC<J޹{'i`H%B~T|IM6%CY,_C0|^4\~DfYZn faL,)8k^ZT+:gft^ oGŠd@.1 *nj|qL%9iJ-4}G1{QtA+jmqiBE5₯! zO3'K8V~"u:dZV@!z*7`ŴJcgo){u#px_@` ЕiJN_}(^$g`coDp9O_qL2-L9”4wfVҢg!NڍY_ZIc䮶^5 zhmC%ME#D;!'Z]~ݐݝgKnw>:u!;';3i؉^ƗWjԟ!ߧcZ>]kFeΩ̤CͰ!Vw5mꪣ7q}qM)&Az}ʣpp! =?cP ^@kVB~VC=up?oPKj~AK-Kdoc/search/GeneralM.htmlXm0!(:Rf;uĄ6նI ݴ-̑lvn,a?zàsEz^] mקm> Ϭ3۾RB'Zǯl{6Yc{pm__ljmݽsN3 fgOn 1MgVh&Kj~H8TyՄsMU7,;UCGrkh1w>)2%]cDZjT4 R8IwrUhhJDt%'3շm þhܽߐHR'=&!dƚI_mzt<$e.`|4.ȟ?Me8qLst"Y@΅)yl= o}$I2EŦ{#EH8'/ۍSş 㷭BCx~4nee5ml55tΈ˃@l33UVe̩Jb xڃA.p$6[',PG"E#$pfm pWÅLgf=ms/_BZfYPnOKsQw -׷o+&!Z 9\+4AMɂ)S@ A5Y* B $BJ< \ |*&u\@Sܾ,yR*!NlY2.x*.P]&y%HFXa:o0 3{U^9h`VU3p'5SG%I#\ p36] ut%Z۬EFc\- ?+jV 9uݘZVZUy9D PQXz*=4aHU=4ɍʿO6Պ;Qa(bmk-U- TB,Ĝfߊ[ a0 Uv ɰ#cX V.][`%T7aHua9Kh`퍑I˺ZWedGL=TN `eE7Q/Q_)m뵥=Qe߶ͤ+:L 3foN5O}N"8|;j4kѺez–8`sF7zrGmL~DpGbs`ܩY  45:mn]Z{aZPKj~A{/doc/search/GeneralN.htmlYێ0}Gy4.m(MPVxZ q^@;3IڤnEHl29s|2;NƋ3z;ݛ=`//6/MzN,8|%aaߊY,LP]86Sޥ" Cbʁ/b)ߜ%Vo}Qd[OM=acٹUrdx־/'٬|WQe)e$gjӋ3z9j!,簶.R!5v 0U>!,T~{0ҿ@sMTscy _5F@%loFōÓQΟ뎼:(\I/#:LRhMR׬"sEf%cG)č6r!Ms]"A AQ溄&B"q_GC89k:awhC Pf`3%'m߹>8-V$wƼu]ݐ[I^@Ot 4"N,BQ2U(hHS*|G1y:ASCbn#D uI R9P\uTB D-@Y;v5VJfP܀ckRoP dpy[X3hZWUCX6XH3+V^VՍx7]bϷo/1M;/L' Ͻ+Ol Y~q~.^uACV_{G\`=?PKj~A6 x doc/search/GeneralO.htmlV0}7!?ctۃ_Q$?P2emNn6P 9g=o 矦cx9y5|&! ҺxBvXȔ̯x?ekׯ]_1i Vc_l5˵7 viMK| Jt~{BgH3bL#Іb$[c@dM#b8Ӓ,xM7tƔkg3`1 %I1Jh*1*S%jjI&wu?F]-IULڸG"rm"2Ӭ$ 6=ӎ&/0؝Ixyv/X$, եF"Vw`äDw{t&wm5@E7Fv)JɃ`pQ4qwT} ;gW3mNڍ4lcdkq bƹ*hl0MIRݖi^+PE<`RgLuƹU6GMш*FDV/)lirEAםZG-'41Ӛ@ ΅u,Y5'{2\)g[̭>^1+zk5|: ."~LzBTku46X2xQ,:Z,]3҅N#o b%ۋ^%=\Ш*LVEӿ0+:P T:;KzvS2]/VSG4WyePKj~AN@Zdoc/search/GeneralP.htmlX]0}whaGK쮺~tUǧN )E`:wo Jm!:θsBp|9|34tp϶>8xaFx!eƶWzn1ۓ+d[(|qd WZj|_P )KY,i,{uB1r;Kz-m|J}5 8 ,:bAH^\!0Zp:wey `˃D~J||"K2w3wrwȽ̘FnHp%i2+*PPc3F<__fWz98[ U^4X+H}/X1 [S@l~mmg˩4H]rc'hIXZ/)tMN\ Bh~jk!+ Hv)64l0avr W*¦ XHafOV`L.qV{F>Wh_vU0 8\oJŨ*^㘆/X iKE?v9,X.f֒@n܌j9j{5dT F2J'ϦVZ|KOa1c5w .sWaw=$- dz`Ո;۴WaڭrV5W-'VsZ+*q˱;']9!}ɣ,#X7m?0tRun}u~ᮕH-/IHa-. G["X-NuBUw`4:jҏS~~jswTQ]нS(\0:PKj~Ac@doc/search/GeneralR.htmlX_o0G;@+h< AC[WM6vZ sӦ&٦Iso>:荿N\~8;!!!c9"䤏+#d\:˗32I3WqH%B_9 ]MsF3EF_Ypq'%3^ #>XߊhȟS!r/;o׍',rT9c #/%Fs\82; } E4et/tAG&o~ɲYZX ,-SQ)] X+ԧ*4BܗЂ =w^kI@:e%]1D䶎^i [1* $`-GÑA7u d忎t pz]ECS.&#()'Ji]hrDh&NO%V^YYd;2Θfk=٠[N>cQAMR*@b>0O#kh0`7J-*GdX[~X~"TM.QRafgQC˜L:$ǢUZ[b`w-rX,ALdJxO5ɱp5RְW&Wc*eT-YD">Q9P%vEW(wa{H#곆VVWaSu eB<^J܀?Щ5a٩N թc*9i}\:ćih`T!i" ԩ`P*&XP?gacCx-en;f ? 9Q E ng;,zV7.巚Uπ4n `_czPKj~AlS>>doc/search/GeneralS.htmlYm0!(:|;&D)W(pM9t_Mރϝػ@/.;\N uϮ0c)7;ϝsۻv:$/N\!yJ'n߿wmoLI&TZ4RIS-2Q|,o*÷(.޷^㶗Oic! cJ%F PƜ}8Vr'$NX8(!hJFDf$26\-ˀE &DwY6Jx8bHhXzHQ {5*.M7btq<(-c goW0Rn KV< @Sʉ,SNtB(1KS3e4YTD iBQ9)OɳWv;Gy@P*q:jx.h=I E#$ A8Hg: `g䋶G,kX-F6x,&sx0懱*r2dJu7={%r6gCi,AYQH7C6X pd$3%Z8KhV:CIV-zhfff"eh0+ btֺvLj('Y?8<dˍozeP |H؀$OR5l<}]2eLf*-" בC:9n qyFr nSZ4QdP YJ_z2Gd\4Јnc @n&ibL-kQt`eڎL~s`W63^vq6MJ2nN`3m%`hTu!KX"K.eRK} ۑF^hգ֫Uͪl L"Q% 2Pⴲ evdڦx]j_adu w 0QQWȔȒKxZ+CzѾ֎֊^kvX:ZZk1ibl/k^Kߍoސ)p^^weZ000OQLVqjɵj<<;<4 \ɓ. *t@ ƥRr/10Ga$pIꊡ0;Vżf>%T[G \L8pSߢN,! P-7WvF8Zې!֪T<7`}7jaeC̬~kRej?T?PKj~A(doc/search/GeneralSymbols.htmlU]07?kb ?cdۅQ$/񊔵/vn0vsg=}?LGbL>}5Jy@p>GhUOnx{k" r1$[=b1_vZ; !k@+ǕK滊#(*Cq$PXgcRO`̐u;mɹC<"( $5 {'Iժ+:{ ߊa1HFe ITWu5tvhJSMcurH%tFo-7.]tQ}e;(eb7܆`B98q>v߿IrypB\qCgP C]; .~x/Q|| amO{ij#NwQ<8b&)bK~b<ghP}bS#ѥԆqRڊ>]UfuJ[X* Cՠn(rf0" iו#%8\]&h~Yݳv륖-pkPJh~ROt!.%7%X '_3Oi"S%N87H‡Qj0Lkm>К- ^c%;j$ݘuP;˨LJ]V:y(_렓tPr'8ǑĒ:^uԴA~PKj~Adoc/search/GeneralT.htmlX_0w0JѶ9wU'&I wwh fn,νǎuCs4p/O;vxFڔ+J%Y>%BNI/{LgmMBbw#g̹f ,Z#W)(O.5 fL*OK9q|G.Vzs5\c0 h&ńPD,J djd)w?ZAn DV~3vJ`aEBA̔r@Y:LKX@c$sBUVhc)K& CdRF7Fo {F@PZ < LWt&Y"PЂK=&ϟInk) d E;b2vɋnckIE{W8j0Tf$"J^Iq(hzf㘣!n5` jk3mgxʯ;tƃ*ԃ&BlnT\ 1I6e8nGJ\bbzD{YGf?Q?~ yv653 aS*T@i ?O~~sa􋟊Oh[7rat,*wFDrPTIvb9A|~{JV9`REm oжP%! QR E.#YZe}R3š ,xq7!j(2׊Ufd2;^3ŷ_ۘ޶ *@ o2s/V+.`:q*򼹭l\oQ bnoVgan|,%aҘ\@[,7'm`U^-VK!l{{if4ڐ5H v޹{onc2 =3 DDc'k~FނIŵs9}{~&?䑃^G\-8i0O)LJ4faB`'T%A|`K62%DVX_f_#/bJ9x,,p&WY1G|Q {;ufR&.]^CdJwp!*)vqu GSC)4o;p4lFLgEh(<-THcAo uXf!V(*ڹ1dtNN[/w*nDPI0 ҧ5Ë́tNǣH)e?UmʁW)+%Z>ۭyh'TdOe5WWX2XLR&!:ȵJ}G/lǹ tЁuso~d9뛙Qv؟ny[LEDۃ.P}dTt@x+Y̏d{u5⚔sȪ>Oma6Ԏ措kR3m-[99bM^5۹`FEl48j-Hژ3}nv͒2eM !*\ B,X[6l^5a9ZcKn\dlH2VYa][2-jҡrBdMuq_[;+/etKO.Jj4;a4K*F>id$>1- T &MEӻOٳM]U~}}%r{#%/:!l>.T~ 똉RlCުon mNxo PKj~AY(Ӛdoc/search/GeneralV.htmlY]o0}G?@+h2>݀!@HHi 8Ml]Mڒ{ι׾=wy4~~O>}Do>#>Ϭ#>9/L_jVO-{r2,d=;'-_ؽ{%;$H1 ,\:xI9S,饴5 *K08,:bAHyB`t`˲0 DI@dm{9'T8[[A2cy,1%[|"8jXgǟ^Wpz3Vr.}g^CX+JC?\nCTs7Wʍ)wÀm4ݩ"DM('hFgDfDyZR.B' &U!V8 9g1x􎎞k'O*ħn-PUGI-%E)wGH-%mS.jx~%@jC5nh6 02bayil8UՌ%.)|VgiէӘ)V4풗]y,b@Dlsԧy "EqKa8`(HZt hMl<ˆƤd8M)9%5E&iļβԫuԞsךzZU:9'ũktqT\@yWף_d~Eؘ|o;;p ;=cXG<E~\5\%yFW7X` KQC4u!fbS&q7R-a-ŨeGx& eꦣ-r[gN2 В^:`V Zjz˒n )vJی4PO )D댱Ybc֊Xesxϖg @OaLxfI󉤝T]aҐmU|U,aJ2V{4 Laq[U]UU[&+8D%Y5 %3[U=.߷8 f5>h(&%ڱ׬XLӞ*G8%U.IKEQ&o˛&iw;u4H"&98(j $&g\%zsU& )\` ̊*Ӟ; 88Q/( ?PDnc#]B}O.D)⌡1K7zQf}pq>wCFdv-2%hX9(Q\#Mԇmnnsfq9B mPKj~A#e doc/search/GeneralW.htmlW[0~w0Jq타zE2>1 4Z :w7M9@2twoſ}}ѻhۋ-B;tG]x 1±13BVzI5'KrbH6JDc捛7|+S n( -5wdjxjZu1[ f>GQL&0zzC?x`m 1#iQ,GYPz)t9%:VQ "g怟-8 ,\,S(J,φ(:O5F2}+) pX56Prjn3Ԙ*\ټ4&|VJ>ˍotU `a@?Zȋr"\QQ\ue%WZ? 70 YihgJ.Pn?x< vͧJ"e[X qx94Vi !yX>= XӄT"$:ؔoexۥv%jXO\cS5FCnr&lSFrjBf@S>_M^+lwS5#0ɨ p$tF>=~Ӎ~PX ,2,buGX fcAl3]{o$7lH4ކ 1w~OM+n^2 pཆgz_&Pz 㳒/pG 9uA]ohV ؞UeS(ǵŜ L{{}O`|n OƐ_66ht^j{;j/Q,!sMq9]Ts/vb},p+O %tRA^0vI9'(@=UY{97`9X**Kͪ'OK&̃v܆GoPKj~A[Ydoc/search/GeneralX.htmlUn0} Zc6CmZn2tl8D[MHsc&\kw<]Z6g.X^5Tyqpe*tvsT=!a7or_ TKlt _mNgGPKj~AL[doc/search/GeneralY.htmlUn0} Zc6CmZn @:cgES}v T&$r{ι}|k6nn{wy}IHk3 Af,K: |/K%˜Զ.P,K23k@U%d̦6-}NRƠvsOzc'6 HKX ڣbZJXa*֢Kء6UGTVxAhڮ@˸7\韇={ڦ VYиT r4T!&6v~gKG PKk~Aq?!doc/search/PropertiesA.htmlX]0}w0JhTi'6Z :w~,-+Ka0i=&'ֽt6ӓO`agO{ u1 R+WZ=E\xzON.J0W!Oyй{;V@X 0 #aKxh:uL!p'*Sa| ܀Ie:VȢ@ІRC*JJs+%6DgNxAXEHWXD~B|j$K2pS7ݕeo2!҆c'T&cM >qpZ]ȹu:wKК Tuiw^L<,b䬟ۯK_M} ƠӹyN3Bӈ k0"*$}G`Id<']@J2@;JԴ/@"B>y ΰ'aџNiӉ@i&,!daXC \xT]01qOKY5n_K&]Hc\}eѠ)xa2Y/o}k|T&Hɮ-E;v6@݈ տ PS)y?!^+h}|YS*Vyj,M*qԉz \Ŗ-q'WX_CUu=݃Ix7z&a]H_n[]za:-w~5bnn`ߒt M?Lo>Itn RKb8 Ags[[.ȈT:#fX.l$ UBxR|z-_a1dmHy5%G "Uk |)&n 2RY%[B<:+4mUytTOZ PKk~A%/Xdoc/search/PropertiesB.htmlWێ0}Gy^B䁶"Tr7 $q^w|I6)ZmLɱgso?6ӛ`>=>c<g 2{zF마Oo[$~v/Q ݽsힳ$J4C̣ ,46΅n$_.t?O^Bω4vۘ%% "NH"DG1IÜ@Vdbm]~8l-j`Y~Lpey6[*X \8|2N zw9[ tyfy$i:AAYAv_W8PޘB^o,~Cєr"i[0"2$G`EX O4zMj [(J.8K@csuE8bwFTi@7^Ev"Pz!4+Bs$(wOXdW>]Fթ+j5!< NT"3 {%i, cyPczЅ;6+9MyUt,4٦ ?A%*'CUsp2;걹( |*[YWvQ4L!yMTdBhg"ǜeˈT= s(h%>PM*x` 4gaCTA[<\ Ć@!{i7Wk/LYCIR'k(5StBGAwI\ 7z%?d"ow+%KSdX Y{OЬ ]vEH7n \⦓pB&Ә<@y[<wwB*mi8Y5p &ƭ;VN͐%6> @C [_PKk~A7^' doc/search/PropertiesD.htmlV]0}wa ~m(ONhTCSD)\{ufIN%58O?z-߿x{0at'cxfT^a?Xڕ|c,4)o޸y#t8\ JX!lʭm0@Ge%Feġ򯠅[)RK"%Xj1r3H`$%_ _T/aTDrc"2VEYLBRZ3Fj*x༲:co:36Fhw.]\Ѝά0ֻ.qDb} )0v~1AW^]!+ ͭHa*1`-T&] _#\ZF^q>,T|['@&Ed")!8|&̔Nz)MGOjtH<φ8uN6̴Nb!ENqKv jd!;$Z+or~OԪP98ZR@'u{$6E#>\cy\b *W>BiqΫ{ݥvnVS. ٟ\]KІ/]J|B̘/E*𵺗dQ~CEІ EMiEi9woZf 69B>oRXU_]%;n0HAmV}WhY 1k8 J۳CRFw4L!6"9y~qk8(UA됃r@HpX<&Z5ǫ[-ԥ^S} PKk~Aج doc/search/PropertiesF.htmlVߓ0~w!a G>xPI 8fh/nxNߣW{~~ܧt08ңt8/_Pl1* z1{KOzTF&[ov>š!Ep_fgƛnsQlEK47k9}fߐ"lK F-BXT$X,;f7UT”9WˣnΗ(Le^TFA#,hu6Pi۷̕htXF NlTjxqFQ o8ݗ O\-ZE)?;D ϸbhE#f H?@kt*3<}d57#Ā jم+T(tzGϺɎ[J88b~6\\L 5@YVOBOGsb:g`q֖v!i^B˘7!g̨m]^.R\b"(Yw77vrL%P)c<ٮR5̧,||vV#%>Id%ba? TLXɜ+r}_,K $N:$LЇ8IB7˜Le޹йW_[`E&żC߿+؇RKurôJt_-ŕ4<Knfv18:':|yV{)'ҜiN@n;H2'8J͟RBsy>W8#2i9F-}k8UVv>H3-!J#aEpqivRh3DKC,.]R6\$Nu.6|_?;]3ZɵnAm犻 5GXCqG~Rwv}e]Otقm0QϿPKk~Aw屎'doc/search/PropertiesG.htmlUQO0~G?K6M#mǘTmٴ'nڙT}vH}}%<\G?]2EP@6!Q;Npn"d\1jJF2趃g'-Ja( |8eq8熂S"]D-U$~! qSHfTin#,?A,Bڬ2g+Z5aLW:GFxxW@aPӅ(9BeQ:MSB0~BsH4Xd:8b\E-Hx&SrX9ږGn}{N)yW2ʤ\]a*D'DsYFN xKFV=US{5nsɮWc%6BX#%/K@e:@M6VadZG]G=bŹQz_O|_^ϡhf%Z,٫颣uw▁j.ϘejY*ɤ/h pgȒ重x ]eG'?rho#uY2kU2m9^N]xֱ({+aoVe4[lԣ{p2R zXB7ѡ(PaP0?|=;~PW= ܔn$]\K殩VUBҧHsZto%hh!nW^:[G |v?_PKk~Af Q doc/search/PropertiesI.htmlV] 7?fg؇:sqSV؆Pn..Kj̒8ЇƷo{Oy zx; F)!`d-b2޼qFx)K[ ^!_+JPOI˥#B/AAp>4΅ 2vs"2c,5'c@Bbq&ӢS'N˜YM,?{ #@Sc4VeUN87UnI#P,AۺjzFVݼ!Кi6\uiwp+ZXB1pR~vkK8V~ hNC\rM-g0J*3waŵJ=go)Fsx +';תJIӹ}_mJd(XXG4>!"m8d[:9̔f\'xfJX;)wҮ}5,\NL*Cp ޤ1oѹ;4SEK^!+ = ^m{l\T;vɦ<ᰇDŽw!v9yjtL|4#s*ifŊwieU%:0q';Qu>28/I|^삭=/3}M򿘩.:QD0~-NqcC:qhʃ{iST&~5Mu2Ro͖)h5aWseơ*3=ȹov7CBEڸ St =;ܽij0n펪i A]@QZJWX* dJ=ꏣPKk~A%k doc/search/PropertiesL.htmlUn0} Zc6CmL"T@:gES}vJR}}ιԹiO~ mr݇UMHgq EHw-.Yx}ɈmoEIqc6 F_2M*xOf&!,@=hb-TL/gT|:Bl@`%PѕI\j~j';WA/CX)q<kCTvD1AS`*ddЂq2L9h;r#mw}6^7r[j<9gR㸉 r*xh>5q>-k;kH,3'";nwWE M{{+vQi[a1 $1$i=u{k~-Oy DC|knS쿰>n-Tv&GkS@@9, *;5Eu9ëM/nèFDenB/0h?wE%< fjjt~1P h P*n+㬴e{593%RtrNd.F%!pp;ޜ(2n H>Ia0:dž (3Nu^K )Xus~E hDŽPKСJrR&lbZ%'ZuX8/SQ2}6@vD"$xg4h*UĕE!OS0U΢jJ#iX_|fÑ9W&Ẏ=ցǶ :Kl2˥6\I Fl$VtT Ep6u6i`{F7*Y#ze C q"niJx,c}O0k']%YoY6D*k]^JXyEGN㪃D$:2OйKzR[Я[M{ɹq9V`{/02qփmU饑l\LCox,t" _:Y~5єiNge;ΆNMS g!#~3ћ|*Wb+bŎ(@!gVT;gjCǦ(%aTEM9SZF 7aZmlj}L8r(Q1p5^qjr|>Zfp#/lc¯0/h?wjt&5Fn@#of[;ZnKWOVM{v]X>_0PKk~A$doc/search/PropertiesN.htmlUM0#s$.B@[`[mqZ9;N3mK*5{o2874#L?x6P| ~EzOC :ax62ansܽsNI,O[N!?rK75']L,_Cdp ^$,9,;Zf 拘! ZRA鲶 ,V[h0Ox[psIUL0cb2UuS8FX3EiJ~T,d]^Ӿw Z \+WYSɄk]Z#Q^!qG%U߿) μ q5mHv:,5n{9齽\Cx3}w ///@>>36b 16 Km6yLY5['=f) G$?=9=I~.<]Zr\2VH8X CƢO_%IR}2#m%%#<XgRAlKE} ”բ 5=koEX$~<w|̴B!몮&MF[Kg^VWM{V^šX4\]^S:T8I@؝$ɭ ^B ma]m.R+xH> oT$ -_{ٹ+:ޣg}S.oy PR-R2Sga@@)m iWYݕ%>cbltƕhC6OGehtö9 *nVv{77;v52xS3H!b ˛rc L<=Ɔ#d\fC76 6=g~taYgQIo޸y#i\J:^!_|VN*M$^B'>lɍ.y?}=!i\ Y$ĺm!RJG!eX9O,؊ 䥃E2y|Ƭjg @y,`#xi&d˪Hn年U hFs]tO@}+nЙ}wj;C7&wCb۵GR}vAkK U?(9ӿ!KN ma]exٻZ=gQ ZFٹ+LtzɁjSHΔC rH'4fLcg6B, [ 1MBԽcp(q\2]JrigC6>H繏LJXNTT[p{$70mثcs;rQrvv5E`OOBT3?{/s-<ٗѕw`M /7;ZfJ67|%CQ H-ON/L#;ſԆqPm|* d@'S~]mih5aU蠄&07oD4yti]mYmBn3yv sFkn&H@9@|']8!l?U딗/ 8 PKk~Ab doc/search/PropertiesR.htmlV]0}wphG>8 O;ɖj$nҔVawf 9ܜcu2aQPDȗ}BAx{ !cs2-m)􈱺,f۷bO%,Kn)xUJZ.m4TAdOK<%dK ɧ9JcQH͒s:~KˌA{L\aWTpVQMP" nr;?iЩӄfL<$m֟%K#AJ7tڍ^qjohdAVd"败|ݵUx\νȽ.l>ՋvWUc/~-Xd0ч&vD~U84 kj>twUt _ahwj%7XA;l ";NPۑ.35_mF;uqh1+L%&AzyypPt{wh;o,<:~b-|uҡdXPKk~Aw4doc/search/PropertiesS.htmlX[0~w0JrmTE:>1 P-MMRP-:gn{ Ź}tчh^_):v ϵN^PZ1rFGn"zrEIݾuc3, KEy[u1퓋5DIŵi{Nߑ䑋^G\9i0_)O]LJt˜(_Fg)q[)go jਕ2Sɐ3ϯJ#@ s/sin 1b4qi߁Ddy;AFю2M9Pz< ^7r9,ɢ^݂!#1Eq/z1ge{tʊ}HD S',J1'nƯAB &gp dO"k[0T?`7FI(y E¥:!Q@%x ң?N*%flV q)edO~^e2bHdܪ * )kC״h `RѐQ]k$;c:xwYڙ}&EIaB SN@MժNj~`̈j2Sā_mt@J:] ]| 23:poCdҺ^mPe6byXoŲn D4H.%m}dYL{77zrEߴYW[|e%]Cxsð6y0W &ԙL;͢pMiUѪ9t}ewXܨ8#ۍYZ'$8IP%[8/o@nIj;1:%aag~ PKk~A. doc/search/PropertiesT.htmlVێ0}G@+]B䁶T vwqJj3>sg<'1xӟ~9>;? {`:hYX[̔Nz<7OSzm&)/f+lRh;̅>ۜRSKf)rM&OxZ~:YĬiA +$]$hKq:}ީ 'PKk~AEdoc/search/PropertiesU.htmlTn0}V,vB,E[WM6ñ;NPsg&C4ը( YlGp)l K$[r;+FeIQ||t|8\1a eP_ Ä fU$~! q HVTifهC6gzŘA`,%Z#X)ăHN3m DeNŲK}k:{Z%5ny'>8;6eZA©Ȣ,dutɍXiR\IFh<B{PMNjhl uC-VvMj655Ɋx, k30x~gO[3^V[B]\2N3]pZEH?0w':]S=mڃ@V`/=-;i?S ܧ>//PKk~A0{Y doc/search/PropertiesW.htmlV]07?z!DgnPQ$xEZXu@4w߮ !a]y޾kO?k4~Yox@zG ͆ltzNχ Aeb ׯ]8Lq!/\Gr+rL(o⫥%)Fya&H,n3aR!,F5-1TE DWL, `- 2/K+f?gtR>y'ǣ~>[d̘UQt Sf֌A#VGx4x[:c okr:s6Fh.UR 3drn|ۨ7Ӗ{Ol~ȫr"BB3+8oшR TbF%9vCiM 𮁐@ jJE^ޣq6*(ɣq+8+̗q$qh<h4:Dd)X`WoҾ !mΆ8d\HהZ*Ѕo +q=s$60C*-L/LlWsRA!7o 5@8c\/Br^yb}OjDV#r\Mz'*ڥiOԳjT2u1Op43yztX +Nv+e.gG`Wq o'\=!4+kmX˜S8>̐F8|}X=hy z}QF I*L۞7% pim#CKVtfuP={|aw]oGO8C8)՗'/GM< OPKk~A[Ydoc/search/PropertiesX.htmlUn0} Zc6CmZn2tl8D[MHsc&\kw<]Z6g.X^5Tyqpe*tvsT=!a7or_ TKlt _mNgGPKk~AL[doc/search/PropertiesY.htmlUn0} Zc6CmZn @:cgES}v T&$r{ι}|k6nn{wy}IHk3 Af,Kj 񙫓%Q@P@>6QAm}ja qXkO_|"-P;XىXrhƢ:)PfV"ުwبEǚ45Q4dRq_>4K'q>r&WyU1b[Uo@x APҬKE`eT&װ'o ~+)`@Re6f}Lsf:,E-gh¥JD/dM73o*6)F(_;9y.lPIg1k!v 4HAP|B< ,L9 OPTYi>]ʁE?RY:?˴[)&1ŒhltiΈ6O@Lc&! |4X=ʂgȃg LZ G``vzoQ%k|4FѬ'Fʪߩ&=1OxcN1v*u.B1+ˢ)f6Uw0< X>e_M}YCRS1MM[y5!0:,:XP殈=20W E d(m_EF @6ND} (|j65Mљځ-.$v_/jwq4̝ |+PKk~A^5Bdoc/search/VariablesC.htmlY_o0G;@+h2 AC[WM&vZ s&&EV|vs?8LN];; ܳ/}<96/#>b)7Zs=/O@.GBF-Sd ל-P#stUw4wNctKǗc BMD>-۠%E)wGH$)!& GhFeӓX'E]^,gDPE)T?Y97sӄpHa:^/f,rsM'!ǹH4dVk7`2Mc2*%TQ6EžtY9ƬWO7l)CY0ŸkW*c0ewXYDuUDFm BS(/mK[3ٞ-&)QzMK{ϫ#׶5ayD;*Hx+bb83}?7˶#{,`KUe+m7³QQmY2 ŃlfVajwъͭhaP.Ɉ:n{ U|}~*\p o0v>2[rЗAڿ$vktw-,IBx9@Aj[C;ϓ bU I9IZyZpճ fzZ 8F͜6FPgZ]w7X¨.?w˥q j]T[#Ǭc7 &BuhVCeR+WصdY=>2~hKUv$ؔ V_g'yr% L$r`Z˯}D%uFXzmɆcِc¿Z٨h32s" wP6 %TqWzƛ.>[u9qҭpEcMDm݈ ]upE?AXPXYGMf7+h9jÇe/PKk~AJPtZa doc/search/VariablesD.htmlV߯0~78 ^H.馬MK;D:d~G`a2ׯ`髳 (Άa~ԧt4&@rǔn6hs/fIg|4n%u\'kׯ>ƹ`2!mC~Cˬ%HH+VgPf(H[%[iYդ @y4d0^o!ڄLtYSL [Ig'(M@W񄌇o=FFwZKqU+ܙhc ':$zp Z`t4 sbw ;t^_!saNpoa\emX c Ng(Q ZFم+L:݇}jSO_Җ!IZ3"2Ksm0I2!-YfT2ѡt8rLAg#6پ2/LJ\B@V,us,60ʙY_d;v52c3)WLk GaoI K &$hGo!WK\]ӝv>!|s6Yo%zuk W5gKq5jXoWqb&B?B=^مyrA_!.9vNAMQ5sY.l:Є !h߿y>|=\N-%&Da5'a\qP ڹ9@|I(p0ZOڒVIҡ::K Q7?PKk~AA doc/search/VariablesE.htmlV]07?z!DY3F]E"11!e=iignw!.$99='50}whŻ7{|y8 d8zãOh^?#dۇT)}$Gʬ>Fe a8y (5C~&) ӛr(o6pe>GɊ* &4{{gR#͎^WDkV Țf"Kq*҂:sZ%%軝nሟd;pu'2/)P>.K$e?N*[uJn5(w.]ɤXۓ *3!6{mt5qy3)Cw^~NB^E 0ء15 e (I8҈BޭrtciJQx<{Wn*c*nlqqj,P;HAHgR1PQ%ib}2VROnxX Jߛ0j :Ȟf3:wtj[/$Ksi =К h ̥ʳT].nd6JmsϞŗB 8t^fb &YB5_KN9y^Drj$-nYPh؛'s\Y^éR[W Q]OA=5 t<V_͚X]p\!v#nbupUq72s Wt Y![tвu }qVh8C?G_nQ]עGفPKk~At_ doc/search/VariablesF.htmlW]0}w0?Ѷ(2 PI [7M]e49O?4~yaҏ(0 cgk~HJ^ ,ţF!qxgq/a*xkܗe1U 2h&x?=i).M)^pn02i-@tҌ HAeIf+6qsZE3L9#~ OF -YkkR sAiM~Le޹Uſ!޽LYp}c mOB 6#x%r FԖ ̜k+ GRvFsx_@` Еj I{{N*gəd[rbx\cLcKgLiu҃ a 9L*(cj_:\vkZl(Ҙn:5FwqvLUAVhR-gJ5&&4='[PL' B~ oa{q5|Qo}#p$?c7WdZz2,t,ҷzs xd=ӇV2mI9lyXH }im9D j7HAcք@ΰi.|YjzaB*Aҕ:saj0c F]A ΀N`σ;s%)4;m9ÏvSPKk~A'~doc/search/VariablesH.htmlU]o0}p罀SӚaNEvSeb3vf;l&v\s׾9 N!|~;> x{ GPnmjWs2=%~ۅx#"Yq)KBU2A}%-6%GU,!˩6&gO{Ƣ?As ckMιE`e 5L$Ȃ0.J yE/!ҙ0Sq BfӮJXږW]|S$ Bf{4ViL9UZwr&~ jnکG⢤Z{R/fJbׇ\ + sis(wjk4nT`v_g|6x\xB]|Oh.H}6˹IG ڰ%gw s ѡ>XjōbVR:ARIaV̦gB`G;h : OlV8'ꥃUL. ӼPKk~A,`Ӎ doc/search/VariablesI.htmlV]07?zѵ.T"yAWm_F>4!a]szn=λӠ^޾AG~|Ц3CҢϭ-RZ)􌎮U"آjY-7oĮ?4^ːSJ..Fu)0]f#>Cٜi#l~"z8 "O\# \i DL*0E9SD-0yg @x4@#x|AQVP0ͯrk Q'y[ڷ 9E.VFh7/MY!+-hNqٞ/FI)snJhfG53[iNh)Bȣn-Avt4ZɁyS'=ŷtjhh\-TBb 4l 4)4:iL)YdC qok_u4fM9nOJ%mW~{gvfz{~\2 K"O=&,bڔzJꍅCeV.ŸR|²/3]@"Y(kg/V6N?0{ +:TvM&AЩVې+Ct"Kfj~^.svӦ?⚭XRx131Λcf.9-<[V:;^ ӆ@/l̄b옇wP}Tdؙ:ԭݹw/2ͅIM0еpby\ws=g3¥)sNYN0#:]2~C R0w٬ ..&TH5\a/) w>9~epY.>jPKk~A~*doc/search/VariablesL.htmlU]o0}p=fm7MmۘZnSe錝MPB%jB"+M{sЅ+^^ڀB~ ;~ 19! NT32a͂6*K NMÃÃph f(8.eR&L0^ AW2GdNf&>8iL3WDksŦ˜xYL`ctbV%yVII.{#c Lאpu2/*.+@+I;7h{JMdShL\i\\'I+@a-7g; ŨyQԫ%,v@<ݼL{C/L0E Ka>5:2ǰdJgR{ı7ZOH-xXtieJ.P*&]槙+D.r)p5fxA멷}.}j bw9Uآ/Sgw *LѾtmrQdtܗP'>YCU>5T3g^{iU@8t:B† ]|z%US;@ Aǀ$GM+[xpn!iٻlX \('PKk~AkWԾ doc/search/VariablesM.htmlV[0~w0huu|bB&5I=i V.,Ismr;~^G_MHgq'~n#<3&Ab}dxEmof2EQil$8}G$ 2f( ^0LoFۅذ!343k9oH1bmVc# kLI}8%T 47S1-蔅ܙVq GNZq'peB1Z/"07I^$Ľ·rhryo+Lټ4DE*5$m ;'Φ5yrZzS԰WGM(GhΔN@,z pm!V)j:ډ*֣g`]AIx!j! m!R1_Q`34*a*lqsNi]jWruEWmIj;2xA}w?~HZ)( ʵhFP_F%I@$*Cr9 RZI:05*DSmy_tY5{M%BbڠN1ՌL6i֯gn/3y>Y.e2Ŵf lob3!@dPZK8m71EYg}fEf+ߡbZոRcKךb={ڇ ͚dC}^nۋu\~'鞈͒,Z wΖD(5z<77ݲKhN`U;)_CS Xo!HO^RϠ{U tq5lf˙]Z]$ \=s:tb7~y0vNڹQ$mgNka;&>ְPRWCRQhoFKPKk~AXdoc/search/VariablesO.htmlU]o0}p罀SӚaN-EvSeb錝4gǁ4jB"׾'yw}؇/S^~<=KHo 7CHͭ->Z5VzFߍv!t:,f i<甥[ ^!?|K#(AZǐͩ6&O{"?@s c+͜s:~CˌA0| I%v'`2x.(դ7`xy$̸ 2QLPc4TEY8RX3ts5z*3GJKg)[}#9o hNZ@Et^k'WD2~n8YG4>"ybcilDp(͸N:q!LA3iFeJ#w.>/+l#N*}[Nsߕm$J}?~)kig ݱFbDڠbB#*0i-I WBKɦ.jԢPBfj|uOpXe*t/gM=D]2Pgfs)MX6ނ5Wzs\}}:a-4!jک0M!h $G07+]R fە mǩZhyGm'-[[_Iy`F{S 3GPKk~AbXdoc/search/VariablesP.htmlUˮ0#ٴ)I.R+7'(/UjƞsN|86y5^O ~l $b1c$$c|p;T [8]qwČyfW\4"iC+D +iQhYH Xd'>l˵A^>4.r4 1.l---3V:!b;K2Nd:/-\n*9E3:kHT{caJ*r\gs4UaIP"!ɫ& O-վEWk:~_Eڹ[Xpz`7")>iA)ׯA}w_!SEfV0Q {&Wn{=Fpx_@`-]kJ`4}xݯ1L ,.O&mҘ9d[*VJ 2, SaQɅhFȝ/GMu˲\*sۨ8~MYi]IsquQr펭ZԻ*3ބحRvyOL YxK^TRxaFv3p1v3S ˿yU&Jފdkwx퉟,ui$5yCUFU}2S/Ͷhҙ6l k~H8}>~TdHKEnʂ J"yﲐtvyBnW: O\jn^:4ד ME PKk~A3/ doc/search/VariablesR.htmlVݲ0wwBmh 8 WLhB&)Xݤ)a&n o gCz-x`}_xzG13->DRx6a?XuQ<1 7n<W8\3Ccطo"ؗ0aY3?a v Y>^Oaf\|eԦ̘^1f 0_!X) B+5Ks2"҂,zC6deZ%y5pKDzIFXE>eD% EfRC [IhGը=@}+nKY(L}邟T& *nXov]R3GΦ; Wt a,J0"P${`ÔRAZu#4vC8ax@%8,>븅ֳږG훍KG]~7PKk~Afdoc/search/VariablesS.htmlWߓ0~w!a9}Pqu|bB&5IAt4 =8ZtnH7}_7M먏N>GOwKHoҳO BCR!Y?v\%w;KO.2 oݾ. }7a"a?hqݙlRQ`,d* Eq.\/4dr3S$"M Sڧq}$L]) t=Jq9\y&jU(D1v%o沏HX\//qYpݑOox|B!wn #78͸ ^\n1Mێi;lg*YĊw8MVGEW"\s+$,xr&ZzkT5}i_?G~po0SPKk~AxrDdoc/search/VariablesV.htmlU]O0}G?y/F4$`RiOȍ&,3i&80Rsmsro|?W۰'3^vy|=қ! @GBV^`!d2"~׋"=ei4CoC?攅k V?d4ϴ7)s ri~%AS.'($RL9״H)aL,hasbT$\CJyA~ Qh n+O{ij#NI48b&)3|/y Py{橣sa &A-O(c:S{y̕rfm]s=zsgKrreިSB'MR/ĤYS_^4:ܐD_YEl* q E_WC_kpmK Qҏ#?*Rp ރwM^;BX9ʭSLVu)HSW# b#]{v]MP ؜j/fb&l%&C)z~ *5pp? `vЁ (M*Tdoc/styles/main.cssrD)1R\)x[XDFc|I!kQE\k{{Z%|}wܟ9ٔfuV_g Z<0NY) }bպI{I-'USHкhNޖ3>* ^3Ȭ\m:dե6"KD'STMH-HÁ(d\=h*.MÚg3Vp)R"h%πC$|Ϊ| So)оɇ~w Ttϸve%EZ.W9IYMl.nʦMRi9ki ĉ<rptc%kf|E_+d׬hE5LJ83;F;ƛ\5+gkg=ϳq2nJS))XzV] NZfL<:' q1{N5X=g0.WrH|Ӳ-j_$ ңp>>CEW N>xͯr1# 8bA@45㏤R* 9p+o0aƋ5V>JokaV#&eb 8 wf?' x7_@k=֔5k1ECƉثh`_\8z &>%OUmm/87+h{~i&]N#ճ\}ɌR}g:;1=V{1\5m~YpeqڶhJZt(2 !WE \؍j+Z]$WL&t{%͟i9l O6(%`}qP*=l_)hdlZ2>>—#)/x1Ɇk8܃Ŵ_.L\v^h5߁6_c\.Acg8~'R뙜m:w,g3!m87*3%"z8,Q.(BU թy7mʯ%LVA8>+j2 K#4pϚ^a&phpNx9C7x9U ?E%VC`CLHkqctPެVed=ebip6Veϖ Z-ӝЃճO讛\J5`kٴֵMU6 F?gutkZhς QG"FdtDP\$Rն 7\ոaG&8)őnDB`-S;4{ ,mg[fY}c_뫯DXɮ &3t/3=isw7v>FDw;章<#j9I9#-܉ˮ).gzPD / ^uoNv1Ӵ| *c<]U-N-n [?"EW O&5¡ԭwoҎq*W_j) oRi|Zn pb15W2($ȋ~-.yarfA/@2bcr-SdVk&/aqep+R WKO[9CbV9Wgz1Ǟ59vxu S*u&dRUkP!쑩豳JYQPyK*u+ }Gn)xNy-&Xe/*C`].y:D tVe]*fPS{w~E; uques 99Qj .5y}$\hh%RLZ6S&ʒF._7@p7߷ pXx K ;ƿ"t\> zЕAi'o |Cc n+  Vp+j^5: xu9b|V y (bZ$@ޛ7`'~Cp7r1ξr,>c@ߙn|]u̱4wo`HS<<_;$V@yZG>"{)@Qح)0)%` j y$շ~@D{'*Z,sZ1(?@Bl#HC{ZMWil5o`4y \0֎,'9`φQowѱpݱaEOaGN<88Epqp،.XS K d(V."nξ:nsP$-]+B҆|{Fy^B. [(fqӗ)"7W]_oP03h,V3:kk_$t&߄m`k`t4f ܍Eg6.ڋb0t?zuVx#zO`'3h~}tr6U5FC vhƒ@݉gT +P<`46j_#j (wwc9ITf;B(FRap/T,k _и t_AD%$G,]XYhYAY A0xjl_WM;fu#<~{bh1Bc GIb x(Q-<k^y*ClW+莡uaNpSY9p$EPKk~AW~ doc/Topics.txtVɎ1#%qKb"!NwubؑЈ畗t2M*?q~)ݝݿwhҁWLoT2ȵp[^yj7nyO])dRvw{nHGicHmf͟=?w߾x|6o^}ރtdaTpK`+wp!,~N^/Yu3?WH_q|x--#g^,uH)n:җks:`- zLxC bFr;0tǽ[ówO&m|jnG??t7O68<05yV)X$3@r:6{U6^r PGYPv_ 1BA +q6o aeLI{%tЌNJޥsPKdiq=t"uQRWHq:){I )[`pM"=nԈ0cl8ˁˡ*aפm"Bg`%^nO@%a:ae*rjK>yιrz'mzLJ9,5E8Oj>KDT2~,Q &Bdx>O{ WJf_*!+AJu9U⛟!*~*S#PvdF` %};#^Z+GKhUIYoAqw^.]uMnMsm,hx4I]T[0`Α:խp+AU(1ƣ֘fN"o QVh~e,yVאe k #=-0B&?"O"_4V.Z%RR=Wl_iB (u`Rw i|GXg#JvoW%tR.<5jyZʋY@$ͼp⽡+J 4(0&׾-<9V\!Tع.Fq f iP$hB;VG:-P|K)?e5b/9{+]Z@nyE rcU-ʚsmkTPKF<(@֦\enum/border_style.luamo@ ǟSէUZ[cHDiBY'np*.풖M&}%|[*wy6aՔy8wTゥ ^ko~d6!|2%4EX-o&<12lM5)jF Á"pGx 5) 8V5lqok[tq |?=nT!g 2c|r,z(i ]UX+OyrOxG=ZK;ayrŔȥ F=%k+YR4Zx:?wM5.nrAqlU?`eKH4+] lex?q-FKa3(_I/eF E*VHTʼNH>J+r}%0󣊺)/s)=S;BtWMPKF<(@ߖaenum/bounding_mode.luaOO@O1Ihc&&$BLivu٭[0~ww(\Ԟ7o~v0P&f:+`eҦPߘzC= aD蜴9j4BH'3PrUIm7LC9FʸO L)f @H3B_ǖ3&pmV(|}>QIO.[*Ap+т4o<Ua/[ 5K W|e,PmϘ;/;L_;/vE]>w2N[ >(]<i yWٚ {m;nF-!} PK=Z@N\cenum/box_mode.lua]QMO@=0 *&QIlbJ;NNA0wg[f͛ަ: DuZ w;"S7*zI7CȬFPT!Πhȗ3av;Ja6 dਬ)v702s֪͙CRBnǹ3&އ` X*Y|[<*,*g2 bpf`&s4Qi1ӦaJ_rz.`n.urIgDܪi-ojgtQOv ?: G]W٥6 R)H:x_GݸC# PK!@[oenum/font_style.lua]P]O@|. a'H(D41.qW"|ľٙN^_]ƉIrte &bT"hm]^`HR43(M h0MAp\qYq"[Ė.Ⱥ]5͆ia` ܀m!a9U154F2<5A߹d)Y,q z)k\zG uca?ZAE/T [IIPG B'k&AyZh-:ƇC^<$rk3yo8sC7o3Oh]N"X^]ФT-տs[b#ZamuH3熿PKF<(@~&&K;enum/font_weight.lua]AO@m0 hc&Xc"S6,u;@ Ծ{uM^&f*[6օDrgjmwapq9xBkEZ^NC2i"]D&HU| lR癄p ?ja~rI nTX oKlИl6[H$ͻǥPX.ЪrU[wvo,PU6[aXRQih VG쭖i!84Ϗ@T퇜#*Hm,ߓf[NKs]1tsH|u^ [)읤e6PK2@OfPzenum/gauge_fill.luamAO@4 ă0$E/Nƥ[[ 3SMv7o6 e^氌8G S7Ѫ|砟 `ru=UΩJJ0H Cι2Ȕ&826՘|Ib Ӣ X>@\Wi!s)n0Fz3:"z-0sO,l # 2kIg@z.1} 2q8%[oXj ']Hfs:67Cw˄΄]0$Bd.N,,,Kԙ 0un>L%)STQ!;NXl=h$_p.nϷj[t'PKF<(@=Penum/gradient_mode.luaRMk0=a) 6GB@JBQY{VrGrͶg$c7$a7-cZ9"3c1N}cjGzoo1RȔ !/Np9rfDZdkV"+^+ gn{`3TS5 \<^RgVŵ7(z\]YHQ(#naG.d0DhMhBah@Ǝt[1Нr DVy`Vu**e-էZCذߊE:,{r`d<:&W;^ݰ!tǗ-` 4`TewkT6GBi" %pj|BVeq"z֣ "OJn{y; ~~R;ǶVkSGq`[PKa1(@S׭ enum/init.luaTn0 =;@e6$[r(Rb3VW$Y6GJ-"{|d<69+ эGp덃S09i}YXA*pC98vntkJjL;hb)OGZYgiS-_%ˆGthl< .ݮAH KYrr^u$.XT%QIԲJ=7tQتU%tC2A^)`_#4,^}fˍ1wəsٿ$|64r$2Z7Z; !HwLw cCP`hn]QID~2зz(fZ`t~営YfY n!1UH̴" ;OuW5vIœW:KܾAkuS4/slJD95`>NQG79:E9:ƸFu+ra.hߓAc1yPK0 @4NM init.luaW_o0N~⡕J >uaA ;n9z%Ts }$5]>ߑ_#oo jh2'TG#''>Wf| 'zz8X'3VG]>_pav.A^59<dvZ$ZLT}86,@D^q9-L'WW:b2#q &"ɂý.U K`0Rá^{6,`TS3zmpضUbt='7l?n$;GX4+\ 䢡:[ZxfR 계TB䊑KbO7y K|xPK p@lib/PKd@Fa lib/init.luaWY0~n~ŨъP qHH\|@U&5MvoNrMb|3\qoܠw/ =SZhGgMYaY,1ݹu=rfE/uƳSS뒚zXjz UqE asvnaWuI߄V"4N~  2aGA+V6UjmO֞T]Bͷ8~MYe U1"oI^806N v[,[&VzwVU2CUyӤ` K[*'H`{UgaӸEdFpjgl eWjcs mc|'h41Ab.8Xi΋Q+f hs\?9 f=n!Y`X>}t[DiE ~/Q ߹xX_9ǐ&_CŽ+ =v365 "skyDN䚂,9[Z1=1h*Sb9d7aيʃ %<QN;W{Kj<ġ-_R_5V#Qn`6U"bk!Z&4y/zkD%LsmWT)ϤBjTj|bnwsK4v 3!'cG"x9 $ƕ˙B#_gB z=49Ֆ'V0y$Kq.OMu3gCl;\$0}lD%m q9ȗ'Dyv ZaϷ!xT<@oPK<(@jf license.txteR[o0~G?nc\0ZnrL>o!Fb~eVw;(zLit2XJPVV;XG١uݟvz퉸3! dbޙ$**e&|Nw.wJ&$ b}KWs BQ*2 K*e\Ζx ;-#ꢐĨdR*eʕ,C4Œy`d|*~C9g)*,]^qտPK@66READMEMN0DeoH Tx,8v_j)GIfgގ)i"I`?G- o}09#iB%$zN6c{KErjiQxV0gYtGLj]0'ZGGZ,̓}`jR^UWВZD ,.8Mﱮ0|^/xz+*]\*aF#C;V/ۂpi(A_Lc U?UݫGz S 3.6e{*PK[@'<O vyzor.xmlko6s ?pTtCdHҦ֬El̐mV#K$7ݑ,n9dx")=MR? tBa4ᓫ˳?Ϟ> r>4{ o $>?DR0'K>˳(I% Tσoh\^:}:@4 &g~Y<2ElRVzKRЛѣKfS/;he$&~ f(]4 //fɀDd~xHh XP烁g:Y2xxO%K8JH!CǞ M&Ec2ᔦrx1) r');cP~pQFeY͔s/N$J,W!?b?ㅤi #ߎ%*61F ! Ԣ\/ͨNN q [0BUV͖[!MJyi)!nJFT }=3޿/1=j"0 G~sd[EE-_-/,h6E_ JhMX:|g|hz ߖDIG_ǹ GKY44u]O|]`Q_tF?S#|X8920qxC )|JΪD"8׬ƸRP \}]y)VC&%up=՘_|G(,gpi<}J.4ă%) +| I> Q\{%peéreY4#`6ZPR֔^-M :!W6a}h>^̀~~%?)A nckY!>o]`}U^%-Ҍ?iX_hżֹ?3#CLxZLr4sprsrs^/7 huҋlPeEViCظ8Ŗo)~Ff.K&~(E9g G$Dp o3I(E"IǰtJaGEY5Ϧ~gjFeu&ጆ{ 4&}ZO2a N~z%{zHX ͰxSn%wS񀼅rq 86*ژ W--4ex[(B~^WtlPQ3G=/ N*9vۃ3"5 zvrBG que0I+ʶ`(jW)ǰ+&ЀmٱJzvm6KiQ +*}TTQWJR.) 1O.ו ITpxQWﮁ1,7_ِ.{z u& Ӛ)9~6o1ЏB!ej`fC{푦E00^RN4$E@]VYNYdGhԡp)LlѸCs[d0G >7ZD(^!w3@c>l6L35.i)lVيڣ Z|XC 58$cSl9k X&9s4;r? N۳+ eU~߸è{ x\CJl2I [9xA3Gee118sRK!@3_Ĩ4, M[0UӂPHy߇>ܟ{q噧2Fh;s7Yew"3Ne{Ko>siEvЙP⎚V<~|k*WkL$E4cR:t4hCx.,eƹeƑH, [B:+Gh)2,W ,Pb8蘓{{:%L.YrX_Nvp&dU?[Q }y]i'!5[Be9F<%&uIdH?җ-&6@Jle26eڮ+e_w{x_=C*ZڦhzU6-T ɣRVIrWW=`{h[T>[=WcmuI \??`B|w%`e7|I< L 0YU$l>yœ|q۽!Wub b8[A(1-G34a, ]2Ovŷhks_v\fݥJ\Spu6{ |Ƕb NpӽEok4nqtiF+j;yYlسizNB|P3,N!%IF -component/border_side.luaPKe@x( ?3component/brush.luaPKe@PR +6component/color.luaPK@2  ;component/font.luaPK֩@ Nw i?component/gradient.luaPKj@ wEcomponent/hover.luaPK;(@<K  Jcomponent/image.luaPKˆ@e5 Ocomponent/map.luaPK-(@A  .Ucomponent/margin.luaPK@- - _Ycomponent/mini_console.luaPK;(@0/n  Udcomponent/padding.luaPK@?%-  hcomponent/position.luaPK@ b pcomponent/size.luaPK @ 6ycompound/PK]@HRf ]ycompound/box.luaPKk@f ?= 0compound/chat.luaPK @ , % compound/gauge.luaPK (vF@doc/PK 'vF@ doc/Data/PKk~Aȉ >doc/Data/ClassHierarchy.ndPK k~Al doc/Data/ConfigFileInfo.ndPKk~A5@ ߙdoc/Data/FileInfo.ndPK k~Aњ doc/Data/ImageFileInfo.ndPK k~Aњ 8doc/Data/ImageReferenceTable.ndPKk~AOh }doc/Data/IndexInfo.ndPKk~A9 doc/Data/PreviousMenuState.ndPKk~A*hc doc/Data/PreviousSettings.ndPKk~AoL5X doc/Data/SymbolTable.ndPK @ ,doc/files/PK 'vF@Tdoc/files/base/PKj~A3| doc/files/base/frame-lua.htmlPKj~AQx ; doc/files/base/hud-lua.htmlPKj~Aj8p $. doc/files/base/init-lua.htmlPKj~Aikg ~F ,doc/files/base/options-lua.htmlPK 'vF@doc/files/component/PKj~A, m Q' 9doc/files/component/background-lua.htmlPKj~AO?aLfc# ~doc/files/component/border-lua.htmlPKj~AL=Iu 1X( %,doc/files/component/border_side-lua.htmlPKj~A9zݰ :" 9doc/files/component/brush-lua.htmlPKj~A~ sD" Ddoc/files/component/color-lua.htmlPKj~A?Mh O! Qdoc/files/component/font-lua.htmlPKj~A-ҿ :G% ]doc/files/component/gradient-lua.htmlPKj~AAL YV" jdoc/files/component/hover-lua.htmlPKj~Aiu} F" wdoc/files/component/image-lua.htmlPKj~A#Ei ^ idoc/files/component/map-lua.htmlPKj~AH R# Ydoc/files/component/margin-lua.htmlPKj~A\A_) doc/files/component/mini_console-lua.htmlPKj~A8 R$ )doc/files/component/padding-lua.htmlPKj~Av.~ 5[% Mdoc/files/component/position-lua.htmlPKj~A [! mdoc/files/component/size-lua.htmlPK @doc/files/compound/PKj~A*0f F doc/files/compound/box-lua.htmlPKj~AV' doc/files/compound/chat-lua.htmlPKj~AoM! doc/files/compound/gauge-lua.htmlPK @doc/files/enum/PKj~Ar{ ^*! doc/files/enum/alignment-lua.htmlPKj~A< e ;-$ doc/files/enum/border_style-lua.htmlPKj~A6/)% "doc/files/enum/bounding_mode-lua.htmlPKj~AҌX}& +doc/files/enum/box_mode-lua.htmlPKj~A04)" 4doc/files/enum/color_mode-lua.htmlPKj~An(' =doc/files/enum/font_decoration-lua.htmlPKj~Ag$(" Fdoc/files/enum/font_style-lua.htmlPKj~AtvV'# Odoc/files/enum/font_weight-lua.htmlPKj~A|&" Xdoc/files/enum/gauge_fill-lua.htmlPKj~AZ8)% adoc/files/enum/gradient_mode-lua.htmlPKj~A(oţ h1 jdoc/files/enum/init-lua.htmlPKj~ALޔ>' tdoc/files/enum/repeat-lua.htmlPKj~Anը'$ z}doc/files/enum/tab_location-lua.htmlPKj~AʤB 8 ddoc/files/init-lua.htmlPK F@ېdoc/files/lib/PKj~A) 8 doc/files/lib/init-lua.htmlPKj~A͛! doc/files/license-txt.htmlPK @ 7doc/index/PKk~APUZ _doc/index.htmlPKk~A vd doc/index/Classes.htmlPKk~A{tS! doc/index/Events.htmlPKk~A.ɜ r sdoc/index/Functions.htmlPKk~AR1yB& doc/index/Functions2.htmlPKj~Aۋ ydoc/index/General.htmlPKj~A= Hdoc/index/General2.htmlPKj~AzzSb hdoc/index/General3.htmlPKj~A$; ,doc/index/General4.htmlPKj~A@"^ oGdoc/index/General5.htmlPKk~Au% bdoc/index/Properties.htmlPKk~A]- D ^~doc/index/Properties2.htmlPKk~AG Êdoc/index/Variables.htmlPKk~AXD-qp {doc/index/Variables2.htmlPK 'vF@߶doc/javascript/PK%O<}iZ_d doc/javascript/main.jsPK =]ƅN doc/javascript/prettify.jsPKk~A )R,  doc/javascript/searchdata.jsPKk~A  doc/Languages.txtPKk~A0y %doc/Menu.txtPK @ )doc/search/PKk~A] *doc/search/ClassesB.htmlPKk~ATSi `-doc/search/ClassesC.htmlPKk~A1y  \0doc/search/ClassesE.htmlPKk~APA#e :3doc/search/ClassesF.htmlPKk~A(y 76doc/search/ClassesG.htmlPKk~A0a 79doc/search/ClassesH.htmlPKk~A 3<doc/search/ClassesI.htmlPKk~A ?doc/search/ClassesL.htmlPKk~Ap Adoc/search/ClassesM.htmlPKk~A oH Edoc/search/ClassesN.htmlPKk~A! Idoc/search/ClassesO.htmlPKk~AN|% aLdoc/search/ClassesP.htmlPKk~AJ [Odoc/search/ClassesS.htmlPKk~A. =Rdoc/search/ClassesV.htmlPKk~Ag Udoc/search/EventsV.htmlPKk~Ai`.+ Xdoc/search/FunctionsA.htmlPKk~A(=T w[doc/search/FunctionsC.htmlPKk~A]P _doc/search/FunctionsD.htmlPKk~At4NI  bdoc/search/FunctionsE.htmlPKk~AvH fdoc/search/FunctionsG.htmlPKk~Ai%H* idoc/search/FunctionsH.htmlPKk~A  rldoc/search/FunctionsI.htmlPKk~A.< modoc/search/FunctionsM.htmlPKk~Al!R  rdoc/search/FunctionsN.htmlPKk~A{B#  vdoc/search/FunctionsO.htmlPKk~ARx͂ ydoc/search/FunctionsP.htmlPKk~Atl5n%  |doc/search/FunctionsR.htmlPKk~A`Ƌ doc/search/FunctionsS.htmlPKk~A( doc/search/FunctionsSymbols.htmlPKk~AgC doc/search/FunctionsU.htmlPKk~A= doc/search/FunctionsV.htmlPKj~A[3. ׎doc/search/GeneralA.htmlPKj~ATT" ;doc/search/GeneralB.htmlPKj~A!%sr4 ^doc/search/GeneralC.htmlPKj~Az8\ doc/search/GeneralD.htmlPKj~Ab}wA doc/search/GeneralE.htmlPKj~Av=.) {doc/search/GeneralF.htmlPKj~A+7r doc/search/GeneralG.htmlPKj~A  doc/search/GeneralH.htmlPKj~AsK?y doc/search/GeneralI.htmlPKj~Aq"M  Ydoc/search/GeneralL.htmlPKj~AK-K doc/search/GeneralM.htmlPKj~A{/ doc/search/GeneralN.htmlPKj~A6 x  doc/search/GeneralO.htmlPKj~AN@Z doc/search/GeneralP.htmlPKj~Ac@ doc/search/GeneralR.htmlPKj~AlS>> doc/search/GeneralS.htmlPKj~A( 0doc/search/GeneralSymbols.htmlPKj~A `doc/search/GeneralT.htmlPKj~A!$| doc/search/GeneralU.htmlPKj~AY(Ӛ fdoc/search/GeneralV.htmlPKj~A#e  6doc/search/GeneralW.htmlPKj~A[Y doc/search/GeneralX.htmlPKj~AL[ Qdoc/search/GeneralY.htmlPKj~A doc/search/NoResults.htmlPKk~Aq?! doc/search/PropertiesA.htmlPKk~A%/X doc/search/PropertiesB.htmlPKk~A)S T {doc/search/PropertiesC.htmlPKk~A7^'  doc/search/PropertiesD.htmlPKk~Aج  cdoc/search/PropertiesF.htmlPKk~Aw屎' Hdoc/search/PropertiesG.htmlPKk~A[d wdoc/search/PropertiesH.htmlPKk~Af Q  doc/search/PropertiesI.htmlPKk~A%k  doc/search/PropertiesL.htmlPKk~AC*  "doc/search/PropertiesM.htmlPKk~A$ &doc/search/PropertiesN.htmlPKk~AD, ;*doc/search/PropertiesO.htmlPKk~Ar5 m-doc/search/PropertiesP.htmlPKk~Ab  0doc/search/PropertiesR.htmlPKk~Aw4 v4doc/search/PropertiesS.htmlPKk~A.  8doc/search/PropertiesT.htmlPKk~AE <doc/search/PropertiesU.htmlPKk~A0{Y  ?doc/search/PropertiesW.htmlPKk~A[Y TCdoc/search/PropertiesX.htmlPKk~AL[ Fdoc/search/PropertiesY.htmlPKk~AΌ  Idoc/search/VariablesA.htmlPKk~Aih Mdoc/search/VariablesB.htmlPKk~A^5B IRdoc/search/VariablesC.htmlPKk~AJPtZa  Wdoc/search/VariablesD.htmlPKk~AA  H[doc/search/VariablesE.htmlPKk~At_  _doc/search/VariablesF.htmlPKk~A"  cdoc/search/VariablesG.htmlPKk~A'~ [fdoc/search/VariablesH.htmlPKk~A,`Ӎ  idoc/search/VariablesI.htmlPKk~A~* Omdoc/search/VariablesL.htmlPKk~AkWԾ  qpdoc/search/VariablesM.htmlPKk~AX gtdoc/search/VariablesO.htmlPKk~AbX wdoc/search/VariablesP.htmlPKk~A3/  zdoc/search/VariablesR.htmlPKk~Af ~doc/search/VariablesS.htmlPKk~A6x  doc/search/VariablesT.htmlPKk~AxrD doc/search/VariablesV.htmlPKk~A_-  doc/search/VariablesW.htmlPK (vF@ Adoc/styles/PK=>M*T jdoc/styles/main.cssPKk~AW~  doc/Topics.txtPK m@enum/PKF<(@;B  enum/alignment.luaPKF<(@֦\ ^enum/border_style.luaPKF<(@ߖa enum/bounding_mode.luaPK=Z@N\c %enum/box_mode.luaPKF<(@)? enum/color_mode.luaPKF<(@EvN enum/font_decoration.luaPK!@[o @enum/font_style.luaPKF<(@~&&K; enum/font_weight.luaPK2@OfPz ]enum/gauge_fill.luaPKF<(@=P enum/gradient_mode.luaPKa1(@S׭ enum/init.luaPKF<(@r=| enum/repeat.luaPK9 @ c2 enum/tab_location.luaPK0 @4NM  minit.luaPK p@lib/PKd@Fa lib/init.luaPK<(@jf license.txtPK@66 PREADMEPK[@'<O vyzor.xmlPK; mudlet-2.1/src/TAction.cpp0000644000175000017500000002601212070466512015016 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "TDebug.h" #include #include "TAction.h" #include "Host.h" #include "HostManager.h" #include "EAction.h" #include "TFlipButton.h" #include "TToolBar.h" using namespace std; TAction::TAction( TAction * parent, Host * pHost ) : Tree( parent ) , mpToolBar( 0 ) , mpEasyButtonBar( 0 ) , mButtonState( 1 ) , mPosX( 0 ) , mPosY( 0 ) , mNeedsToBeCompiled( true ) , mModuleMember(false) , mModuleMasterFolder(false) , exportItem(true) , mButtonColumns( 1 ) , mIsLabel( false ) , mUseCustomLayout( false ) , mButtonColor( QColor( 255,255,255) ) , mpHost( pHost ) { } TAction::TAction( QString name, Host * pHost ) : Tree(0) , mpToolBar( 0 ) , mpEasyButtonBar( 0 ) , mButtonState( 1 ) , mPosX( 0 ) , mPosY( 0 ) , mName( name ) , mNeedsToBeCompiled( true ) , mModuleMember(false) , mModuleMasterFolder(false) , mButtonColumns( 1 ) , exportItem(true) , mIsLabel( false ) , mUseCustomLayout( false ) , mButtonColor( QColor( 255,255,255) ) , mpHost( pHost ) { } TAction::~TAction() { if( ! mpHost ) { return; } mpHost->getActionUnit()->unregisterAction(this); } bool TAction::registerAction() { if( ! mpHost ) { qDebug() << "ERROR: TAction::registerTrigger() pHost=0"; return false; } return mpHost->getActionUnit()->registerAction( this ); } void TAction::compileAll() { mNeedsToBeCompiled = true; if( ! compileScript() ) { if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::red))<<"ERROR: Lua compile error. compiling script of action:"<>0;} mOK_code = false; } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TAction * pChild = *it; pChild->compileAll(); } } void TAction::compile() { if( mNeedsToBeCompiled ) { if( ! compileScript() ) { if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::red))<<"ERROR: Lua compile error. compiling script of action:"<>0;} mOK_code = false; } } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TAction * pChild = *it; pChild->compile(); } } bool TAction::setScript( QString & script ) { mScript = script; mNeedsToBeCompiled = true; mOK_code = compileScript(); return mOK_code; } bool TAction::compileScript() { mFuncName = QString("Action")+QString::number( mID ); QString code = QString("function ")+ mFuncName + QString("()\n") + mScript + QString("\nend\n"); QString error; if( mpHost->mLuaInterpreter.compile( code, error ) ) { mNeedsToBeCompiled = false; mOK_code = true; return true; } else { mOK_code = false; setError( error ); return false; } } void TAction::execute(QStringList & list ) { qDebug()<<"TAction::execute() called: depricated!"; } void TAction::_execute(QStringList & list) { if( ( mCommandButtonUp.size() > 0 ) && ( mButtonState == 1 ) ) { mpHost->send( mCommandButtonUp ); } if( ( mCommandButtonDown.size() > 0 ) && ( mButtonState == 2 ) ) { mpHost->send( mCommandButtonDown ); } if( mNeedsToBeCompiled ) { if( ! compileScript() ) { mpHost->mpConsole->activateWindow(); mpHost->mpConsole->setFocus(); return; } } mpHost->mpConsole->mButtonState = mButtonState; mpHost->mLuaInterpreter.call( mFuncName, mName ); // move focus back to the active console / command line mpHost->mpConsole->activateWindow(); mpHost->mpConsole->setFocus(); } void TAction::expandToolbar( mudlet * pMainWindow, TToolBar * pT, QMenu * menu ) { typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TAction * pChild = *it; QIcon icon( pChild->mIcon ); QString name = pChild->getName(); TFlipButton * button = new TFlipButton( pT,pChild, pChild->mID, mpHost ); button->setIcon( icon ); button->setText( name ); button->setCheckable( pChild->mIsPushDownButton ); button->setChecked( (pChild->mButtonState==2) ); qDebug()<<"button="<mName<<" checked="<<(pChild->mButtonState==2); button->setFlat( mButtonFlat ); button->setStyleSheet( css ); pT->addButton( button ); if( pChild->mIsFolder ) { QMenu * newMenu = new QMenu( pT ); button->setMenu( newMenu ); newMenu->setStyleSheet( css ); pChild->insertActions( pMainWindow, pT, newMenu ); } } } void TAction::insertActions( mudlet * pMainWindow, TToolBar * pT, QMenu * menu ) { mpToolBar = pT; QIcon icon( mIcon ); EAction * action = new EAction( icon, mName, pMainWindow ); action->setCheckable( mIsPushDownButton ); action->mID = mID; action->mpHost = mpHost; action->setStatusTip( mName ); menu->addAction( action ); //mudlet::self()->bindMenu( menu, action ); if( mIsFolder ) { QMenu * newMenu = new QMenu( pMainWindow ); newMenu->setStyleSheet( css ); action->setMenu( newMenu ); typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TAction * pChild = *it; pChild->insertActions( pMainWindow, pT, newMenu ); } } } void TAction::expandToolbar( mudlet * pMainWindow, TEasyButtonBar * pT, QMenu * menu ) { typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TAction * pChild = *it; if( ! pChild->isActive() ) continue; QIcon icon( pChild->mIcon ); QString name = pChild->getName(); TFlipButton * button = new TFlipButton( pT,pChild, pChild->mID, mpHost ); button->setIcon( icon ); button->setText( name ); button->setCheckable( pChild->mIsPushDownButton ); button->setFlat( mButtonFlat ); button->setStyleSheet( css ); button->setChecked( (pChild->mButtonState==2) ); //FIXME: Heiko April 2012: only run checkbox button scripts, but run them even if unchecked if( pChild->mIsPushDownButton && mpHost->mIsProfileLoadingSequence ) //&& pChild->mButtonState == 2 ) { qDebug()<<"expandToolBar() name="<mName<<" executing script"; QStringList bla; pChild->_execute(bla); } pT->addButton( button ); if( pChild->mIsFolder ) { QMenu * newMenu = new QMenu( button ); button->setMenu( newMenu ); newMenu->setStyleSheet( css ); pChild->fillMenu( pT, newMenu ); } } } void TAction::fillMenu( TEasyButtonBar * pT, QMenu * menu ) { typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TAction * pChild = *it; if( ! pChild->isActive() ) continue; mpEasyButtonBar = pT; QIcon icon( mIcon ); EAction * action = new EAction( icon, pChild->mName, mudlet::self() ); action->setCheckable( pChild->mIsPushDownButton ); action->mID = pChild->mID; action->mpHost = mpHost; action->setStatusTip( pChild->mName ); action->setChecked((pChild->mButtonState==2)); //FIXME: Heiko April 2012 -> expandToolBar() if( pChild->mIsPushDownButton && mpHost->mIsProfileLoadingSequence )//&& pChild->mButtonState == 2 ) { qDebug()<<"fillMenu() name="<mName<<" executing script"; QStringList bla; pChild->_execute(bla); } menu->addAction( action ); if( pChild->mIsFolder ) { QMenu * newMenu = new QMenu; action->setMenu( newMenu ); newMenu->setStyleSheet( css ); pChild->fillMenu( pT, newMenu ); //mudlet::self()->bindMenu( menu, action ); } } } void TAction::insertActions( mudlet * pMainWindow, TEasyButtonBar * pT, QMenu * menu ) { mpEasyButtonBar = pT; QIcon icon( mIcon ); EAction * action = new EAction( icon, mName, pMainWindow ); action->setCheckable( mIsPushDownButton ); action->mID = mID; action->mpHost = mpHost; action->setStatusTip( mName ); menu->addAction( action ); //mudlet::self()->bindMenu( menu, action ); } TAction& TAction::clone(const TAction& b) { mName = b.mName; mCommandButtonUp = b.mCommandButtonUp; mCommandButtonDown = b.mCommandButtonDown; mRegex = b.mRegex; mScript = b.mScript; mIsPushDownButton = b.mIsPushDownButton; mIsFolder = b.mIsFolder; mpHost = b.mpHost; mNeedsToBeCompiled = b.mNeedsToBeCompiled; mIcon = b.mIcon; mpToolBar = b.mpToolBar; return *this; } bool TAction::isClone( TAction & b ) const { return ( mName == b.mName && mCommandButtonUp == b.mCommandButtonUp && mCommandButtonDown == b.mCommandButtonDown && mRegex == b.mRegex && mScript == b.mScript && mIsPushDownButton == b.mIsPushDownButton && mIsFolder == b.mIsFolder && mpHost == b.mpHost && mNeedsToBeCompiled == b.mNeedsToBeCompiled && mpToolBar == b.mpToolBar && mIcon == b.mIcon ); } mudlet-2.1/src/mudlet_documentation.txt0000755000175000017500000071507011513237311017743 0ustar csmallcsmallMudlet Manual ============= .Table of Contents **************** . <> . <> .. <> .. <> .. <> .. <> .. <> .. <> .. <> ... <> ... <> ... <> ... <> ... <> ... <> ... <> ..... <> ..... <> .... <> .... <> ... <> .. <> .. <> .. <> . <> .. <> .. <> ... <> ... <> .. <> .. <> .. <> .. <> .. <> .. <> .. <> . <> .. <> .. <> . <> .. <> .. <> .. <> .. <> . <> . <> . <> **************** [[introduction]] == Introduction Welcome to *Mudlet*, a modern MUD client for GNU/Linux, Windows and Mac OSX that offers all the tools to get the most out of your gaming experience. Throughout this document we hope to familiarize you with the basic aspects of Mudlet, from the interface to its _very_ powerful and feature rich scripting backend The main focus in the development of Mudlet has been efficiency and performance, but we also try to make it as easily accessible as possible. However, keep in mind that this is a complex piece of software with a large set of tools that does require some deeper understanding of the underlying principles. To use Mudlet in any meaningful way, you have to take a closer look at the technical section in this manual. If you are not familiar with using modern MUD clients in general you should also take a look at the general introduction to MUD clients section at the beginning of this manual. You are welcome to ask questions on the forum of our website. If you find a bug, please let us know. http://www.youtube.com/watch?v=c1Llvwy0Y_Y&feature=PlayList&p=A40A1E6E5AEB8874&index=0&playnext=1[Watch the introductory Mudlet 1.0 screencast by Vadim Peretokin.] [[diag_variables]] [icon="images/icons/diag_variables.png"] NOTE: Everything is centered around the central Lua scripting unit. Everything shares the same variables & functions and everything is accessible from anywhere. === Quick Start To connect to the MUD of your choice, click on `Connect`. ! * Create a new profile by clicking on `Add New Profile`. * Specify the `host` and the `port` of the MUD (This information is usually found on the MUD's homepage). * Now just click `Connect` to play! == 1. General Introduction to Modern MUD Clients === 1.1 Mudlets automation features Mudlet offers a vast array of standard features to automate or otherwise improve your gaming experience. These include, but are not limited to: - *Aliases* – user-defined text input, which is converted into a different, usually longer input before being sent to the MUD, e.g. +gg+ → +get gold from ground;put gold in 2.bag+. - *Keybindings* – also known as hotkeys, allow executing certain user-defined commands by simultaneously pressing a specific combination of keys, e.g. +CTRL+H+ → +send say Hello Miyuki!+ to the MUD or +plays La Marseillaise+ - *Triggers* – execute user-defined commands upon receiving specific out from the MUD, e.g. MUD sends +You see Elyssa standing here.+ → send +poke Elyssa+ to the MUD. - *Timers* – delay the execution of a command or execute it after a specified period of time, e.g. +throw gauntlet to Eric+-+wait 3 seconds+-+exclaim Let us end this here!+ - *Variables* – allow the user to store text or numbers for easier use inside scripts. - *Events* – allow the user to make triggers for specific events like when Mudlet has connected to the MUD, or even user-defined events to use in complex system making. Scripting allows the user to create automation utilities (triggers, aliases) with the Lua scripting language. The possibilities of what can be achieved by using this technique are, practically speaking, endless - ranging from teaching the client how to heal your character in combat for you to creating a fully automated robot (known as `bot`s) that will completely take over the control for your character (especially useful for completing repetitive, rudimentary tasks). === 1.2 Automation and MUD rules Effectively speaking, it is possible to create an AI (Artificial Intelligence) that does everything you can do in a MUD. Even more so, the program will be able outperform you in almost every routine operation. The difficulty of creating such a program depends on the task it has to perform: gathering loot being very easy, walking through a dungeon and leveling you character being moderately easy and socially interacting with other real people being outrageously difficult (see http://alice.pandorabots.com/[A.L.I.C.E.]). In the end of the day, you're teaching your client to process information and act the way you consider best suited. Because scripting is so powerful, it can give you a competitive advantage that some people consider it unfair or even cheating. As of the moment of this writing (2 November 2008), this sort of automation can be best observed in commercial massively-multiplayer online role-playing games (MMORPG), known as gold-farming or power-leveling. The basic idea is creating a system that will raise your character to the maximum level and gather in-game currency in the process, both of which can be effectively exchanged for real-world currency. The spread of the above aspects can have much more far reaching consequences than just being unfair, such as inflation, loss of balance in terms of game-mechanics or, ultimately, a complete crash of in-game economy. For more information see the paper http://papers.ssrn.com/sol3/papers.cfm?abstract_id=1235602["Simple Economics of Real-Money Trading in Online Games"] by Jun-Sok Huhh of the Seoul National University. For these, and various other, reasons the administrators and owners of the corresponding virtual worlds can forbid the usage of automation tools. A failure to comply can result in suspension or deletion of the user's character or account for future denial of service. By including scripting support in Mudlet, we effectively give you the ability to create and utilize AI tool-kits, however, we do not endorse or promote the usage of these systems if it's prohibited in your MUD. Keep in mind that by cheating you can lessen the quality of gameplay for both, your fellow players and yourself. === 1.3 Basic scripting The following part of the guide is written for new beginners in scripting. If you're coming over from zMud or cMud, you may move on to section two. ==== 1.4 Variables - basics Variables are containers for data. In Lua, they can store numbers or words. You can use variables to store important information like how much gold do you have, or have them remember things for you. The syntax for making a variable remember a number is the following: --------- variable = number --------- Or to make it remember some text: [source,lua] ----- variable = "variable_name" ---- For example, here we'll set the `myhealth` variable to number `1345`, and the `myname` variable to `Bob`: [source,lua] ----- myhealth = 1345 myname = "Bob" ----- You can also do basic maths easily, for example: [source,lua] ----- a = 2 + 2 --sets variable a to the value of 4 b = a - 1 --sets variable b to the value of 3 ----- To concatenate strings together, you can use the `..` expression: [source,lua] ------ first_name = "Joe" last_name = "Plumber" full_name = firstname .. " " .. last_name --sets the full_name variable to "Joe Plumber", with a space in between. ----- ==== 1.5 How to send text to the mud To send a command to the MUD, you can use the `send()` function. Data inside the quotes is sent to the MUD. For example, the following code sends the command to `eat bread`: [source,lua] ----- send("eat bread") ----- If you'd like to include variables in the send command, you need to prefix and suffix them with two dots outside the quotes, like this: ---- send("My name is " .. full_name .. ". What's yours?") ------ ==== 1.6 How to echo text to yourself To echo (show text to yourself) you can use the `echo()` or the `insertText()` function. For example, the following code will display `Time to eat dinner!` on your screen: ----- echo("Time to eat dinner") ------ If you'd like to include variables in your echo, you concatenate the value of your variable to the text: --------- my_gold = 5 echo("I have " .. my_gold .. " pieces of gold!") ----- ==== 1.7 Aliases The aliases are the most basic way of automating the gameplay - you can use aliases to shorten the amount of typing you do. For example: .Example - Brew'o'Matic 6000 __________________________ You're walking around the epic dungeon of the Unholy Firedragon of Westersand, gathering roots in order to brew a potion and thus restore the growth of hair on Farmer Benedict's bald head. Once you see a root, you need to: .......................... open the bag of tools get the sickle of damnation from the bag of tools cut the root of hair-growth clean the sickle of damnation of deadly root acid put the sickle of damnation in the bag of tools close the bag of tools open the magical bag of storing take the root put the root into the magical bag of storing close the magical of storing .......................... and once you're done, do the exact same thing nine more times... trice a day. __________________________ Alternatively, you just create an alias that would do this all with a single command - for example, `quest`. ===== 1.8 Making a simple alias To get started, go click on the `Aliases` button in Mudlet, and then on the `Add` one. This will make a blank alias for you, which we'll now fill in. The `Alias name` field is optional - it's mainly used for the alias listing that you see on the left as an easy way to distinguish all of the aliases. You can just name our alias `test` for now. The `Pattern` field is where you put your regex pattern to describe on what command that you are typing in the command line, your new alias will spring into action. Let's say, we want our new alias to send the command "say hello" whenever we type "sh". The regex pattern would be "^sh$". Then we put "say hello" into the substitution field. After you have saved and activated your new alias "test", whenever you type "sh" Mudlet will not send "sh", but "say hello" instead. We call this substitution process alias expansion. Mudlet uses Perl regular expression aliases. Regexes are a special way of matching patterns of words. For the beginners it is enough to think of them as a general way to specify the words itself and their placement within the line. For basic alias it is enough to know that the character ^ symbolizes the beginning of the line and the character $ symbolizes the end of the line. If you want to make an alias "tw" that sends the command "take weapon", you don't have to care about placement or pattern matching in general. All you need to do is fill "tw" in the field called "Regex" and type "take weapon" in the field called "substitution". Then you need to save the new alias by clicking on the "Save" icon in the top middle. The symbol for unsaved items disappears and makes way for a little blue checkbox. If this box is checked the alias is active. If the blue box is empty, the alias is deactivated and will not work unless you press the "activate" toggle padlock icon. Now you are ready to go. Type "tw" in the command line and press the enter key. Mudlet will send "take weapon" to the MUD. Alias as basically, a feature to save you a bit of typing - much like buttons which will be described in detail in section two of the manual. To learn more about more complex aliases have a look at section 2 of the manual. ==== 1.9 Simple Triggers Triggers are an automation feature offered in all MUD clients. They help you respond quicker a particular situation and generally make things more convenient for you since you need to do less manual work as your triggers will do the hard work for you often times. This helps you concentrate more on the important aspects of the game and lessen stress. The way a trigger works is simple: You define some text that you want to trigger some action. This is called the trigger pattern. When the trigger "sees" this text in the MUD output, it'll run the commands you've told it to. Example: Whenever you see a bunny, you want to attack it. You type "bunny" in the data field titled "add to list" and then either press the enter key or click on the little + icon next to the input line to add this word to the list of texts this trigger fires on. Now you type "kill bunny" in the field called "send plain text". Then click on the save icon to save the trigger and activate your new trigger (= blue checkbox icon in front of the trigger name in the trigger tree on the right side is checked). When the trigger is active each time the word "bunny" will appear in the MUD output, your trigger will issue the command "kill bunny" automatically as long as it is active. When you want to stop hunting bunnies, you can simply select the bunny trigger and then click on the padlock icon to deactivate the trigger. The trigger will stop firing until you re-enable it again via the padlock icon. If you lock a group of triggers or an entire trigger branch, all triggers in this branch will be locked until you remove the lock again. The locking starts from the root of the tree down to the end. As soon as a lock is met the trigger engine will skip the locked branch. Locking and unlocking branches is one of the most common actions you have to take care of when playing. You turn on your defensive triggers when engaging into a battle and you turn them off afterwards, or you turn on your harvesting triggers only when you are going to harvest. TIP: *Beginners should use Mudlets automated highlight triggers in the beginning to highlight the text that has been triggered on to get the hang of the different trigger and pattern types. Click on the "highlight trigger" option and pick a foreground and a background color that you like to highlight your trigger with. When the trigger matches it automatically highlights its pattern. This is the most used form of triggers in mudding as it is a quick way of highlighting words that are important to you at the moment. You don't have to know anything about scripting, regular expressions etc. to use highlight triggers. Just type in the word you like to be highlighted, select appropriate colors, save the new trigger and activate it.* ===== 1.10 Matching one unknown You can also set up a trigger to gather the scimitars, gold or whatever the skeletons could carry around with them. Since we do not know what the loot is, we will need to set up a trigger to match the line and take whatever was dropped. Examples: ---- The skeleton drops ring. The skeleton drops gold. The skeleton drops scimitar. ---- +The skeleton drops_+ is the generic segment of the line, the loot itself varies. Thus, we need to tell the client to +take_+ whatever the skeleton dropped. We do this by setting up a so-called +regular expression+: ---- Perl Style Regular Expression: The skeleton drops (.*)\. Script: send("take " .. matches[2]) ---- The expression +(.*)+ matches any characters that the client receives between +The skeleton drops_+ (NB: notice the blank at the end) and the full-stop. +matches[2]+ simply transfers _the first matched text fitting the search criteria_ into the output (matches[1] contains the entire matched text, matches[2] contains the first capture group. More on this in section two of the manual). ===== 1.11 Matching multiple unknowns Now, let's try making a trigger that would gather the loot from anybody: ---- Perl Style Regular Expression: (.*) drops (.*). Script: send("take " .. matches[3]) ---- In this case, any time somebody, or something, drops something else, or someone else, the client will pick it up. Note that we used +matches[3]+ instead of +matches[2]+ this time, in order to pick up the second match. If we used +matches[2]+, we'd end up picking up the skeleton's corpse. ===== 1.12 Matching known variants If you're playing a MUD in English, you'll notice that these triggers probably won't work due to English syntax. Compare: ---- The skeleton drops apple. The skeleton drops an apple. ---- Chances are that you'll see the later a little more often. If we used our old RegEx, the output would look something like this. ---- INPUT: The skeleton drops an apple. OUTPUT: take an apple ---- Most MUDs can't handle determiners, such as articles (i.e. +a+, +an+, +the+) or quantifiers (e.g. +five+, +some+, +each+), in user-input. To match this line we could either create multiple triggers matching every possible article or a regular expression filtering out these words: ---- Perl Style Regular Expression: (.*) drops (a|an|the|some|a couple of|a few|) (.*). Script: send("take " .. matches[4]) ---- Once again, note that we're using the third match (+matches[4]+) this time. NOTE: Certain other languages, with a morphology richer than that of English, might require a somewhat different approach. If you're stuck, and your MUD-administrators don't prohibit the use of triggers, try asking on the corresponding world's forums. For more information, see the chapter Regular Expressions. ==== 1.13 explain basic regex characters (^, $, (\w+), (\d+) and .*) and how to use them properly. ==== Retrieving wildcards from triggers Wildcards from triggers are stored in the _matches[]_ table. The first wildcard goes into _matches[1]_, second into _matches[2]_, and so on, for however many wildcards do you have in your trigger. For example, you'd like to say out loud how much gold did you pick up from a slain monster. The message that you get when you pick up the gold is the following: ---- You pick up 16 gold. ---- A trigger that matches this pattern could be the following: ---- Perl Style Regular Expression: You pick up (\d+) gold ---- And in your code, the variables +matches[2]+ will contain the amount of gold you picked up (in this case, _16_). So now to say out loud how much gold did you loot, you can do the following: ---- Script: echo("I got " .. matches[2] .. " gold!") ---- ===== More advanced example Here's an example by Heiko, which makes you talk like Yoda: ---- Perl Style Regular Expression: ^say (\w+) *(\w*) .*?(.*) Script: send( "say "..matches[4].." "..matches[2].." "..matches[3] ) ---- What it does here is save the +first word+, the +second word+ and then the +rest of the text+ into wildcards. It then says +rest of the text+ first, then the +first word+ and then the +second word+. ==== 1.14 How to highlight words To highlight something in the MUD output, make a trigger and use the "highlight trigger" option to highlight the matched trigger pattern. Optionally, you can also make use of the <> and <> functions in scripting to highlight. ==== 1.15 Keybindings Keybindings, or hotkeys, are in many respects very similar to aliases, however, instead of typing in what you want to be done, you simply hit a key (or combination of keys) and let the Mudlet do the work. .Example - You don't drink tea, you sip it! **** You're participating in an in-game tea sipping contest. The winner is the first person to sip an Earl Grey, should the quiz-master make a vague reference to a series of tubes, or a Ceylon Mint, if he begins talking about the specific theory of relativity. In order to give us a competitive advantage, we will define two keybindings: **** ---- HOTKEY: F1 command on button down: sip earl gray HOTKEY: F2 command on button down: sip ceylon mint ---- Now you just have to listen, or rather read, carefully and hit either F1 or F2 to claim that prize. Another practical use for keybindings would be creating a so-called "targeting system", which is especially useful for grinding down armies of pumpkin-men in MUDs without auto-attack. See the Variables chapter for further details. ==== 1.16 Timers Timers, as the name suggests, can be used to execute a specific command at a certain time, after a certain time or once every so often. .Example - Don't miss the training! **** Your character can train in his attributes once every three hours. You could either try tracking this manually or add a trigger starting timer after each training. Once the three hours have passed, your character will conveniently say to himself that it is time to do a couple of push-ups. **** [[manual]] == Main Manual == Multi Session Gaming Mudlet lets you play several simultaneous MUD sessions. However, currently we have the restriction that you cannot use the same profile twice. Consequently, if you want to play three characters on the same MUD at the same time, you need to make 3 profiles with 3 different names e.g. ernie@avalon.de, bert@avalon.de etc. [[splitScreen]] == Split Screen Mudlet has a _split screen_. If you scroll up in the MUD text screen (or any other mini console window), the screen will split in two parts. The lower part will follow the MUD output while the upper part will stay focused on your scrolling. This way you can read easier through old passages without missing what is going on at the moment. Split screen can be activated via the scroll bar, page up / page down keys or the mouse wheel. Scrolling back to the end will close the split screen automatically. A click on the middle mouse button will close the split screen immediately as well as pressing control+return on the keyboard. The size of the 2 parts of the split screen can be modified by dragging the separator bar in the middle with the mouse. Split screen usage is necessary when selecting text in order to copy it to trigger editor e.g. when making triggers. If you don't use split screen when selecting text, new arriving text will upset your selection. [[commandLine]] == Command Line Auto-Completion, Tab-Completion and Command History Mudlets command line is especially designed for MUD and MUSH playing. It aims at reducing the amount of typing by using autocompletion and tab completion schemes that are optimized for typical MUD playing situations. The command line offers tab completion (TAB key with or without shift) and autocompletion (cursor up and cursor down keys). ======= 1. _Tab completion_ searches the last 100 lines in the MUD output buffer for words matching the word that you are currently typing. This is useful if you have to type complicated long names. You only have to type the first letters and then press the tab key until the proposal is what you want. 2. _Autocompletion_ tries to match your current typing with your command history. Example: If you typed the same command a while ago, you only have to start typing the first couple of letters and then press the cursor up key until the proposal matches the command that you want to use. 3. _Command History_: If you haven't started to type anything yet, you can browse through your command history with the cursor up and cursor down keys. However, if you have started typing pressing cursor up will result in a shot at autocompletion. 4. _ESC_:To get out of autocompletion you can press the ESC key any time. After pressing ESC the entire text gets selected and you can overwrite it or get back into command history mode. ======= [[logging]] == Logging Output to text or HTML Log Files Press on the little button with the blue folder with the green arrow icon on the lower right side of the command line to turn on plain text logging. Click again to stop logging. This will inform you about the file name and path of the log file. If you want to log in color you can chose to log to files in html format, but note that due to the nature of HTML, these log files tend to get _very_ large quickly. Log files can be found at the mudlet home directory in your profile directory. To get the path to your mudlet home directory you can run a script like this one: ------- echo( getMudletHomeDir() .. "\n" ) ------- Log files are stored in "/logs". Each profile has its own path. Log files have a similar naming convention to the autosaved profiles: date#time.txt or date#time.html [[export]] == Exporting and Importing Profiles or Packages Mudlet supports XML packages that can be imported and exported while playing. You can find a package section on the forum at http://mudlet.sourceforge.net where you can download demo packages or ready made packages for your MUD or upload your own packages to share your work with other players. A package can contain anything ranging from a single trigger to hundreds of button groups, trigger groups aliases - in other words, entire "systems". === Importing Packages To import a package, open the script editor and click the import icon, select your xml package file and import it. Package files might be compressed to save space. If the file is compressed, you'll need to uncompress it before importing it. The imported package will be stored permanently in your profile when you safe the profile. If you don't like the imported package, delete its components manually or simply don't save the profile. Then the new content will be lost on restart. Good packages will be organized in such a way that they will be easy to update or remove. Packages are nothing else, but profiles - or parts of profiles that can be exchanged, imported and exported between your own profiles and between different players. From a technical perspective a package and a profile xml file are the same thing. === Exporting Packages Exporting items or groups is also easy. Select your item or a group containing many items or subgroups and then click on the "Export" button. You'll be prompted for a file name and that's it. Package file names should end with ".xml" to make import easier for users on all platforms. You can send your cool trigger, buttons, timers etc. to your friends or use them in another profile of yours. Exporting your good stuff is strongly recommended as it makes MUDding more enjoyable for everybody. Share your knowledge and help others! Mudlet stores your saved profiles as XML files in your home directory under "/current". To get run a script like this: ------- echo( getMudletHomeDir() .. "\n" ) ------- To export your entire profile e. g. to make a backup on a flash drive, use the "save profile as" button. You can export packages of a trigger branch, alias branch, function key, scripts etc. by clicking on a folder in the tree of the particular item in question and then click on the export icon. You'll be asked to give a filename for your package. You can export arbitrarily complex structures by moving them into a folder that e.g. is named after the package you'd like to make. === Sharing your System with others - Making complex Packages If you have written a nice set of triggers, buttons, scripts etc. or maybe even a fully fledged "system" of some sort and you want to share it with others, you can make a nice packages that other people can import with a single mouse click. The recommended procedure to make a large package that contains groups of all sorts of items e.g. trigger groups, individual triggers, scripts, buttons, aliases etc., is to export the entire profile with "save profile as". Then create a new empty profile e.g. with your package name. Don't give a server or port name in the connection dialog and "connect". Mudlet will load the new empty profile although you are offline. Open the script editor and import your previously exported profile and then delete all items that are not part of the package that you are making. Finally, make a folder (group) that is named after your package name and version number e.g. "Johnny's curing system 12-3-2009" and move all respective items into this folder and repeat the same procedure for all triggers/aliases/scripts etc.. This will make it much easier for other people to import your package and stay updated if you release a newer version. Then save your profile and use the "save profile as" button to create your package. [[variables]] == Using Variables in Mudlet Using Variables in Mudlet One of the major design goals in Mudlet was to integrate scripts and variables into triggers/aliases/buttons etc. as seamlessly as possible. The usage of variables in Mudlet is distinctly different from the other major clients, as native Lua scripting has been integrated into Mudlet from the ground up. As scripts are so closely intertwined with the core of Mudlet, variables do not need any special treatment as in other clients i.e. there is no need for code such as: ---- totalKills = getVariable("killedMonsters") + getVariable("killedVillains") echo( "kills=" .. totalKills ) ---- In Mudlet, the above code translates into: ---- totalKills = killedMonsters + killedVillains echo( "kills=" .. totalKills ) ---- If you define a variable in any given script in Mudlet, be it a trigger, a button, an alias key, an event handler, a free function, etc. It can be used from within any context without any special getVariable() type of function or any special variable symbols, such as @myVar etc.. In Mudlet all variables are native Lua variables. Each session (= profile/connection tab) runs in its own dedicated Lua interpreter. Consequently, all scripts of a profile are compiled into the same Lua interpreter and thus their code runs in the same variable space. All scripts from another simultaneously opened profile will not interfere because each profile uses its own Lua interpreter. [[diag_variables]] [icon="./images/icons/diag_variables.png"] NOTE: Everything shares the same variables & functions. To give you an example: Let's make a little trigger that counts how many monsters you have killed. Each time you have made a new kill, the trigger matches on the kill message and runs a little script that increases the amount of kills by one each time the trigger fires - in other words, each time you kill a monster and the kill message is sent from the MUD. For the kill counter we declare a variable and call it [red]+myKills+. This variable is going to hold the number of kills we've made so far. The script will look like this: ------- myKills = myKills + 1 ------- Then we add a little alias, a button or a keybindings that executes another little script that prints your current kill statistics on the screen. The attached script would look like this: ---------- echo( "I have killed " .. myKills .. " monsters today." ) ---------- *********************** .Lua Primer: Variables, Strings & numbers Lua variables can be either a string or a number. They are whatever there were initially initialized with or what data type they can be converted to. ---- a = "Jim" b = "Tom" c = 350 d = 1 ----- Then you can write: ----- e = c + d and e will equal 351 e = a .. b and e will equal "JimTom" note that you cant use a+b to concatenate string values. For this you must use .. e = a .. c and e will equal "Jim350" ----- There is another form of variables in Lua called tables which can be used for lists, arrays or dictionaries. This is explained later. For an in-depth coverage of variables in Lua take a look at a Lua tutorial e. g. this one on numbers http://Lua-users.org/wiki/NumbersTutorial and this one on strings http://Lua-users.org/wiki/StringsTutorial or this one on Lua tables http://Lua-users.org/wiki/TablesTutorial ************************* Let's get back to our example. The trigger script expects [red]+myKills+ to be a number so you have to initialze the variable myKills to 0 before running the script for the first time. The best place to initialize variables is in script script *outside of a function definition* as this code is executed when the session is loaded or if you compile the script again after you have edited it. To do this click on the "Scripts" icon and select the standard script "My Global Variable Definitions". If you are using an older version of Mudlet or a profile that doesn't have this script item, simply click on the "Add" icon and make your own script. You can call it whatever you want to. Add following code to initialize your new variable myKills to a number and set its value to 0: ----- myKills = 0 ----- Whenever you edit this script, it will be recompiled and the code will be run as it is not part of a function definition. This is the major difference between trigger-scripts, alias-scripts etc. and script-scripts. Script-scripts can contain an unlimited amount of function definitions and also *free code* i. e. code outside of a function definition - code that is not enclosed by function xyz() .... end. On saving the script the script gets compiled and the free code is run instantly. All other item scripts, i. e. trigger-scripts etc., secretly define a function name for the script and thus the script is not free code, but function code. When a trigger fires Mudlet calls this invisible function name to run the script e.g. trigger738(), button82(), alias8(). This means that if you define variables inside a trigger script the variable will not be defined before the trigger runs for the first time. However, if you define this variable as free code in a script-script the definition becomes available immediately on script save. Now, whenever you add new variables to your variable definition script, the script gets run and your old variables will be reinitialized and reset to 0. This will be no big problem in most cases as you won't work on your systems while really playing in most cases. To solve this problem you have two options: *First option*: Add a script group (a folder) and add a new script item for each variable you define. This way, editing a variable definition will only reset the edited variable and none of the others that are defined in different scripts. This has the added advantage that you have a nice graphical overview of your defined variables. [[diag_variable_orga_screen_small]] [icon="./images/icons/variable_orga_screen_small.png"] NOTE: Organize your variables *Second option (more advanced)*: Change the variable initialization to only initialize the variable if it hasn't been initialized before, thus keeping the values of previously defined variables. This would look like this: -------- if myKills == nil then -- this code initializes the variable myKills to the number 0 if it hasn't been initialed before myKills = 0 end -------- In Lua all undefined variables are initialized to the value [red]+nil+. The value [red]+nil+ is not the same thing as the number [red]+0+ or the empty string [red]+""+. What it means is that a variable that has the value [red]+nil+ has not been declared yet and does not exist. If a variable does not exist, it cannot be used as its value is undefined at this point. Consequently, increasing the value of [red]+nil+ by one is impossible as the variable doesn't exist yet and will lead to a Lua error. The above script simply checks if the variable myKills has been defined yet and if it hasn't, it will declare the variable and set its value to 0. === Lists Having variables that hold a single value is the most important usage of variables, but very often you'll like to define variables that hold a list of values e. g. a list of your enemies, a list the items you are currently carrying etc.. To define a variable to be a list you need to declare it to be a Lua table. Let's declare the variable [red]+myEnemies+ as a list containing the names of your enemies: [source,lua] ------ *Source* block Use: highlight code listings (require `source-highlight`) myEnemies = {} ------ You can now add new enemies to this list by calling the Lua function listAdd( listName, item ) e.g. ----- listAdd( myEnemies, "Tom" ) listAdd( myEnemies, "Jim" ) ----- To print the contents of your enemy list on the screen you can run this script ------- listPrint( myEnemies ) ------- Now let's make a little alias that adds a new name to your enemy list when you type "add enemy " followed by the name of the enemy e. g. "add enemy Peter" Open the alias editor by clicking on the alias icon. Click on the "Add" icon to add a new alias. Choose any name you like for your alias e.g. "add new enemy" and then define following pattern for the alias: [blue,#b0e0e6]+^add enemy (.*)+ Then add this little script in the script editor below: ------ listAdd( myEnemies, matches[2] ) echo( "Added a new enemy:" .. matches[2] .. "\n" ) ------ Save the alias and try. Alias are explained in detail below. Another way to declare a list is to define its values directly. ------ myEnemies = { "Peter", "Jim", "Carl", "John" } ------ To remove an item from the list you can use the function listRemove( listName, item ). === Saving Variable Values to Disc Having statistics scripts that last as long as the session lasts is a nice thing, but it makes more sense to write the variables to disc and reload them when you play the next time. To do this you have to save your variables. Mudlet has 2 ways to implement variable persistence. First, you can tell Mudlet to save all of your variables on exit automatically and ask Mudlet to automatically restore them when the session gets reloaded the next time you play on this profile. Second, you can take care of saving your variables yourself and reloading them yourself. This gives you more control and will be the preferred solution in bigger systems. To be continued ... [[alias]] == Input Triggers - Mudlets Alias Engine IMPORTANT: QUICKSTART: Here is a video tutorial on how to do basic aliases in Mudlet: http://blip.tv/file/2288749 Alias are triggers that operate on user input. Mudlet uses hierarchically ordered powerful Perl regex expression alias. We have explicitly chosen not to offer multi condition alias, alias chains or the same trigger types the trigger engine offers because this would be way over the top and is simply not needed for alias expansion - although it should be noted that the processes are closely related, except that aliases, i.e. input triggers, operate on a different data stream, namely the user input stream, whereas triggers operate on the MUD output data stream. The only real difference between output triggers and input triggers is that input triggers can change the input stream they work on, whereas output triggers cannot change the stream itself - output triggers can change what is printed on the screen as a result of the stream, but they cannot change the stream itself. This is a fundamental difference and a deeper understanding is key to getting to grips with Mudlets alias engine. When you enter a command on the keyboard and press enter or return, the text that you have typed in the command line will be forwarded to the alias unit, i. e. the input trigger unit, in form of the Lua variable [red]+command+. This variable will be matched against all active alias in the hierarchy unless access to an alias branch is locked by the user or by a script. *If an input trigger matches, it will intercept the user command and the original command will be ignored*. Upon a match the clear text command is being send as a command to the MUD in replacement of the original command, if a clear text command has been specified by the user _and_ the attached alias script is being executed. However, the initial command that the user has typed in the command line will *not* be sent unless you do this as part of your script. Consequently, if you want your input trigger to send a command to the MUD, you'll either have to specify a clear text command for simple cases or send commands via the attached alias script e.g. send("kill monster"). You may argue that you feel that it is unnecessary work to be forced to send a command replacement yourself, but this very fact makes our alias system way more powerful because it gives you complete control about what is happening. Why is this so? The initial user command is being held in the Lua variable [red]+command+. When this value changes within the alias unit processing chain, the initial user input that the input triggers work on can be rewritten and changed in the process. Consequently, you can substitute the user input step by step - or alias by alias - without that anything happens as far as sending commands is being concerned unless you explicitly decide to do so. [[aliasProcessing]] [icon="./images/icons/diagram_alias.png"] NOTE: . The example in the diagram above shows 2 matching aliases, but only one of them sends commands to the MUD - and only if the player is healthy enough to attack the opponent. The other alias that matched the user input (enemy) choses a fitting opponent and sets the variable enemy accordingly, otherwise it issues a warning that attacking one of the available enemies would be too dangerous. For an input trigger to match the command text the same rules as explained above in the trigger section apply. However, to simplify matters there is only one alias type. As alias are not performance critical we could reduce the amount of trigger types to just Perl regex as this type can do it all and performance is no issue with alias as the amount of data is much less. Even if you type like a madman you'll never get close to sending the same amount of text to the MUD than the amount of text the MUD sends back to you. What does it mean that a regex is true or "matched"? A trigger or an alias fires - or executes its commands/script - when the text matches the pattern of the trigger or alias. In most cases this means that the text contains the trigger/alias pattern. If the regex pattern is [blue,#b0e0e6]+reen+ then a text "The green house" will match because "reen" is contained in the text. More complex regex patterns can also hold information on where in the text a certain pattern must occur in order to match. [blue,#b0e0e6]+^tj+ only matches when the letters "tj" occur at the beginning of the text. Consequently, a text like "go tj" would not match. Regex patterns can also capture data like numbers, sequences of letters, words etc. at certain positions in the text. This is very useful for MUD related scripting and this is why it is explained below. Let's get back to alias. We start with a simple example. We want Mudlet to send "put weapon in bag" whenever we type "pwb". Consequently, the pattern is [,#b0e0e6]+pwb+ and as the task is so simple it's enough to enter "put weapon in bag" in the send field. Then we click on save to save the changes and activate the alias by clicking on the padlock icon. Then we leave the trigger editor and test our new alias. After typing "pwb" and pressing return Mudlet will send the command "put weapon in bag" to the MUD. Let's move on to a more complicated example that is needed very often. We want our script to automatically put the weapon in the correct bag as we have many bags and many weapons. The pattern stays the same. [,#b0e0e6]+\^pwb+ The \^ at the beginning of the line means that the command starts with pwd and no other letter in front of this. If we define our pattern more clearly, the pattern will match less often. Without the [,#b0e0e6]+^+ the alias will match and the alias script will always be run whenever there is the sequence of letters "pwd" in your commands. This may not always be what you want. This is why it's usually a good idea to make the pattern definition as exact as needed by being _less_ general. The more general the pattern, the more often it will match. Back to our task: The pattern is [,#b0e0e6]+\^pwb+. Let's assume that we have defined 2 variables in some other script. The variable "weapon" is the weapon we use and the variable "bag" is the name of the bag. NOTE: In Mudlet global variables can be accessed anywhere from within Mudlet scripts - no matter if they have been defined in a trigger script, in an alias script or in a key or button script. As soon as it's been defined it somewhere it is usable. To make sure that a variable is local only, i. e. cannot be referenced from other scripts, you have to use the keyword local in front of your variable definition. Back to our alias: Pattern is:[,#b0e0e6]+^pwb+ Script is: -------- send( "put " .. weapon .. " in " .. bag ) -------- Depending on the values of our variables Weapon and bag the command "^pwd" will be substituted with an appropriate command. To set your weapon and bag variables we use 2 more aliases: Alias to set the weapon: [,#b0e0e6]+^uw (\w+)+ Script: ------------- weapon = matches[2]; send( "wield " .. weapon ) ------------- To set our bag variable: Pattern:[,#b0e0e6]+^set bag (.*)+ ------------- bag = matches[2] ------------- Now let's go back to our initial problem. We want an alias to put our current weapon into our current bag. But what happens if we are in the middle of a fight and absolutely need to sip a healing potions because we are close to death and cannot take the risk that the bag may be too full to take the weapon? We want to upgrade out little alias to take into account that the bag may be full and chose an empty bag instead. To do this we set up a trigger that detects messages that indicate that the attempt to put the weapon in the bag failed. In this trigger we execute this little bag-is-full-detection-trigger Trigger Pattern: (type substring) "Your bag is full." script: ------------- bagIsFull = true; ------------- This detection trigger will set the variable bagIsFull to true as soon as it sees the message "Your bag is full.". Then you know that you have to use your spare bag to take the weapon. Now we have the tools to write an improved version of our little alias script: --------------- if bagIsFull then send( "put " .. weapon .. " in " .. spareBag ) else send( "put " .. weapon .. " in " .. bag ) end --------------- The next example is one of the most common aliases a tell alias: Pattern:[,#b0e0e6]+^tj (.*)+ Script: --------------- send( "tell Jane " .. matches[2] --------------- Sadly, Jane is your fiancée and the one thing she is a vegetarian and absolutely hates all words that relate to meat. Luckily, you know enough about aliases by now to make her believe that you'd never ever even think about meat. So you head to your global function script (any script item will do as long as you define your variables *outside of* your function definitions. See the scripts chapter below for more information. In your script "my global functions" you add a Lua table containing a list of all of all words that a vegetarian might hate. For example: ------------- happyJaneTable = { "meat", "burger", "steak", "hamburger", "chickenburger" } ------------------ Now you can upgrade your tell-jane script to automatically search our tell for all words that Jane might not like. In case such a word is found we substitute the entire tell with "How is the weather?". ----------------- for key, value in ipairs( happyJaneTable ) do -- looking at each element of the list badWord = happyJaneTable[key] -- check out the Lua table chapter below for more info begin, end = string.find( command, badWord ) -- begin holds the start position of the word, end* the end-position if begin ~= nil then -- we have found a bad word send( "tell Jane How is the weather?" ) return end end ----------------- [[triggers]] == Mudlets Trigger Engine Unlike alias that define patterns that match on user input, triggers define patterns that match on MUD output. In other words, triggers react to text that has been sent by the MUD, whereas alias react to user commands that have been typed into the command line. [[simpleTriggerMatching]] === Simple Trigger Matching [icon="./images/icons/scriptEditorScreen.png"] NOTE: .script editor screenshot IMPORTANT: QUICKSTART: Here is a simple *video tutorial* on how to make basic triggers in Mudlet: http://blip.tv/file/2288760 To begin with, click on the "Add" button to create a new trigger. Then put the text pattern that you'd like to trigger on into the trigger conditions table on the right side of the screen above the script editor. Afterwards, chose the correct pattern type of your trigger pattern in the drop down list on the right side of the trigger pattern i.e. in the second column of the trigger pattern table. If you define multiple patterns in the same trigger, your trigger will run whenever any one of these patterns matches unless you chose the AND-trigger option, in which case the trigger will only fire if all patterns match within a specified amount of lines from the MUD. For more advanced information on AND and OR trigger see the corresponding AND/OR trigger section below. The next step is to define what should happen when the trigger matches. Usually, this will be done by a Lua script in the Lua editor below the table with the pattern list. In the beginning, you can simply chose the "highlight trigger" option to make your trigger highlight the text that it has triggered on or send a clear text command to the MUD whenever the trigger fires until you have learned enough Lua to more meaningful scripts. Clear text command can be defined in the "send plain text" input box next to the trigger name above the pattern table. Finally, you need to save the new trigger and then activate it with the padlock icon button. By default, new triggers are deactivated and thus will do nothing unless you explicitly activate them. Activated triggers show a green tick in the little blue box on the left side of the trigger name in the trigger tree on the left side of the script editor dialog. There is three ways to save your changes. 1. click on the save icon 2. adding a new trigger 3. clicking on another trigger item. Triggers that have not been saved yet cannot be activated. If you see a bug icon instead of an activation box, there is some error that prevents to activate your trigger. Check the error message above the pattern table. **** Example: You want to trigger on the word "pond" in a line such as: "The frog swims in the pond. Plop." All you need to do is add "pond" as a pattern and chose "substring" as a pattern type. Then enter the command you like to send to the MUD if the trigger matches. For example enter "drink water" into the "send plain text" input box and activate your new trigger. Your new trigger will send the command "drink water" to the MUD any time it sees the word "pond" somewhere in the MUD output. **** [[highlighters]] === Simple Highlighter Triggers TIP: *Beginners should use Mudlets automated highlight triggers in the beginning to get the hang of the different trigger and pattern types quicker. Click on the "highlight trigger" option and pick a foreground and a background color. When the trigger matches it automatically highlights its pattern. This is the most used form of triggers in mudding as it is a quick way of highlighting words that are important to you at the moment. This helps you spot things at a single glance instead of reading the entire text. You don't have to know anything about scripting, regular expressions etc. to use highlight triggers. Just type in the word you like to be highlighted, select appropriate colors, save the new trigger and activate it.* More advanced users will often want to do custom highlighting from within scripts. This is how it works: If you want to highlight the word "pond" in the above example you have to add the following little Lua script to the script editor on the lower right side of the Script Editor window: ---- selectString( "pond", 1 ) fg( "red " ) bg( "blue" ) resetFormat() ---- [[andandorTriggers]] === "AND" and "OR" Condition Triggers AND -Triggers execute their respective command or script only if all conditions in their respective conditions expression list are fulfilled. OR-Triggers execute when *any* one of their conditions is true. To make OR-Triggers you simply have to add a few conditions to the conditions list e.g. in our example: "pond", "frog", "Plop". The trigger will now also execute on lines like this: "A frog is green" or "You hear a loud Plop!" However, it will not execute on "With a loud plop the frog dived into the water." because "plop" in the line is in lower case letters and your condition specified a "P" in upper case. The simplest form of AND-Triggers in Mudlet are Trigger Chains or Filter Chains, whatever you'd like to call it. [[triggerChains]] === Trigger Chains & Filter Chains "Chains" and "filters" are different trigger group entities in Mudlet and serve completely different ends. == Chains A chain is defined in Mudlet by making a trigger group and adding a trigger pattern to the group. A group without a pattern is a simple trigger group that serves no other purposes than adding structure to your trigger system in order to organize your triggers better. Such a normal trigger group will always grant access to its children unless it has been explicitly disabled (= all access to itself or any of its children is locked) either manually or by a script. A trigger group with a defined trigger pattern, however, will behave like a normal trigger and match if the pattern matches. Such a trigger group is called "chain head". A chain head will only grant access to its children if the trigger pattern has matched and the chain has been enabled. Thus, chains can be looked at as a mechanism to automatically enable and disable triggers or groups of triggers when a certain condition has been met i. e. the trigger pattern of the chain head has been matched. (However, technically this is not correct as disabled child triggers will not be invoked if the chain head matches. In other words, in chains you can still enabled/disabled elements. The idea of a chain can better be described by necessary and sufficient condition - both of which need to be met before a child trigger is being run.) Adding child triggers to this group will add elements to the trigger chain. These chain elements will only be activated if the chain head has matched before and thus opened the trigger chain. The chain stays open until the "keep chain open for x lines" value has been reached. The default is 0 which means that the chain only stays open for the current line. When access to the chain has been granted all child triggers will be tested against the content of the current line.. Consequently, trigger chains are a means to automatically enable/disable trigger groups without the hassle of enabling and disabling trigger groups manually. This has 2 important advantages: Chains are faster than conventional solutions and chains reduce the complexity of your scripts and greatly reduce the usual system bugs that inevitably go along with enable/disable trigger xy function calls as it's very difficult and error prone to enable and disable your triggers correctly in large complex trigger systems. This is one of the most powerful features in Mudlet and should be used whenever possible. == Filters You can turn a trigger chain head into a filter by checking the "filter" option. This changes the content of what is forwarded as trigger text to the children triggers in the chain. Chains forward the content of the current line as trigger text whereas filters forward the matched pattern instead of the current line. In other words, the text of the current line is filtered according to the pattern of the filter. For example: You want to know the exits in the current room. The simplest solution is a simple filter on "You see exits to: (.*)" Then you simply add triggers to the filter chain such as "north", "south", "west", "east" etc. The direction triggers will only be called if the filter head has matched. Imagine the following scenario: You want to collect some berries. You know that the room contains some berries if the room description contains the words "You are inside a forrest." You make a new substring trigger for this line, but instead of choosing a regular trigger, you chose to add a new trigger group. Now you add "You are inside a forest" to the expression list of the trigger group. *When adding conditions to a trigger group, the trigger group turns from an organizational unit into a filter unit.* From now on this folder is a filter and will only let data pass through that matches it's condition. In our case this is exactly what we want, because we don't want to collect all sorts of berries, but we only want 2 particular kinds, namely, strawberries and blackberries, and we know that these berries can only be trusted if they are picked inside a forest as other areas may contain contaminated berries. Now you add two regular triggers to our berry-in-the-forrest filter - one containing the condition: "strawberries" and the other one "blackberries". Then we add the commands to pick the particular kind of berry to both triggers (send field). Now what happens is that as soon as a room description reads "You are inside a forrest." the filter will let the line containing the room description pass through to our two berry triggers and they will issue commands to pick berries, if there are such berries. However, in any other situation the words "strawberries" and "blackberries" will *NOT* trigger a pick - only in the above scenario when the filter parent's condition is met. This is a very nice way to solve complicated problems with a few easy filter chains. This example is trivial, but using filter chains will rapidly show you how formerly complicated things that could only be solved with very complicated regular expressions can be solved easily now with a couple of filter chains. It should be noted that filter chains only work on single lines. This means that if the filter chain head "You are inside a forrest" is in a different line than the other child chain element triggers (stawberr- and black berry triggers) the triggers will not fire as the line that is being let through the filter does not contain the words strawberries or blackberries. Most MUDs, however, offer a feature that lets your client do the word wrapping. This is a very powerful tool for scripting and should be enabled by you in your MUD as then the entire room description or the entire tell will be sent out to Mudlet in one line and Mudlet will do the word wrapping for you. Now you can use filter chains much more effectively as the line content comprises many lines. Triggering will become much easier. Ask your MUD operators how to enable this feature. Most big MUDs can do this these days. Let's look at a practical example for a trigger chain: ************* .Practical example: Prompt Detection Trigger Chain that raises a prompt event and checks balance My newbie prompt on Achaea looks like this [blue]+500h, 500m ex-+ when I have balance and [blue]+500h, 500m ex-+ when I have lost balance. We are going to develop a prompt detection trigger that raises the event gotPrompt and sets the variables myBalance=true or myBalance=false; To begin with, we add a new trigger group and add the Perl regex pattern to detect the prompt: ----- ^(\d+)h, (\d+)m ----- The pattern reads in plain English: At the beginning of a prompt line there are is a number directly followed by the letter h, a comma, a space and another number followed by the letter h. Whenever this pattern matches the trigger will fire and we'll know that we have a prompt line. We use the 2 numbers that we captured in our pattern to update our health and mana stats. Detecting balance is more difficult as balance is indicated by the letters [blue]+ex-+ on the same line after the prompt and imbalance is indicated by the letters [blue]+e-+. As we have set a pattern in a trigger group (folder), the folder is turned into a filter or a trigger chain head. It will now only let data through to its children when its own pattern is matched. In other words, *the child triggers of the trigger chain will only receive data on prompt lines.* We are going to take advantage of this by adding two simple substring triggers to detect balance and imbalance. The balance trigger pattern is [,#b0e0e6]+ex-+ and the imbalance detector pattern is [,#b0e0e6]+e-+. On the screen this looks like this: [icon="./images/icons/prompt_detection6.png"] NOTE: . In the two balance detection triggers we now write myBalance=false and myBalance=true respectively plus a little echo on the screen that shows our current balance status. The outcome looks like this: [icon="./images/icons/prompt_detection1.png"] NOTE: . We could now add a call deleteLine() to the prompt detection trigger to erase the prompt from the screen if we don't want to see it as we have computed all relevant information. ************** [[multilineTriggers]] === Multi-Line Triggers and Multi-Condition Triggers Multi Condition Triggers are the most advanced feature of Mudlets trigger engine. Like trigger chains or filter chains they are a form of AND-Triggers. All conditions in the list must have matched within the specified margin of lines (delta), in order to trigger the script. Normal triggers fire and run the script as soon as one of the conditions in the regex list is met i.e. if one of the regex/string matches match - or the Lua function condition returns true, the trigger script is run. In multiline triggers, however, each single regex/string/Lua function condition in the list has to have matched within the specified margin of lines at least once to trigger the script. *The sequence of the conditions is binding.* This means that if the 10th regex on the regex list would be matched on the eleventh line after the match of the first line happened, the trigger will *NOT* run unless the margin of lines is set to 11. If condition #3 is true but currently #2 is waiting to be true, condition #3 is ignored and must be true again after condition #2 has been true. Conditions can also be Lua Functions or plain Lua code that returns a boolean truth value. You can mix all types of conditions to build complex multi-condition triggers that only fire if all conditions are met. This is a very powerful feature as it reduces the amount of scripting to a minimum or even takes away with the need to script formerly complex processes completely. Multicondition triggers are multi-line triggers, i. e. the conditions can all be met in a single line or many lines after the first condition has been fulfilled. This effectively reduces the amount of complexity as you have all the important conditions placed into a single trigger and all the tedious bookkeeping, variable and condition state accounting is being done by Mudlets trigger engine. The result of this is that the amount of manual condition checking via many different trigger scripts and legions of if condition1 == true then check condition2 can be forgotten about. All you have to do is to define the conditions and the final action that is taken if the trigger fires. [icon="./images/icons/trigger_problem.png"] NOTE: This diagram shows what steps are involved in the process of problem solving with Mudlets trigger engine. The main question is: How do we arrive at a solution to our problem, and how can we simplify the problem as much as possible? Example: Let's go back to our pond & frog example. We have explained the difference between AND-triggers and OR-triggers. If you have a room description consisting of 3 lines: ---- 1. You see a pond 2. You see a frog. 3. The frog sits on a stone. ---- Every single one of these 3 lines will be fed into the trigger engine one after another. If we define an OR-trigger with a condition list consisting of 3 condition patterns: condition #1 pattern = pond condition #2 pattern = frog condition #3 pattern = stone Whether or not a condition is found to be true *also* depends on another property, namely the *type* of the condition. The condition type can be among others: ==== 1. substring matching -> the condition is true if the condition pattern is a substring of the output line from the MUD. In other words: If the pattern "pond" is contained in any line of output, the condition is true. 2. begin of line matching -> the condition is only true if the condition pattern can be found at the beginning of a line from the MUD. 3. Perl regular expression -> the condition is true if the Perl regex pattern is matched. You'll find more information on Perl regex below. 4. Lua code that returns a truth value e.g. a call to a function check() that return either true or false depending on the condition ==== In our example we chose condition type "substring" for all three conditions. Consequently, the trigger will fire the command or script 3 times i. e. the trigger will do on each line it is matched against because in every line at least one condition evaluates to true because the pattern is a substring of the line. .... in line #1 we get: pond = true. in line #2 we get frog = true and in line #3 two conditions are true i.e. frog=true and stone = true .... Because an OR-trigger fires on the first condition that is true and ignores the rest the trigger will only execute 3 times on these 3 lines although 4 conditions are true. *CAUTION: The multi line condition switch must be turned off to get an OR-trigger! If the multi-line condition switch is turned on the trigger becomes and AND trigger which means that the trigger only fires if all conditions are true and fulfilled in the correct sequence. With OR-triggers the sequence is irrelevant.* To complicate matters, however, you don't want your trigger to fire 3 commands, because you want to use this room description as a whole to fire your trigger e. g. this pond is the only kind of ponds in the entire world that doesn't have poisoned water. So you want to make sure that you only drink water from a pond of this kind and from no other pond. Your solution is to use Multi Condition Triggers (MCT). If you check the MCT checkbox this trigger will fire only once from now on - and only if all conditions are met i e. when you can guarantee that you only drink water from a good pond because your drinking trigger is matching on the entire room description despite that this room description my be spread over a number of lines. (NOTE: If you have word wrap turned off in your MUD chances are that the entire room description will be contained in a single line, but we are trying to keep the examples as easy as possible.) Sadly, there are many unfriendly people in this world and somebody goes around and poisons your good ponds. Consequently, you would want to examine the frog and find out if it is poisoned before drinking water from the pond. This is difficult because the villain is a mean magician who used illusion spells to make everything look like the good pond. To solve the problem you can now resort to Lua function conditions in the trigger condition list that perform certain check ups to put the current room description into a wider context e. g. check if you have been here before etc. This adds yet another level of complexity to your problem but this is a very powerful means to use the full potential of Mudlets MCTs. You can combine all forms of conditions with trigger chains, filters and Lua functions. Mudlet gives you relatively easy to use tools that require no programming background. However, these tools can evolve into complex powerful problem solving mechanisms if they are combined with each other thus enabling non-programmer users to solve problems that would need a profound programming background in other MUD clients. However, unlocking the full potential of Mudlet requires you do learn some Lua basics. In this manual we'll try to be as easy on you as we can in this respect, but it's highly recommended that you dig deeper into Lua after a while. It's one of the easiest fully fledged scripting languages available, easy to learn and the fastest of them all, and this is why it has been chosen by us. You don't need to become a programmer to be able to use Mudlet effectively. All you have to know is how to work with variables and how to do if conditions and maybe a few loops. But knowing more won't harm you and it will make your systems more effective. === Lua Code Conditions & Variable Triggers - Expression Triggers In a Lua Code/Function Condition (LFC) you can run Lua code inside the trigger engine directly. The easiest example would be a simple variable trigger: Add a new trigger and chose pattern type Lua Function Condition. Then define this pattern: [blue,#b0e0e6]+if health <= 100 then escape() end+ Another formulation of the same would be: [blue,#b0e0e6]+checkHealth()+ For the last formulation to work you have defined a Lua function checkHealth(). Open the script editor, add a new script "health care" and add this code to the new script-script. ------ function checkHealth() if health <= 100 then echo( "WARNING: Low health! I have to run away!\n" ) startEscape() return true else return false end end -------- ************* .Lua Syntax Primer: Expressions ------------------ if A == B then (...) ----> if A equals B if A ~= B then (...) ----> if A *NOT* equals B if A <= B then (...) ----> if A is smaller or equal to B if A >= B then (...) ----> if A is greater or equal to B if A < B then (...) ----> if A is smaller than B if A > B then (...) ----> if A is greater than B ------------------- The operators 'and' and 'or' behave differently in Lua than in most other programming languages as they are not guaranteed to return a boolean value. For more information look here: *************** Lua function conditions effectively means that you run the Lua code they represent on every single line that is received from the MUD, unless the LFCs are part of a multi-condition trigger, in which case the LFCs would only be run when they would be the current test-condition of their respective trigger state. LFCs are implemented in such a way that the trigger engine only calls the compiled byte code, but running as few scripts as possible is always the best idea. LFCs are nice and handy, and for most people the performance aspect will not be relevant at all. [[generatingTriggers]] === Scripting: Generating Triggers - Special Trigger Types for Scripting Needs [[tempTriggers]] === Temporary Triggers (scripting only) Temporary triggers are lightweight triggers that are tailored for typical scripting needs. These are only available via Lua scripting. They are not stored in profiles, but stay in memory as long as the program runs or until they are deleted (killTimer()). There are several forms of temp-triggers that address different scripting needs. Check the Lua API table for reference. [[lineTriggers]] === Line Triggers (scripting only) Line triggers trigger on a specified line in the future - or a sequence of lines - irrespective of the content of the line. This type of trigger can be very handy in scripting if you know what is coming e.g. you want to parse a table from the MUD, maps etc. [[enablingTriggers]] === Enabling and Disabling Triggers in Scripts enableTrigger() disableTrigger() [[testingTriggers]] === Testing your triggers ==== Externally http://regexpal.com/[RegexPal] - a good website for testing your triggers against a set of text. http://code.google.com/p/kiki-re/[[kiki-re] - stand-alone program which will also tell you which matches are translated to what wildcard number. [[timers]] == The Timer Engine Mudlet supports 4 different sort of timers: ======= . *Regular GUI Timers* that fire repeatedly in a certain interval specified by the user. . *Offset Timers* are child timers of a parent timer and fire a single shot after a specified timeout after their parent fired its respective timeout. This interval is an offset to the interval of its parent timer. Example: parent timer fires every 30 seconds and by doing so kicks off 3 offset timers with an offset of 5 seconds each. Consequently, the 3 children fire 5 seconds after each time the parent timer fired. Offset timers differ visually from regular timers and are represented with a + icon for offset. Offset timers can be turned on and off by the user just like any other timer. . *Temporary Timers* are very useful, and are the most common type of timer used for scripting purposes. They behave like regular timers, but they are one shot only timers. . *Batch Job Timers* are a form of timer that issue a sequence of commands/scripts according to a certain timeout instead of a single command/script. This is a very important tool if the sequence of commands is important. Timers depend largely on the operating system you are using and it cannot be guaranteed under certain conditions that if you have set up 5 timers to fire after 1.3 seconds that the sequence in which they fire is the same sequence in which they were created. If the sequence of commands is important, you should always use batch job timers as this form of timers guarantees that the sequence of commands is observed. For example: If you want to make an auto-miner bot that digs its way into a gold mine digging left, down, down, right, left, down until a trigger catches a message that indicates that the mine is going to collapse and bury your poor soul unless you run for your life and head out of the mine. In this scenario the sequence of commands is vital as you'd lose your way and die. This is a classical case for a batch job timer. ======== The most common usage of temporary timers is the function tempTimer(). It lets you specify a timeout after which a script is being run e.g. ------ tempTimer( 0.3, [[send("kill rat")]] ) ------ This will issue the command "kill rat" after 0.3 seconds. Other clients call this kind of function wait() or doAfter() etc. It is one of the most used functions in MUD scripting. tempTimer() is a single shot timer. It will only fire once and is then marked for deletion. TempTriggers(), by contrast, live through the entire session and are never deleted unless you explicitly delete them or disable them. Another often used function in the context of timers is enableTimer( timerName ), or disableTimer( timerName ). Those are the counterparts of enableTrigger( triggerName ) and disableTrigger( triggerName ), enableKey( keyName ) etc.. *NOTE: Temporary timers cannot be accessed from the GUI and are not saved in profiles.* To be continued .... [[buttons]] == Buttons and Custom User Toolbars [[diag_buttons]] [icon="./images/icons/cssButtons.png"] NOTE: . [[scripting]] == Scripting with Mudlet [[luaSyntax]] Lua tables can basically be considered multidimensional arrays and dictionaries at the same time. If we have the table matches, matches[1] is the first element, matches[n] the n-th element. ----- a = "Tom" matches[1] = "Betty" b = matches[1] c = a .. b and e will equal "TomBetty" ----- To output a table you can use a convenience function printTable( name ). This function is defined in LuaGlobal.lua and can be found in your home directory under ./mudlet (note the leading dot ) Profiles and mudlet_documentation.html are stored in this directory as well. == Lua interface functions to Mudlet - or how do I access triggers, timers etc. from Lua scripts How to get data from regex capture groups? Regular expression capture groups (e.g. "(\d+)" ) are passed on to Lua scripts as a Lua table matches. To make use of this information inside Lua scripts, you need to specify the number of the capture group within the regex. Example: You have (\d+) weapons and they are (?:(\b\w+\W+)+) This regex contains 3 capture groups, but only the 2 green colored ones contain data as the red capture group is a non-capturing group. Consequently, your Lua script gets passed only 2 instead of 3 capture groups and matches[3] is undefined. In your Lua script you may write following program in order to print the number and status of your weapons on the screen: **** You have (\d+) weapons and they are (?:(\b\w+\W+)+) **** ---- number_of_weapons = matches[1] status_of_weapons = matches[2] notice = number_of_weapons .. status_of_weapons echo( notice ) send( "put weapons in backpack" ) -- the following 2 lines color the first capture -- group red and the second group blue -- see below for details selectCaptureGroup( 1 ) setFgColor( 255,0,0 ) selectCaptureGroup( 2 ) setFgColor( 0,0,255 ) ---- The best way is to use selectCaptureGroup( number ) to select the proper capture group and then perform your actions on it e.g. replace(), highlight etc. Note: Both selectCaptureGroup() and matches[n] start with group 1. How to select all occurrences of "Tom" and highlight them? You add a function like this to a script containing you main function definitions. Note that script items differ from all other "scripts" in triggers, timers, actions etc. because they require you to put your code in proper functions that can be called by your other trigger-scripts, timer-scripts etc. via normal function calls. Trigger-scripts, timer-scripts etc. cannot contain any function definitions because they are automatically generated functions themselves because this makes usage a lot easier. To come back to our question how to select all occurrences of "Tom" and highlight them: ---- function setBgColorAll( word, r, g, b ) i = 0 word_count = 1 while i > -1 do i = selectString(word, word_count) if i == -1 then return end word_count = word_count +1 setBgColor( r, g, b ) end end ----- Then you simply define a substring matching trigger on the word "Tom" and in the trigger script you call above function: ---- setBgColorAll("Tom", 255,50,50) ----- === Sending commands to the MUD or printing information messages on the screen To print information messages on the session screen you can use the echo( message ) function, or insertText( text). Currently, it only takes one string as argument. To send a command to the MUD, you can use the send( command ) function. Note: everything you send via send() will be processed by the alias processing unit. In Alias scripts the command that is being sent to the MUD is contained in the variable command that you can change in the context of Alias scripts. Alias take regular expressions, as well. As a result, you can use following regex and script to talk like Yoda: Perl regex: ---- say (\w+).*(\w*).*(.*) ---- script: ---- send( "say " .. matches[3] .." " .. matches[1] .." ".. matches[2] ) ----- Note: The variable "command" contains what was entered in the command line or issued via the expandAlias( ) function. If you use expandAlias( command ) inside an alias script the command would be doubled. You have to use send( ) inside an alias script to prevent recursion. This will send the data directly and bypass the alias expansion. ==== Changing text from the MUD or reformatting text (highlight, make bold etc.) When sending commands to the MUD - from now on referred to as output stream - alias scripts find the command that was issued by the user stored in the variable "command". By manipulating the value, the command can easily be changed before it is being sent to the MUD. However, things get much more complicated with the data received from the MUD – from now on referred to as input stream. Before triggers can be run on the MUD data, Mudlet has to strip all format codes from the text and store it in data structures associated with the text. Consequently, the text that is being passed on to the trigger processing unit is a small subset of the data received from the MUD. If you want to edit, replace, delete or reformat text from within your trigger scripts you have to keep this in mind if you don't want to lose all text format information such as colors etc. As the text is linked with data structures containing the format of the text, the cursor position inside the line is important if data is being changed. You select a word or a sequence of characters from the line and then issue commands to do actions on the selected data. Replacing the word "Tom" with "Betty" in the line: Jim, Tom and Lucy are learning a new spell. This could be done with following script: ---- selectString("Tom",1) replace("Betty") ----- Things get more complicated if there are two or more occurrences of "Tom" in the line e.g. Jim and Tom like magic. Jim, Tom and Lucy are learning a new spell. The above example code would select the first occurrence of "Tom" in this line and ignore the second. If you want to work on the the second occurrence of "Tom" you have to specify the occurrence number in the call to select(). ----- selectString( "Tom", 2 ) replace( "Betty" ) ---- This code would change the second "Tom" and leave the first "Tom" alone. The function call ---- replaceAll( "Betty" ) ----- will replace all occurrences of "Tom" with "Betty" in the line if "Tom" has been selected before. replaceAll() is a convenience function defined in LuaGlobal.lua. Colorization example: You want to change to color of the words "ugly monster" to red on a white background. You add a new trigger and define the regex: ugly monster In the script you write: ----- selectString("ugly monster", 1 ) setFgColor(255,0,0) setBgColor(255,255,255) resetFormat() ----- Another means to select text is to select a range of characters by specifying cursor positions. If we have following line: Jim and Tom like magic. Jim, Tom and Lucy are learning a new spell. ---- selectSection( 28, 3 ) ---- This example would select the second Tom. The first argument to selectSection is the cursor position within the line and the second argument is the length of the selection. ---- selectCaptureGroup( number ) ---- === Deleting Text - Gagging This function selects the captureGroup number if you use Perl regular expressions containing capture groups. The first capture group starts with index 1. ---- deleteLine() ----- This function deletes the current line - or any line where the cursor is currently placed. You can use repeated calls to this function to effectively erase the entire text buffer. If you want to delete or gag certain words only, you can select the text that you want to delete and then replace it with an empty string e.g: If you get this line form the MUD: "Mary and Tom walk to the diner." ----- selectString( "Tom", 1 ) replace( "" ) ----- Then the output will be changed to: "Mary and walk to the diner." === Cursor Movement and Cursor Placement moveCursor( windowName, x, y ) This will move the user cursor of window windowName to the absolute (x/y) coordinates in the text. moveCursor( "main", 20, 3950 ) will move the cursor on the 20th character from the left on line number 3950. To determine the current cursor position you can use getLineNumber() and getColumnNumber() as well as getLastLineNumber() to get the number of the last line in the text buffer. moveCursorEnd("main") will move the cursor of the main display to end of the buffer. This is always a new line of size 1 containing the character '\n'. number_of_last_line_in_text = getLineCount() returns the number of the last line of the text in the console buffer. This number will change as soon as a new '\n' is printed either by the user or when a new line arrives from the MUD. All lines from the MUD are terminated with '\n' which is called line feed or the new line character. This control character ends the current line and move the cursor to the beginning of the next line, thus creating a new, empty line below the line that contains the '\n'. line_number_of_the_current_cursor_position = getLineNumber() column_number_of_the_current_cursor_position = getColumnNumber() luaTable_containing_textlines = getLines( absolute_line_number_from, absolute_line_number_to ) this will return a Lua table containing all lines between the absolute positions from and to. NOTE: This function uses absolute line numbers, not relative ones like in moveCursor(). This little demo script shows you how to use cursor functions: moveCursor() return true or false depending on whether the move was possible. User defined dockable windows You may want to use dock windows to display information you gathered in your scripts, or you may want to use them as chat windows etc. Adding a user defined window: openUserWindow( string window_name ) echoUserWindow( string window_name, string text ) setWindowSize( int x, int y ) clearWindow( string window_name ) Dynamic Timers tempTimer( double timeout, string lua code_to_execute, string/float/int timer_name ) disableTimer( name ) enableTimer( name ) == Dynamic Triggers triggerID = tempTrigger( regex, code ) creates a fast substring matching trigger triggerID = tempRegexTrigger( regex, code ) creates a regular expression matching trigger [[events]] == Registering Event Handlers and Raising Events raiseEvent( string name, args ) As an example, your prompt trigger could raise an onPrompt event if you want to attach 2 functions to it. In your prompt trigger, all you'd need to do is raiseEvent("onPrompt") Now we go about creating functions that attach to the event. Lets say the first one is check_health_stuff() and the other is check_salve_stuff(). We would like these to be executed when the event is raised. So create a script and give it a name of check_health_stuff. In the Add user defined event handler, type onPrompt, and press enter to add it to the list. In the script box, create: function check_health_stuff()blah blah end. When the onPrompt event comes along, that script catches it, and does check_health_stuff() for you. === Default events raised by Mudlet Mudlet itself also creates events for your scripts to hook on. The following events are generated currently: [[sysWindowResizeEvent]] ==== sysWindowResizeEvent Raised when the main window is resized, with the new height and width coordinates passed to the event. A common usecase for this event is to move/resize your UI elements according to the new dimensions. ===== Example This sample code will echo whenever a resize happened with the new dimensions: -------- function resizeEvent( event, x, y ) echo("RESIZE EVENT: event="..event.." x="..x.." y="..y.."\n") end -------- [[sysWindowMousePressEvent]] ==== sysWindowMousePressEvent Raised when a mouse button is _pressed down_ anywhere on the main window (note that a click is composed of a mouse press and mouse release). The button number and the x,y coordinates of the click are reported. ===== Example -------- function onClickHandler( event, button, x, y ) echo("CLICK event:"..event.." button="..button.." x="..x.." y="..y.."\n") end -------- [[sysWindowMouseReleaseEvent]] ==== sysWindowMouseReleaseEvent Raised when a mouse button is _released_ after being pressed down anywhere on the main window (note that a click is composed of a mouse press and mouse release). See <> for example use. [[atcp_events]] ==== ATCP events Mudlets ATCP implementation generates events for each message that comes, allowing you to trigger on them easily. Since ATCP messages vary in name, event names will vary as well. See the <> section on how to use them. == Handling Tables in Lua Nick Gammon has written a very nice overview on how to deal with Lua tables. You can find it here: http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=6036. [[example1]] .How to use multilinematches[n][m] (The following example can be tested on the MUD batmud.bat.org) In the case of a multiline trigger with these 2 Perl regex as conditions: ---- ^You have (\w+) (\w+) (\w+) (\w+) ^You are (\w+).*(\w+).* ---- The command "score" generates the following output on batMUD: ----- You have an almost non-existent ability for avoiding hits. You are irreproachably kind. You have not completed any quests. You are refreshed, hungry, very young and brave. Conquer leads the human race. Hp:295/295 Sp:132/132 Ep:182/181 Exp:269 > ---- If you add this script to the trigger: ---- showMultimatches() ---- The script, i.e. the call to the function showMultimatches() generates this output: ---- ------------------------------------------------------- The table multimatches[n][m] contains: ------------------------------------------------------- regex 1 captured: (multimatches[1][1-n]) key=1 value=You have not completed any quests key=2 value=not key=3 value=completed key=4 value=any key=5 value=quests regex 2 captured: (multimatches[2][1-n]) key=1 value=You are refreshed, hungry, very young and brave key=2 value=refreshed key=3 value=young key=4 value=and key=5 value=brave ------------------------------------------------------- ---- The function showMultimatches() prints out the content of the table multimatches[n][m]. You can now see what the table multimatches[][] contains in this case. The first trigger condition (=regex 1) got as the first full match "You have not completed any quests". This is stored in multimatches[1][1] as the value of key=1 in the sub-table matches[1] which, in turn, is the value of key=1 of the table multimatches[n][m]. The structure of the table multimatches: ---- multimatches { 1 = { matches[1] of regex 1 matches[2] of regex 1 matches[3] of regex 1 ... matches[n] of regex 1 }, 2 = { matches[1] of regex 2 matches[2] of regex 2 ... matches[n] of regex 2 }, ... ... n = { matches[1] of regex n matches[2] of regex n ... matches[n] of regex n } } ----- The sub-table matches[n] is the same table matches[n] you get when you have a standard non-multiline trigger. The value of the first key, i. e. matches[1], holds the first complete match of the regex. Subsequent keys hold the respective capture groups. For example: Let regex = "You have (\d+) gold and (\d+) silver" and the text from the MUD = "You have 5 gold and 7 silver coins in your bag." Then matches[1] contains "You have 5 gold and 7 silver", matches[2] = "5" and matches[3] = "7". In your script you could do: ---- myGold = myGold + tonumber( matches[2] ) mySilver = mySilver + tonumber( matches[3] ) ---- However, if you'd like to use this script in the context of a multiline trigger, matches[] would not be defined as there are more than one regex. You need to use multimatches[n][m] in multiline triggers. Above script would look like this if above regex would be the first regex in the multiline trigger: ---- myGold = myGold + tonumber( multimatches[1][2] ) mySilver = mySilver + tonumber( multimatches[1][3] ) ---- What makes multiline triggers really shine is the ability to react to MUD output that is spread over multiple lines and only fire the action (=run the script) if all conditions have been fulfilled in the specified amount of lines. [[scripting-howtos]] == Scripting howtos === How to highlight my current target? You can put the following script into your targetting alias: ---- if id then killTrigger(id) end id = tempTrigger(target, [[selectString("]] .. target .. [[", 1) fg("gold") resetFormat()]]) ---- Where `target` is your target variable. Note that you have to use the full name, capitalized. If you'd like the script to auto-capitalize for you, you can use this version*: ---- target = target:title() if id then killTrigger(id) end id = tempTrigger(target, [[selectString("]] .. target .. [[", 1) fg("gold") resetFormat()]]) ---- ^*requires Mudlet 1.1.0 [[atcp]] == ATCP Since version 1.0.6, Mudlet includes support for ATCP. This is primarily available on IRE-based MUDs, but Mudlets impelementation is generic enough such that any it should work on others. The latest ATCP data is stored in the `atcp` table. Whenever new data arrives, the previous is overwritten. An event is also raised for each ATCP message that arrives. To find out the available messages available in the `atcp` table and the event names, you can use `display(atcp)`. Note that while the typical message comes in the format of Module.Submodule, ie Char.Vitals or Room.Exits, in Mudlet the dot is removed - so it becomes CharVitals and RoomExits. Here's an example: --------- room_number = tonumber(atcp.RoomNum) echo(room_number) --------- === Triggering on ATCP events If you'd like to trigger on ATCP messages, then you need to create scripts to attach handlers to the ATCP messages. The ATCP handler names follow the same format as the `atcp` table - RoomNum, RoomExits, CharVitals and so on. While the concept of handlers for events is to be explained elsewhere in the manual, the quick rundown is this - place the event name you'd like your script to listen to into the `Add User Defined Event Handler:` field and press the + button to register it. Next, because scripts in Mudlet can have multiple functions, you need to tell Mudlet which function should it call for you when your handler receives a message. You do that by setting the `Script name:` to the function name in the script you'd like to be called. For example, if you'd like to listen to the RoomExits event and have it call the `process_exits()` function - register RoomExits as the event handler, make the script name be `process_exits`, and use this in the script: ---------- function process_exits(event, args) echo("Called event: " .. event .. "\nWith args: " .. args) end ---------- Feel free to experiment with this to achieve the desired results. A http://forums.mudlet.org/viewtopic.php?f=6&t=1243[ATCP demo package] is also available on the forums for using event handlers and parsing its messages into Lua datastructures. [[aardwolf102]] == Aardwolf's 102 subchannel Similar to ATCP, Aardwolf includes a hidden channel of information that you can access in Mudlet since 1.1.1. Mudlet deals with it in the same way as with ATCP, so for full usage instructions see the <> section. All data is stored in the `channel102` table, such you can do ----- display(channel102) ----- To see all the latest information that has been received. The event to create handlers on is titled `channel102Message`, and you can use the <> function to send text via the 102 channel back to Aardwolf. [[db]] == db: Mudlet DB Frontend The DB package is meant to provide easier access to a database, so you don't have to know SQL or use the luasql module to set and get at your data. However, it does require that the luasql module be compiled and included in Mudlet to function - and this all is available since Mudlet 1.0.6. === Creating a Database Before you can store anything in a database, you need to create one. You may have as many independent databases as you wish, with each having as many unique tables-- what we will call sheets in this package, so as to avoid confusion with Lua tables - think spreadsheets. To create a database, you use the db:create() function, passing it the name of your database and a Lua table containing its schema configuration. A schema is a mold for your database - it defines what goes where. Using the spreadsheet example, ths would mean that you'd define what goes into each column. A simple example: ----- db:create("people", {friends={"name", "city", "notes"}, enemies={"name", "city", "notes"}}) ----- This will create a database which contains two sheets: one named friends, the other named enemies. Each has three columns, name, city and notes-- and the datatype of each are strings, though the types are very flexible and can be changed basically whenever you would like. It'll be stored in a file named Database_people.db in your Mudlet config directory on the hard drive should you want to share it. It's okay to run this function repeatedly, or to place it at the top-level of a script so that it gets run each time the script is saved: the DB package will not wipe out or clear the existing data in this case. More importantly, this allows you to add columns to an existing sheet. If you change that line to: ----- db:create("people", {friends={"name", "city", "notes"}, enemies={"name", "city", "notes", "enemied"}}) ----- It will notice that there is a new column on enemies, and add it to the existing sheet-- though the value will end up as nil for any rows which are already present. Similarly, you can add whole new sheets this way. It is not presently possible to -remove- columns or sheets without deleting the database and starting over. A note on column or field names: you may not create a field which begins with an underscore. This is strictly reserved to the db package for special use. === Adding Data To add data to your database, you must first obtain a reference (variable) for it. You do that with the db:get_database function, such as: ----- local mydb = db:get_database("people") ----- The database object contains certain convenience functions (discussed later, but all are preceded with an underscore), but also a reference to every sheet that currently exists within the database. You then use the db:add() function to add data to the specified sheet. ----- db:add(mydb.friends, {name="Ixokai", city="Magnagora"}) ----- If you would like to add multiple rows at once to the same table, you can do that by just passing in multiple tables: ----- db:add(mydb.friends, {name="Ixokai", city="Magnagora"}, {name="Vadi", city="New Celest"}, {name="Heiko", city="Hallifax", notes="The Boss"} ) ----- Notice that by default, all columns of every table are considered optional-- if you don't include it in the add, then it will be set to its default value (which is nil by default) For those familiar with databases: with the DB package, you don't have to worry about 'committing' or 'rolling back' any changes, it will commit after each action automatically. If you would like more control then this, see Transactions below. You also cannot control what is the primary key of any sheets managed with DB, nor do you have to create one. Each row will get a unique integer ID that automatically increments, and this field can be accessed as "_row_id". === Querying Putting data in isn't any fun if you can't get it out. If you want every row from the sheet, you can do: ----- db:fetch(mydb.friends) ----- But rarely is that actually useful; usually you want to get only select data. For example, you only want to get people from the city of Magnagora. To do that you need to specify what criteria the system should use to determine what to return to you. It looks like this: ----- db:fetch(mydb.friends, db:eq(mydb.friends.city, "Magnagora")) ----- So the basic command is - `db:fetch(_sheet_, _what to filter by_)` The following filter operations are defined: ----- db:eq(field, value[, case_insensitive]) -- Defaults to case insensitive, pass true as the last arg to reverse this behavior. db:not_eq(field, value[, case_insensitive) -- Not Equal To db:lt(field, value) -- Less Than db:lte(field, value) -- Less Than or Equal to. db:gt(field, value) -- Greater Than db:gte(field, value) -- Greater Than or Equal To db:is_nil(field) -- If the column is nil db:is_not_nil(field) -- If the column is not nil db:like(field, pattern) -- A simple matching pattern. An underscore matches any single character, and a percent(%) matches zero or more characters. Case insensitive. db:not_like(field, pattern) -- As above, except it'll give you everything but what you ask for. db:between(field, lower_bound, upper_bound) -- Tests if the field is between the given bounds (numbers only). db:not_between(field, lower_bound, upper_bound) -- As above, only... not. db:in_(field, table) -- Tests if the field is in the values of the table. NOTE the trailing underscore! db:not_in(field, table) -- Tests if the field is NOT in the values of the table * ----- The db:in_ operator takes a little more explanation. Given a table, it tests if any of the values in the table are in the sheet. For example: ----- db:in_(mydb.friends.city, {"Magnagora", "New Celest"}) ----- It tests if `city == "Magnagora" OR city == "New Celest"`, but with a more concise syntax for longer lists of items. There are also two logical operators: ----- db:AND(operation1, ..., operationN) db:OR(operation1, operation2) ----- You may pass multiple operations to db:fetch in a table array, and they will be joined together with an AND by default. For example: ----- db:fetch(mydb.friends, {db:eq(mydb.friends.city, "Magnagora"), db:like(mydb.friends.name, "X%")} ) ----- This will return every record in the sheet which is in the city of Magnagora, and has a name that starts with an X. Again note that in LIKE patterns, a percent is 'zero or more characters' -- this is the same effect as "X.*" in pcre patterns. Similarly, an underscore matches any single characters and so is the same as a dot in pcre. Passing multiple expressions in an array to db:fetch is just a convenience, as its exactly the same as: ----- db:fetch(mydb.friends, db:AND(db:eq(mydb.friends.city, "Magnagora"), db:like(mydb.friends.name, "I%"))) ----- The db:OR operation only takes two arguments, and will check to see if either of the two is true. You can nest these logical operators as deeply as you need to. You can also just pass in a string directly to db:fetch, but you have to be very careful as this will be passed straight to the SQL layer. If you don't know any SQL then you want to avoid this... for example, in SQL there's a very big difference between double and single quotes. If you don't know that, then stick to the db functions. But an example is: ----- db:fetch(mydb.friends, "city == 'Magnagora'") ----- Now, the return value of db:fetch() is always a table array that contains a table dictionary representing the full contents of all matching rows in the sheet. These are standard Lua tables, and you can perform all normal Lua operations on them. For example, to find out how many total items are contained in your results, you can simply do #results. If a request from the friends sheet were to return one row that you stored in the results variable, it would look like this if passed into the display() function: ----- table { 1: table { 'name': 'Bob', 'city': 'Magnagora', 'notes': 'Trademaster of Tailoring' } } ----- And if you were to echo(#results), it would show 1. The order of the returned rows from db:fetch is generally the same as the order in which you entered them into the database, but no actual guarantees are made to this. If you care about the order then you can pass one or two optional parameters after the query to db:fetch() to control this. The first table array of fields that indicate the column names to sort by; the second is a flag to switch from the default ascending(smallest to largest) sort, to a descending(largest to smallest) sort. For example: ----- db:fetch(mydb.friends, db:eq(mydb.friends.city, "Magnagora"), {mydb.friends.city}) ----- This will return all your friends in Magnagora, sorted by their name, from smallest to largest. To reverse this, you would simply do: ----- db:fetch(mydb.friends, db:eq(mydb.friends.city, "Magnagora"), {mydb.friends.city}, true) ----- Including more then one field in the array will indicate that in the case that two rows have the same value, the second field should be used to sort them. If you would like to return ALL rows from a sheet, but still sort them, you can do that by passing nil into the query portion. For example: ----- db:fetch(mydb.friends, nil, {mydb.friends.city, mydb.friends.name}) ----- This will return every friend you have, sorted first by city and then their name. === Indexes and Types The sheets we've defined thus far are very simple, but you can take more control over the process if you need to. For example, you may assign default values and types to columns, and the DB package will attempt to coerce them as appropriate. To do that, you change your db:create() call as: ----- db:create("people", { friends={"name", "city", "notes"}, enemies={ name="", city="", notes="", enemied="", kills=0 } }) ----- This is almost the same as the original definition, but we've defined that our first four fields are strings with a default value of blank, and the new kills field which is an integer that starts off at 0. The only way to set a datatype is to set a default value at this time. Please note, beneath the DB package is http://www.sqlite.org/[SQLite], and SQLite is very data-type neutral. It doesn't really care very much if you break those rules and put an integer in a string field or vice-versa, but the DB package will -- to a limited degree -- attempt to convert as appropriate, especially for the operations that work on numbers. You may also create both standard and unique indexes. A unique index enforces that a certain criteria can only happen once in the sheet. Now, before you go and make indexes, pause and consider. There is no right or wrong answer when it comes to what to index: it depends on what kind of queries you do regularly. If in doubt, don't make an index. Indexes will speed up reading data from the sheet, but they will slow down writing data. To add an index, pass either the _index or _unique keys in the table definition. An example: ----- db:create("people", { friends={"name", "city", "notes"}, enemies={ name="", city="", notes="", enemied="", kills=0, _index = { "city" }, _unique = { "name" } } }) ----- You can also create compound indexes, which is a very advanced thing to do. One could be: `_unique = { {"name", "city"} }` This would produce an effect that there could be only one "Bob" in Magnagora, but he and "Bob" in Celest could coexist happily. Now, bear in mind: `_index = { "name", "city"}` creates two indexes in this sheet. One on the city field, one on the name field. But, `_index = { {"name", "city"} }` creates one index: on the combination of the two. Compound indexes help speed up queries which frequently scan two fields together, but don't help if you scan one or the other. The admonition against making indexes willy-nilly holds double for compound indexes: do it only if you really need to! ==== Uniqueness As was specified, the _unique key can be used to create a unique index. This will make it so a table can only have one record which fulfills that index. If you use an index such as _unique = { "name" } then names must be unique in the sheet. However, if you use an index such as _unique = { {"name", "city"} } then you will allow more then one person to have the same name -- but only one per city. Now, if you use db:add() to insert a record which would violate the unique constraint, a hard error will be thrown which will stop your script. Sometimes that level of protection is too much, and in that case you can specify how the db layer handles violations. There are three possible ways in which the layer can handle such violations; the default is to FAIL and error out. You can also specify that the db layer should IGNORE any commands that would cause the unique constraint to be violated, or the new data should REPLACE the existing row. For example: ----- db:add(mydb.enemies, {name="Bob", city="Sacramento"}) db:add(mydb.enemies, {name="Bob", city="San Francisco"}) ----- With the name field being declared to be unique, these two commands can't succeed normally. The first db:add() will create a record with the name of Bob, and the second would cause the uniqueness of the name field to be violated. With the default behavior (FAIL), the second db:add() call will raise an error and halt the script. If you want the IGNORE behavior, the second command will not cause any errors and it will simply fail silently. Bob's city will still be Sacramento. With the REPLACE behavior, the second command will cause its data to completely overwrite and replace the first record. Bob's city will now be San Francisco. A word of caution with REPLACE, given: ----- db:add(mydb.enemies, {name="Bob", city="Sacramento", notes="This is something."}) db:add(mydb.enemies, {name="Bob", city="San Francisco"}) ----- With the REPLACE behavior, the second record will overwrite the first-- but the second record does not have the notes field set. So Bob will now not have any notes. It doesn't -just- replace existing fields with new ones, it replaces the entire record. To specify which behavior the db layer should use, add a _violations key to the table definition: ----- db:create("people", { friends={"name", "city", "notes"}, enemies={ name="", city="", notes="", enemied="", kills=0, _index = { "city" }, _unique = { "name" }, _violations = "IGNORE" } }) ----- Note that the _violations behavior is sheet-specific. ==== Timestamps In addition to strings and floats, the db module also has basic support for timestamps. In the database itself this is recorded as an integer (seconds since 1970) called an epoch, but you can easily convert them to strings for display, or even time tables to use with Lua's built-in time support. The most common use for the Timestamp type is where you want the database to automatically record the current time whenever you insert a new row into a sheet. The following example illustrates that: ----- local mydb = db:create("combat_log", { kills = { name = "", area = "", killed = db:Timestamp("CURRENT_TIMESTAMP"), _index = { {"name", "killed"} } } } ) db:add(mydb.kills, {name="Drow", area="Undervault"}) results = db:fetch(mydb.kills) display(results) ----- The result of that final display would show you this on a newly created sheet: ----- table { 1: table { '_row_id': 1 'area': 'Undervault' 'name': 'Drow' 'killed': table { '_timestamp': 1264317670 } } ----- As you can see from this output, the killed fields contains a timestamp-- and that timestamp is stored as an epoch value. For your convienance, the db.Timestamp type offers three functions to get the value of the timestamp in easy formats. They are as_string, as_number and as_table, and are called on the timestamp value itself. The as_number function returns the epoch number, and the as_table function returns a time table. The as_string function returns a string representation of the timestamp, with a default format of "%m-%d-%Y %H:%M:%S". You can override this format to anything you would like. Details of what you can do with epoch values, time tables, and what format codes you can use are specified in the Lua manual at: http://www.lua.org/pil/22.1.html for the Lua date/time functions. A quick example of the usage of these functions is: ----- results = db:fetch(mydb.kills) for _, row in ipairs(results) do echo("You killed " .. row.name .. " at: " .. row.killed:as_string() .."\n") end ----- === Deleting The db:delete function is used to delete rows from the sheet. It takes two arguments, the first being the sheet you are deleting and the second a query string built using the same functions used to build db:fetch() queries. For example, to delete all your enemies in the city of Magnagora, you would do: ----- db:delete(mydb.enemies, db:eq(mydb.enemies.city, "Magnagora")) ----- Be careful in writing these! You may inadvertantly wipe out huge chunks of your sheets if you don't have the query parameters set just to what you need them to be. Its advised that you first run a db:fetch() with those parameters to test out the results they return. As a convienence, you may also pass in a result table that was previously retrieved via db:fetch and it will delete only that record from the table. For example, the following will get all of the enemies in Magnagora, and then delete the first one: ----- results = db:fetch(mydb.enemies, db:eq(mydb.enemies.city, "Magnagora")) db:delete(mydb.enemies, db:eq(mydb.enemies._row_id, results[1]._row_id)) ----- That is equivelent to: ----- db:delete(mydb.enemies, results[1]) ----- You can even pass a number directly to db:delete if you know what _row_id you want to purege. A final note of caution: if you want to delete all the records in a sheet, you can do so by only passing in the table reference. To try to protect you from doing this inadvertantly, you must also pass 'true' as the query after: ----- db:delete(mydb.enemies, true) ----- === Updating If you make a change to a table that you have received via db:fetch(), you can save those changes back to the database by doing: ----- db:update(mydb.enemies, results[1]) ----- A more powerful (and somewhat dangerous, be careful!) function to make changes to the database is db:set, which is capable of making sweeping changes to a column in every row of a sheet. Beware, if you have previously obtained a table from db:fetch, that table will NOT represent this change. The db:set() function takes two arguments: the field to change, the value to set it to, and the db:fetch() like query to indicate which rows should be affected. If you pass true as the last argument, ALL rows will be changed. To clear out the notes of all of our friends in Magnagora, we could do: ----- db:set(mydb.friends.notes, "", db:eq(mydb.friends.notes, "Magnagora")) ----- Be careful in writing these! === Transactions As was specified earlier, by default the db module commits everything immediately whenever you make a change. For power-users, if you would like to control transactions yourself, the following functions are provided on your database instance: ----- local mydb = db:get_database("my_database") mydb._begin() mydb._commit() mydb._rollback() mydb._end() ----- Once you issue a mydb._begin() command, autocommit mode will be turned off and stay off until you do a mydb._end(). Thus, if you want to always use transactions explicitly, just put a mydb._begin() right after your db:create() and that database will always be in manual commit mode. [[migrating]] == Migrating to Mudlet === From Nexus ==== Trigger patterns Lets start with triggers. For translating Nexus patterns into Mudlet, use the following table below. Make sure to set the pattern type in Mudlet to be `perl regex`, because the default `substring` works differently. [width="100%", cols="20%,20%,60%", options="header"] |======= |Mudlet |Nexus |What it does |(\w+) |\{w} |Match one or more non-whitespace characters (a \'word') |(\d+) |\{d} |Match one or more numeric digits (a number) |([abc]) |{[abc]} |Match one or more of either \'a', \'b' or \'c'. (a character class) |([^abc]) |{[^abc]} |Match one or more of anything EXCEPT \'a', \'b', or \'c' |(.*) |{*} |Match zero or more characters (anything) |^ |{<} |Match the beginning of a line (not the actual newline character) |$ |{>} |Match the end of a line (not the actual newline character) |======= NOTE: If you just have a pattern with a {<} and {>} and nothing else, copy the pattern over without the {<}{>} and select the `exact match` pattern type. For example `{<}You sit down.{>}` in Nexus would become `You sit down.` in Mudlet with the pattern type of `exact match`. This is easier to read and matches way faster! ==== Basic scripting The Nexus way of doing a function is like this: #'function' `stuff it does`. In Mudlet, it's 'function('`stuff it does`')'. Note that if you'd like to give text to a function, you put it inside double or single quotes. ===== Nexus --------- #send hi #echo Hello to me! --------- ===== Mudlet --------- send ("hi") echo ("Hello to me!") --------- If you'd like to use a variable inside text, you'd put it outside the quotes and glue it together with two dots. ===== Nexus --------- #set number 1234 #echo My number is: $number #echo the $number is in the middle of my text --------- ===== Mudlet --------- number = 1234 echo ("My number is: " .. number) echo ("the " .. number .. " is in the middle of my text") --------- ==== wildcards in Mudlet To use the wildcard variable in Nexus, you'd use $1 for the first match, $2 for the second and so on. In Mudlet, the matches[] table contains the matches - and it starts placing the matches from 2. So the Nexus $1 would be matches[2], $2 would be matches[3]. --------- Nexus: {w} kicks you. #set badguy $1 #echo $badguy kicked me! Mudlet: (\w+) kicks you\. badguy = matches[2] echo(badguy .. " kicked me!") --------- Another example would be the targetting alias: --------- Nexus: alias name: t alias script: #set target $1 Mudlet: alias pattern: ^t (.*)$ alias script: target = matches[2] --------- The reason the first match goes into matches[2] and not matches[1] is because matches[1] contains the part of the line that matched your trigger / alias. ==== #wait in Mudlet In Nexus, a `#wait` will _freeze_ the script while it's executing - such that commands after it are delayed. In Mudlet, we use <> which that works a bit differently - it doesn't freeze the script, but instead makes it so commands a tempTimer is asked to do will get done in the future. So the difference is that a tempTimer doesn't freeze the commands following it at all, everything gets done at once as usual. Just things a tempTimer was asked to do get done in the future. --------- Nexus script: #send hello #wait 1000 #send hi #wait 500 #send bye Mudlet: send("hello") tempTimer(1, [[send("hi")]]) tempTimer(1.5, [[send("bye")]]) --------- ==== ifs in Mudlet Next are the '#if' statements. Here's a table comparing the syntaxes of Nexus and Mudlet: [width="100%", frame="topbot", options="header,verse"] |=========== |Mudlet |Nexus |if then end |#if #if { 0 1 0 #ff0000 #ffff00 #000000 #000000 highlight exits 0 0 0 #ff0000 #ffff00 #000000 #000000 exits exit: EXIT EXITS 0 0 0 0 exits 0 99 0 #ff0000 #ffff00 #000000 #000000 up 0 d 0 0 0 #ff0000 #ffff00 #000000 #000000 down 0 n 0 99 0 #ff0000 #ffff00 #000000 #000000 north 0 w 0 0 0 #ff0000 #ffff00 #000000 #000000 west 0 e 0 0 0 #ff0000 #ffff00 #000000 #000000 east 0 s 0 0 0 #ff0000 #ffff00 #000000 #000000 south 0 nw 0 99 0 #ff0000 #ffff00 #000000 #000000 northwest 0 ne 0 0 0 #ff0000 #ffff00 #000000 #000000 northeast 0 sw 0 0 0 #ff0000 #ffff00 #000000 #000000 southwest 0 se 0 0 0 #ff0000 #ffff00 #000000 #000000 southeast 0 generic mapper script commands moving directions ^out$ ^out$ ^in$ ^in$ ^d$ ^d$ ^u$ ^u$ ^se$ ^se$ ^sw$ ^sw$ ^ne$ ^ne$ ^nw$ ^nw$ ^e$ ^e$ ^w$ ^w$ ^s$ ^s$ ^n$ ^n$ tools ^deleteMap$ ^deleteMap$ generic mapper scripts mudlet-2.1/src/dlgAboutDialog.h0000644000175000017500000000320511513237311015774 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _dlg_about_dialog_h #define _dlg_about_dialog_h #include "ui_about_dialog.h" #include class dlgAboutDialog : public QDialog , public Ui::about_dialog { Q_OBJECT public: dlgAboutDialog(QWidget * parent = 0); }; #endif mudlet-2.1/src/FindPCRE.cmake0000755000175000017500000000251411513237311015303 0ustar csmallcsmall# Locate PCRE library # This module defines # PCRE_FOUND, if false, do not try to link to PCRE # PCRE_LIBRARIES # PCRE_INCLUDE_DIR, where to find pcre.h FIND_PATH(PCRE_INCLUDE_DIR pcre.h HINTS $ENV{PCRE_DIR} PATHS ~/Library/Frameworks /Library/Frameworks /usr/local /usr /sw # Fink /opt/local # DarwinPorts /opt/csw # Blastwave /opt ) FIND_LIBRARY(PCRE_LIBRARY NAMES pcre HINTS $ENV{PCRE_DIR} PATHS ~/Library/Frameworks /Library/Frameworks /usr/local /usr /sw /opt/local /opt/csw /opt ) FIND_LIBRARY(PCRECPP_LIBRARY NAMES pcrecpp HINTS $ENV{PCRE_DIR} PATHS ~/Library/Frameworks /Library/Frameworks /usr/local /usr /sw /opt/local /opt/csw /opt ) FIND_LIBRARY(PCREPOSIX_LIBRARY NAMES pcreposix HINTS $ENV{PCRE_DIR} PATHS ~/Library/Frameworks /Library/Frameworks /usr/local /usr /sw /opt/local /opt/csw /opt ) SET( PCRE_LIBRARIES "${PCRE_LIBRARY};${PCRECPP_LIBRARY};${PCREPOSIX_LIBRARY}" CACHE STRING "PCRE Libraries") INCLUDE(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set PCRE_FOUND to TRUE if # all listed variables are TRUE FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARIES PCRE_INCLUDE_DIR) MARK_AS_ADVANCED(PCRE_INCLUDE_DIR PCRE_LIBRARIES PCRE_LIBRARY PCRECPP_LIBRARY PCREPOSIX_LIBRARY) mudlet-2.1/src/dlgSearchArea.cpp0000644000175000017500000000302311513237311016131 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "dlgSearchArea.h" dlgSearchArea::dlgSearchArea(QWidget * pF):QWidget(pF) { // init generated dialog setupUi(this); } mudlet-2.1/src/dlgOptionsAreaTriggers.cpp0000644000175000017500000000305611513237311020074 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "dlgOptionsAreaTriggers.h" dlgOptionsAreaTriggers::dlgOptionsAreaTriggers(QWidget * pF):QWidget(pF) { // init generated dialog setupUi(this); } mudlet-2.1/src/TTextEdit.cpp0000644000175000017500000014621212070466512015340 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn KoehnHeiko@googlemail.com * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "mudlet.h" #include "TDebug.h" #include "TTextEdit.h" #include TTextEdit::TTextEdit( TConsole * pC, QWidget * pW, TBuffer * pB, Host * pH, bool isDebugConsole, bool isSplitScreen ) : QWidget( pW ) , mCursorY( 0 ) , mIsCommandPopup( false ) , mIsTailMode( true ) , mShowTimeStamps( isDebugConsole ) //private , mForceUpdate( false ) , mHighlight_on( false ) , mHighlightingBegin( false ) , mHighlightingEnd( false ) , mInit_OK( false ) , mInversOn( false ) , mIsDebugConsole( isDebugConsole ) , mIsMiniConsole( false ) , mIsSplitScreen( isSplitScreen ) , mLastRenderBottom( 0 ) , mMouseTracking( false ) , mPainterInit( false ) , mpBuffer( pB ) , mpConsole( pC ) , mpHost( pH ) , mpScrollBar( 0 ) { if( ! mIsDebugConsole ) { mFontHeight = QFontMetrics( mpHost->mDisplayFont ).height(); mFontWidth = QFontMetrics( mpHost->mDisplayFont ).width( QChar('W') ); mScreenWidth = 100; if( (width()/mFontWidth ) < mScreenWidth ) { mScreenWidth = 100;//width()/mFontWidth; } mpHost->mDisplayFont.setFixedPitch(true); #if defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && QT_VERSION >= 0x040800) QPixmap pixmap = QPixmap( mScreenWidth*mFontWidth*2, mFontHeight*2 ); QPainter p(&pixmap); p.setFont(mpHost->mDisplayFont); const QRectF r = QRectF(0,0,mScreenWidth*mFontWidth*2,mFontHeight*2); QRectF r2; const QString t = "1234"; p.drawText(r,1,t,&r2); mLetterSpacing = (qreal)((qreal)mFontWidth-(qreal)(r2.width()/t.size())); mpHost->mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, mLetterSpacing ); #endif setFont( mpHost->mDisplayFont ); } else { initDefaultSettings(); mIsDebugConsole = true; mFontHeight = QFontMetrics( mDisplayFont ).height(); mFontWidth = QFontMetrics( mDisplayFont ).width( QChar('W') ); mScreenWidth = 100; mDisplayFont.setFixedPitch(true); #if defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && QT_VERSION >= 0x040800) QPixmap pixmap = QPixmap( mScreenWidth*mFontWidth*2, mFontHeight*2 ); QPainter p(&pixmap); p.setFont(mDisplayFont); const QRectF r = QRectF(0,0,mScreenWidth*mFontWidth*2,mFontHeight*2); QRectF r2; const QString t = "1234"; p.drawText(r,1,t,&r2); mLetterSpacing = (qreal)((qreal)mFontWidth-(qreal)(r2.width()/t.size())); mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, mLetterSpacing ); #endif setFont( mDisplayFont ); } mScreenHeight = height() / mFontHeight; mScreenWidth = 100; setMouseTracking( true ); setFocusPolicy( Qt::NoFocus );//Qt::WheelFocus ); QCursor cursor; cursor.setShape(Qt::IBeamCursor); setCursor( cursor ); //setAutoFillBackground( true ); //experimental //setAttribute( Qt::WA_InputMethodEnabled, true ); setAttribute( Qt::WA_OpaquePaintEvent );//was disabled setAttribute( Qt::WA_DeleteOnClose ); QPalette palette; palette.setColor( QPalette::Text, mFgColor ); palette.setColor( QPalette::Highlight, QColor(55,55,255) ); palette.setColor( QPalette::Base, mBgColor ); setPalette(palette); showNewLines(); setMouseTracking( true ); // test fix for MAC setEnabled( true ); //test fix for MAC } void TTextEdit::forceUpdate() { mForceUpdate = true; update(); } void TTextEdit::needUpdate( int y1, int y2 ) { if( ! mIsTailMode ) { return; } if( mScreenHeight == 0 ) return; int top = imageTopLine(); int bottom = y2-y1; if( top > 0 ) { top = (y1 - top) % mScreenHeight; } else { top = y1 % mScreenHeight; } QRect r( 0, top*mFontHeight, mScreenWidth*mFontWidth, bottom*mFontHeight ); mForceUpdate = true; update( r ); } void TTextEdit::focusInEvent ( QFocusEvent * event ) { update(); QWidget::focusInEvent( event ); } void TTextEdit::slot_toggleTimeStamps() { mShowTimeStamps = !mShowTimeStamps; forceUpdate(); update(); } void TTextEdit::slot_scrollBarMoved( int line ) { if( mpConsole->mpScrollBar ) { disconnect( mpConsole->mpScrollBar, SIGNAL(valueChanged(int)), this, SLOT(slot_scrollBarMoved(int))); mpConsole->mpScrollBar->setRange( 0, mpBuffer->getLastLineNumber() ); mpConsole->mpScrollBar->setSingleStep( 1 ); mpConsole->mpScrollBar->setPageStep( mScreenHeight ); mpConsole->mpScrollBar->setValue( line ); scrollTo( line ); connect( mpConsole->mpScrollBar, SIGNAL(valueChanged(int)), this, SLOT(slot_scrollBarMoved(int))); } } void TTextEdit::initDefaultSettings() { mFgColor = QColor(192,192,192); mBgColor = QColor(0,0,0); mDisplayFont = QFont("Bitstream Vera Sans Mono", 10, QFont::Courier); // mDisplayFont.setWordSpacing( 0 ); #if defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && QT_VERSION >= 0x040800) QPixmap pixmap = QPixmap( mScreenWidth*mFontWidth*2, mFontHeight*2 ); QPainter p(&pixmap); p.setFont(mDisplayFont); const QRectF r = QRectF(0,0,mScreenWidth*mFontWidth*2,mFontHeight*2); QRectF r2; const QString t = "1234"; p.drawText(r,1,t,&r2); mLetterSpacing = (qreal)((qreal)mFontWidth-(qreal)(r2.width()/t.size())); mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, mLetterSpacing ); #endif mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, mLetterSpacing ); mDisplayFont.setFixedPitch(true); setFont( mDisplayFont ); mCommandLineFont = QFont("Bitstream Vera Sans Mono", 10, QFont::Courier); mCommandSeperator = QString(";"); mWrapAt = 100; mWrapIndentCount = 5; } /* void TTextEdit::setScroll(int cursor, int lines) { disconnect( mpScrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); mpScrollBar->setRange( 0, lines - mScreenHeight ); mpScrollBar->setSingleStep( 1 ); mpScrollBar->setPageStep( mScreenHeight ); mpScrollBar->setValue( cursor ); connect( mpScrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int))); } */ /*std::string TTextEdit::getCurrentTime() { time_t t; time(&t); tm lt; ostringstream s; s.str(""); struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); localtime_r( &t, < ); s << "["<= 0x040800) QPixmap pixmap = QPixmap( 2000,600 ); QPainter p(&pixmap); mDisplayFont.setLetterSpacing(QFont::AbsoluteSpacing, 0); if( ! p.isActive() ) return; p.setFont(mDisplayFont); const QRectF r = QRectF(0,0,2000,600); QRectF r2; const QString t = "1234"; p.drawText(r,1,t,&r2); mLetterSpacing = (qreal)((qreal)mFontWidth-(qreal)(r2.width()/t.size())); mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, mLetterSpacing ); #endif return; //NOTE: das ist wichtig, damit ich keine floating point exception bekomme, wenn mScreenHeight==0, was hier der Fall wäre } if( ! mIsDebugConsole && ! mIsMiniConsole ) { mFontWidth = QFontMetrics( mpHost->mDisplayFont ).width( QChar('W') ); mFontDescent = QFontMetrics( mpHost->mDisplayFont ).descent(); mFontAscent = QFontMetrics( mpHost->mDisplayFont ).ascent(); mFontHeight = mFontAscent + mFontDescent; mBgColor = mpHost->mBgColor; mFgColor = mpHost->mFgColor; #if defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && QT_VERSION >= 0x040800) QPixmap pixmap = QPixmap( mScreenWidth*mFontWidth*2, mFontHeight*2 ); QPainter p(&pixmap); mpHost->mDisplayFont.setLetterSpacing(QFont::AbsoluteSpacing, 0); if( p.isActive() ) { p.setFont(mpHost->mDisplayFont); const QRectF r = QRectF(0,0,mScreenWidth*mFontWidth*2,mFontHeight*2); QRectF r2; const QString t = "1234"; p.drawText(r,1,t,&r2); mLetterSpacing = (qreal)((qreal)mFontWidth-(qreal)(r2.width()/t.size())); mpHost->mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, mLetterSpacing ); } #endif } else { mFontWidth = QFontMetrics( mDisplayFont ).width( QChar('W') ); mFontDescent = QFontMetrics( mDisplayFont ).descent(); mFontAscent = QFontMetrics( mDisplayFont ).ascent(); mFontHeight = mFontAscent + mFontDescent; #if defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && QT_VERSION >= 0x040800) QPixmap pixmap = QPixmap( mScreenWidth*mFontWidth*2, mFontHeight*2 ); QPainter p(&pixmap); mDisplayFont.setLetterSpacing(QFont::AbsoluteSpacing, 0); if( p.isActive() ) { p.setFont(mDisplayFont); const QRectF r = QRectF(0,0,mScreenWidth*mFontWidth*2,mFontHeight*2); QRectF r2; const QString t = "1234"; p.drawText(r,1,t,&r2); mLetterSpacing = (qreal)((qreal)mFontWidth-(qreal)(r2.width()/t.size())); mDisplayFont.setLetterSpacing( QFont::AbsoluteSpacing, mLetterSpacing ); } #endif } mScreenHeight = visibleRegion().boundingRect().height()/mFontHeight; int currentScreenWidth = visibleRegion().boundingRect().width() / mFontWidth; if( ! mIsDebugConsole && ! mIsMiniConsole ) { if( mpHost->mScreenWidth > currentScreenWidth ) { if( currentScreenWidth < 100 ) { mScreenWidth = 100; } else { mScreenWidth = currentScreenWidth; mpHost->mScreenWidth = mScreenWidth; } } else { mpHost->mScreenWidth = currentScreenWidth; mScreenWidth = currentScreenWidth; } mpHost->mScreenHeight = mScreenHeight; } else { mScreenWidth = currentScreenWidth; } } void TTextEdit::showNewLines() { if( ! mIsSplitScreen ) { if( ! isTailMode() ) { return; } } else { if( isHidden() ) { return; } } //int lines = mpBuffer->newLines; mCursorY = mpBuffer->size(); if( ! mIsSplitScreen ) { mpBuffer->mCursorY = mpBuffer->size(); } if( mCursorY > mScreenHeight ) { mScrollUp = true; } mOldScrollPos = mpBuffer->getLastLineNumber(); if( ! mIsSplitScreen ) { if( mpConsole->mpScrollBar && mOldScrollPos > 0 ) { disconnect( mpConsole->mpScrollBar, SIGNAL(valueChanged(int)), mpConsole->console, SLOT(slot_scrollBarMoved(int))); mpConsole->mpScrollBar->setRange( 0, mpBuffer->getLastLineNumber() ); mpConsole->mpScrollBar->setSingleStep( 1 ); mpConsole->mpScrollBar->setPageStep( mScreenHeight ); if( mpConsole->console->isTailMode() ) { mpConsole->mpScrollBar->setValue( mpBuffer->mCursorY ); } connect( mpConsole->mpScrollBar, SIGNAL(valueChanged(int)), mpConsole->console, SLOT(slot_scrollBarMoved(int))); } } update(); } void TTextEdit::scrollTo( int line ) { if( (line > -1) && (line < mpBuffer->size()) ) { if( (line < (mpBuffer->getLastLineNumber()-mScreenHeight) && mIsTailMode ) ) { mpConsole->console2->mCursorY = mpBuffer->size(); mpConsole->console2->mIsTailMode = true; mIsTailMode = false; mpConsole->console2->show(); mpConsole->console2->forceUpdate(); } else if( (line > (mpBuffer->getLastLineNumber()-mScreenHeight)) && !mIsTailMode ) { mpConsole->console2->mCursorY = mpConsole->buffer.getLastLineNumber(); mpConsole->console2->hide(); mpConsole->console->mCursorY = mpConsole->buffer.getLastLineNumber(); mpConsole->console->mIsTailMode = true; mpConsole->console->updateScreenView(); mpConsole->console->forceUpdate(); } mpBuffer->mCursorY = line; mScrollVector = 0; update(); } } void TTextEdit::scrollUp( int lines ) { if( mIsSplitScreen ) return; lines = bufferScrollUp( lines ); if( lines == 0 ) return; else { mIsTailMode = false; lines = mScreenHeight; mScrollVector = 0; update(); } } void TTextEdit::scrollDown( int lines ) { if( mIsSplitScreen ) return; lines = bufferScrollDown( lines ); if( lines == 0 ) return; else { mScrollVector = 0; update(); } } inline void TTextEdit::drawBackground( QPainter & painter, const QRect & rect, const QColor & bgColor ) { QRect bR = rect; painter.fillRect( bR.x(), bR.y(), bR.width(), bR.height(), bgColor );//QColor(rand()%255,rand()%255,rand()%255));//bgColor); } inline void TTextEdit::drawCharacters( QPainter & painter, const QRect & rect, QString & text, bool isBold, bool isUnderline, bool isItalics, QColor & fgColor, QColor & bgColor ) { if( ( painter.font().bold() != isBold ) || ( painter.font().underline() != isUnderline ) || (painter.font().italic() != isItalics) ) { QFont font = painter.font(); font.setBold( isBold ); font.setUnderline( isUnderline ); font.setItalic( isItalics ); #if defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && QT_VERSION >= 0x040800) font.setLetterSpacing(QFont::AbsoluteSpacing, mLetterSpacing); #endif painter.setFont( font ); } if( painter.pen().color() != fgColor ) { painter.setPen( fgColor ); } #if defined(Q_OS_MAC) || (defined(Q_OS_LINUX) && QT_VERSION >= 0x040800) QPointF _p(rect.x(), rect.bottom()-mFontDescent); painter.drawText( _p, text ); #else painter.drawText( rect.x(), rect.bottom()-mFontDescent, text ); #endif } void TTextEdit::drawFrame( QPainter & p, const QRect & rect ) { QPoint P_topLeft = rect.topLeft(); QPoint P_bottomRight = rect.bottomRight(); int x_topLeft = P_topLeft.x(); int x_bottomRight = P_bottomRight.x(); if( x_bottomRight > mScreenWidth * mFontWidth ) x_bottomRight = mScreenWidth * mFontWidth; int x1 = x_topLeft / mFontWidth; int x2 = x_bottomRight / mFontWidth; int lineOffset = imageTopLine(); bool invers = false; if( mHighlight_on && mInversOn ) { invers = true; } int from = 0; for( int i=from; i(mpBuffer->buffer.size()) <= i+lineOffset ) { break; } int timeOffset = 0; if( mShowTimeStamps ) { if( mpBuffer->timeBuffer.size() > i+lineOffset ) { timeOffset = mpBuffer->timeBuffer[i+lineOffset].size()-1; } } int lineLength = mpBuffer->buffer[i+lineOffset].size() + timeOffset; for( int i2=x1; i2timeBuffer[i+lineOffset]; bool isBold = false; bool isUnderline = false; bool isItalics = false; QRect textRect = QRect( mFontWidth * i2, mFontHeight * i, mFontWidth * timeOffset, mFontHeight ); QColor bgTime = QColor(22,22,22); QColor fgTime = QColor(200,150,0); drawBackground( p, textRect, bgTime ); drawCharacters( p, textRect, text, isBold, isUnderline, isItalics, fgTime, bgTime ); i2+=timeOffset; } else { if( i2 >= x2 ) { break; } text = mpBuffer->lineBuffer[i+lineOffset].at(i2-timeOffset); TChar & f = mpBuffer->buffer[i+lineOffset][i2-timeOffset]; int delta = 1; QColor fgColor = QColor(f.fgR, f.fgG, f.fgB ); QColor bgColor = QColor(f.bgR, f.bgG, f.bgB ); while( i2+delta+timeOffset < lineLength ) { if( mpBuffer->buffer[i+lineOffset][i2+delta-timeOffset] == f ) { text.append( mpBuffer->lineBuffer[i+lineOffset].at(i2+delta-timeOffset) ); delta++; } else { break; } } if( invers || ( bgColor != mBgColor ) ) { QRect textRect = QRect( mFontWidth * i2, mFontHeight * i, mFontWidth * delta, mFontHeight ); if( invers ) drawBackground( p, textRect, fgColor ); else drawBackground( p, textRect, bgColor ); } if( ( p.font().bold() != f.bold ) || ( p.font().underline() != f.underline ) || (p.font().italic() != f.italics) ) { QFont font = p.font(); font.setBold( f.bold ); font.setUnderline( f.underline ); font.setItalic( f.italics ); font.setLetterSpacing( QFont::AbsoluteSpacing, mLetterSpacing ); p.setFont( font ); } if( ( p.pen().color() != fgColor ) || ( invers ) ) { if( invers ) p.setPen( bgColor ); else p.setPen( fgColor ); } p.drawText( mFontWidth*i2,(mFontHeight*i)-mFontDescent, text ); i2+=delta; } } } mScrollVector = 0; } void TTextEdit::updateLastLine() { qDebug()<<"--->ACHTUNG: error: updateLastLine() called"; QRect r( 0, (mScreenHeight-1)*mFontHeight, mScreenWidth*mFontWidth, mScreenHeight*mFontHeight ); mForceUpdate = true; update( r ); } void TTextEdit::drawForeground( QPainter & painter, const QRect & r ) { //int lastLine = mpBuffer->buffer.size(); QPixmap screenPixmap; QPixmap pixmap = QPixmap( mScreenWidth*mFontWidth, mScreenHeight*mFontHeight ); pixmap.fill( palette().base().color() ); QPainter p( &pixmap ); p.setCompositionMode( QPainter::CompositionMode_Source ); if( ! mIsDebugConsole && ! mIsMiniConsole ) { p.setFont( mpHost->mDisplayFont ); p.setRenderHint( QPainter::TextAntialiasing, !mpHost->mNoAntiAlias ); } else { p.setFont( mDisplayFont ); p.setRenderHint( QPainter::TextAntialiasing, false ); } QPoint P_topLeft = r.topLeft(); QPoint P_bottomRight = r.bottomRight(); int x_topLeft = 0;//P_topLeft.x(); int y_topLeft = P_topLeft.y(); int x_bottomRight = P_bottomRight.x(); int y_bottomRight = P_bottomRight.y(); if( x_bottomRight > mScreenWidth * mFontWidth ) { x_bottomRight = mScreenWidth * mFontWidth; } int x1 = x_topLeft / mFontWidth; int y1 = y_topLeft / mFontHeight; int x2 = x_bottomRight / mFontWidth; int y2 = y_bottomRight / mFontHeight; int lineOffset = imageTopLine(); //bool invers = false; //int _c = 0; int from = 0; if( lineOffset == 0 ) { mScrollVector = 0; } else { mScrollVector = lineOffset - mLastRenderBottom; } bool noScroll = false; bool noCopy = false; if( abs( mScrollVector ) > mScreenHeight || mForceUpdate || lineOffset < 10 ) { mScrollVector = 0; noScroll = true; } if( ( r.height() < rect().height() ) && ( lineOffset > 0 ) ) { p.drawPixmap( 0, 0, mScreenMap ); if( ! mForceUpdate && ! mMouseTracking ) { from = y1; noScroll = true; noCopy = true; } else { from = y1; y2 = mScreenHeight; noScroll = true; mScrollVector = 0; } } if( ( ! noScroll ) && ( mScrollVector >= 0 ) && ( mScrollVector <= mScreenHeight ) && ( ! mForceUpdate ) ) { if( mScrollVector*mFontHeight < mScreenMap.height() && mScreenWidth*mFontWidth <= mScreenMap.width() && (mScreenHeight-mScrollVector)*mFontHeight > 0 && (mScreenHeight-mScrollVector)*mFontHeight <= mScreenMap.height() ) { screenPixmap = mScreenMap.copy( 0, mScrollVector*mFontHeight, mScreenWidth*mFontWidth, (mScreenHeight-mScrollVector)*mFontHeight ); p.drawPixmap( 0, 0, screenPixmap ); from = mScreenHeight - mScrollVector - 1; } } else if( ( ! noScroll ) && ( mScrollVector < 0 && mScrollVector >= ((-1)*mScreenHeight) ) && ( ! mForceUpdate ) ) { if( abs(mScrollVector)*mFontHeight < mScreenMap.height() && mScreenWidth*mFontWidth <= mScreenMap.width() && (mScreenHeight-abs(mScrollVector))*mFontHeight > 0 && (mScreenHeight-abs(mScrollVector))*mFontHeight <= mScreenMap.height() ) { screenPixmap = mScreenMap.copy( 0, 0, mScreenWidth*mFontWidth, (mScreenHeight-abs(mScrollVector))*mFontHeight ); p.drawPixmap( 0, abs(mScrollVector)*mFontHeight, screenPixmap ); from = 0; y2 = abs(mScrollVector); } } QRect deleteRect = QRect( 0, from*mFontHeight, x2*mFontHeight, (y2+1)*mFontHeight);//rect.width(), rect.height()-from*mFontHeight ); drawBackground( p, deleteRect, mBgColor );//QColor(rand()%255,rand()%255,rand()%255));//mBgColor ); for( int i=from; i<=y2; i++ ) { if( static_cast(mpBuffer->buffer.size()) <= i+lineOffset ) { break; } mpBuffer->dirty[lineOffset+i] = false; int timeOffset = 0; if( mShowTimeStamps ) { timeOffset = 13; } int lineLength = mpBuffer->buffer[i+lineOffset].size() + timeOffset; //int doubleByteOffset = 0; for( int i2=x1; i2timeBuffer[i+lineOffset]; bool isBold = false; bool isUnderline = false; bool isItalics = false; QRect textRect = QRect( mFontWidth * i2, mFontHeight * i, mFontWidth * timeOffset, mFontHeight ); QColor bgTime = QColor(22,22,22); QColor fgTime = QColor(200,150,0); drawBackground( p, textRect, bgTime ); drawCharacters( p, textRect, text, isBold, isUnderline, isItalics, fgTime, bgTime ); i2+=timeOffset; } else { if( i2 >= x2 ) { break; } text = mpBuffer->lineBuffer[i+lineOffset].at(i2-timeOffset); TChar & f = mpBuffer->buffer[i+lineOffset][i2-timeOffset]; int delta = 1; QColor fgColor; QColor bgColor; if( f.invers ) { bgColor = QColor(f.fgR, f.fgG, f.fgB ); fgColor = QColor(f.bgR, f.bgG, f.bgB ); } else { fgColor = QColor(f.fgR, f.fgG, f.fgB ); bgColor = QColor(f.bgR, f.bgG, f.bgB ); } while( i2+delta+timeOffset < lineLength ) { if( mpBuffer->buffer[i+lineOffset][i2+delta-timeOffset] == f ) { text.append( mpBuffer->lineBuffer[i+lineOffset].at(i2+delta-timeOffset) ); delta++; } else { break; } } QRect textRect; /*if( mpHost->mEncoding != 2 ) { textRect = QRect( mFontWidth * i2 + doubleByteOffset, mFontHeight * i, mFontWidth * delta, mFontHeight ); } else { int unicode = text[0].unicode(); if( unicode >= 0x4E00 && unicode <= 0x9FCB ) { textRect = QRect( mFontWidth * i2 + doubleByteOffset, mFontHeight * i, mFontWidth * 2 * delta, mFontHeight ); doubleByte = true; doubleByteOffset += mFontWidth*2; } else { textRect = QRect( mFontWidth * i2 + doubleByteOffset, mFontHeight * i, mFontWidth * delta, mFontHeight ); } }*/ textRect = QRect( mFontWidth * i2, mFontHeight * i, mFontWidth * delta, mFontHeight ); if( f.invers || ( bgColor != mBgColor ) ) { drawBackground( p, textRect, bgColor ); } drawCharacters( p, textRect, text, f.bold, f.underline, f.italics, fgColor, bgColor ); i2+=delta; } } } p.end(); painter.setCompositionMode( QPainter::CompositionMode_Source ); painter.drawPixmap( 0, 0, pixmap ); if( ! noCopy ) { mScreenMap = pixmap.copy(); } mScrollVector = 0; mLastRenderBottom = lineOffset; mForceUpdate = false; } void TTextEdit::paintEvent( QPaintEvent* e ) { const QRect & rect = e->rect(); if( mFontWidth <= 0 || mFontHeight <= 0 ) return; if( mScreenHeight <= 0 || mScreenWidth <= 0 ) { mScreenHeight = height()/mFontHeight;//e->rect().height(); mScreenWidth = 100;//e->rect().width(); if( mScreenHeight <= 0 || mScreenWidth <= 0 ) return; } QPainter painter( this ); if( ! painter.isActive() ) return; QRect borderRect = QRect( 0, mScreenHeight*mFontHeight, rect.width(), rect.height() ); drawBackground( painter, borderRect, mBgColor ); QRect borderRect2 = QRect( rect.width()-mScreenWidth, 0, rect.width(), rect.height() ); drawBackground( painter, borderRect2, mBgColor ); drawForeground( painter, rect ); mUpdateSlice = false; } void TTextEdit::highlight() { QRegion newRegion; int lineDelta = abs( mPA.y() - mPB.y() ) - 1; if( lineDelta > 0 ) { QRect rectFirstLine( mPA.x()*mFontWidth, (mPA.y()-imageTopLine())*mFontHeight, mScreenWidth*mFontWidth, mFontHeight ); newRegion += rectFirstLine; QRect rectMiddlePart( 0, (mPA.y()+1-imageTopLine())*mFontHeight, mScreenWidth*mFontWidth, lineDelta*mFontHeight ); newRegion += rectMiddlePart; QRect rectLastLine( 0, (mPB.y()-imageTopLine())*mFontHeight, mPB.x()*mFontWidth, mFontHeight ); newRegion += rectLastLine; } if( lineDelta == 0 ) { QRect rectFirstLine( mPA.x()*mFontWidth, (mPA.y()-imageTopLine())*mFontHeight, mScreenWidth*mFontWidth, mFontHeight ); newRegion += rectFirstLine; QRect rectLastLine( 0, (mPB.y()-imageTopLine())*mFontHeight, mPB.x()*mFontWidth, mFontHeight ); newRegion += rectLastLine; } if( lineDelta < 0 ) { QRect rectFirstLine( mPA.x()*mFontWidth, (mPA.y()-imageTopLine())*mFontHeight, (mPB.x()-mPA.x())*mFontWidth, mFontHeight ); newRegion += rectFirstLine; } QRect _r = mSelectedRegion.boundingRect(); if( lineDelta < 0 ) { _r.setWidth( mScreenWidth*mFontWidth ); } update( _r ); mSelectedRegion = mSelectedRegion.subtracted( newRegion ); int y1 = mPA.y(); for( int y=y1; y<=mPB.y(); y++ ) { int x = 0; if( y == y1 ) { x = mPA.x(); } for( ; ; x++ ) { if( (y == mPB.y()) && (x > mPB.x()) ) { break; } mpBuffer->dirty[y] = true; if( x < static_cast(mpBuffer->buffer[y].size()) ) { mpBuffer->buffer[y][x].invers = true; } else { break; } } } update( mSelectedRegion.boundingRect() ); mSelectedRegion = newRegion; } void TTextEdit::unHighlight( QRegion & region ) { int y1 = mPA.y(); if( y1 < 0 ) { return; } for( int y=y1; y<=mPB.y(); y++ ) { int x = 0; if( y == y1 ) { x = mPA.x(); } for( ; ; x++ ) { if( (y == mPB.y()) && (x > mPB.x()) ) { break; } if( y >= static_cast(mpBuffer->buffer.size()) ) { break; } mpBuffer->dirty[y] = true; if( x < static_cast(mpBuffer->buffer[y].size()) ) { mpBuffer->buffer[y][x].invers = false; mpBuffer->dirty[y] = true; } else { break; } } } mForceUpdate = true; update(); } void TTextEdit::swap( QPoint & p1, QPoint & p2 ) { QPoint tmp = p1; p1 = p2; p2 = tmp; } #include void TTextEdit::mouseMoveEvent( QMouseEvent * event ) { if( (mFontWidth == 0) | (mFontHeight == 0) ) return; int x = event->x() / mFontWidth;// bugfix by BenH (used to be mFontWidth-1) if( mShowTimeStamps ) { x -= 13; } int y = ( event->y() / mFontHeight ) + imageTopLine(); //qDebug()<<"Mouse: x()="<x()<<" y()="<y()<< "x="<y() < 10 ) { mpConsole->scrollUp( 3 ); } if( event->y() > height()-10 ) { mpConsole->scrollDown( 3 ); } //int x, y; int timeOffset = 0; y = ( event->y() / mFontHeight ) + imageTopLine(); if( mShowTimeStamps ) { if( mpBuffer->timeBuffer.size() > y ) { timeOffset = 13;//mpBuffer->timeBuffer[y].size()-1; } } x = ( event->x() / mFontWidth ) - timeOffset; if( ( x < 0 ) || ( y < 0 ) || ( y > (int) mpBuffer->size()-1 ) ) { qDebug()<<"Mouse SELECT: ERROR#1"; return; } QPoint PC( x, y ); if( ( mPA.y() == mPB.y() ) && ( mPA.x() > mPB.x() ) ) { swap( mPA, mPB ); } if( mPA.y() > mPB.y() ) { swap( mPA, mPB ); } QPoint p1 = mPA-PC; QPoint p2 = mPB-PC; if( p1.manhattanLength() < p2.manhattanLength() ) { if( mPA.y() < PC.y() || ( (mPA.x() < PC.x()) && (mPA.y() == PC.y()) ) ) { int y1 = PC.y(); for( int y=y1; y>=mPA.y(); y-- ) { if( y >= static_cast(mpBuffer->buffer.size()) || y < 0 ) break; int x = mpBuffer->buffer[y].size()-1; if( y == y1 ) { x = PC.x(); if( x >= static_cast(mpBuffer->buffer[y].size()) ) x = static_cast(mpBuffer->buffer[y].size())-1; if( x < 0 ) x = 0; } mpBuffer->dirty[y] = true; for( ; ; x-- ) { if( ( y == mPA.y() ) && ( x < mPA.x() ) ) { break; } if( x < static_cast(mpBuffer->buffer[y].size()) && x >= 0 ) { mpBuffer->buffer[y][x].invers = false; } else { break; } } } mP_aussen = mPA; } else mP_aussen = PC; mPA = PC; } else { if( mPB.y() > PC.y() || (mPB.x() > PC.x() && mPB.y() == PC.y()) ) { int y1 = PC.y(); for( int y=y1; y<=mPB.y(); y++ ) { int x = 0; if( y == y1 ) { x = PC.x(); } if( y >= static_cast(mpBuffer->buffer.size()) || y < 0 ) break; mpBuffer->dirty[y] = true; for( ; ; x++ ) { if( ( y == mPB.y() ) && ( x > mPB.x() ) ) { break; } if( x < static_cast(mpBuffer->buffer[y].size()) ) { mpBuffer->buffer[y][x].invers = false; } else { break; } } } mP_aussen = mPB; } else mP_aussen = PC; mPB = PC; } if( ( mPA.y() == mPB.y() ) && ( mPA.x() > mPB.x() ) ) { swap( mPA, mPB ); } if( mPA.y() > mPB.y() ) { swap( mPA, mPB ); } mP_aussen = PC; highlight(); } void TTextEdit::contextMenuEvent ( QContextMenuEvent * event ) { // int x = event->x() / mFontWidth; // int y = ( event->y() / mFontHeight ) + imageTopLine(); // if( y < static_cast(mpBuffer->buffer.size()) ) // { // if( x < static_cast(mpBuffer->buffer[y].size()) ) // { // if( mpBuffer->buffer[y][x].link > 0 ) // { // QStringList command = mpBuffer->mLinkStore[mpBuffer->buffer[y][x].link]; // QStringList hint = mpBuffer->mHintStore[mpBuffer->buffer[y][x].link]; // if( command.size() > 1 ) // { // QMenu * popup = new QMenu( this ); // for( int i=0; iaddAction( hint[i] ); // mPopupCommands[hint[i]] = command[i]; // } // else // { // pA = popup->addAction( command[i] ); // mPopupCommands[command[i]] = command[i]; // } // connect( pA, SIGNAL(triggered()), this, SLOT(slot_popupMenu())); // } // popup->popup( event->globalPos() ); // } // mIsCommandPopup = true; // return; // } // } // } // mIsCommandPopup = false; // QAction * action = new QAction("copy", this ); // action->setStatusTip(tr("copy selected text to clipboard")); // connect( action, SIGNAL(triggered()), this, SLOT(slot_copySelectionToClipboard())); // QAction * action2 = new QAction("copy as HTML", this ); // action->setStatusTip(tr("copy selected text in HTML format with colors for usage in web browsers")); // connect( action2, SIGNAL(triggered()), this, SLOT(slot_copySelectionToClipboardHTML())); // QMenu * popup = new QMenu( this ); // popup->addAction( action ); // popup->addAction( action2 ); // popup->popup( mapToGlobal( event->pos() ), action ); event->accept(); return; } void TTextEdit::slot_popupMenu() { QAction * pA = (QAction *)sender(); if( ! pA ) { return; } QString cmd; if( mPopupCommands.contains( pA->text() ) ) { cmd = mPopupCommands[pA->text()]; } mpHost->mLuaInterpreter.compileAndExecuteScript( cmd ); } void TTextEdit::mousePressEvent( QMouseEvent * event ) { if( ! mpConsole->mIsSubConsole && ! mpConsole->mIsDebugConsole ) { TEvent me; me.mArgumentList.append( "sysWindowMousePressEvent" ); switch( event->button() ) { case Qt::LeftButton: me.mArgumentList.append( QString::number(1) ); break; case Qt::RightButton: me.mArgumentList.append( QString::number(2) ); break; case Qt::MidButton: me.mArgumentList.append( QString::number(3) ); break; default: me.mArgumentList.append( 0 ); break; } me.mArgumentList.append( QString::number(event->x()) ); me.mArgumentList.append( QString::number(event->y()) ); me.mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); me.mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); me.mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); me.mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); mpHost->raiseEvent( &me ); } if( event->button() == Qt::LeftButton ) { int x = event->x() / mFontWidth; if( mShowTimeStamps ) { x -= 13; } int y = ( event->y() / mFontHeight ) + imageTopLine(); if( x < 0 ) x = 0; if( y < 0 ) y = 0; if( y < static_cast(mpBuffer->buffer.size()) ) { if( x < static_cast(mpBuffer->buffer[y].size()) ) { if( mpBuffer->buffer[y][x].link > 0 ) { QStringList command = mpBuffer->mLinkStore[mpBuffer->buffer[y][x].link]; QString func; if( command.size() > 0 ) { func = command.at(0); mpHost->mLuaInterpreter.compileAndExecuteScript( func ); return; } } } } mMouseTracking = true; //int x = event->x() / mFontWidth; //int y = ( event->y() / mFontHeight ) + imageTopLine(); unHighlight( mSelectedRegion ); mSelectedRegion = QRegion( 0, 0, 0, 0 ); qDebug()<<"x="<setStatusTip(tr("copy selected text to clipboard")); connect( action, SIGNAL(triggered()), this, SLOT(slot_copySelectionToClipboard())); QAction * action2 = new QAction("copy HTML", this ); action->setStatusTip(tr("copy selected text with colors as HTML (for web browsers)")); connect( action2, SIGNAL(triggered()), this, SLOT(slot_copySelectionToClipboardHTML())); QMenu * popup = new QMenu( this ); popup->addAction( action ); popup->addAction( action2 ); popup->popup( mapToGlobal( event->pos() ), action ); event->accept(); return; } if( event->button() == Qt::MidButton ) { mpConsole->console2->mCursorY = mpConsole->buffer.size();// mpConsole->console2->hide(); mpBuffer->mCursorY = mpBuffer->size(); mpConsole->console->mCursorY = mpConsole->buffer.size();// mpConsole->console->mIsTailMode = true; mpConsole->console->updateScreenView(); mpConsole->console->forceUpdate(); event->accept(); return; } QWidget::mousePressEvent( event ); } void TTextEdit::slot_copySelectionToClipboard() { copySelectionToClipboard(); } void TTextEdit::slot_copySelectionToClipboardHTML() { copySelectionToClipboardHTML(); } void TTextEdit::copySelectionToClipboard() { if( ( mPA.y() == mPB.y() ) && ( mPA.x() > mPB.x() ) ) { swap( mPA, mPB ); } if( mPA.y() > mPB.y() ) { swap( mPA, mPB ); } QString text; for( int y=mPA.y(); y<=mPB.y()+1; y++ ) { if( y >= static_cast(mpBuffer->buffer.size()) ) { QClipboard * clipboard = QApplication::clipboard(); clipboard->setText( text ); mSelectedRegion = QRegion( 0, 0, 0, 0 ); forceUpdate(); return; } int x = 0; if( y == mPA.y() ) x = mPA.x(); while( x < static_cast( mpBuffer->buffer[y].size() ) ) { text.append( mpBuffer->lineBuffer[y].at(x) ); if( y >= mPB.y() ) { if( ( x == mPB.x() ) || ( x >= static_cast( mpBuffer->buffer[y].size() - 1 ) ) ) { QClipboard * clipboard = QApplication::clipboard(); clipboard->setText( text ); mSelectedRegion = QRegion( 0, 0, 0, 0 ); forceUpdate(); return; } } x++; } text.append("\n"); } } void TTextEdit::copySelectionToClipboardHTML() { if( ( mPA.y() == mPB.y() ) && ( mPA.x() > mPB.x() ) ) { swap( mPA, mPB ); } if( mPA.y() > mPB.y() ) { swap( mPA, mPB ); } QString text = ""); for( int y=mPA.y(); y<=mPB.y(); y++ ) { if( y >= static_cast(mpBuffer->buffer.size()) ) return; int x = 0; if( y == mPA.y() ) { x = mPA.x(); text.append(mpBuffer->bufferToHtml( QPoint(x,y), QPoint(-1,y))); } else if ( y == mPB.y() ) { x = mPB.x(); text.append(mpBuffer->bufferToHtml( QPoint(0,y), QPoint(x,y))); } else text.append(mpBuffer->bufferToHtml( QPoint(0,y), QPoint(-1,y))); } QClipboard * clipboard = QApplication::clipboard(); clipboard->setText( text ); mSelectedRegion = QRegion( 0, 0, 0, 0 ); forceUpdate(); return; } void TTextEdit::mouseReleaseEvent( QMouseEvent * event ) { if( event->button() == Qt::LeftButton ) { mMouseTracking = false; } if( ! mpConsole->mIsSubConsole && ! mpConsole->mIsDebugConsole ) { TEvent me; me.mArgumentList.append( "sysWindowMouseReleaseEvent" ); switch( event->button() ) { case Qt::LeftButton: me.mArgumentList.append( QString::number(1) ); break; case Qt::RightButton: me.mArgumentList.append( QString::number(2) ); break; case Qt::MidButton: me.mArgumentList.append( QString::number(3) ); break; default: me.mArgumentList.append( QString::number(0) ); break; } me.mArgumentList.append( QString::number(event->x()) ); me.mArgumentList.append( QString::number(event->y()) ); me.mArgumentTypeList.append( ARGUMENT_TYPE_STRING ); me.mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); me.mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); me.mArgumentTypeList.append( ARGUMENT_TYPE_NUMBER ); mpHost->raiseEvent( &me ); } } void TTextEdit::showEvent( QShowEvent * event ) { updateScreenView(); mScrollVector=0; repaint(); QWidget::showEvent( event ); } void TTextEdit::resizeEvent( QResizeEvent * event ) { updateScreenView(); if( ! mIsSplitScreen && ! mIsDebugConsole ) { mpHost->adjustNAWS(); } QWidget::resizeEvent( event ); } void TTextEdit::wheelEvent ( QWheelEvent * e ) { //int delta = e->delta() / 8 / 15; int k = 3;//10 + (abs(delta) * 50) - 50; if( e->delta() < 0 ) { mpConsole->scrollDown( abs( k ) ); e->accept(); return; } if( e->delta() > 0 ) { mpConsole->scrollUp( k ); e->accept(); return; } e->ignore(); return; } int TTextEdit::imageTopLine() { if( ! mIsSplitScreen ) { mCursorY = mpBuffer->mCursorY; } if( mCursorY > mScreenHeight ) { if( isTailMode() ) { if( mpBuffer->lineBuffer[mpBuffer->getLastLineNumber()] == "" ) { return mCursorY - mScreenHeight - 1; } else { return mCursorY - mScreenHeight; } } else { return mCursorY - mScreenHeight; } } else { return 0; } } bool TTextEdit::isTailMode() { /*if( ( mpBuffer->mCursorY >= (int) mpBuffer->size()-1 ) || ( mIsTailMode ) || ( (int)mpBuffer->size() <= mScreenHeight) )*/ if( mIsTailMode ) { mIsTailMode = true; return true; } else { return false; } } int TTextEdit::bufferScrollUp( int lines ) { if( (mpBuffer->mCursorY - lines) >= mScreenHeight ) { mpBuffer->mCursorY -= lines; mIsTailMode = true; return lines; } else { mpBuffer->mCursorY -= lines; if( mCursorY < 0 ) { int delta = mCursorY; mpBuffer->mCursorY = 0; return delta; } else return 0; } } int TTextEdit::bufferScrollDown( int lines ) { if( ( mpBuffer->mCursorY + lines ) < (int)(mpBuffer->size()-1 - mScreenHeight) ) { if( mpBuffer->mCursorY + lines < mScreenHeight + lines ) { mpBuffer->mCursorY = mScreenHeight+lines; if( mpBuffer->mCursorY > (int)(mpBuffer->size()-1 ) ) { mpBuffer->mCursorY = mpBuffer->size()-1; mIsTailMode = true; } } else { mpBuffer->mCursorY += lines; mIsTailMode = false; } return lines; } else { mIsTailMode = true; mpBuffer->mCursorY = mpBuffer->lineBuffer.size(); forceUpdate(); return 0; } } mudlet-2.1/src/dlgOptionsAreaTriggers.h0000644000175000017500000000344711513237311017545 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef DLG_OptionsAreaTriggers_H #define DLG_OptionsAreaTriggers_H #include "ui_options_area_triggers.h" #include #include "TTrigger.h" //#include //#include class dlgOptionsAreaTriggers : public QWidget , public Ui::options_area_triggers { Q_OBJECT public: dlgOptionsAreaTriggers(QWidget *); signals: public slots: }; #endif mudlet-2.1/src/TimerUnit.h0000644000175000017500000000750111647202526015046 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _TIMER_UNIT_H #define _TIMER_UNIT_H #include "TTimer.h" #include #include #include #include #include #include class TTimer; class Host; class TimerUnit { friend class XMLexport; friend class XMLimport; public: TimerUnit( Host * pHost ) : mpHost(pHost), mMaxID(0), statsActiveTriggers(0), statsTriggerTotal(0), statsTempTriggers(0) {;} void removeAllTempTimers(); std::list getTimerRootNodeList() { return mTimerRootNodeList; } TTimer * getTimer( int id ); TTimer * findTimer( QString & name ); void compileAll(); bool enableTimer( QString & ); bool disableTimer( QString & ); bool killTimer( QString & name ); bool registerTimer( TTimer * pT ); void unregisterTimer( TTimer * pT ); void reParentTimer( int childID, int oldParentID, int newParentID, int parentPosition = -1, int childPosition = -1 ); void stopAllTriggers(); void reenableAllTriggers(); void markCleanup( TTimer * ); void doCleanup(); QString assembleReport(); qint64 getNewID(); void uninstall( QString ); void _uninstall( TTimer * pChild, QString packageName ); QMultiMap mLookupTable; QMutex mTimerUnitLock; int statsActiveTriggers; int statsTriggerTotal; int statsTempTriggers; QList uninstallList; private: TimerUnit(){;} void _assembleReport(TTimer *); TTimer * getTimerPrivate( int id ); void addTimerRootNode( TTimer * pT, int parentPosition = -1, int childPosition = -1 ); void addTimer( TTimer * pT ); void _removeTimerRootNode( TTimer * pT ); void _removeTimer( TTimer *); Host * mpHost; QMap mTimerMap; std::list mTimerRootNodeList; qint64 mMaxID; bool mModuleMember; std::list mCleanupList; }; #endif mudlet-2.1/src/TAction.h0000644000175000017500000001444412070466512014471 0ustar csmallcsmall #ifndef _TACTION_H_ #define _TACTION_H_ /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "Tree.h" #include #include "Host.h" #include #include "TToolBar.h" #include "TFlipButton.h" #include class TAction : public Tree, QObject { friend class XMLexport; friend class XMLimport; public: virtual ~TAction(); TAction( TAction * parent, Host * pHost ); TAction( QString name, Host * pHost ); TAction & clone(const TAction & ); void compileAll(); QString getName() { return mName; } void setName( QString name ) { mName = name; } void setButtonColor( QColor c ) { mButtonColor = c; } QColor getButtonColor() { return mButtonColor; } void setButtonRotation( int r ) { mButtonRotation = r; } int getButtonRotation() { return mButtonRotation; } void setButtonColumns( int c ) { mButtonColumns = c; } int getButtonColumns() { return mButtonColumns; } bool getButtonFlat() { return mButtonFlat; } void setButtonFlat( bool flat ) { mButtonFlat = flat; } void setSizeX( int s ) { mSizeX = s; } int getSizeX() { return mSizeX; } void setSizeY( int s ) { mSizeY = s; } int getSizeY() { return mSizeY; } void fillMenu( TEasyButtonBar * pT, QMenu * menu ); void compile(); bool compileScript(); void execute(QStringList &); void _execute(QStringList &); QString getIcon() { return mIcon; } void setIcon( QString & icon ) { mIcon = icon; } QString getScript() { return mScript; } bool setScript( QString & script ); QString getCommandButtonUp() { return mCommandButtonUp; } void setCommandButtonUp( QString cmd ) { mCommandButtonUp = cmd; } void setCommandButtonDown( QString command ) { mCommandButtonDown = command; } QString getCommandButtonDown() { return mCommandButtonDown; } bool isFolder() { return mIsFolder; } bool isPushDownButton() { return mIsPushDownButton; } void setIsPushDownButton( bool b ) { mIsPushDownButton = b; } void setIsFolder( bool b ) { mIsFolder = b; } bool registerAction(); void insertActions( mudlet * pMainWindow, TToolBar * pT, QMenu * menu ); void expandToolbar( mudlet * pMainWindow, TToolBar * pT, QMenu * menu ); void insertActions( mudlet * pMainWindow, TEasyButtonBar * pT, QMenu * menu ); void expandToolbar( mudlet * pMainWindow, TEasyButtonBar * pT, QMenu * menu ); bool isClone(TAction & ) const; TToolBar * mpToolBar; TEasyButtonBar * mpEasyButtonBar; int mButtonState; int mPosX; int mPosY; int mOrientation; int mLocation; QString mName; QString mCommandButtonUp; QString mCommandButtonDown; QRegExp mRegex; QString mScript; bool mIsPushDownButton; bool mIsFolder; bool mNeedsToBeCompiled; QString mIcon; QIcon mIconPix; int mButtonRotation; int mButtonColumns; bool mButtonFlat; int mSizeX; int mSizeY; bool mIsLabel; bool mUseCustomLayout; QString css; QColor mButtonColor; Host * mpHost; bool exportItem; private: TAction(){}; QString mFuncName; bool mModuleMember; bool mModuleMasterFolder; }; #endif mudlet-2.1/src/dlgNotepad.h0000644000175000017500000000321211513237311015172 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn - KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _dlg_notepad_h #define _dlg_notepad_h class Host; #include "ui_notes_editor.h" class dlgNotepad : public QMainWindow , public Ui::NotesEditor { Q_OBJECT public: dlgNotepad( Host * ); void save(); void restore(); Host * mpHost; }; #endif mudlet-2.1/src/MudletCPack.cmake0000755000175000017500000000310711513237311016104 0ustar csmallcsmallSET(PACKAGE_NAME "Mudlet") SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../COPYING") SET(CPACK_PACKAGE_EXECUTABLES "mudlet" "Mudlet") SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Mudlet") SET(CPACK_PACKAGE_INSTALL_DIRECTORY "Mudlet") #SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/icons\\\\mudlet.bmp" ) SET(CPACK_CREATE_DESKTOP_LINKS "mudlet") SET(CPACK_PACKAGE_VENDOR "Mudlet") SET(CPACK_PACKAGE_VERSION_MAJOR "0") SET(CPACK_PACKAGE_VERSION_MINOR "0") SET(CPACK_PACKAGE_VERSION_PATCH "1") INSTALL(FILES LuaGlobal.lua DESTINATION bin) INSTALL(FILES mudlet_documentation.html DESTINATION bin) IF(WIN32 AND NOT UNIX) FIND_PACKAGE(MinGW REQUIRED) SET(CPACK_NSIS_INSTALLED_ICON_NAME "mudlet.exe") SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} Mudlet") SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.mudlet.org") SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.mudlet.org") SET(CPACK_NSIS_CONTACT "bruno@mudlet.org") INSTALL(PROGRAMS mudlet.exe DESTINATION bin) INSTALL(FILES ${QT_LIBRARY_DIR}/qscintilla2.dll DESTINATION bin) INSTALL(FILES ${QT_BINARY_DIR}/QtCore4.dll DESTINATION bin) INSTALL(FILES ${QT_BINARY_DIR}/QtGui4.dll DESTINATION bin) INSTALL(FILES ${QT_BINARY_DIR}/QtNetwork4.dll DESTINATION bin) INSTALL(FILES ${QT_BINARY_DIR}/QtWebKit4.dll DESTINATION bin) INSTALL(FILES ${LUA_INCLUDE_DIR}/lua51.dll DESTINATION bin) INSTALL(FILES ${CMAKE_MINGW_DLL} DESTINATION bin) ELSE(WIN32 AND NOT UNIX) SET(CPACK_STRIP_FILES "mudlet") SET(CPACK_SOURCE_STRIP_FILES "") ENDIF(WIN32 AND NOT UNIX) INCLUDE(CPack) INCLUDE(InstallRequiredSystemLibraries)mudlet-2.1/src/FontManager.h0000644000175000017500000000222011513237311015310 0ustar csmallcsmall/* * FontManager.h * * Copyright 2009 Vadim Peretokin * * Add your name to the copyright notice above if you do any work with * this file. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ #ifndef FONTMANAGER_H #define FONTMANAGER_H #include class FontManager { public: void addFonts(); void loadFonts(QString folder); }; #endif mudlet-2.1/src/TEvent.h0000644000175000017500000000321711513237311014323 0ustar csmallcsmall #ifndef _TEVENT_H_ #define _TEVENT_H_ /*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #define ARGUMENT_TYPE_NUMBER 0 #define ARGUMENT_TYPE_STRING 1 class TEvent { public: QStringList mArgumentList; QList mArgumentTypeList; }; #endif mudlet-2.1/src/dlgActionMainArea.cpp0000644000175000017500000000303011513237311016744 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "dlgActionMainArea.h" dlgActionMainArea::dlgActionMainArea(QWidget * pF) : QWidget(pF) { // init generated dialog setupUi(this); } mudlet-2.1/src/dlgTriggerEditor.cpp0000644000175000017500000100713012070466512016717 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "dlgTriggerEditor.h" #include "Host.h" //#include #include "HostManager.h" #include "TriggerUnit.h" #include "TTrigger.h" #include "TAction.h" #include //#include //#include #include #include #include #include "dlgTriggersMainArea.h" #include "dlgOptionsAreaTriggers.h" #include "dlgOptionsAreaAction.h" #include "dlgOptionsAreaTimers.h" #include "dlgOptionsAreaScripts.h" #include "dlgOptionsAreaAlias.h" #include "dlgAliasMainArea.h" #include "dlgActionMainArea.h" #include "dlgScriptsMainArea.h" #include "dlgSearchArea.h" #include "dlgKeysMainArea.h" #include "dlgOptionsAreaTimers.h" #include "TTreeWidget.h" #include "mudlet.h" #include "XMLexport.h" #include "XMLimport.h" #include "dlgColorTrigger.h" #include "dlgTriggerPatternEdit.h" #include "THighlighter.h" #include "TTextEdit.h" using namespace std; const int dlgTriggerEditor::cmTriggerView = 1; const int dlgTriggerEditor::cmTimerView = 2; const int dlgTriggerEditor::cmAliasView = 3; const int dlgTriggerEditor::cmScriptView = 4; const int dlgTriggerEditor::cmActionView = 5; const int dlgTriggerEditor::cmKeysView = 6; const QString msgInfoAddAlias = "Alias are input triggers. To make a new alias: 1. Define an input trigger pattern with a Perl regular expression. " \ "2. Define a command to send to the MUD in clear text instead of the alias patternor write a script for more complicated needs. " \ "3. Activate the alias. "\ "Check the manual for more information"; const QString msgInfoAddTrigger = "To add a new trigger: 1. Define a pattern that you want to trigger on. 2. select the appropriate pattern type."\ "3. Define a clear text command that you want to send to the MUD if the trigger finds the pattern in the text from the MUD or write a script."\ "4. Activate the trigger." \ "Check the manual for more information"; const QString msgInfoAddScript = "Check the manual for more information"; const QString msgInfoAddTimer = "Check the manual for more information"; const QString msgInfoAddButton = "To add a new button: 1. Add a new group to define a new Button bar in case you don't have any."\ "2. Add new buttons to a button bar." \ "Check the manual for more information"; const QString msgInfoAddKey = "To add a new key binding 1. add a new key 2. click on grab key and then press your key combination. NOTE: If you want to bind a key combination you must hold down the modifier keys (e.g. control, shift etc.) down before clicking on grab key. " \ "3. Define a command that is executed when the key is hit. 4. Activate the new key binding." \ "Check the manual for more information"; dlgTriggerEditor::dlgTriggerEditor( Host * pH ) : mCurrentAlias( 0 ) , mCurrentTrigger( 0 ) , mCurrentTimer( 0 ) , mCurrentAction( 0 ) , mCurrentScript( 0 ) , mCurrentKey( 0 ) , mpCurrentActionItem( 0 ) , mpCurrentKeyItem( 0 ) , mpCurrentTimerItem( 0 ) , mpCurrentScriptItem( 0 ) , mpCurrentTriggerItem( 0 ) , mpCurrentAliasItem( 0 ) , mpHost( pH ) { // init generated dialog setupUi(this); setUnifiedTitleAndToolBarOnMac( true ); //MAC OSX: make window moveable setWindowTitle( mpHost->getName() ); QIcon winIcon(":/icons/mudlet_editor.png"); setWindowIcon( winIcon ); QStatusBar * statusBar = new QStatusBar(this); statusBar->setSizeGripEnabled( true ); setStatusBar( statusBar ); statusBar->show(); mIsGrabKey = false; QVBoxLayout * pVB1 = new QVBoxLayout(mainArea); // system message area mpSystemMessageArea = new dlgSystemMessageArea( mainArea ); QSizePolicy sizePolicy6( QSizePolicy::Expanding, QSizePolicy::Fixed ); mpSystemMessageArea->setSizePolicy( sizePolicy6 ); pVB1->addWidget( mpSystemMessageArea ); connect( mpSystemMessageArea->messageAreaCloseButton, SIGNAL(pressed()), mpSystemMessageArea, SLOT(hide())); // main areas mpTriggersMainArea = new dlgTriggersMainArea( mainArea ); pVB1->setContentsMargins(0,0,0,0); QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); mpTriggersMainArea->setSizePolicy( sizePolicy ); pVB1->addWidget( mpTriggersMainArea ); //mIsTriggerMainAreaEditRegex = false; //mpTriggerMainAreaEditRegexItem = 0; mpTriggersMainArea->lineEdit_soundFile->hide(); //connect(mpTriggersMainArea->lineEdit, SIGNAL(returnPressed()), this, SLOT(slot_trigger_main_area_add_regex())); //connect(mpTriggersMainArea->listWidget_regex_list, SIGNAL(itemClicked ( QListWidgetItem *)), this, SLOT(slot_trigger_main_area_edit_regex(QListWidgetItem*))); connect(mpTriggersMainArea->pushButtonFgColor, SIGNAL(clicked()), this, SLOT(slot_colorizeTriggerSetFgColor())); connect(mpTriggersMainArea->pushButtonBgColor, SIGNAL(clicked()), this, SLOT(slot_colorizeTriggerSetBgColor())); connect(mpTriggersMainArea->pushButtonSound, SIGNAL(clicked()), this, SLOT(slot_soundTrigger())); mpTimersMainArea = new dlgTimersMainArea( mainArea ); QSizePolicy sizePolicy7(QSizePolicy::Expanding, QSizePolicy::Fixed); mpTimersMainArea->setSizePolicy( sizePolicy7 ); pVB1->addWidget( mpTimersMainArea ); mpAliasMainArea = new dlgAliasMainArea( mainArea ); QSizePolicy sizePolicy8(QSizePolicy::Expanding, QSizePolicy::Fixed); mpAliasMainArea->setSizePolicy( sizePolicy8 ); pVB1->addWidget( mpAliasMainArea ); mpActionsMainArea = new dlgActionMainArea( mainArea ); //QSizePolicy sizePolicy8(QSizePolicy::Expanding, QSizePolicy::Fixed); mpActionsMainArea->setSizePolicy( sizePolicy8 ); connect( mpActionsMainArea->pushButton_chose_icon, SIGNAL( pressed()), this, SLOT(slot_chose_action_icon())); connect( mpActionsMainArea->pushButton_color, SIGNAL(pressed()), this, SLOT(slot_choseButtonColor())); pVB1->addWidget( mpActionsMainArea ); mpKeysMainArea = new dlgKeysMainArea( mainArea ); mpKeysMainArea->setSizePolicy( sizePolicy8 ); pVB1->addWidget( mpKeysMainArea ); connect(mpKeysMainArea->pushButton_grabKey, SIGNAL(pressed()), this, SLOT(slot_grab_key())); mpScriptsMainArea = new dlgScriptsMainArea( mainArea ); QSizePolicy sizePolicy9(QSizePolicy::Expanding, QSizePolicy::Fixed); mpScriptsMainArea->setSizePolicy( sizePolicy9 ); pVB1->addWidget( mpScriptsMainArea ); mIsScriptsMainAreaEditHandler = false; mpScriptsMainAreaEditHandlerItem = 0; connect(mpScriptsMainArea->lineEdit, SIGNAL(returnPressed()), this, SLOT(slot_script_main_area_add_handler())); connect(mpScriptsMainArea->listWidget_registered_event_handlers, SIGNAL(itemClicked ( QListWidgetItem *)), this, SLOT(slot_script_main_area_edit_handler(QListWidgetItem*))); // source editor area mpSourceEditorArea = new dlgSourceEditorArea( mainArea ); QSizePolicy sizePolicy5(QSizePolicy::Expanding, QSizePolicy::Expanding); mpSourceEditorArea->setSizePolicy( sizePolicy5 ); pVB1->addWidget( mpSourceEditorArea ); QPlainTextEdit * editp = mpSourceEditorArea->editor; editp->setWordWrapMode( QTextOption::NoWrap ); //QLineEdit * mpCursorPositionIndicator = new QLineEdit; //(QMainWindow::statusBar())->addWidget( mpCursorPositionIndicator ); connect(editp,SIGNAL(cursorPositionChanged()), this, SLOT(slot_cursorPositionChanged())); // option areas QHBoxLayout * pHB2 = new QHBoxLayout(popupArea); QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Maximum); popupArea->setMinimumSize(200,60); // pHB2->setMaximumSize(170); pHB2->setSizeConstraint( QLayout::SetMaximumSize ); mpErrorConsole = new TConsole(mpHost,false, popupArea); mpErrorConsole->setWrapAt(100); mpErrorConsole->console->slot_toggleTimeStamps(); mpErrorConsole->print("*** starting new session ***\n"); pHB2->setContentsMargins(0,0,0,0); pHB2->addWidget( mpErrorConsole ); mpErrorConsole->show(); mpOptionsAreaTriggers = new dlgOptionsAreaTriggers( popupArea ); mpOptionsAreaTriggers->setSizePolicy( sizePolicy2 ); pHB2->addWidget( mpOptionsAreaTriggers ); mpOptionsAreaAlias = new dlgOptionsAreaAlias( popupArea ); mpOptionsAreaAlias->setSizePolicy( sizePolicy2 ); pHB2->addWidget( mpOptionsAreaAlias ); mpOptionsAreaActions = new dlgOptionsAreaAction( popupArea ); mpOptionsAreaActions->setSizePolicy( sizePolicy2 ); pHB2->addWidget( mpOptionsAreaActions ); mpOptionsAreaScripts = new dlgOptionsAreaScripts( popupArea ); mpOptionsAreaScripts->setSizePolicy( sizePolicy2 ); pHB2->addWidget( mpOptionsAreaScripts ); mpOptionsAreaTimers = new dlgOptionsAreaTimers( popupArea ); mpOptionsAreaTimers->setSizePolicy( sizePolicy2 ); pHB2->addWidget( mpOptionsAreaTimers ); mpSearchArea = tree_widget_search_results_main;//new dlgSearchArea( popupArea ); connect( messageAreaCloseButton, SIGNAL(clicked()), this, SLOT( slot_show_search_area())); //mpSearchArea->setSizePolicy( sizePolicy2 ); //pHB2->addWidget( mpSearchArea ); // additional settings treeWidget->setColumnCount(1); treeWidget->setIsTriggerTree(); treeWidget->setRootIsDecorated( false ); treeWidget->setHost( mpHost ); treeWidget->header()->hide(); connect( treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slot_itemClicked(QTreeWidgetItem*,int)) ); tree_widget_search_results_main->hide(); // hide search results mpOptionsAreaTriggers->hide(); mpOptionsAreaAlias->hide(); mpOptionsAreaScripts->hide(); mpOptionsAreaTimers->hide(); mpOptionsAreaActions->hide(); treeWidget_alias->hide(); treeWidget_alias->setHost( mpHost ); treeWidget_alias->setIsAliasTree(); treeWidget_alias->setColumnCount(1); treeWidget_alias->header()->hide(); treeWidget_alias->setRootIsDecorated( false ); connect( treeWidget_alias, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slot_itemClicked(QTreeWidgetItem*,int)) ); treeWidget_actions->hide(); treeWidget_actions->setHost( mpHost ); treeWidget_actions->setIsActionTree(); treeWidget_actions->setColumnCount(1); treeWidget_actions->header()->hide(); treeWidget_actions->setRootIsDecorated( false ); connect( treeWidget_actions, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slot_itemClicked(QTreeWidgetItem*,int)) ); treeWidget_timers->hide(); treeWidget_timers->setHost( mpHost ); treeWidget_timers->setIsTimerTree(); treeWidget_timers->setColumnCount(1); treeWidget_timers->header()->hide(); treeWidget_timers->setRootIsDecorated( false ); connect( treeWidget_timers, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slot_itemClicked(QTreeWidgetItem*,int)) ); treeWidget_keys->hide(); treeWidget_keys->setHost( mpHost ); treeWidget_keys->setIsKeyTree(); treeWidget_keys->setColumnCount(1); treeWidget_keys->header()->hide(); treeWidget_keys->setRootIsDecorated( false ); connect( treeWidget_keys, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slot_itemClicked(QTreeWidgetItem*,int)) ); treeWidget_scripts->hide(); treeWidget_scripts->setHost( mpHost ); treeWidget_scripts->setIsScriptTree(); treeWidget_scripts->setColumnCount(1); treeWidget_scripts->header()->hide(); treeWidget_scripts->setRootIsDecorated( false ); connect( treeWidget_scripts, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slot_itemClicked(QTreeWidgetItem*,int)) ); QAction * viewTriggerAction = new QAction(QIcon(":/icons/tools-wizard.png"), tr("Triggers"), this); viewTriggerAction->setStatusTip(tr("Show Triggers")); connect(viewTriggerAction, SIGNAL(triggered()), this, SLOT(slot_show_triggers() )); QAction * viewActionAction = new QAction(QIcon(":/icons/bookmarks.png"), tr("Buttons"), this); viewActionAction->setStatusTip(tr("Show Buttons")); connect(viewActionAction, SIGNAL(triggered()), this, SLOT(slot_show_actions() )); QAction * viewAliasAction = new QAction(QIcon(":/icons/system-users.png"), tr("Aliases"), this); viewAliasAction->setStatusTip(tr("Show Aliases")); viewAliasAction->setEnabled( true ); connect( viewAliasAction, SIGNAL(triggered()), this, SLOT( slot_show_aliases())); QAction * showTimersAction = new QAction(QIcon(":/icons/chronometer.png"), tr("Timers"), this); showTimersAction->setStatusTip(tr("Show Timers")); connect( showTimersAction, SIGNAL(triggered()), this, SLOT( slot_show_timers())); QAction * viewScriptsAction = new QAction(QIcon(":/icons/document-properties.png"), tr("Scripts"), this); viewScriptsAction->setEnabled( true ); viewScriptsAction->setStatusTip(tr("Show Scripts")); connect( viewScriptsAction, SIGNAL(triggered()), this, SLOT( slot_show_scripts())); QAction * viewKeysAction = new QAction(QIcon(":/icons/preferences-desktop-keyboard.png"), tr("Keys"), this); viewKeysAction->setStatusTip(tr("Keybindings")); viewKeysAction->setEnabled( true ); connect( viewKeysAction, SIGNAL(triggered()), this, SLOT( slot_show_keys())); QAction * toggleActiveAction = new QAction(QIcon(":/icons/document-encrypt.png"), tr("Activate"), this); toggleActiveAction->setStatusTip(tr("Toggle Active or Non-Active Mode for Triggers, Scripts etc.")); connect( toggleActiveAction, SIGNAL(triggered()), this, SLOT( slot_toggle_active())); connect( treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), SLOT( slot_toggle_active())); connect( treeWidget_alias, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), SLOT( slot_toggle_active())); connect( treeWidget_timers, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), SLOT( slot_toggle_active())); connect( treeWidget_scripts, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), SLOT( slot_toggle_active())); connect( treeWidget_actions, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), SLOT( slot_toggle_active())); connect( treeWidget_keys, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), SLOT( slot_toggle_active())); QAction * addTriggerAction = new QAction(QIcon(":/icons/document-new.png"), tr("Add Item"), this); addTriggerAction->setStatusTip(tr("Add new Trigger, Script, Alias or Filter")); connect( addTriggerAction, SIGNAL(triggered()), this, SLOT( slot_add_new())); QAction * deleteTriggerAction = new QAction(QIcon(":/icons/edit-delete-shred.png"), tr("Delete Item"), this); deleteTriggerAction->setStatusTip(tr("Delete Trigger, Script, Alias or Filter")); connect( deleteTriggerAction, SIGNAL(triggered()), this, SLOT( slot_delete_item())); QAction * addFolderAction = new QAction(QIcon(":/icons/folder-new.png"), tr("Add Group"), this); addFolderAction->setStatusTip(tr("Add new Group")); connect( addFolderAction, SIGNAL(triggered()), this, SLOT( slot_add_new_folder())); QAction * showSearchAreaAction = new QAction(QIcon(":/icons/edit-find-user.png"), tr("Search"), this); //showSearchAreaAction->setShortcut(tr("Ctrl+F")); showSearchAreaAction->setStatusTip(tr("Show Search Results List")); connect( showSearchAreaAction, SIGNAL(triggered()), this, SLOT( slot_show_search_area())); QAction * saveAction = new QAction(QIcon(":/icons/document-save-as.png"), tr("Save Item"), this); //saveAction->setShortcut(tr("Ctrl+S")); saveAction->setStatusTip(tr("Save Edited Trigger, Script, Alias etc. If information has been edited, it must be saved or the changes will be lost.")); connect( saveAction, SIGNAL(triggered()), this, SLOT( slot_save_edit() )); QAction * importAction = new QAction(QIcon(":/icons/import.png"), tr("Import"), this); importAction->setEnabled( true ); connect( importAction, SIGNAL(triggered()), this, SLOT( slot_import())); QAction * exportAction = new QAction(QIcon(":/icons/export.png"), tr("Export"), this); exportAction->setEnabled( true ); connect( exportAction, SIGNAL(triggered()), this, SLOT( slot_export())); QAction * saveMenu = new QAction(QIcon(":/icons/document-save-all.png"), tr("Save Profile"), this); saveMenu->setEnabled( true ); connect( saveMenu, SIGNAL(triggered()), this, SLOT( slot_profileSaveAction())); QAction * profileSaveAction = new QAction(QIcon(":/icons/document-save-all.png"), tr("Save Profile"), this); profileSaveAction->setEnabled( true ); connect( profileSaveAction, SIGNAL(triggered()), this, SLOT( slot_profileSaveAction())); QAction * saveProfileAsAction = new QAction(QIcon(":/icons/utilities-file-archiver.png"), tr("Save Profile As"), this); saveProfileAsAction->setEnabled( true ); connect( saveProfileAsAction, SIGNAL(triggered()), this, SLOT( slot_profileSaveAsAction())); QAction * viewStatsAction = new QAction(QIcon(":/icons/view-statistics.png"), tr("Statistics"), this); viewStatsAction->setEnabled( true ); connect( viewStatsAction, SIGNAL(triggered()), this, SLOT( slot_viewStatsAction())); QAction * viewErrorsAction = new QAction(QIcon(":/icons/errors.png"), tr("errors"), this); viewErrorsAction->setEnabled( true ); connect( viewErrorsAction, SIGNAL(triggered()), this, SLOT( slot_viewErrorsAction())); //Action * saveProfileMenu = new QMenu( this ); //saveProfileMenu->addAction( profileSaveAction ); //saveProfileMenu->addAction( saveProfileAsAction ); //saveMenu->setMenu( saveProfileMenu ); /*QAction * actionProfileBackup = new QAction(QIcon(":/icons/utilities-file-archiver.png"), tr("Backup Profile"), this); actionProfileBackup->setStatusTip(tr("Backup Profile"));*/ QAction * showDebugAreaAction = new QAction(QIcon(":/icons/tools-report-bug.png"), tr("Debug"), this); showDebugAreaAction->setEnabled( true ); showDebugAreaAction->setToolTip(tr("Activates Debug Messages -> system will be *MUCH* slower")); connect( showDebugAreaAction, SIGNAL(triggered()), this, SLOT( slot_debug_mode() )); QAction * addTriggerMenuAction = new QAction(QIcon(":/icons/tools-wizard.png"), tr("Triggers"), this); viewTriggerAction->setStatusTip(tr("Add Trigger")); connect(addTriggerMenuAction, SIGNAL(triggered()), this, SLOT(slot_addTrigger())); QAction * addAliasMenuAction = new QAction(QIcon(":/icons/system-users.png"), tr("Aliases"), this); addAliasMenuAction->setStatusTip(tr("Add Alias")); addAliasMenuAction->setEnabled( true ); connect( addAliasMenuAction, SIGNAL(triggered()), this, SLOT( slot_addAlias())); QAction * addTimersMenuAction = new QAction(QIcon(":/icons/chronometer.png"), tr("Timers"), this); addTimersMenuAction->setStatusTip(tr("Add Timer")); addTimersMenuAction->setEnabled( true ); connect( addTimersMenuAction, SIGNAL(triggered()), this, SLOT( slot_addTimer())); QAction * addScriptsMenuAction = new QAction(QIcon(":/icons/document-properties.png"), tr("Scripts"), this); addScriptsMenuAction->setStatusTip(tr("Add Script")); addScriptsMenuAction->setEnabled( true ); connect( addScriptsMenuAction, SIGNAL(triggered()), this, SLOT( slot_addScript())); QAction * addKeysMenuAction = new QAction(QIcon(":/icons/preferences-desktop-keyboard.png"), tr("Keys"), this); addKeysMenuAction->setStatusTip(tr("Add Keys")); addKeysMenuAction->setEnabled( true ); connect( addKeysMenuAction, SIGNAL(triggered()), this, SLOT( slot_addKey())); QMenu * addTriggerMenu = new QMenu( this ); addTriggerMenu->addAction( addTriggerMenuAction ); addTriggerMenu->addAction( addTimersMenuAction ); addTriggerMenu->addAction( addScriptsMenuAction ); addTriggerMenu->addAction( addAliasMenuAction ); addTriggerMenu->addAction( addKeysMenuAction ); //addTriggerAction->setMenu( addTriggerMenu ); QAction * addTriggerGroupMenuAction = new QAction(QIcon(":/icons/tools-wizard.png"), tr("Triggers"), this); addTriggerGroupMenuAction->setStatusTip(tr("Add Trigger Group")); connect(addTriggerGroupMenuAction, SIGNAL(triggered()), this, SLOT(slot_addTriggerGroup())); QAction * addAliasGroupMenuAction = new QAction(QIcon(":/icons/system-users.png"), tr("Aliases"), this); addAliasGroupMenuAction->setStatusTip(tr("Add Alias Group")); addAliasGroupMenuAction->setEnabled( true ); connect( addAliasGroupMenuAction, SIGNAL(triggered()), this, SLOT( slot_addAliasGroup())); QAction * addTimersGroupMenuAction = new QAction(QIcon(":/icons/chronometer.png"), tr("Timers"), this); addTimersGroupMenuAction->setStatusTip(tr("Add Timer Group")); addTimersGroupMenuAction->setEnabled( true ); connect( addTimersGroupMenuAction, SIGNAL(triggered()), this, SLOT( slot_addTimerGroup())); QAction * addScriptsGroupMenuAction = new QAction(QIcon(":/icons/document-properties.png"), tr("Scripts"), this); addScriptsGroupMenuAction->setStatusTip(tr("Add Script Group")); addScriptsGroupMenuAction->setEnabled( true ); connect( addScriptsGroupMenuAction, SIGNAL(triggered()), this, SLOT( slot_addScriptGroup())); //QAction * addFiltersGroupMenuAction = new QAction(QIcon(":/icons/view-filter.png"), tr("Filters"), this); //addFiltersGroupMenuAction->setStatusTip(tr("Add Filter Group")); //addFiltersGroupMenuAction->setEnabled( false ); //connect( viewFiltersAction, SIGNAL(triggered()), this, SLOT( showFiltersView())); QMenu * addTriggerGroupMenu = new QMenu( this ); addTriggerGroupMenu->addAction( addTriggerGroupMenuAction ); addTriggerGroupMenu->addAction( addTimersGroupMenuAction ); addTriggerGroupMenu->addAction( addScriptsGroupMenuAction ); addTriggerGroupMenu->addAction( addAliasGroupMenuAction ); //addTriggerGroupMenu->addAction( addFiltersGroupMenuAction ); //addFolderAction->setMenu( addTriggerGroupMenu ); //toolBar->addSeparator(); toolBar = new QToolBar(); toolBar->setIconSize(QSize(mudlet::self()->mMainIconSize*8,mudlet::self()->mMainIconSize*8)); toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); toolBar->setMovable(true); toolBar->addAction( toggleActiveAction ); toolBar->addAction( saveAction ); toolBar->addSeparator(); toolBar->addAction( addTriggerAction ); toolBar->addAction( addFolderAction ); toolBar->addSeparator(); toolBar->addAction( deleteTriggerAction ); toolBar->addAction( importAction ); toolBar->addAction( exportAction ); toolBar->addAction( saveProfileAsAction ); toolBar->addAction( profileSaveAction ); toolBar2 = new QToolBar(); toolBar2->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); toolBar2->setIconSize(QSize(mudlet::self()->mMainIconSize*8,mudlet::self()->mMainIconSize*8)); toolBar2->addAction( viewTriggerAction ); toolBar2->addAction( viewAliasAction ); toolBar2->addAction( viewScriptsAction ); toolBar2->addAction( showTimersAction ); toolBar2->addAction( viewKeysAction ); toolBar2->addAction( viewActionAction ); toolBar2->addAction( showSearchAreaAction ); toolBar2->addAction( viewErrorsAction ); toolBar2->addAction( viewStatsAction ); toolBar2->addAction( showDebugAreaAction ); toolBar2->setMovable( true ); toolBar2->setOrientation(Qt::Vertical); QMainWindow::addToolBar(Qt::LeftToolBarArea, toolBar2 ); QMainWindow::addToolBar(Qt::TopToolBarArea, toolBar ); mpSourceEditorArea->editor->setFont( mpHost->mDisplayFont ); /*mpSourceEditorArea->script_scintilla->setUtf8( true ); setFont( QFont("Bitstream Vera Sans Mono", 10, QFont::Courier ) ); mpSourceEditorArea->script_scintilla->setFont( QFont("Bitstream Vera Sans Mono", 10, QFont::Courier ) ); mpLuaLexer = new QsciLexerLua(this); mpLuaLexer->setFont( QFont("Bitstream Vera Sans Mono", 10, QFont::Courier ) ); mpSourceEditorArea->script_scintilla->setLexer( mpLuaLexer ); mpSourceEditorArea->script_scintilla->setAutoCompletionThreshold( 3 ); if( mpHost->mNoAntiAlias ) mpSourceEditorArea->script_scintilla->setAutoCompletionSource( QsciScintilla::AcsAll ); mpSourceEditorArea->script_scintilla->setMarginLineNumbers( 1, true ); mpSourceEditorArea->script_scintilla->setMarginWidth( 1, 40 ); mpSourceEditorArea->script_scintilla->setMarginWidth( 2, 20 ); mpSourceEditorArea->script_scintilla->setMarginLineNumbers( 2, false );*/ connect( comboBox_search_triggers, SIGNAL( activated( const QString )), this, SLOT(slot_search_triggers( const QString ) ) ); connect( this, SIGNAL( update() ), this, SLOT( slot_update() ) ); connect( treeWidget, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), this, SLOT( slot_trigger_clicked( QTreeWidgetItem *, int) ) ); connect( treeWidget_keys, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), this, SLOT( slot_key_clicked( QTreeWidgetItem *, int) ) ); connect( treeWidget_timers, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), this, SLOT( slot_timer_clicked( QTreeWidgetItem *, int) ) ); connect( treeWidget_scripts, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), this, SLOT( slot_scripts_clicked( QTreeWidgetItem *, int) ) ); connect( treeWidget_alias, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), this, SLOT( slot_alias_clicked( QTreeWidgetItem *, int) ) ); connect( treeWidget_actions, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), this, SLOT( slot_action_clicked( QTreeWidgetItem *, int) ) ); connect( this, SIGNAL (accept()), this, SLOT (slot_connection_dlg_finnished())); //connect( mpSearchArea, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT( slot_item_clicked_search_list(QTreeWidgetItem*, int))); connect( tree_widget_search_results_main, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT( slot_item_clicked_search_list(QTreeWidgetItem*, int))); //connect( mpTriggersMainArea->toolButton_add, SIGNAL(pressed()), this, SLOT(slot_trigger_main_area_add_regex())); //connect( mpTriggersMainArea->toolButton_update, SIGNAL(pressed()), this, SLOT(slot_trigger_main_area_add_regex())); //connect( mpTriggersMainArea->toolButton_remove, SIGNAL(pressed()), this, SLOT( slot_trigger_main_area_delete_regex())); connect( mpScriptsMainArea->toolButton_add, SIGNAL(pressed()), this, SLOT(slot_script_main_area_add_handler())); connect( mpScriptsMainArea->toolButton_remove, SIGNAL(pressed()), this, SLOT( slot_script_main_area_delete_handler())); mpTriggersMainArea->hide(); mpTimersMainArea->hide(); mpScriptsMainArea->hide(); mpAliasMainArea->hide(); mpActionsMainArea->hide(); mpKeysMainArea->hide(); mpSourceEditorArea->hide(); mpSystemMessageArea->hide(); mpOptionsAreaTriggers->hide(); mpOptionsAreaAlias->hide(); mpOptionsAreaActions->hide(); mpOptionsAreaScripts->hide(); mpOptionsAreaTimers->hide(); treeWidget->show(); treeWidget_alias->hide(); treeWidget_actions->hide(); treeWidget_timers->hide(); treeWidget_scripts->hide(); treeWidget_keys->hide(); popupArea->hide(); frame_4->hide(); mpSearchArea->hide(); readSettings(); setTBIconSize( 0 ); //connect( mpTriggersMainArea->listWidget_regex_list, SIGNAL(cellChanged(int,int)), this, SLOT(slot_set_pattern_type_color(int,int))); tree_widget_search_results_main->setColumnCount( 4 ); QStringList labelList; labelList << "Type" << "Name" << "Where" << "What"; tree_widget_search_results_main->setHeaderLabels( labelList ); mpScrollArea = mpTriggersMainArea->scrollArea; HpatternList = new QWidget; QVBoxLayout * lay1 = new QVBoxLayout( HpatternList ); lay1->setContentsMargins(0,0,0,0); lay1->setSpacing(0); mpScrollArea->setWidget( HpatternList ); for( int i=0; i<50; i++) { dlgTriggerPatternEdit * pItem = new dlgTriggerPatternEdit(HpatternList); QStringList _patternList; _patternList << "substring" << "perl regex" << "begin of line substring" << "exact match" << "Lua function" << "line spacer" << "color trigger"; QComboBox * pBox = pItem->patternType; pBox->addItems( _patternList ); pBox->setItemData(0, QVariant(i) ); connect( pBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slot_set_pattern_type_color(int))); connect( pItem->fgB, SIGNAL(pressed()), this, SLOT(slot_color_trigger_fg())); connect( pItem->bgB, SIGNAL(pressed()), this, SLOT(slot_color_trigger_bg())); HpatternList->layout()->addWidget( pItem ); mTriggerPatternEdit.push_back( pItem ); pItem->mRow = i; pItem->fgB->hide(); pItem->bgB->hide(); pItem->number->setText( QString::number( i ) ); pItem->number->show(); } } void dlgTriggerEditor::slot_viewStatsAction() { mpHost->mpConsole->showStatistics(); mudlet::self()->raise(); mudlet::self()->activateWindow(); mudlet::self()->raise(); } void dlgTriggerEditor::slot_viewErrorsAction() { if( frame_4->isHidden() )frame_4->show(); else frame_4->hide(); mpErrorConsole->show(); popupArea->show(); } void dlgTriggerEditor::setTBIconSize( int s ) { if( mudlet::self()->mMainIconSize > 2 ) { toolBar->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); toolBar2->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); } else { toolBar->setToolButtonStyle( Qt::ToolButtonIconOnly ); toolBar2->setToolButtonStyle( Qt::ToolButtonIconOnly ); } toolBar->setIconSize(QSize(mudlet::self()->mMainIconSize*8,mudlet::self()->mMainIconSize*8)); toolBar2->setIconSize(QSize(mudlet::self()->mMainIconSize*8,mudlet::self()->mMainIconSize*8)); treeWidget->setIconSize(QSize(mudlet::self()->mTEFolderIconSize*8,mudlet::self()->mTEFolderIconSize*8)); treeWidget_alias->setIconSize(QSize(mudlet::self()->mTEFolderIconSize*8,mudlet::self()->mTEFolderIconSize*8)); treeWidget_timers->setIconSize(QSize(mudlet::self()->mTEFolderIconSize*8,mudlet::self()->mTEFolderIconSize*8)); treeWidget_scripts->setIconSize(QSize(mudlet::self()->mTEFolderIconSize*8,mudlet::self()->mTEFolderIconSize*8)); treeWidget_keys->setIconSize(QSize(mudlet::self()->mTEFolderIconSize*8,mudlet::self()->mTEFolderIconSize*8)); treeWidget_actions->setIconSize(QSize(mudlet::self()->mTEFolderIconSize*8,mudlet::self()->mTEFolderIconSize*8)); } void dlgTriggerEditor::slot_choseButtonColor() { QColor color = QColorDialog::getColor(); QPalette palette; palette.setColor( QPalette::Button, color ); mpActionsMainArea->pushButton_color->setPalette( palette ); } void dlgTriggerEditor::closeEvent(QCloseEvent *event) { writeSettings(); event->accept(); } void dlgTriggerEditor::readSettings() { QSettings settings("Mudlet", "Mudlet 1.0"); QPoint pos = settings.value("script_editor_pos", QPoint(10, 10)).toPoint(); QSize size = settings.value("script_editor_size", QSize(600, 400)).toSize(); resize( size ); move( pos ); } void dlgTriggerEditor::writeSettings() { QSettings settings("Mudlet", "Mudlet 1.0"); settings.setValue("script_editor_pos", pos()); settings.setValue("script_editor_size", size()); } void dlgTriggerEditor::slot_switchToExpertMonde() { // toolButton_add_trigger->show(); //toolButton_search_area->show(); //toolButton_add_trigger_group->show(); //toolButton_options_area->show(); //toolButton_toggle_active_trigger->show(); //toolButton_delete_trigger->show(); } void dlgTriggerEditor::slot_item_clicked_search_list(QTreeWidgetItem* pItem, int mode ) { qDebug()<<"dlgTriggerEditor::slot_item_clicked_search_list item="<text(0); if( pItem->text(0) == QString("Trigger") ) { QList foundItemsList = treeWidget->findItems( pItem->text(1), Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive, 0); for( int i=0; idata(0, Qt::UserRole).toInt(); int idSearch = pItem->data(0, Qt::UserRole).toInt(); if( idTree == idSearch ) { treeWidget->setCurrentItem( pI, 0 ); treeWidget->scrollToItem( pI ); slot_show_triggers(); slot_trigger_clicked( pI, 0 ); return; } } } if( pItem->text(0) == QString("Alias") ) { QList foundItemsList = treeWidget_alias->findItems( pItem->text(1), Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive, 0); for( int i=0; idata(0, Qt::UserRole).toInt(); int idSearch = pItem->data(0, Qt::UserRole).toInt(); if( idTree == idSearch ) { treeWidget_alias->setCurrentItem( pI, 0 ); treeWidget_alias->scrollToItem( pI ); slot_show_aliases(); slot_alias_clicked( pI, 0 ); return; } } } if( pItem->text(0) == QString("Script") ) { QList foundItemsList = treeWidget_scripts->findItems( pItem->text(1), Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive, 0); for( int i=0; idata(0, Qt::UserRole).toInt(); int idSearch = pItem->data(0, Qt::UserRole).toInt(); if( idTree == idSearch ) { treeWidget_scripts->setCurrentItem( pI, 0 ); treeWidget_scripts->scrollToItem( pI ); slot_show_scripts(); slot_scripts_clicked( pI, 0 ); return; } } return; } if( pItem->text(0) == QString("Button") ) { QList foundItemsList = treeWidget_actions->findItems( pItem->text(1), Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive, 0); for( int i=0; idata(0, Qt::UserRole).toInt(); int idSearch = pItem->data(0, Qt::UserRole).toInt(); if( idTree == idSearch ) { treeWidget_actions->setCurrentItem( pI, 0 ); treeWidget_actions->scrollToItem( pI ); slot_show_actions(); slot_action_clicked( pI, 0 ); return; } } return; } if( pItem->text(0) == QString("Timer") ) { QList foundItemsList = treeWidget_timers->findItems( pItem->text(1), Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive, 0); for( int i=0; idata(0, Qt::UserRole).toInt(); int idSearch = pItem->data(0, Qt::UserRole).toInt(); if( idTree == idSearch ) { treeWidget_timers->setCurrentItem( pI, 0 ); treeWidget_timers->scrollToItem( pI ); slot_show_timers(); slot_timer_clicked( pI, 0 ); return; } } return; } if( pItem->text(0) == QString("Key") ) { QList foundItemsList = treeWidget_keys->findItems( pItem->text(1), Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive, 0); for( int i=0; idata(0, Qt::UserRole).toInt(); int idSearch = pItem->data(0, Qt::UserRole).toInt(); if( idTree == idSearch ) { treeWidget_keys->setCurrentItem( pI, 0 ); treeWidget_keys->scrollToItem( pI ); slot_show_keys(); slot_key_clicked( pI, 0 ); return; } } return; } } void dlgTriggerEditor::slot_search_triggers( const QString s ) { QRegExp pattern = QRegExp( s ); //mpSourceEditorArea->highlighter->rehighlight(); tree_widget_search_results_main->clear(); tree_widget_search_results_main->show(); // type | name | line number/pattern/name what has been found //------------------------------------------------------------------------- //trigger | name | line 204: a la sd akd //trigger | asdf | pattern: ^alsd //trigger | asdf | name | if( true ) { std::list nodes = mpHost->getTriggerUnit()->getTriggerRootNodeList(); typedef list::const_iterator I; for( I it = nodes.begin(); it != nodes.end(); it++) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TTrigger * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Trigger" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList regexList = pChild->getRegexCodeList(); resultList = regexList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "pattern" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } recursiveSearchTriggers( pChild, s ); } } if( true ) { std::list nodes = mpHost->getAliasUnit()->getAliasRootNodeList(); typedef list::const_iterator I; for( I it = nodes.begin(); it != nodes.end(); it++) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TAlias * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Alias" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } if( pChild->getRegexCode().indexOf( s, 0, Qt::CaseInsensitive ) > -1 ) { QStringList sl; sl << "Alias" << pChild->getName() << "pattern" << pChild->getRegexCode(); if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } recursiveSearchAlias( pChild, s ); } } if( true ) { std::list nodes = mpHost->getScriptUnit()->getScriptRootNodeList(); typedef list::const_iterator I; for( I it = nodes.begin(); it != nodes.end(); it++) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TScript * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Script" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } recursiveSearchScripts( pChild, s ); } } if( true ) { std::list nodes = mpHost->getActionUnit()->getActionRootNodeList(); typedef list::const_iterator I; for( I it = nodes.begin(); it != nodes.end(); it++) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TAction * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Button" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } recursiveSearchActions( pChild, s ); } } if( true ) { std::list nodes = mpHost->getTimerUnit()->getTimerRootNodeList(); typedef list::const_iterator I; for( I it = nodes.begin(); it != nodes.end(); it++) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TTimer * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Timer" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } recursiveSearchTimers( pChild, s ); } } if( true ) { std::list nodes = mpHost->getKeyUnit()->getKeyRootNodeList(); typedef list::const_iterator I; for( I it = nodes.begin(); it != nodes.end(); it++) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TKey * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Key" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } recursiveSearchKeys( pChild, s ); } } mpSourceEditorArea->highlighter->setSearchPattern( s ); } void dlgTriggerEditor::recursiveSearchTriggers( TTrigger * pTriggerParent, const QString & s ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TTrigger * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Trigger" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList regexList = pChild->getRegexCodeList(); resultList = regexList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "pattern" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } if( pChild->hasChildren() ) { recursiveSearchTriggers( pChild, s ); } } } void dlgTriggerEditor::recursiveSearchAlias( TAlias * pTriggerParent, const QString & s ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TAlias * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Alias" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } if( pChild->getRegexCode().indexOf( s, 0, Qt::CaseInsensitive ) > -1 ) { QStringList sl; sl << "Alias" << pChild->getName() << "pattern" << pChild->getRegexCode(); if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } if( pChild->hasChildren() ) { recursiveSearchAlias( pChild, s ); } } } void dlgTriggerEditor::recursiveSearchScripts( TScript * pTriggerParent, const QString & s ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TScript * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Script" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } if( pChild->hasChildren() ) { recursiveSearchScripts( pChild, s ); } } } void dlgTriggerEditor::recursiveSearchActions( TAction * pTriggerParent, const QString & s ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TAction * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Button" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } if( pChild->hasChildren() ) { recursiveSearchActions( pChild, s ); } } } void dlgTriggerEditor::recursiveSearchTimers( TTimer * pTriggerParent, const QString & s ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TTimer * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Timer" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } if( pChild->hasChildren() ) { recursiveSearchTimers( pChild, s ); } } } void dlgTriggerEditor::recursiveSearchKeys( TKey * pTriggerParent, const QString & s ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { QTreeWidgetItem * pItem; QTreeWidgetItem * parent = 0; TKey * pChild = *it; QString n = pChild->getName(); if( n.indexOf( s, 0, Qt::CaseInsensitive ) != -1 ) { QStringList sl; sl << "Key" << pChild->getName() << "name"; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } QStringList scriptList = pChild->getScript().split("\n"); QStringList resultList = scriptList.filter( s, Qt::CaseInsensitive ); for( int i=0; igetName() << "script" << resultList[i]; if( ! parent ) { parent = new QTreeWidgetItem( sl ); parent->setFirstColumnSpanned( false ); parent->setData(0, Qt::UserRole, pChild->getID() ); tree_widget_search_results_main->addTopLevelItem( parent ); } else { pItem = new QTreeWidgetItem( parent, sl ); pItem->setFirstColumnSpanned( false ); pItem->setData(0, Qt::UserRole, pChild->getID() ); parent->addChild( pItem ); parent->setExpanded( true ); } } if( pChild->hasChildren() ) { recursiveSearchKeys( pChild, s ); } } } void dlgTriggerEditor::slot_addActionGroup() { addAction( true ); //add action group } void dlgTriggerEditor::slot_addAction() { addAction(false); //add normal action } void dlgTriggerEditor::slot_addAliasGroup() { addAlias( true ); //add alias group } void dlgTriggerEditor::slot_addAlias() { addAlias(false); //add normal alias } void dlgTriggerEditor::slot_addScriptGroup() { addScript( true ); //add alias group } void dlgTriggerEditor::slot_addScript() { addScript(false); //add normal alias } void dlgTriggerEditor::slot_addKeyGroup() { addKey( true ); //add alias group } void dlgTriggerEditor::slot_addKey() { addKey(false); //add normal alias } void dlgTriggerEditor::slot_addTriggerGroup() { addTrigger(true); //add trigger group } void dlgTriggerEditor::slot_addTrigger() { addTrigger(false); //add normal trigger } void dlgTriggerEditor::slot_addTimerGroup() { addTimer( true ); } void dlgTriggerEditor::slot_addTimer() { addTimer( false ); //add normal trigger } void dlgTriggerEditor::slot_deleteAlias() { QTreeWidgetItem * pItem = treeWidget_alias->currentItem(); if( ! pItem ) return; QTreeWidgetItem * pParent = pItem->parent(); TAlias * pT = mpHost->getAliasUnit()->getAlias(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; if( pParent ) { pParent->removeChild( pItem ); } else { qDebug()<<"ERROR: dlgTriggerEditor::slot_deleteAlias() child to be deleted doesnt have a parent"; } delete pT; mCurrentAlias = 0; } void dlgTriggerEditor::slot_deleteAction() { QTreeWidgetItem * pItem = treeWidget_actions->currentItem(); if( ! pItem ) return; QTreeWidgetItem * pParent = pItem->parent(); TAction * pT = mpHost->getActionUnit()->getAction(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; if( pParent ) { pParent->removeChild( pItem ); } else { qDebug()<<"ERROR: dlgTriggerEditor::slot_deleteAction() child to be deleted doesnt have a parent"; } delete pT; mCurrentAction = 0; mpHost->getActionUnit()->updateToolbar(); } void dlgTriggerEditor::slot_deleteScript() { QTreeWidgetItem * pItem = treeWidget_scripts->currentItem(); if( ! pItem ) return; QTreeWidgetItem * pParent = pItem->parent(); TScript * pT = mpHost->getScriptUnit()->getScript(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; if( pParent ) { pParent->removeChild( pItem ); } else { qDebug()<<"ERROR: dlgTriggerEditor::slot_deleteScript() child to be deleted doesnt have a parent"; } delete pT; mCurrentScript = 0; } void dlgTriggerEditor::slot_deleteKey() { QTreeWidgetItem * pItem = treeWidget_keys->currentItem(); if( ! pItem ) return; QTreeWidgetItem * pParent = pItem->parent(); TKey * pT = mpHost->getKeyUnit()->getKey(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; if( pParent ) { pParent->removeChild( pItem ); } else { qDebug()<<"ERROR: dlgTriggerEditor::slot_deleteScript() child to be deleted doesnt have a parent"; } delete pT; mCurrentKey = 0; } void dlgTriggerEditor::slot_deleteTrigger() { QTreeWidgetItem * pItem = treeWidget->currentItem(); if( ! pItem ) return; QTreeWidgetItem * pParent = pItem->parent(); TTrigger * pT = mpHost->getTriggerUnit()->getTrigger(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; if( pParent ) { pParent->removeChild( pItem ); } else { qDebug()<<"ERROR: dlgTriggerEditor::slot_deleteTrigger() child to be deleted doesnt have a parent"; } delete pT; mCurrentTrigger = 0; } void dlgTriggerEditor::slot_deleteTimer() { QTreeWidgetItem * pItem = treeWidget_timers->currentItem(); if( ! pItem ) return; QTreeWidgetItem * pParent = pItem->parent(); if( ! pItem ) return; TTimer * pT = mpHost->getTimerUnit()->getTimer(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; if( pParent ) { pParent->removeChild( pItem ); } else { qDebug()<<"ERROR: dlgTriggerEditor::slot_deleteTimer() child to be deleted doesnt have a parent"; } delete pT; mCurrentTimer = 0; } void dlgTriggerEditor::slot_trigger_toggle_active() { QTreeWidgetItem * pItem = (QTreeWidgetItem *)treeWidget->currentItem(); if( ! pItem ) return; QIcon icon; TTrigger * pT = mpHost->getTriggerUnit()->getTrigger(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; pT->setIsActive( ! pT->shouldBeActive() ); if( pT->isFilterChain() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-locked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-grey-locked.png")), QIcon::Normal, QIcon::Off); } } } else if( pT->isFolder() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue-locked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, pT->getName() ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); } showInfo( QString( "Trying to %2 Trigger %1 %3." ) .arg(pT->getName()) .arg( pT->shouldBeActive() ? "activated" : "deactivated" ) .arg( pT->state() ? "succeeded" : QString("failed reason:") + pT->getError() ) ); if( pItem->childCount() > 0 ) { children_icon_triggers( pItem ); } } void dlgTriggerEditor::children_icon_triggers( QTreeWidgetItem * pWidgetItemParent ) { for( int i = 0; ichildCount(); i++ ) { QTreeWidgetItem * pItem = pWidgetItemParent->child(i); TTrigger * pT = mpHost->getTriggerUnit()->getTrigger(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; QIcon icon; if( pItem->childCount() > 0 ) { children_icon_triggers( pItem ); } if( pT->state() ) { if( pT->isFilterChain() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-locked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-grey-locked.png")), QIcon::Normal, QIcon::Off); } } } else if( pT->isFolder() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue-locked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png"),0,Qt::MonoOnly), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png"),0,Qt::MonoOnly), QIcon::Normal, QIcon::Off); } } } //pItem->setDisabled(!pT->ancestorsActive()); pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } } void dlgTriggerEditor::slot_timer_toggle_active() { QTreeWidgetItem * pItem = (QTreeWidgetItem *)treeWidget_timers->currentItem(); if( ! pItem ) return; QIcon icon; TTimer * pT = mpHost->getTimerUnit()->getTimer(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; if( ! pT->isOffsetTimer() ) pT->setIsActive( ! pT->shouldBeActive() ); else pT->setShouldBeActive( ! pT->shouldBeActive() ); if( pT->isFolder() ) { // disable or enable all timers in the respective branch // irrespective of the user defined state. if( pT->shouldBeActive() ) { pT->enableTimer( pT->getID() ); } else { pT->disableTimer( pT->getID() ); } if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-green.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-green-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isOffsetTimer() ) { // state of offset timers is managed by the trigger engine if( pT->shouldBeActive() ) { pT->enableTimer( pT->getID() ); icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-on.png")), QIcon::Normal, QIcon::Off); } else { pT->disableTimer( pT->getID() ); icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-off.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->shouldBeActive() ) { pT->enableTimer( pT->getID() ); icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { pT->disableTimer( pT->getID() ); icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, pT->getName() ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); } showInfo( QString( "Trying to %2 Timer %1 %3." ) .arg(pT->getName()) .arg( pT->shouldBeActive() ? "activated" : "deactivated" ) .arg( pT->state() ? "succeeded" : QString("failed reason:") + pT->getError() ) ); } void dlgTriggerEditor::slot_alias_toggle_active() { QTreeWidgetItem * pItem = (QTreeWidgetItem *)treeWidget_alias->currentItem(); if( ! pItem ) return; QIcon icon; TAlias * pT = mpHost->getAliasUnit()->getAlias(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; qDebug()<<"aliasToggleActive()"; pT->setIsActive( ! pT->shouldBeActive() ); if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, pT->getName() ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); } showInfo( QString( "Trying to %2 Alias %1 %3." ) .arg(pT->getName()) .arg( pT->shouldBeActive() ? "activate" : "deactivate" ) .arg( pT->state() ? "succeeded" : QString("failed reason:") + pT->getError() ) ); if( pItem->childCount() > 0 ) { children_icon_alias( pItem ); } } void dlgTriggerEditor::children_icon_alias( QTreeWidgetItem * pWidgetItemParent ) { for( int i = 0; ichildCount(); i++ ) { QTreeWidgetItem * pItem = pWidgetItemParent->child(i); TAlias * pT = mpHost->getAliasUnit()->getAlias(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; QIcon icon; if( pItem->childCount() > 0 ) { children_icon_alias( pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet-locked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png"),0,Qt::MonoOnly), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png"),0,Qt::MonoOnly), QIcon::Normal, QIcon::Off); } } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } } void dlgTriggerEditor::slot_script_toggle_active() { QTreeWidgetItem * pItem = (QTreeWidgetItem *)treeWidget_scripts->currentItem(); if( ! pItem ) return; QIcon icon; TScript * pT = mpHost->getScriptUnit()->getScript(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; pT->setIsActive( ! pT->shouldBeActive() ); if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, pT->getName() ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); } showInfo( QString( "Trying to %2 Script %1 %3." ) .arg(pT->getName()) .arg( pT->shouldBeActive() ? "activated" : "deactivated" ) .arg( pT->state() ? "succeeded" : QString("failed reason:") + pT->getError() ) ); } void dlgTriggerEditor::slot_action_toggle_active() { QTreeWidgetItem * pItem = (QTreeWidgetItem *)treeWidget_actions->currentItem(); if( ! pItem ) return; QIcon icon; TAction * pT = mpHost->getActionUnit()->getAction(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; pT->setIsActive( ! pT->shouldBeActive() ); if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, pT->getName() ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); } showInfo( QString( "Trying to %2 Action %1 %3." ) .arg(pT->getName()) .arg( pT->shouldBeActive() ? "activated" : "deactivated" ) .arg( pT->state() ? "succeeded" : QString("failed reason:") + pT->getError() ) ); mpHost->getActionUnit()->updateToolbar(); } void dlgTriggerEditor::slot_key_toggle_active() { QTreeWidgetItem * pItem = (QTreeWidgetItem *)treeWidget_keys->currentItem(); if( ! pItem ) return; QIcon icon; TKey * pT = mpHost->getKeyUnit()->getKey(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; pT->setIsActive( ! pT->shouldBeActive() ); if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, pT->getName() ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); } showInfo( QString( "Trying to %2 Key %1 %3." ) .arg(pT->getName()) .arg( pT->shouldBeActive() ? "activated" : "deactivated" ) .arg( pT->state() ? "succeeded" : QString("failed reason:") + pT->getError() ) ); if( pItem->childCount() > 0 ) { children_icon_key( pItem ); } } void dlgTriggerEditor::children_icon_key( QTreeWidgetItem * pWidgetItemParent ) { for( int i = 0; ichildCount(); i++ ) { QTreeWidgetItem * pItem = pWidgetItemParent->child(i); TKey * pT = mpHost->getKeyUnit()->getKey(pItem->data(0, Qt::UserRole).toInt()); if( ! pT ) return; QIcon icon; if( pItem->childCount() > 0 ) { children_icon_key( pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan-locked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png"),0,Qt::MonoOnly), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png"),0,Qt::MonoOnly), QIcon::Normal, QIcon::Off); } } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } } void dlgTriggerEditor::addTrigger( bool isFolder ) { saveTrigger(); QString name; if( isFolder ) name = "New Trigger Group"; else name = "New Trigger"; QStringList regexList; QList regexPropertyList; QString script = ""; QStringList nameL; nameL << name; QTreeWidgetItem * pParent = (QTreeWidgetItem*)treeWidget->currentItem(); QTreeWidgetItem * pNewItem = 0; TTrigger * pT = 0; if( pParent ) { int parentID = pParent->data(0, Qt::UserRole).toInt(); TTrigger * pParentTrigger = mpHost->getTriggerUnit()->getTrigger( parentID ); if( pParentTrigger ) { // insert new items as siblings unless the parent is a folder if( ! pParentTrigger->isFolder() ) { // handle root items if( ! pParentTrigger->getParent() ) { goto ROOT_TRIGGER; } else { // insert new item as sibling of the clicked item if( pParent->parent() ) { pT = new TTrigger( pParentTrigger->getParent(), mpHost ); pNewItem = new QTreeWidgetItem( pParent->parent(), nameL ); pParent->parent()->insertChild( 0, pNewItem ); } } } else { pT = new TTrigger( pParentTrigger, mpHost ); pNewItem = new QTreeWidgetItem( pParent, nameL ); pParent->insertChild( 0, pNewItem ); } } else goto ROOT_TRIGGER; } else { //insert a new root item ROOT_TRIGGER: pT = new TTrigger( name, regexList, regexPropertyList, false, mpHost ); pNewItem = new QTreeWidgetItem( mpTriggerBaseItem, nameL ); treeWidget->insertTopLevelItem( 0, pNewItem ); } if( ! pT ) return; pT->setName( name ); pT->setRegexCodeList( regexList, regexPropertyList ); pT->setScript( script ); pT->setIsFolder( isFolder ); pT->setIsActive( false ); pT->setIsMultiline( false ); pT->mStayOpen = 0; pT->setConditionLineDelta( 0 ); pT->registerTrigger(); int childID = pT->getID(); pNewItem->setData( 0, Qt::UserRole, childID ); QIcon icon; if( isFolder ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-red.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/document-save-as.png")), QIcon::Normal, QIcon::Off); } pNewItem->setIcon( 0, icon ); if( pParent ) pParent->setExpanded( true ); mpTriggersMainArea->lineEdit_trigger_name->clear(); mpTriggersMainArea->perlSlashGOption->setChecked( false ); mpSourceEditorArea->editor->clear(); mpTriggersMainArea->trigger_command->clear(); mpTriggersMainArea->filterTrigger->setChecked( false ); mpTriggersMainArea->spinBox_stayOpen->setValue( 0 ); mpTriggersMainArea->spinBox_linemargin->setValue( 0 ); mpTriggersMainArea->checkBox_multlinetrigger->setChecked( false ); QPalette pal = palette(); QColor color = pal.color( QPalette::Button ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); mpTriggersMainArea->pushButtonFgColor->setChecked( false ); mpTriggersMainArea->pushButtonBgColor->setChecked( false ); mpTriggersMainArea->colorizerTrigger->setChecked( false ); treeWidget->setCurrentItem( pNewItem ); mCurrentTrigger = pNewItem; showInfo( msgInfoAddTrigger ); slot_trigger_clicked( treeWidget->currentItem(), 0 ); } void dlgTriggerEditor::addTimer( bool isFolder ) { saveTimer(); QString name; if( isFolder ) name = "New Timer Group"; else name = "New Timer"; QString command = ""; QTime time; QString script = ""; QStringList nameL; nameL << name; QTreeWidgetItem * pParent = (QTreeWidgetItem*)treeWidget_timers->currentItem(); QTreeWidgetItem * pNewItem = 0; TTimer * pT = 0; if( pParent ) { int parentID = pParent->data(0, Qt::UserRole).toInt(); TTimer * pParentTrigger = mpHost->getTimerUnit()->getTimer( parentID ); if( pParentTrigger ) { // insert new items as siblings unless the parent is a folder if( ! pParentTrigger->isFolder() ) { // handle root items if( ! pParentTrigger->getParent() ) { goto ROOT_TIMER; } else { // insert new item as sibling of the clicked item if( pParent->parent() ) { pT = new TTimer( pParentTrigger->getParent(), mpHost ); pNewItem = new QTreeWidgetItem( pParent->parent(), nameL ); pParent->parent()->insertChild( 0, pNewItem ); } } } else { pT = new TTimer( pParentTrigger, mpHost ); pNewItem = new QTreeWidgetItem( pParent, nameL ); pParent->insertChild( 0, pNewItem ); } } else goto ROOT_TIMER; } else { //insert a new root item ROOT_TIMER: pT = new TTimer( name, time, mpHost ); pNewItem = new QTreeWidgetItem( mpTimerBaseItem, nameL ); treeWidget_timers->insertTopLevelItem( 0, pNewItem ); } if( ! pT ) return; pT->setName( name ); pT->setCommand( command ); pT->setScript( script ); pT->setIsFolder( isFolder ); pT->setIsActive( false ); pT->registerTimer(); int childID = pT->getID(); pNewItem->setData( 0, Qt::UserRole, childID ); QIcon icon; if( isFolder ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-red.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/document-save-as.png")), QIcon::Normal, QIcon::Off); } pNewItem->setIcon( 0, icon ); if( pParent ) pParent->setExpanded( true ); //FIXME //mpOptionsAreaTriggers->lineEdit_trigger_name->clear(); mpTimersMainArea->lineEdit_command->clear(); mpSourceEditorArea->editor->clear(); treeWidget_timers->setCurrentItem( pNewItem ); mCurrentTimer = pNewItem; showInfo( msgInfoAddTimer ); slot_timer_clicked( treeWidget_timers->currentItem(), 0 ); } void dlgTriggerEditor::addKey( bool isFolder ) { saveKey(); QString name; if( isFolder ) name = "New Key Group"; else name = "New Key"; QString script = ""; QStringList nameL; nameL << name; QTreeWidgetItem * pParent = (QTreeWidgetItem*)treeWidget_keys->currentItem(); QTreeWidgetItem * pNewItem = 0; TKey * pT = 0; if( pParent ) { int parentID = pParent->data(0, Qt::UserRole).toInt(); TKey * pParentTrigger = mpHost->getKeyUnit()->getKey( parentID ); if( pParentTrigger ) { // insert new items as siblings unless the parent is a folder if( ! pParentTrigger->isFolder() ) { // handle root items if( ! pParentTrigger->getParent() ) { goto ROOT_KEY; } else { // insert new item as sibling of the clicked item if( pParent->parent() ) { pT = new TKey( pParentTrigger->getParent(), mpHost ); pNewItem = new QTreeWidgetItem( pParent->parent(), nameL ); pParent->parent()->insertChild( 0, pNewItem ); } } } else { pT = new TKey( pParentTrigger, mpHost ); pNewItem = new QTreeWidgetItem( pParent, nameL ); pParent->insertChild( 0, pNewItem ); } } else goto ROOT_KEY; } else { //insert a new root item ROOT_KEY: pT = new TKey( name, mpHost ); pNewItem = new QTreeWidgetItem( mpKeyBaseItem, nameL ); treeWidget_keys->insertTopLevelItem( 0, pNewItem ); } if( ! pT ) return; pT->setName( name ); pT->setKeyCode( -1 ); pT->setKeyModifiers( -1 ); pT->setScript( script ); pT->setIsFolder( isFolder ); pT->setIsActive( false ); pT->registerKey(); int childID = pT->getID(); pNewItem->setData( 0, Qt::UserRole, childID ); QIcon icon; if( isFolder ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-red.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/document-save-as.png")), QIcon::Normal, QIcon::Off); } pNewItem->setIcon( 0, icon ); if( pParent ) pParent->setExpanded( true ); mpKeysMainArea->lineEdit_command->clear(); mpKeysMainArea->lineEdit_key->setText("no key chosen"); mpSourceEditorArea->editor->clear(); treeWidget_keys->setCurrentItem( pNewItem ); mCurrentKey = pNewItem; showInfo( msgInfoAddKey ); slot_key_clicked( treeWidget_keys->currentItem(), 0 ); } void dlgTriggerEditor::addAlias( bool isFolder ) { saveAlias(); QString name; if( isFolder ) name = "New Alias Group"; else name = "New Alias"; QString regex = ""; QString command = ""; QString script = ""; QStringList nameL; nameL << name; QTreeWidgetItem * pParent = (QTreeWidgetItem*)treeWidget_alias->currentItem(); QTreeWidgetItem * pNewItem = 0; TAlias * pT = 0; if( pParent ) { int parentID = pParent->data(0, Qt::UserRole).toInt(); TAlias * pParentTrigger = mpHost->getAliasUnit()->getAlias( parentID ); if( pParentTrigger ) { // insert new items as siblings unless the parent is a folder if( ! pParentTrigger->isFolder() ) { // handle root items if( ! pParentTrigger->getParent() ) { goto ROOT_ALIAS; } else { // insert new item as sibling of the clicked item if( pParent->parent() ) { pT = new TAlias( pParentTrigger->getParent(), mpHost ); pNewItem = new QTreeWidgetItem( pParent->parent(), nameL ); pParent->parent()->insertChild( 0, pNewItem ); } } } else { pT = new TAlias( pParentTrigger, mpHost ); pNewItem = new QTreeWidgetItem( pParent, nameL ); pParent->insertChild( 0, pNewItem ); } } else goto ROOT_ALIAS; } else { //insert a new root item ROOT_ALIAS: pT = new TAlias( name, mpHost ); pT->setRegexCode( regex ); pNewItem = new QTreeWidgetItem( mpAliasBaseItem, nameL ); treeWidget_alias->insertTopLevelItem( 0, pNewItem ); } if( ! pT ) return; pT->setName( name ); pT->setCommand( command ); pT->setRegexCode( regex ); pT->setScript( script ); pT->setIsFolder( isFolder ); pT->setIsActive( false ); pT->registerAlias(); int childID = pT->getID(); pNewItem->setData( 0, Qt::UserRole, childID ); QIcon icon; if( isFolder ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-red.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/document-save-as.png")), QIcon::Normal, QIcon::Off); } pNewItem->setIcon( 0, icon ); if( pParent ) pParent->setExpanded( true ); mpAliasMainArea->lineEdit_alias_name->clear(); mpAliasMainArea->pattern_textedit->clear(); mpAliasMainArea->substitution->clear(); mpSourceEditorArea->editor->clear(); mpAliasMainArea->lineEdit_alias_name->setText( name ); treeWidget_alias->setCurrentItem( pNewItem ); mCurrentAlias = pNewItem; showInfo(msgInfoAddAlias); slot_alias_clicked( treeWidget_alias->currentItem(), 0 ); } void dlgTriggerEditor::addAction( bool isFolder ) { saveAction(); QString name; if( isFolder ) name = "new menu"; else name = "new button"; QString cmdButtonUp = ""; QString cmdButtonDown = ""; QString script = ""; QStringList nameL; nameL << name; QTreeWidgetItem * pParent = (QTreeWidgetItem*)treeWidget_actions->currentItem(); QTreeWidgetItem * pNewItem = 0; TAction * pT = 0; if( pParent ) { int parentID = pParent->data(0, Qt::UserRole).toInt(); TAction * pParentTrigger = mpHost->getActionUnit()->getAction( parentID ); if( pParentTrigger ) { // insert new items as siblings unless the parent is a folder if( ! pParentTrigger->isFolder() ) { // handle root items if( ! pParentTrigger->getParent() ) { goto ROOT_ACTION; } else { // insert new item as sibling of the clicked item if( pParent->parent() ) { pT = new TAction( pParentTrigger->getParent(), mpHost ); pNewItem = new QTreeWidgetItem( pParent->parent(), nameL ); pParent->parent()->insertChild( 0, pNewItem ); } } } else { pT = new TAction( pParentTrigger, mpHost ); pNewItem = new QTreeWidgetItem( pParent, nameL ); pParent->insertChild( 0, pNewItem ); } } else goto ROOT_ACTION; } else { //insert a new root item ROOT_ACTION: name = "new toolbar"; pT = new TAction( name, mpHost ); pT->setCommandButtonUp( cmdButtonUp ); QStringList nl; nl << name; pNewItem = new QTreeWidgetItem( mpActionBaseItem, nl ); treeWidget_actions->insertTopLevelItem( 0, pNewItem ); } if( ! pT ) return; pT->setName( name ); pT->setCommandButtonUp( cmdButtonUp ); pT->setCommandButtonDown( cmdButtonDown ); pT->setIsPushDownButton( false ); pT->mLocation = 1; pT->mOrientation = 1; pT->setScript( script ); pT->setIsFolder( isFolder ); pT->setIsActive( false ); pT->registerAction(); int childID = pT->getID(); pNewItem->setData( 0, Qt::UserRole, childID ); QIcon icon; if( isFolder ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-red.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/document-save-as.png")), QIcon::Normal, QIcon::Off); } pNewItem->setIcon( 0, icon ); if( pParent ) pParent->setExpanded( true ); mpActionsMainArea->lineEdit_action_button_down->clear(); mpActionsMainArea->lineEdit_action_button_up->clear(); mpActionsMainArea->lineEdit_action_icon->clear(); mpActionsMainArea->checkBox_pushdownbutton->setChecked(false); mpSourceEditorArea->editor->clear(); mpHost->getActionUnit()->updateToolbar(); treeWidget_actions->setCurrentItem( pNewItem ); mpCurrentActionItem = pNewItem; mCurrentAction = pNewItem; showInfo( msgInfoAddButton ); slot_action_clicked( treeWidget_actions->currentItem(), 0 ); } void dlgTriggerEditor::addScript( bool isFolder ) { saveScript(); QString name; if( isFolder ) name = "New Script Group"; else name = "NewScript"; QStringList mainFun; mainFun << "-------------------------------------------------\n" << "-- Put your Lua functions here. --\n" << "-- --\n" << "-- Note that you can also use external Scripts --\n" << "-------------------------------------------------\n"; QString script = mainFun.join(""); QStringList nameL; nameL << name; QTreeWidgetItem * pParent = (QTreeWidgetItem*)treeWidget_scripts->currentItem(); QTreeWidgetItem * pNewItem = 0; TScript * pT = 0; if( pParent ) { int parentID = pParent->data(0, Qt::UserRole).toInt(); TScript * pParentTrigger = mpHost->getScriptUnit()->getScript( parentID ); if( pParentTrigger ) { // insert new items as siblings unless the parent is a folder if( ! pParentTrigger->isFolder() ) { // handle root items if( ! pParentTrigger->getParent() ) { goto ROOT_SCRIPT; } else { // insert new item as sibling of the clicked item if( pParent->parent() ) { pT = new TScript( pParentTrigger->getParent(), mpHost ); pNewItem = new QTreeWidgetItem( pParent->parent(), nameL ); pParent->parent()->insertChild( 0, pNewItem ); } } } else { pT = new TScript( pParentTrigger, mpHost ); pNewItem = new QTreeWidgetItem( pParent, nameL ); pParent->insertChild( 0, pNewItem ); } } else goto ROOT_SCRIPT; } else { //insert a new root item ROOT_SCRIPT: pT = new TScript( name, mpHost ); pNewItem = new QTreeWidgetItem( mpScriptsBaseItem, nameL ); treeWidget_scripts->insertTopLevelItem( 0, pNewItem ); } if( ! pT ) return; pT->setName( name ); pT->setScript( script ); pT->setIsFolder( isFolder ); pT->setIsActive( false ); pT->registerScript(); int childID = pT->getID(); pNewItem->setData( 0, Qt::UserRole, childID ); QIcon icon; if( isFolder ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-red.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/document-save-as.png")), QIcon::Normal, QIcon::Off); } pNewItem->setIcon( 0, icon ); if( pParent ) pParent->setExpanded( true ); mpScriptsMainArea->lineEdit_scripts_name->clear(); //FIXME mpScriptsMainArea->pattern_textedit->clear(); mpSourceEditorArea->editor->setPlainText( script ); mCurrentScript = pNewItem; treeWidget_scripts->setCurrentItem( pNewItem ); slot_scripts_clicked( treeWidget_scripts->currentItem(), 0 ); } void dlgTriggerEditor::slot_saveTriggerAfterEdit() { return saveTrigger(); /* QString name = mpTriggersMainArea->lineEdit_trigger_name->text(); QString command = mpTriggersMainArea->trigger_command->text(); mpTriggersMainArea->lineEdit->clear(); bool isMultiline = mpTriggersMainArea->checkBox_multlinetrigger->isChecked(); QList itemList; for( int i=0; ilistWidget_regex_list->count(); i++ ) { QListWidgetItem * pItem = mpTriggersMainArea->listWidget_regex_list->item(i); itemList << pItem; } QStringList regexList; QList regexPropertyList; for( int i=0; itext().size() < 1 ) continue; regexList << itemList[i]->text(); QColor fgColor = itemList[i]->foreground().color(); QColor bgColor = itemList[i]->background().color(); if( (fgColor == QColor(0,0,0)) && (bgColor == QColor(255,255,255)) ) { regexPropertyList << REGEX_SUBSTRING; } if( (fgColor == QColor(0,0,255)) && (bgColor == QColor(255,255,255)) ) { regexPropertyList << REGEX_PERL; } if( (fgColor == QColor(195,0,0)) && (bgColor == QColor(55,55,55)) ) { regexPropertyList << REGEX_BEGIN_OF_LINE_SUBSTRING; } if( (fgColor == QColor(0,155,0)) && (bgColor == QColor(255,255,255)) ) { regexPropertyList << REGEX_EXACT_MATCH; } if( (fgColor == QColor(155,155,0)) && (bgColor == QColor(0,0,0)) ) { regexPropertyList << REGEX_LUA_CODE; } } QString script = mpSourceEditorArea->script_scintilla->text(); QTreeWidgetItem * pItem = treeWidget->currentItem(); if( pItem ) { int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); TTrigger * pT = mpHost->getTriggerUnit()->getTrigger( triggerID ); if( pT ) { pT->setName( name ); pT->setCommand( command ); pT->setRegexCodeList( regexList, regexPropertyList ); pT->setTriggerType( mpTriggersMainArea->comboBox_regexstyle->currentIndex() ); pT->setScript( script ); pT->setIsMultiline( isMultiline ); pT->mPerlSlashGOption = mpTriggersMainArea->perlSlashGOption->isChecked(); pT->mFilterTrigger = mpTriggersMainArea->filterTrigger->isChecked(); pT->setConditionLineDelta( mpTriggersMainArea->spinBox_linemargin->value() ); QPalette FgColorPalette; QPalette BgColorPalette; FgColorPalette = mpTriggersMainArea->pushButtonFgColor->palette(); BgColorPalette = mpTriggersMainArea->pushButtonBgColor->palette(); QColor fgColor = FgColorPalette.color( QPalette::Button ); QColor bgColor = BgColorPalette.color( QPalette::Button ); pT->setFgColor( fgColor ); pT->setBgColor( bgColor ); pT->setIsColorizerTrigger( mpTriggersMainArea->colorizerTrigger->isChecked() ); QIcon icon; if( pT->isFilterChain() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, name ); showInfo( "Success, trigger compiled and is ready for activation. You can activate it with the padlock icon." ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); pItem->setText( 0, name ); } } } else { showError("Error: No item selected! Which item do you want to save?"); } mpTriggerMainAreaEditRegexItem = 0;*/ } void dlgTriggerEditor::saveTrigger() { QTime t; t.start(); QTreeWidgetItem * pItem = mCurrentTrigger; if( ! pItem ) return; if( ! pItem->parent() ) return; QString name = mpTriggersMainArea->lineEdit_trigger_name->text(); QString command = mpTriggersMainArea->trigger_command->text(); bool isMultiline = mpTriggersMainArea->checkBox_multlinetrigger->isChecked(); QStringList regexList; QList regexPropertyList; for( int i=0; i<50; i++ ) { QString pattern = mTriggerPatternEdit[i]->lineEdit->text(); if( pattern.size() < 1 ) continue; regexList << pattern; int _type = mTriggerPatternEdit[i]->patternType->currentIndex(); if( _type == 0 ) regexPropertyList << REGEX_SUBSTRING; else if( _type == 1 ) regexPropertyList << REGEX_PERL; else if( _type == 2 ) regexPropertyList << REGEX_BEGIN_OF_LINE_SUBSTRING; else if( _type == 3 ) regexPropertyList << REGEX_EXACT_MATCH; else if( _type == 4 ) regexPropertyList << REGEX_LUA_CODE; else if( _type == 5 ) regexPropertyList << REGEX_LINE_SPACER; else if( _type == 6 ) regexPropertyList << REGEX_COLOR_PATTERN; } QString script = mpSourceEditorArea->editor->toPlainText(); if( pItem ) { int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); TTrigger * pT = mpHost->getTriggerUnit()->getTrigger( triggerID ); if( pT ) { QString old_name = pT->getName(); pT->setName( name ); pT->setCommand( command ); pT->setRegexCodeList( regexList, regexPropertyList ); pT->setScript( script ); pT->setIsMultiline( isMultiline ); pT->mPerlSlashGOption = mpTriggersMainArea->perlSlashGOption->isChecked(); pT->mFilterTrigger = mpTriggersMainArea->filterTrigger->isChecked(); pT->setConditionLineDelta( mpTriggersMainArea->spinBox_linemargin->value() ); pT->mStayOpen = mpTriggersMainArea->spinBox_stayOpen->value(); pT->mSoundTrigger = mpTriggersMainArea->soundTrigger->isChecked(); pT->setSound( mpTriggersMainArea->lineEdit_soundFile->text() ); QPalette FgColorPalette; QPalette BgColorPalette; FgColorPalette = mpTriggersMainArea->pushButtonFgColor->palette(); BgColorPalette = mpTriggersMainArea->pushButtonBgColor->palette(); QColor fgColor = FgColorPalette.color( QPalette::Button ); QColor bgColor = BgColorPalette.color( QPalette::Button ); pT->setFgColor( fgColor ); pT->setBgColor( bgColor ); pT->setIsColorizerTrigger( mpTriggersMainArea->colorizerTrigger->isChecked() ); QIcon icon; if( pT->isFilterChain() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-locked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-grey-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue-locked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { if( old_name == "New Trigger" || old_name == "New Trigger Group" ) { QIcon _icon; if( pT->isFolder() ) { _icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue.png")), QIcon::Normal, QIcon::Off); } else { _icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } pItem->setIcon( 0, _icon ); pItem->setText( 0, name ); pT->setIsActive( true ); } else { pItem->setIcon( 0, icon); pItem->setText( 0, name ); } } else { QIcon iconError; pItem->setText( 0, name ); iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); pT->setIsActive( false ); } } } else { showError("Error: No item selected! Which item do you want to save?"); } } void dlgTriggerEditor::slot_saveTimerAfterEdit() { return saveTimer(); /*QString name = mpTimersMainArea->lineEdit_timer_name->text(); QString script = mpSourceEditorArea->script_scintilla->text(); QTreeWidgetItem * pItem = treeWidget_timers->currentItem(); if( pItem ) { int timerID = pItem->data(0, Qt::UserRole).toInt(); TTimer * pT = mpHost->getTimerUnit()->getTimer( timerID ); if( pT ) { pT->setName( name ); QString command = mpTimersMainArea->lineEdit_command->text(); int hours = mpTimersMainArea->timeEdit_hours->time().hour(); int minutes = mpTimersMainArea->timeEdit_minutes->time().minute(); int secs = mpTimersMainArea->timeEdit_seconds->time().second(); int msecs = mpTimersMainArea->timeEdit_msecs->time().msec(); QTime time(hours,minutes,secs,msecs); pT->setTime( time ); pT->setCommand( command ); pT->setName( name ); pT->setScript( script ); // if( pT->isOffsetTimer() ) //{ // pT->setShouldBeActive( true ); // } // else //{ // pT->setIsActive( true ); //} QIcon icon; if( pT->isFolder() ) { if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-green.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-green-locked.png")), QIcon::Normal, QIcon::Off); } } if( pT->isOffsetTimer() ) { if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-on.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-off.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, name ); showInfo( "Success, trigger compiled and is ready for activation. You can activate it with the padlock icon." ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); pItem->setText( 0, name ); } } }*/ } void dlgTriggerEditor::saveTimer() { QTreeWidgetItem * pItem = mCurrentTimer; if( ! pItem ) return; QString name = mpTimersMainArea->lineEdit_timer_name->text(); QString script = mpSourceEditorArea->editor->toPlainText(); if( pItem ) { int timerID = pItem->data(0, Qt::UserRole).toInt(); TTimer * pT = mpHost->getTimerUnit()->getTimer( timerID ); if( pT ) { pT->setName( name ); QString command = mpTimersMainArea->lineEdit_command->text(); int hours = mpTimersMainArea->timeEdit_hours->time().hour(); int minutes = mpTimersMainArea->timeEdit_minutes->time().minute(); int secs = mpTimersMainArea->timeEdit_seconds->time().second(); int msecs = mpTimersMainArea->timeEdit_msecs->time().msec(); QTime time(hours,minutes,secs,msecs); pT->setTime( time ); pT->setCommand( command ); pT->setName( name ); pT->setScript( script ); QIcon icon; if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-green.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-green-locked.png")), QIcon::Normal, QIcon::Off); } } if( pT->isOffsetTimer() ) { if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-on.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-off.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); pT->setIsActive( true ); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, name ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); pItem->setText( 0, name ); } } } } void dlgTriggerEditor::slot_saveAliasAfterEdit() { return saveAlias(); /*qDebug()<<"slot_saveAliasAfterEdit()"; bool state = true; QString name = mpAliasMainArea->lineEdit_alias_name->text(); QString regex = mpAliasMainArea->pattern_textedit->text(); if( (name.size() < 1) || (name=="New Alias") ) { name = regex; } QString substitution = mpAliasMainArea->substitution->text(); QString script = mpSourceEditorArea->script_scintilla->text(); QTreeWidgetItem * pItem = treeWidget_alias->currentItem(); if( pItem ) { int triggerID = pItem->data(0, Qt::UserRole).toInt(); TAlias * pT = mpHost->getAliasUnit()->getAlias( triggerID ); if( pT ) { pT->setName( name ); pT->setCommand( substitution ); pT->setRegexCode( regex ); pT->setScript( script ); pT->setIsActive( true );//FIXME: discuss if new triggers are automatically active QIcon icon; if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, name ); showInfo( "Success, trigger compiled and is ready for activation. You can activate it with the padlock icon." ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); pItem->setText( 0, name ); } } }*/ } void dlgTriggerEditor::saveAlias() { QTreeWidgetItem * pItem = mCurrentAlias; if( ! pItem ) { return; } QString name = mpAliasMainArea->lineEdit_alias_name->text(); QString regex = mpAliasMainArea->pattern_textedit->text(); if( (name.size() < 1) || (name=="New Alias") ) { name = regex; } QString substitution = mpAliasMainArea->substitution->text(); QString script = mpSourceEditorArea->editor->toPlainText(); if( pItem ) { int triggerID = pItem->data(0, Qt::UserRole).toInt(); TAlias * pT = mpHost->getAliasUnit()->getAlias( triggerID ); if( pT ) { QString old_name = pT->getName(); pT->setName( name ); pT->setCommand( substitution ); pT->setRegexCode( regex ); pT->setScript( script ); QIcon icon; if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet-locked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { if( old_name == "New Alias" )//|| old_name == "New Alias Group" ) { QIcon _icon; if( pT->isFolder() ) { if( pT->ancestorsActive() ) _icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet.png")), QIcon::Normal, QIcon::Off); else _icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) _icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); _icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } pItem->setIcon( 0, _icon ); pItem->setText( 0, name ); pT->setIsActive( true ); } else { pItem->setIcon( 0, icon); pItem->setText( 0, name ); } } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); pItem->setText( 0, name ); } } } } void dlgTriggerEditor::slot_saveActionAfterEdit() { return saveAction(); /*QString name = mpActionsMainArea->lineEdit_action_name->text(); QString cmdDown = mpActionsMainArea->lineEdit_action_button_down->text(); QString cmdUp = mpActionsMainArea->lineEdit_action_button_up->text(); QString icon = mpActionsMainArea->lineEdit_action_icon->text(); QString script = mpSourceEditorArea->script_scintilla->text(); QColor color = mpActionsMainArea->pushButton_color->palette().color(QPalette::Button); int sizeX = mpActionsMainArea->buttonSizeX->text().toInt(); int sizeY = mpActionsMainArea->buttonSizeY->text().toInt(); int posX = mpActionsMainArea->buttonPosX->text().toInt(); int posY = mpActionsMainArea->buttonPosY->text().toInt(); int rotation = mpActionsMainArea->buttonRotation->currentIndex(); int columns = mpActionsMainArea->buttonColumns->text().toInt(); bool flatButton = mpActionsMainArea->buttonFlat->isChecked(); bool isChecked = mpActionsMainArea->checkBox_pushdownbutton->isChecked(); int location = mpActionsMainArea->comboBox_location->currentIndex(); int orientation = mpActionsMainArea->comboBox_orientation->currentIndex(); bool useCustomLayout = mpActionsMainArea->useCustomLayout->isChecked(); QTreeWidgetItem * pItem = treeWidget_actions->currentItem(); if( pItem ) { int triggerID = pItem->data(0, Qt::UserRole).toInt(); TAction * pT = mpHost->getActionUnit()->getAction( triggerID ); if( pT ) { pT->setName( name ); pT->setCommandButtonDown( cmdDown ); pT->setCommandButtonUp( cmdUp ); pT->setIcon( icon ); pT->setScript( script ); pT->setIsPushDownButton( isChecked ); pT->mLocation = location; pT->mOrientation = orientation; pT->setIsActive( true ); pT->setButtonColor( color ); pT->setButtonRotation( rotation ); pT->setButtonColumns( columns ); pT->setButtonFlat( flatButton ); pT->mUseCustomLayout = useCustomLayout; pT->mPosX = posX; pT->mPosY = posY; pT->mSizeX = sizeX; pT->mSizeY = sizeY; pT->css = mpActionsMainArea->css->toPlainText(); QIcon icon; if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, name ); showInfo( "Success, trigger compiled and is ready for activation. You can activate it with the padlock icon." ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); pItem->setText( 0, name ); } } } mpHost->getActionUnit()->updateToolbar();*/ } void dlgTriggerEditor::saveAction() { QTreeWidgetItem * pItem = mCurrentAction; if( ! pItem ) return; QString name = mpActionsMainArea->lineEdit_action_name->text(); QString cmdDown = mpActionsMainArea->lineEdit_action_button_down->text(); QString cmdUp = mpActionsMainArea->lineEdit_action_button_up->text(); QString icon = mpActionsMainArea->lineEdit_action_icon->text(); QString script = mpSourceEditorArea->editor->toPlainText(); QColor color = mpActionsMainArea->pushButton_color->palette().color(QPalette::Button); int sizeX = mpActionsMainArea->buttonSizeX->text().toInt(); int sizeY = mpActionsMainArea->buttonSizeY->text().toInt(); int posX = mpActionsMainArea->buttonPosX->text().toInt(); int posY = mpActionsMainArea->buttonPosY->text().toInt(); int rotation = mpActionsMainArea->buttonRotation->currentIndex(); int columns = mpActionsMainArea->buttonColumns->text().toInt(); //bool flatButton = mpActionsMainArea->buttonFlat->isChecked(); bool isChecked = mpActionsMainArea->checkBox_pushdownbutton->isChecked(); // bottom location is no longer supported i.e. location = 1 = 0 = location top int location = mpActionsMainArea->comboBox_location->currentIndex(); if( location > 0 ) location++; int orientation = mpActionsMainArea->comboBox_orientation->currentIndex(); bool useCustomLayout = mpActionsMainArea->useCustomLayout->isChecked(); if( pItem ) { int triggerID = pItem->data(0, Qt::UserRole).toInt(); TAction * pT = mpHost->getActionUnit()->getAction( triggerID ); if( pT ) { pT->setName( name ); pT->setCommandButtonDown( cmdDown ); pT->setCommandButtonUp( cmdUp ); pT->setIcon( icon ); pT->setScript( script ); pT->setIsPushDownButton( isChecked ); pT->mLocation = location; pT->mOrientation = orientation; pT->setIsActive( pT->shouldBeActive() ); pT->setButtonColor( color ); pT->setButtonRotation( rotation ); pT->setButtonColumns( columns ); // pT->setButtonFlat( flatButton ); pT->mUseCustomLayout = useCustomLayout; pT->mPosX = posX; pT->mPosY = posY; pT->mSizeX = sizeX; pT->mSizeY = sizeY; pT->css = mpActionsMainArea->css->toPlainText(); QIcon icon; if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( ! pT->getParent() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-yellow.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-yellow-locked.png")), QIcon::Normal, QIcon::Off); } } else if( ! pT->getParent()->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-yellow.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-yellow-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan-locked.png")), QIcon::Normal, QIcon::Off); } } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, name ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); pItem->setText( 0, name ); } } } mpHost->getActionUnit()->updateToolbar(); mudlet::self()->processEventLoopHack(); } void dlgTriggerEditor::slot_saveScriptAfterEdit() { return saveScript(); /*QString name = mpScriptsMainArea->lineEdit_scripts_name->text(); QString script = mpSourceEditorArea->script_scintilla->text(); QList itemList; for( int i=0; ilistWidget_registered_event_handlers->count(); i++ ) { QListWidgetItem * pItem = mpScriptsMainArea->listWidget_registered_event_handlers->item(i); itemList << pItem; } QStringList handlerList; for( int i=0; itext().size() < 1 ) continue; handlerList << itemList[i]->text(); } QTreeWidgetItem * pItem = treeWidget_scripts->currentItem(); if( pItem ) { int triggerID = pItem->data(0, Qt::UserRole).toInt(); TScript * pT = mpHost->getScriptUnit()->getScript( triggerID ); if( pT ) { pT->setName( name ); pT->setEventHandlerList( handlerList ); pT->setScript( script ); pT->setIsActive( true );//FIXME: discuss if new triggers are automatically active pT->compile(); QIcon icon; if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, name ); showInfo( "Success, trigger compiled and is ready for activation. You can activate it with the padlock icon." ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); pItem->setText( 0, name ); } } }*/ } void dlgTriggerEditor::saveScript() { QTreeWidgetItem * pItem = mCurrentScript; if( ! pItem ) return; QString old_name; QString name = mpScriptsMainArea->lineEdit_scripts_name->text(); QString script = mpSourceEditorArea->editor->toPlainText(); mpScriptsMainAreaEditHandlerItem = 0; QList itemList; for( int i=0; ilistWidget_registered_event_handlers->count(); i++ ) { QListWidgetItem * pItem = mpScriptsMainArea->listWidget_registered_event_handlers->item(i); itemList << pItem; } QStringList handlerList; for( int i=0; itext().size() < 1 ) continue; handlerList << itemList[i]->text(); } if( pItem ) { int triggerID = pItem->data(0, Qt::UserRole).toInt(); TScript * pT = mpHost->getScriptUnit()->getScript( triggerID ); if( pT ) { old_name = pT->getName(); pT->setName( name ); pT->setEventHandlerList( handlerList ); pT->setScript( script ); pT->compile(); QIcon icon; if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { if( old_name == "New Script" || old_name == "New Script Group" ) { QIcon _icon; if( pT->isFolder() ) { _icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange.png")), QIcon::Normal, QIcon::Off); } else { _icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } pItem->setIcon( 0, _icon ); pItem->setText( 0, name ); pT->setIsActive( true ); } else { pItem->setIcon( 0, icon); pItem->setText( 0, name ); } } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); pItem->setText( 0, name ); } } } } void dlgTriggerEditor::slot_saveKeyAfterEdit() { return saveKey(); /*bool state = true; QString name = mpKeysMainArea->lineEdit_name->text(); if( name.size() < 1 ) { name = mpKeysMainArea->lineEdit_key->text(); } QString command = mpKeysMainArea->lineEdit_command->text(); QString script = mpSourceEditorArea->script_scintilla->text(); QTreeWidgetItem * pItem = treeWidget_keys->currentItem(); if( pItem ) { int triggerID = pItem->data(0, Qt::UserRole).toInt(); TKey * pT = mpHost->getKeyUnit()->getKey( triggerID ); if( pT ) { pItem->setText(0,name ); pT->setName( name ); pT->setCommand( command ); pT->setScript( script ); pT->setIsActive( true ); QIcon icon; if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, name ); showInfo( "Success, trigger compiled and is ready for activation. You can activate it with the padlock icon." ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); pItem->setText( 0, name ); } } }*/ } void dlgTriggerEditor::saveKey() { QTreeWidgetItem * pItem = mCurrentKey; if( ! pItem ) return; QString name = mpKeysMainArea->lineEdit_name->text(); if( name.size() < 1 ) { name = mpKeysMainArea->lineEdit_key->text(); } QString command = mpKeysMainArea->lineEdit_command->text(); QString script = mpSourceEditorArea->editor->toPlainText(); if( pItem ) { int triggerID = pItem->data(0, Qt::UserRole).toInt(); TKey * pT = mpHost->getKeyUnit()->getKey( triggerID ); if( pT ) { pItem->setText(0,name ); pT->setName( name ); pT->setCommand( command ); pT->setScript( script ); QIcon icon; if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet-locked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png")), QIcon::Normal, QIcon::Off); } } if( pT->state() ) { pItem->setIcon( 0, icon); pItem->setText( 0, name ); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); pItem->setText( 0, name ); } } } } void dlgTriggerEditor::slot_deleteProfile() { } void dlgTriggerEditor::slot_set_pattern_type_color( int type ) { QComboBox * pBox = (QComboBox *) sender(); if( ! pBox ) return; int row = pBox->itemData( 0 ).toInt(); if( row < 0 || row >= 50 ) return; dlgTriggerPatternEdit * pItem = mTriggerPatternEdit[row]; QPalette palette; switch( type ) { case 0: palette.setColor( QPalette::Text, QColor(0,0,0) ); pItem->lineEdit->show(); pItem->fgB->hide(); pItem->bgB->hide(); break; case 1: palette.setColor( QPalette::Text, QColor(0,0,255) ); pItem->lineEdit->show(); pItem->fgB->hide(); pItem->bgB->hide(); break; case 2: palette.setColor( QPalette::Text, QColor(195,0,0) ); pItem->lineEdit->show(); pItem->fgB->hide(); pItem->bgB->hide(); break; case 3: palette.setColor( QPalette::Text, QColor(0,195,0) ); pItem->lineEdit->show(); pItem->fgB->hide(); pItem->bgB->hide(); break; case 4: palette.setColor( QPalette::Text, QColor(0,155,155) ); pItem->lineEdit->show(); pItem->fgB->hide(); pItem->bgB->hide(); break; case 5: palette.setColor( QPalette::Text, QColor(137,0,205) ); pItem->lineEdit->show(); pItem->fgB->hide(); pItem->bgB->hide(); break; case 6: palette.setColor( QPalette::Text, QColor(100,100,100) ); pItem->lineEdit->hide(); pItem->fgB->show(); pItem->bgB->show(); break; } //pItem->setPalette( palette ); pItem->lineEdit->setPalette( palette ); } void dlgTriggerEditor::slot_trigger_clicked( QTreeWidgetItem *pItem, int column ) { QTime t; if( ! pItem ) return; mCurrentTrigger = pItem; mpTriggersMainArea->show(); mpSourceEditorArea->show(); mpSystemMessageArea->hide(); mpTriggersMainArea->lineEdit_trigger_name->setText(""); mpSourceEditorArea->editor->setPlainText( "" ); mpTriggersMainArea->checkBox_multlinetrigger->setChecked( false ); mpTriggersMainArea->perlSlashGOption->setChecked( false ); mpTriggersMainArea->filterTrigger->setChecked( false ); mpTriggersMainArea->spinBox_linemargin->setValue( 1 ); if( (pItem == 0) || (column != 0) ) return; int ID = pItem->data( 0, Qt::UserRole ).toInt(); TTrigger * pT = mpHost->getTriggerUnit()->getTrigger( ID ); if( pT ) { QStringList patternList = pT->getRegexCodeList(); QList propertyList = pT->getRegexCodePropertyList(); if( patternList.size() != propertyList.size() ) return; for( int i=0; i= 50 ) break; //pattern liste ist momentan auf 50 begrenzt if( i >= pT->mColorPatternList.size() ) { break; } dlgTriggerPatternEdit * pItem = mTriggerPatternEdit[i]; QComboBox * pBox = pItem->patternType; QPalette palette; switch( propertyList[i] ) { case REGEX_SUBSTRING: palette.setColor( QPalette::Text, QColor(0,0,0) ); pBox->setCurrentIndex( 0 ); pItem->fgB->hide(); pItem->bgB->hide(); pItem->lineEdit->show(); break; case REGEX_PERL: palette.setColor( QPalette::Text, QColor(0,0,255) ); pBox->setCurrentIndex( 1 ); pItem->fgB->hide(); pItem->bgB->hide(); pItem->lineEdit->show(); break; case REGEX_BEGIN_OF_LINE_SUBSTRING: palette.setColor( QPalette::Text, QColor(195,0,0) ); pBox->setCurrentIndex( 2 ); pItem->fgB->hide(); pItem->bgB->hide(); pItem->lineEdit->show(); break; case REGEX_EXACT_MATCH: palette.setColor( QPalette::Text, QColor(0,195,0) ); pBox->setCurrentIndex( 3 ); pItem->fgB->hide(); pItem->bgB->hide(); pItem->lineEdit->show(); break; case REGEX_LUA_CODE: palette.setColor( QPalette::Text, QColor(0,155,155) ); pBox->setCurrentIndex( 4 ); pItem->fgB->hide(); pItem->bgB->hide(); pItem->lineEdit->show(); break; case REGEX_LINE_SPACER: palette.setColor( QPalette::Text, QColor(137,0,205) ); pBox->setCurrentIndex( 5 ); pItem->fgB->hide(); pItem->bgB->hide(); pItem->lineEdit->show(); break; case REGEX_COLOR_PATTERN: palette.setColor( QPalette::Text, QColor(100,100,100) ); pBox->setCurrentIndex( 6 ); pItem->fgB->show(); pItem->bgB->show(); pItem->lineEdit->hide(); QPalette fgPal; QPalette bgPal; if( ! pT->mColorPatternList[i] ) break; QColor fgC = QColor(pT->mColorPatternList[i]->fgR, pT->mColorPatternList[i]->fgG, pT->mColorPatternList[i]->fgB); fgPal.setColor( QPalette::Button, fgC ); QString fgstyleSheet = QString("QPushButton{background-color:")+fgC.name()+QString(";}"); QColor bgC = QColor(pT->mColorPatternList[i]->bgR, pT->mColorPatternList[i]->bgG, pT->mColorPatternList[i]->bgB); bgPal.setColor( QPalette::Button, bgC ); QString bgstyleSheet = QString("QPushButton{background-color:")+bgC.name()+QString(";}"); pItem->fgB->setStyleSheet( fgstyleSheet ); pItem->bgB->setStyleSheet( bgstyleSheet ); break; } pItem->lineEdit->setPalette( palette ); pItem->lineEdit->setText( patternList[i] ); } for( int i=patternList.size(); i<50; i++) { mTriggerPatternEdit[i]->lineEdit->clear(); if( mTriggerPatternEdit[i]->lineEdit->isHidden() ) { mTriggerPatternEdit[i]->lineEdit->show(); } mTriggerPatternEdit[i]->fgB->hide(); mTriggerPatternEdit[i]->bgB->hide(); mTriggerPatternEdit[i]->patternType->setCurrentIndex(0); } QString command = pT->getCommand(); mpTriggersMainArea->lineEdit_trigger_name->setText(pItem->text(0)); mpTriggersMainArea->trigger_command->setText( command ); mpTriggersMainArea->checkBox_multlinetrigger->setChecked( pT->isMultiline() ); mpTriggersMainArea->perlSlashGOption->setChecked( pT->mPerlSlashGOption ); mpTriggersMainArea->filterTrigger->setChecked( pT->mFilterTrigger ); mpTriggersMainArea->spinBox_linemargin->setValue( pT->getConditionLineDelta() ); mpTriggersMainArea->spinBox_stayOpen->setValue( pT->mStayOpen ); mpTriggersMainArea->soundTrigger->setChecked( pT->mSoundTrigger ); mpTriggersMainArea->lineEdit_soundFile->setText( pT->mSoundFile ); QPalette pal = palette(); QColor color = pal.color( QPalette::Button ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); QColor fgColor = pT->getFgColor(); QColor bgColor = pT->getBgColor(); QPalette FgColorPalette; QPalette BgColorPalette; FgColorPalette.setColor( QPalette::Button, fgColor ); BgColorPalette.setColor( QPalette::Button, bgColor ); QString FgColorStyleSheet = QString("QPushButton{background-color:")+fgColor.name()+QString(";}"); QString BgColorStyleSheet = QString("QPushButton{background-color:")+bgColor.name()+QString(";}"); mpTriggersMainArea->pushButtonFgColor->setStyleSheet( FgColorStyleSheet ); mpTriggersMainArea->pushButtonBgColor->setStyleSheet( BgColorStyleSheet ); mpTriggersMainArea->pushButtonFgColor->setPalette( FgColorPalette ); mpTriggersMainArea->pushButtonBgColor->setPalette( BgColorPalette ); mpTriggersMainArea->colorizerTrigger->setChecked( pT->isColorizerTrigger() ); QString script = pT->getScript(); mpSourceEditorArea->editor->setPlainText( script ); /*mpTriggersMainArea->colorTrigger->setChecked( pT->mColorTrigger ); if( pT->mColorTriggerBg ) { QPalette palette; QColor color = pT->mColorTriggerBgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); mpTriggersMainArea->colorTriggerBg->setStyleSheet( styleSheet ); } if( pT->mColorTriggerFg ) { QPalette palette; QColor color = pT->mColorTriggerFgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); mpTriggersMainArea->colorTriggerFg->setStyleSheet( styleSheet ); }*/ if( ! pT->state() ) showError( pT->getError() ); } } void dlgTriggerEditor::slot_alias_clicked( QTreeWidgetItem *pItem, int column ) { if( ! pItem ) return; mCurrentAlias = pItem; mpAliasMainArea->show(); mpSourceEditorArea->show(); mpSystemMessageArea->hide(); mpAliasMainArea->lineEdit_alias_name->clear(); mpAliasMainArea->pattern_textedit->clear(); mpAliasMainArea->substitution->clear(); mpSourceEditorArea->editor->setPlainText( "" ); if( (pItem == 0) || (column != 0) ) { return; } mpAliasMainArea->lineEdit_alias_name->setText(pItem->text(0)); int ID = pItem->data(0,Qt::UserRole).toInt(); TAlias * pT = mpHost->getAliasUnit()->getAlias(ID); if( pT ) { QString pattern = pT->getRegexCode(); QString command = pT->getCommand(); QString name = pT->getName(); mpAliasMainArea->pattern_textedit->clear(); mpAliasMainArea->substitution->clear(); mpAliasMainArea->lineEdit_alias_name->clear(); mpAliasMainArea->pattern_textedit->setText( pattern ); mpAliasMainArea->substitution->setText( command ); mpAliasMainArea->lineEdit_alias_name->setText( name ); QString script = pT->getScript(); mpSourceEditorArea->editor->setPlainText( script ); if( ! pT->state() ) showError( pT->getError() ); } } void dlgTriggerEditor::slot_key_clicked( QTreeWidgetItem *pItem, int column ) { if( ! pItem ) return; mCurrentKey = pItem; mpKeysMainArea->show(); mpSourceEditorArea->show(); mpSystemMessageArea->hide(); mpKeysMainArea->lineEdit_command->clear(); mpKeysMainArea->lineEdit_key->clear(); mpKeysMainArea->lineEdit_name->clear(); mpSourceEditorArea->editor->setPlainText( "" ); if( (pItem == 0) || (column != 0) ) { return; } mpKeysMainArea->lineEdit_key->setText( pItem->text(0) ); int ID = pItem->data( 0, Qt::UserRole ).toInt(); TKey * pT = mpHost->getKeyUnit()->getKey(ID); if( pT ) { QString command = pT->getCommand(); QString name = pT->getName(); mpKeysMainArea->lineEdit_command->clear(); mpKeysMainArea->lineEdit_command->setText( command ); mpKeysMainArea->lineEdit_name->setText( name ); QString keyName = mpHost->getKeyUnit()->getKeyName( pT->getKeyCode(), pT->getKeyModifiers() ); mpKeysMainArea->lineEdit_key->setText( keyName ); QString script = pT->getScript(); mpSourceEditorArea->editor->setPlainText( script ); if( ! pT->state() ) showError( pT->getError() ); } } void dlgTriggerEditor::slot_action_clicked( QTreeWidgetItem *pItem, int column ) { if( ! pItem ) return; mCurrentAction = pItem; mpActionsMainArea->show(); mpSourceEditorArea->editor->show(); mpSystemMessageArea->hide(); mpActionsMainArea->lineEdit_action_button_down->clear(); mpSourceEditorArea->editor->setPlainText( "" ); mpActionsMainArea->lineEdit_action_button_up->clear(); mpActionsMainArea->lineEdit_action_icon->clear(); mpActionsMainArea->lineEdit_action_name->clear(); mpActionsMainArea->checkBox_pushdownbutton->setChecked( false ); mpActionsMainArea->buttonColumns->clear(); //mpActionsMainArea->isLabel->setChecked(false); mpActionsMainArea->useCustomLayout->setChecked(false); mpActionsMainArea->buttonPosX->setText("0"); mpActionsMainArea->buttonPosY->setText("0"); mpActionsMainArea->buttonSizeX->setText("80"); mpActionsMainArea->buttonSizeY->setText("25"); //mpActionsMainArea->buttonFlat->setChecked(false); //mpActionsMainArea->isLabel->setChecked(false); mpActionsMainArea->useCustomLayout->setChecked(false); mpActionsMainArea->css->clear(); if( (pItem == 0) || (column != 0) ) { return; } mpCurrentActionItem = pItem; //remember what has been clicked to save it int ID = pItem->data(0,Qt::UserRole).toInt(); TAction * pT = mpHost->getActionUnit()->getAction(ID); if( pT ) { mpActionsMainArea->lineEdit_action_name->setText( pT->getName() ); mpActionsMainArea->checkBox_pushdownbutton->setChecked( pT->isPushDownButton() ); mpActionsMainArea->lineEdit_action_button_down->setText( pT->getCommandButtonDown() ); mpActionsMainArea->lineEdit_action_button_up->setText( pT->getCommandButtonUp() ); mpActionsMainArea->lineEdit_action_icon->setText( pT->getIcon() ); mpSourceEditorArea->editor->setPlainText( pT->getScript() ); // location = 1 = location = bottom is no longer supported int location = pT->mLocation; if( location > 0 ) location--; mpActionsMainArea->comboBox_location->setCurrentIndex( location ); mpActionsMainArea->comboBox_orientation->setCurrentIndex( pT->mOrientation ); QColor color = pT->getButtonColor(); QPalette palette; palette.setColor( QPalette::Button, color ); mpActionsMainArea->pushButton_color->setPalette( palette ); mpActionsMainArea->buttonRotation->setCurrentIndex( pT->getButtonRotation() ); mpActionsMainArea->buttonColumns->setText( QString::number(pT->getButtonColumns()) ); // mpActionsMainArea->buttonFlat->setChecked( pT->getButtonFlat() ); mpActionsMainArea->buttonSizeX->setText(QString::number(pT->getSizeX()) ); mpActionsMainArea->buttonSizeY->setText(QString::number(pT->getSizeY()) ); //mpActionsMainArea->isLabel->setChecked( pT->mIsLabel ); mpActionsMainArea->useCustomLayout->setChecked( pT->mUseCustomLayout ); mpActionsMainArea->buttonPosX->setText( QString::number(pT->mPosX) ); mpActionsMainArea->buttonPosY->setText( QString::number(pT->mPosY) ); mpActionsMainArea->buttonSizeX->setText( QString::number(pT->mSizeX) ); mpActionsMainArea->buttonSizeY->setText( QString::number(pT->mSizeY) ); mpActionsMainArea->css->clear(); mpActionsMainArea->css->setPlainText( pT->css ); if( ! pT->getParent() ) { mpActionsMainArea->groupBox_toolBar->show(); mpActionsMainArea->groupBox_appearance->hide(); } else { mpActionsMainArea->groupBox_toolBar->hide(); mpActionsMainArea->groupBox_appearance->show(); } if( ! pT->state() ) showError( pT->getError() ); } } void dlgTriggerEditor::slot_scripts_clicked( QTreeWidgetItem *pItem, int column ) { if( ! pItem ) return; mCurrentScript = pItem; mpScriptsMainArea->show(); mpSourceEditorArea->show(); mpSystemMessageArea->hide(); mpSourceEditorArea->editor->setPlainText( "" ); mpScriptsMainArea->lineEdit_scripts_name->clear(); mpScriptsMainArea->listWidget_registered_event_handlers->clear(); if( (pItem == 0) || (column != 0) ) { return; } mpScriptsMainArea->listWidget_registered_event_handlers->clear(); mpScriptsMainArea->lineEdit_scripts_name->setText(pItem->text(0)); int ID = pItem->data(0,Qt::UserRole).toInt(); TScript * pT = mpHost->getScriptUnit()->getScript(ID); if( pT ) { QString name = pT->getName(); QStringList eventHandlerList = pT->getEventHandlerList(); for( int i=0; ilistWidget_registered_event_handlers ); pItem->setText( eventHandlerList[i] ); mpScriptsMainArea->listWidget_registered_event_handlers->addItem( pItem ); } mpScriptsMainArea->lineEdit_scripts_name->clear(); QString script = pT->getScript(); mpSourceEditorArea->editor->setPlainText( script ); mpScriptsMainArea->lineEdit_scripts_name->setText( name ); if( ! pT->state() ) showError( pT->getError() ); } } void dlgTriggerEditor::slot_timer_clicked( QTreeWidgetItem *pItem, int column ) { if( ! pItem ) return; mCurrentTimer = pItem; mpTimersMainArea->show(); mpSourceEditorArea->show(); mpSystemMessageArea->hide(); mpSourceEditorArea->editor->setPlainText( "" ); mpTimersMainArea->lineEdit_command->clear(); mpTimersMainArea->lineEdit_timer_name->clear(); mpTimersMainArea->timeEdit_hours->clear(); mpTimersMainArea->timeEdit_minutes->clear(); mpTimersMainArea->timeEdit_seconds->clear(); mpTimersMainArea->timeEdit_msecs->clear(); if( (pItem == 0) || (column != 0) ) { return; } mpTimersMainArea->lineEdit_timer_name->setText(pItem->text(0)); int ID = pItem->data( 0, Qt::UserRole ).toInt(); TTimer * pT = mpHost->getTimerUnit()->getTimer( ID ); if( pT ) { if( pT->getParent() ) qDebug()<<"[STATUS]: timer ID="<getID()<<" name="<getName()<<" mActive = "<isActive()<<" mUserActiveState="<shouldBeActive()<<" parent="<getParent()->getName(); else qDebug()<<"[STATUS]: timer ID="<getID()<<" name="<getName()<<"> mActive = "<isActive()<<" mUserActiveState="<shouldBeActive()<<" parent=0"; QString command = pT->getCommand(); QString name = pT->getName(); mpTimersMainArea->lineEdit_command->setText( command ); mpTimersMainArea->lineEdit_timer_name->setText( name ); QTime time = pT->getTime(); int hours = time.hour(); int minutes = time.minute(); int secs = time.second(); int msecs = time.msec(); QTime t2(hours,0,0,0); mpTimersMainArea->timeEdit_hours->setTime(t2); QTime t3(0,minutes,0,0); mpTimersMainArea->timeEdit_minutes->setTime(t3); QTime t4(0,0,secs); mpTimersMainArea->timeEdit_seconds->setTime(t4); QTime t5(0,0,0,msecs); mpTimersMainArea->timeEdit_msecs->setTime(t5); QString script = pT->getScript(); mpSourceEditorArea->editor->setPlainText( script ); if( ! pT->state() ) showError( pT->getError() ); } } void dlgTriggerEditor::fillout_form() { mCurrentView = 0; mCurrentTrigger = 0; mCurrentAlias = 0; mCurrentKey = 0; mCurrentAction = 0; mCurrentScript = 0; mCurrentTimer = 0; mNeedUpdateData = false; QStringList sL; sL << "Triggers"; mpTriggerBaseItem = new QTreeWidgetItem( (QTreeWidgetItem*)0, sL ); mpTriggerBaseItem->setBackground(0,QColor(255,254,215,255)); QIcon mainIcon; mainIcon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-wizard.png")), QIcon::Normal, QIcon::Off); mpTriggerBaseItem->setIcon( 0, mainIcon ); treeWidget->insertTopLevelItem( 0, mpTriggerBaseItem ); list baseNodeList = mpHost->getTriggerUnit()->getTriggerRootNodeList(); typedef list::iterator IT; for(IT it=baseNodeList.begin(); it!=baseNodeList.end(); it++ ) { TTrigger * pT = *it; if( pT->isTempTrigger() ) continue; QString s = pT->getName(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( mpTriggerBaseItem, sList); pItem->setData( 0, Qt::UserRole, QVariant(pT->getID()) ); mpTriggerBaseItem->addChild( pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_triggers( pT, (QTreeWidgetItem*)pItem ); } if( pT->state() ) { if( pT->isFilterChain() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-locked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-grey-locked.png")), QIcon::Normal, QIcon::Off); } } } else if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue-locked.png"),0,Qt::MonoOnly), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png"),0,Qt::MonoOnly), QIcon::Normal, QIcon::Off); } } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png")), QIcon::Normal, QIcon::Off); } } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } mpTriggerBaseItem->setExpanded( true ); QStringList sL2; sL2 << "Timers"; mpTimerBaseItem = new QTreeWidgetItem( (QTreeWidgetItem*)0, sL2 ); mpTimerBaseItem->setBackground(0,QColor(255,254,215,255)); QIcon mainIcon2; mainIcon2.addPixmap(QPixmap(QString::fromUtf8(":/icons/chronometer.png")), QIcon::Normal, QIcon::Off); mpTimerBaseItem->setIcon( 0, mainIcon2 ); treeWidget_timers->insertTopLevelItem( 0, mpTimerBaseItem ); mpTriggerBaseItem->setExpanded( true ); list baseNodeList_timers = mpHost->getTimerUnit()->getTimerRootNodeList(); for( list::iterator it = baseNodeList_timers.begin(); it!=baseNodeList_timers.end(); it++ ) { TTimer * pT = *it; if( pT->isTempTimer() ) continue; QString s = pT->getName(); qDebug()<<"init: name="<getName()<<" mUserActiveState="<shouldBeActive(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( mpTimerBaseItem, sList); pItem->setData( 0, Qt::UserRole, QVariant(pT->getID()) ); mpTimerBaseItem->addChild( pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_timers( pT, (QTreeWidgetItem*)pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-green.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-green-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isOffsetTimer() ) { if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-on.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-off.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } mpTimerBaseItem->setExpanded( true ); QStringList sL3; sL3 << "Scripts"; mpScriptsBaseItem = new QTreeWidgetItem( (QTreeWidgetItem*)0, sL3 ); mpScriptsBaseItem->setBackground(0,QColor(255,254,215,255)); QIcon mainIcon3; mainIcon3.addPixmap(QPixmap(QString::fromUtf8(":/icons/accessories-text-editor.png")), QIcon::Normal, QIcon::Off); mpScriptsBaseItem->setIcon( 0, mainIcon3 ); treeWidget_scripts->insertTopLevelItem( 0, mpScriptsBaseItem ); mpScriptsBaseItem->setExpanded( true ); list baseNodeList_scripts = mpHost->getScriptUnit()->getScriptRootNodeList(); for( list::iterator it = baseNodeList_scripts.begin(); it!=baseNodeList_scripts.end(); it++ ) { TScript * pT = *it; QString s = pT->getName(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( mpScriptsBaseItem, sList); pItem->setData( 0, Qt::UserRole, QVariant(pT->getID()) ); mpScriptsBaseItem->addChild( pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_scripts( pT, (QTreeWidgetItem*)pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } mpScriptsBaseItem->setExpanded( true ); QStringList sL4; sL4 << "Aliases - Input Triggers"; mpAliasBaseItem = new QTreeWidgetItem( (QTreeWidgetItem*)0, sL4 ); mpAliasBaseItem->setBackground(0,QColor(255,254,215,255)); QIcon mainIcon4; mainIcon4.addPixmap(QPixmap(QString::fromUtf8(":/icons/system-users.png")), QIcon::Normal, QIcon::Off); mpAliasBaseItem->setIcon( 0, mainIcon4 ); treeWidget_alias->insertTopLevelItem( 0, mpAliasBaseItem ); mpAliasBaseItem->setExpanded( true ); list baseNodeList_alias = mpHost->getAliasUnit()->getAliasRootNodeList(); for( list::iterator it = baseNodeList_alias.begin(); it!=baseNodeList_alias.end(); it++ ) { TAlias * pT = *it; QString s = pT->getName(); // TTimer * pTimer = *it; QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( mpAliasBaseItem, sList); pItem->setData( 0, Qt::UserRole, QVariant(pT->getID()) ); mpAliasBaseItem->addChild( pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_alias( pT, (QTreeWidgetItem*)pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet-locked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png")), QIcon::Normal, QIcon::Off); } } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } mpAliasBaseItem->setExpanded( true ); QStringList sL5; sL5 << "Buttons"; mpActionBaseItem = new QTreeWidgetItem( (QTreeWidgetItem*)0, sL5 ); mpActionBaseItem->setBackground(0,QColor(255,254,215,255)); QIcon mainIcon5; mainIcon5.addPixmap(QPixmap(QString::fromUtf8(":/icons/bookmarks.png")), QIcon::Normal, QIcon::Off); mpActionBaseItem->setIcon( 0, mainIcon5 ); treeWidget_actions->insertTopLevelItem( 0, mpActionBaseItem ); mpActionBaseItem->setExpanded( true ); list baseNodeList_action = mpHost->getActionUnit()->getActionRootNodeList(); for( list::iterator it = baseNodeList_action.begin(); it!=baseNodeList_action.end(); it++ ) { TAction * pT = *it; QString s = pT->getName(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( mpActionBaseItem, sList); pItem->setData( 0, Qt::UserRole, QVariant(pT->getID()) ); mpActionBaseItem->addChild( pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_action( pT, (QTreeWidgetItem*)pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( ! pT->getParent() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-yellow.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-yellow-locked.png")), QIcon::Normal, QIcon::Off); } } else if( ! pT->getParent()->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-yellow.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-yellow-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan-locked.png")), QIcon::Normal, QIcon::Off); } } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } mpActionBaseItem->setExpanded( true ); QStringList sL6; sL5 << "Action Key Bindings"; mpKeyBaseItem = new QTreeWidgetItem( (QTreeWidgetItem*)0, sL6 ); mpKeyBaseItem->setBackground(0,QColor(255,254,215,255)); QIcon mainIcon6; mainIcon6.addPixmap(QPixmap(QString::fromUtf8(":/icons/preferences-desktop-keyboard.png")), QIcon::Normal, QIcon::Off); mpKeyBaseItem->setIcon( 0, mainIcon6 ); treeWidget_keys->insertTopLevelItem( 0, mpKeyBaseItem ); mpKeyBaseItem->setExpanded( true ); list baseNodeList_key = mpHost->getKeyUnit()->getKeyRootNodeList(); for( list::iterator it = baseNodeList_key.begin(); it!=baseNodeList_key.end(); it++ ) { TKey * pT = *it; QString s = pT->getName(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( mpKeyBaseItem, sList); pItem->setData( 0, Qt::UserRole, QVariant(pT->getID()) ); mpKeyBaseItem->addChild( pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_key( pT, (QTreeWidgetItem*)pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( ! pT->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-brown-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan-locked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png")), QIcon::Normal, QIcon::Off); } } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } mpKeyBaseItem->setExpanded( true ); } void dlgTriggerEditor::expand_child_triggers( TTrigger * pTriggerParent, QTreeWidgetItem * pWidgetItemParent ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { TTrigger * pT = *it; QString s = pT->getName(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( pWidgetItemParent, sList); pItem->setData( 0, Qt::UserRole, pT->getID() ); pWidgetItemParent->insertChild( 0, pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_triggers( pT, pItem ); } if( pT->state() ) { if( pT->isFilterChain() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-locked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/filter-grey-locked.png")), QIcon::Normal, QIcon::Off); } } } else if( pT->isFolder() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue-locked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->ancestorsActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png"),0,Qt::MonoOnly), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png"),0,Qt::MonoOnly), QIcon::Normal, QIcon::Off); } } } //pItem->setDisabled(!pT->ancestorsActive()); pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } } void dlgTriggerEditor::expand_child_key( TKey * pTriggerParent, QTreeWidgetItem * pWidgetItemParent ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { TKey * pT = *it; QString s = pT->getName(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( pWidgetItemParent, sList); pItem->setData( 0, Qt::UserRole, pT->getID() ); pWidgetItemParent->insertChild( 0, pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_key( pT, pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-blue-locked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png")), QIcon::Normal, QIcon::Off); } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } } void dlgTriggerEditor::expand_child_scripts( TScript * pTriggerParent, QTreeWidgetItem * pWidgetItemParent ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { TScript * pT = *it; QString s = pT->getName(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( pWidgetItemParent, sList); pItem->setData( 0, Qt::UserRole, pT->getID() ); pWidgetItemParent->insertChild( 0, pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_scripts( pT, pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-orange-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } } void dlgTriggerEditor::expand_child_alias( TAlias * pTriggerParent, QTreeWidgetItem * pWidgetItemParent ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { TAlias * pT = *it; QString s = pT->getName(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( pWidgetItemParent, sList); pItem->setData( 0, Qt::UserRole, pT->getID() ); pWidgetItemParent->insertChild( 0, pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_alias( pT, pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-violet-locked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-grey-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked_grey.png")), QIcon::Normal, QIcon::Off); } else { if( pT->ancestorsActive() ) icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); else icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox-grey.png")), QIcon::Normal, QIcon::Off); } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } } void dlgTriggerEditor::expand_child_action( TAction * pTriggerParent, QTreeWidgetItem * pWidgetItemParent ) { list * childrenList = pTriggerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { TAction * pT = *it; QString s = pT->getName(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( pWidgetItemParent, sList); pItem->setData( 0, Qt::UserRole, pT->getID() ); pWidgetItemParent->insertChild( 0, pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_action( pT, pItem ); } if( pT->state() ) { if( ! pT->getParent()->mPackageName.isEmpty() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-yellow.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-yellow-locked.png")), QIcon::Normal, QIcon::Off); } } else if( pT->isFolder() ) { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-cyan-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } } } void dlgTriggerEditor::expand_child_timers( TTimer * pTimerParent, QTreeWidgetItem * pWidgetItemParent ) { list * childrenList = pTimerParent->getChildrenList(); typedef list::iterator I; for( I it=childrenList->begin(); it!=childrenList->end(); it++ ) { TTimer * pT = *it; QString s = pT->getName(); QStringList sList; sList << s; QTreeWidgetItem * pItem = new QTreeWidgetItem( pWidgetItemParent, sList); pItem->setData( 0, Qt::UserRole, pT->getID() ); pWidgetItemParent->insertChild( 0, pItem ); QIcon icon; if( pT->hasChildren() ) { expand_child_timers( pT, pItem ); } if( pT->state() ) { if( pT->isFolder() ) { if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-green.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/folder-green-locked.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->isOffsetTimer() ) { if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-on.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/offsettimer-off.png")), QIcon::Normal, QIcon::Off); } } else { if( pT->shouldBeActive() ) { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox_checked.png")), QIcon::Normal, QIcon::Off); } else { icon.addPixmap(QPixmap(QString::fromUtf8(":/icons/tag_checkbox.png")), QIcon::Normal, QIcon::Off); } } } pItem->setIcon(0, icon); } else { QIcon iconError; iconError.addPixmap(QPixmap(QString::fromUtf8(":/icons/tools-report-bug.png")), QIcon::Normal, QIcon::Off); pItem->setIcon( 0, iconError ); showError( pT->getError() ); } qDebug()<<"WARNING: dlgTriggerEditor::expand_child_timers() called name:"<getName(); // if( pT->isActive() ) // { // pT->enableTimer();// pT->getName() ); // } // else // { // pT->disableTimer();// pT->getName() ); // } } } void dlgTriggerEditor::slot_connection_dlg_finnished() { } void dlgTriggerEditor::slot_update() { update(); } void dlgTriggerEditor::slot_show_search_area() { if( mpSearchArea->isVisible() ) { mpSearchArea->hide(); popupArea->hide(); } else { mpSearchArea->show(); popupArea->show(); } } void dlgTriggerEditor::saveOpenChanges() { if( !mCurrentView ) { return; } switch( mCurrentView ) { case cmTriggerView: saveTrigger(); break; case cmTimerView: saveTimer(); break; case cmAliasView: saveAlias(); break; case cmScriptView: saveScript(); break; case cmActionView: saveAction(); break; case cmKeysView: saveKey(); break; }; } void dlgTriggerEditor::enterEvent( QEvent *pE ) { if( mNeedUpdateData ) { treeWidget->clear(); treeWidget_alias->clear(); treeWidget_timers->clear(); treeWidget_scripts->clear(); treeWidget_actions->clear(); treeWidget_keys->clear(); fillout_form(); mNeedUpdateData = false; } //QWidget::enterEvent( pE ); } void dlgTriggerEditor::focusInEvent( QFocusEvent * pE ) { if( mNeedUpdateData ) { treeWidget->clear(); treeWidget_alias->clear(); treeWidget_timers->clear(); treeWidget_scripts->clear(); treeWidget_actions->clear(); treeWidget_keys->clear(); fillout_form(); mNeedUpdateData = false; } if( ! mCurrentView ) { mCurrentTrigger = 0; mCurrentAlias = 0; mCurrentKey = 0; mCurrentAction = 0; mCurrentScript = 0; mCurrentTimer = 0; return; } if( mCurrentTrigger ) mCurrentTrigger->setSelected( true ); if( mCurrentTimer ) mCurrentTimer->setSelected( true ); if( mCurrentAlias ) mCurrentAlias->setSelected( true ); if( mCurrentScript ) mCurrentScript->setSelected( true ); if( mCurrentAction ) mCurrentAction->setSelected( true ); if( mCurrentKey ) mCurrentKey->setSelected( true ); //QWidget::focusInEvent( pE ); } void dlgTriggerEditor::focusOutEvent( QFocusEvent * pE ) { saveOpenChanges(); } void dlgTriggerEditor::slot_show_timers() { saveOpenChanges(); if( mNeedUpdateData ) { treeWidget->clear(); treeWidget_alias->clear(); treeWidget_timers->clear(); treeWidget_scripts->clear(); treeWidget_actions->clear(); treeWidget_keys->clear(); fillout_form(); mNeedUpdateData = false; } mCurrentView = cmTimerView; mpTriggersMainArea->hide(); mpTimersMainArea->hide(); mpScriptsMainArea->hide(); mpAliasMainArea->hide(); mpActionsMainArea->hide(); mpKeysMainArea->hide(); mpSystemMessageArea->hide(); mpOptionsAreaTriggers->hide(); mpOptionsAreaAlias->hide(); mpOptionsAreaScripts->hide(); mpOptionsAreaTimers->hide(); mpOptionsAreaActions->hide(); treeWidget->hide(); treeWidget_alias->hide(); treeWidget_timers->hide(); treeWidget_scripts->hide(); treeWidget_actions->hide(); treeWidget_keys->hide(); QTreeWidgetItem * pI = treeWidget_timers->topLevelItem( 0 ); if( pI ) { if( pI->childCount() > 0 ) { mpTimersMainArea->show(); mpSourceEditorArea->show(); slot_timer_clicked( treeWidget_timers->currentItem(), 0 ); } else { mpTimersMainArea->hide(); mpSystemMessageArea->show(); mpSourceEditorArea->hide(); mpSystemMessageArea->notificationAreaIconLabelInformation->show(); mpSystemMessageArea->notificationAreaIconLabelError->hide(); mpSystemMessageArea->notificationAreaIconLabelWarning->hide(); QString msg = "To add a timer click on the 'Add' icon above."; mpSystemMessageArea->notificationAreaMessageBox->setText( msg ); } } treeWidget_timers->show(); } void dlgTriggerEditor::slot_show_triggers() { saveOpenChanges(); if( mNeedUpdateData ) { treeWidget->clear(); treeWidget_alias->clear(); treeWidget_timers->clear(); treeWidget_scripts->clear(); treeWidget_actions->clear(); treeWidget_keys->clear(); fillout_form(); mNeedUpdateData = false; } mCurrentView = cmTriggerView; mpTriggersMainArea->hide(); mpTimersMainArea->hide(); mpScriptsMainArea->hide(); mpAliasMainArea->hide(); mpActionsMainArea->hide(); mpKeysMainArea->hide(); mpSystemMessageArea->hide(); mpOptionsAreaTriggers->hide(); mpOptionsAreaAlias->hide(); mpOptionsAreaScripts->hide(); mpOptionsAreaTimers->hide(); mpOptionsAreaActions->hide(); treeWidget->hide(); treeWidget_alias->hide(); treeWidget_timers->hide(); treeWidget_scripts->hide(); treeWidget_actions->hide(); treeWidget_keys->hide(); QTreeWidgetItem * pI = treeWidget->topLevelItem( 0 ); if( pI ) { if( pI->childCount() > 0 ) { mpTriggersMainArea->show(); mpSourceEditorArea->show(); slot_trigger_clicked( treeWidget->currentItem(), 0 ); } else { mpTriggersMainArea->hide(); mpSourceEditorArea->hide(); mpSystemMessageArea->show(); mpSystemMessageArea->notificationAreaIconLabelInformation->show(); mpSystemMessageArea->notificationAreaIconLabelError->hide(); mpSystemMessageArea->notificationAreaIconLabelWarning->hide(); QString msg = "To add a trigger click on the 'Add' icon above."; mpSystemMessageArea->notificationAreaMessageBox->setText( msg ); } } treeWidget->show(); } void dlgTriggerEditor::slot_show_scripts() { saveOpenChanges(); if( mNeedUpdateData ) { treeWidget->clear(); treeWidget_alias->clear(); treeWidget_timers->clear(); treeWidget_scripts->clear(); treeWidget_actions->clear(); treeWidget_keys->clear(); fillout_form(); mNeedUpdateData = false; } mCurrentView = cmScriptView; mpTriggersMainArea->hide(); mpTimersMainArea->hide(); mpScriptsMainArea->hide(); mpAliasMainArea->hide(); mpActionsMainArea->hide(); mpKeysMainArea->hide(); mpSystemMessageArea->hide(); mpOptionsAreaTriggers->hide(); mpOptionsAreaAlias->hide(); mpOptionsAreaScripts->hide(); mpOptionsAreaTimers->hide(); mpOptionsAreaActions->hide(); treeWidget->hide(); treeWidget_alias->hide(); treeWidget_timers->hide(); treeWidget_scripts->hide(); treeWidget_actions->hide(); mpScriptsMainArea->hide(); treeWidget_keys->hide(); QTreeWidgetItem * pI = treeWidget_scripts->topLevelItem( 0 ); if( pI ) { if( pI->childCount() > 0 ) { mpScriptsMainArea->show(); mpSourceEditorArea->show(); slot_scripts_clicked( treeWidget_scripts->currentItem(), 0 ); } else { mpScriptsMainArea->hide(); mpSourceEditorArea->hide(); mpSystemMessageArea->show(); mpSystemMessageArea->notificationAreaIconLabelInformation->show(); mpSystemMessageArea->notificationAreaIconLabelError->hide(); mpSystemMessageArea->notificationAreaIconLabelWarning->hide(); QString msg = "To make a new general purpose script click on the 'Add' icon above."; mpSystemMessageArea->notificationAreaMessageBox->setText( msg ); } } treeWidget_scripts->show(); } void dlgTriggerEditor::slot_show_keys() { saveOpenChanges(); if( mNeedUpdateData ) { treeWidget->clear(); treeWidget_alias->clear(); treeWidget_timers->clear(); treeWidget_scripts->clear(); treeWidget_actions->clear(); treeWidget_keys->clear(); fillout_form(); mNeedUpdateData = false; } mCurrentView = cmKeysView; mpTriggersMainArea->hide(); mpTimersMainArea->hide(); mpScriptsMainArea->hide(); mpAliasMainArea->hide(); mpActionsMainArea->hide(); mpKeysMainArea->hide(); mpSystemMessageArea->hide(); mpOptionsAreaTriggers->hide(); mpOptionsAreaAlias->hide(); mpOptionsAreaScripts->hide(); mpOptionsAreaTimers->hide(); mpOptionsAreaActions->hide(); treeWidget->hide(); treeWidget_alias->hide(); treeWidget_timers->hide(); treeWidget_scripts->hide(); treeWidget_actions->hide(); treeWidget_keys->hide(); QTreeWidgetItem * pI = treeWidget_keys->topLevelItem( 0 ); if( pI ) { if( pI->childCount() > 0 ) { mpKeysMainArea->show(); mpSourceEditorArea->show(); slot_key_clicked( treeWidget_keys->currentItem(), 0 ); } else { mpKeysMainArea->hide(); mpSourceEditorArea->hide(); mpSystemMessageArea->show(); mpSystemMessageArea->notificationAreaIconLabelInformation->show(); mpSystemMessageArea->notificationAreaIconLabelError->hide(); mpSystemMessageArea->notificationAreaIconLabelWarning->hide(); QString msg = "To make a new key binding click on the 'Add' icon above."; mpSystemMessageArea->notificationAreaMessageBox->setText( msg ); } } treeWidget_keys->show(); } void dlgTriggerEditor::slot_show_aliases() { saveOpenChanges(); if( mNeedUpdateData ) { treeWidget->clear(); treeWidget_alias->clear(); treeWidget_timers->clear(); treeWidget_scripts->clear(); treeWidget_actions->clear(); treeWidget_keys->clear(); fillout_form(); mNeedUpdateData = false; } mCurrentView = cmAliasView; mpTriggersMainArea->hide(); mpTimersMainArea->hide(); mpScriptsMainArea->hide(); mpAliasMainArea->hide(); mpActionsMainArea->hide(); mpKeysMainArea->hide(); mpSourceEditorArea->hide(); mpSystemMessageArea->hide(); mpOptionsAreaTriggers->hide(); mpOptionsAreaAlias->hide(); mpOptionsAreaScripts->hide(); mpOptionsAreaTimers->hide(); mpOptionsAreaActions->hide(); treeWidget->hide(); treeWidget_alias->hide(); treeWidget_timers->hide(); treeWidget_scripts->hide(); treeWidget_actions->hide(); treeWidget_keys->hide(); QTreeWidgetItem * pI = treeWidget_alias->topLevelItem( 0 ); if( pI ) { if( pI->childCount() > 0 ) { mpAliasMainArea->show(); mpSourceEditorArea->show(); slot_alias_clicked( treeWidget_alias->currentItem(), 0 ); } else { mpAliasMainArea->hide(); mpSourceEditorArea->hide(); mpSystemMessageArea->show(); mpSystemMessageArea->notificationAreaIconLabelInformation->show(); mpSystemMessageArea->notificationAreaIconLabelError->hide(); mpSystemMessageArea->notificationAreaIconLabelWarning->hide(); QString msg = "To make a new alias click on the 'Add' icon above."; mpSystemMessageArea->notificationAreaMessageBox->setText( msg ); } } treeWidget_alias->show(); } void dlgTriggerEditor::showError( QString error ) { mpSystemMessageArea->notificationAreaIconLabelInformation->hide(); mpSystemMessageArea->notificationAreaIconLabelError->show(); mpSystemMessageArea->notificationAreaIconLabelWarning->hide(); mpSystemMessageArea->notificationAreaMessageBox->setText( error ); mpSystemMessageArea->show(); } void dlgTriggerEditor::showInfo( QString error ) { mpSystemMessageArea->notificationAreaIconLabelError->hide(); mpSystemMessageArea->notificationAreaIconLabelWarning->hide(); mpSystemMessageArea->notificationAreaIconLabelInformation->show(); mpSystemMessageArea->notificationAreaMessageBox->setText( error ); mpSystemMessageArea->show(); } void dlgTriggerEditor::showWarning( QString error ) { mpSystemMessageArea->notificationAreaIconLabelInformation->hide(); mpSystemMessageArea->notificationAreaIconLabelError->hide(); mpSystemMessageArea->notificationAreaIconLabelWarning->show(); mpSystemMessageArea->notificationAreaMessageBox->setText( error ); mpSystemMessageArea->show(); } void dlgTriggerEditor::slot_show_actions() { saveOpenChanges(); mCurrentView = cmActionView; mpTriggersMainArea->hide(); mpTimersMainArea->hide(); mpScriptsMainArea->hide(); mpAliasMainArea->hide(); mpActionsMainArea->hide(); mpKeysMainArea->hide(); mpSourceEditorArea->hide(); mpSystemMessageArea->hide(); mpOptionsAreaTriggers->hide(); mpOptionsAreaAlias->hide(); mpOptionsAreaScripts->hide(); mpOptionsAreaTimers->hide(); mpOptionsAreaActions->hide(); treeWidget->hide(); treeWidget_alias->hide(); treeWidget_timers->hide(); treeWidget_scripts->hide(); treeWidget_keys->hide(); QTreeWidgetItem * pI = treeWidget_actions->topLevelItem( 0 ); if( pI ) { if( pI->childCount() > 0 ) { mpActionsMainArea->show(); mpSourceEditorArea->show(); slot_action_clicked( treeWidget_actions->currentItem(), 0 ); } else { mpActionsMainArea->hide(); mpSystemMessageArea->show(); mpSystemMessageArea->notificationAreaIconLabelInformation->show(); mpSystemMessageArea->notificationAreaIconLabelError->hide(); mpSystemMessageArea->notificationAreaIconLabelWarning->hide(); QString msg = "To make a new button, you have to add a button bar first and then add buttons to the group. Click on the 'Add Group' icon above to make a button bar."; mpSystemMessageArea->notificationAreaMessageBox->setText( msg ); } } treeWidget_actions->show(); } void dlgTriggerEditor::slot_save_edit() { switch( mCurrentView ) { case cmTriggerView: slot_saveTriggerAfterEdit(); break; case cmTimerView: slot_saveTimerAfterEdit(); break; case cmAliasView: slot_saveAliasAfterEdit(); break; case cmScriptView: slot_saveScriptAfterEdit(); break; case cmActionView: slot_saveActionAfterEdit(); break; case cmKeysView: slot_saveKeyAfterEdit(); break; default: qWarning()<<"ERROR: dlgTriggerEditor::slot_save_edit() undefined view"; }; mpHost->serialize(); } void dlgTriggerEditor::slot_add_new() { switch( mCurrentView ) { case cmTriggerView: slot_addTrigger(); break; case cmTimerView: slot_addTimer(); break; case cmAliasView: slot_addAlias(); break; case cmScriptView: slot_addScript(); break; case cmActionView: slot_addAction(); break; case cmKeysView: slot_addKey(); break; default: qDebug()<<"ERROR: dlgTriggerEditor::slot_save_edit() undefined view"; }; } void dlgTriggerEditor::slot_add_new_folder() { switch( mCurrentView ) { case cmTriggerView: slot_addTriggerGroup(); break; case cmTimerView: slot_addTimerGroup(); break; case cmAliasView: slot_addAliasGroup(); break; case cmScriptView: slot_addScriptGroup(); break; case cmActionView: slot_addActionGroup(); break; case cmKeysView: slot_addKeyGroup(); break; default: qDebug()<<"ERROR: dlgTriggerEditor::slot_save_edit() undefined view"; }; } void dlgTriggerEditor::slot_toggle_active() { switch( mCurrentView ) { case cmTriggerView: slot_trigger_toggle_active(); break; case cmTimerView: slot_timer_toggle_active(); break; case cmAliasView: slot_alias_toggle_active(); break; case cmScriptView: slot_script_toggle_active(); break; case cmActionView: slot_action_toggle_active(); break; case cmKeysView: slot_key_toggle_active(); break; default: qDebug()<<"ERROR: dlgTriggerEditor::slot_save_edit() undefined view"; }; } void dlgTriggerEditor::slot_delete_item() { switch( mCurrentView ) { case cmTriggerView: slot_deleteTrigger(); break; case cmTimerView: slot_deleteTimer(); break; case cmAliasView: slot_deleteAlias(); break; case cmScriptView: slot_deleteScript(); break; case cmActionView: slot_deleteAction(); break; case cmKeysView: slot_deleteKey(); break; default: qDebug()<<"ERROR: dlgTriggerEditor::slot_save_edit() undefined view"; }; } void dlgTriggerEditor::slot_itemClicked( QTreeWidgetItem * pItem, int column ) { if( ! pItem ) return; switch( mCurrentView ) { case cmTriggerView: saveTrigger(); break; case cmTimerView: saveTimer(); break; case cmAliasView: saveAlias(); break; case cmScriptView: saveScript(); break; case cmActionView: saveAction(); break; case cmKeysView: saveKey(); break; }; } void dlgTriggerEditor::slot_script_main_area_edit_handler(QListWidgetItem*) { QListWidgetItem * pItem = mpScriptsMainArea->listWidget_registered_event_handlers->currentItem(); if( ! pItem ) return; mIsScriptsMainAreaEditHandler = true; mpScriptsMainAreaEditHandlerItem = pItem; QString regex = pItem->text(); if( regex.size() < 1 ) { mIsScriptsMainAreaEditHandler = false; return; } mpScriptsMainArea->lineEdit->setText( regex ); } void dlgTriggerEditor::slot_script_main_area_delete_handler() { mpScriptsMainArea->listWidget_registered_event_handlers->takeItem( mpScriptsMainArea->listWidget_registered_event_handlers->currentRow() ); } void dlgTriggerEditor::slot_script_main_area_add_handler() { if( mIsScriptsMainAreaEditHandler ) { if( ! mpScriptsMainAreaEditHandlerItem ) { mIsScriptsMainAreaEditHandler = false; goto LAZY; return; } QListWidgetItem * pItem = mpScriptsMainArea->listWidget_registered_event_handlers->currentItem(); if( ! pItem ) return; pItem->setText( mpScriptsMainArea->lineEdit->text() ); mIsScriptsMainAreaEditHandler = false; mpScriptsMainAreaEditHandlerItem = 0; } else { LAZY: QListWidgetItem * pItem = new QListWidgetItem; pItem->setText( mpScriptsMainArea->lineEdit->text() ); mpScriptsMainArea->listWidget_registered_event_handlers->addItem( pItem ); } mpScriptsMainArea->lineEdit->clear(); } void dlgTriggerEditor::slot_debug_mode() { mudlet::mpDebugArea->setVisible(!mudlet::debugMode); mudlet::debugMode = !mudlet::debugMode; mudlet::mpDebugArea->setWindowTitle("Central Debug Console"); } void dlgTriggerEditor::exportTrigger( QFile & file ) { QString name; TTrigger * pT = 0; QTreeWidgetItem * pItem = treeWidget->currentItem(); if( pItem ) { int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); pT = mpHost->getTriggerUnit()->getTrigger( triggerID ); if( pT ) { name = pT->getName(); } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } XMLexport writer( pT ); if( writer.exportTrigger( & file ) ) { statusBar()->showMessage(tr("Package ")+name+tr(" saved"), 2000); } } void dlgTriggerEditor::exportTimer( QFile & file ) { QString name; TTimer * pT = 0; QTreeWidgetItem * pItem = treeWidget_timers->currentItem(); if( pItem ) { int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); pT = mpHost->getTimerUnit()->getTimer( triggerID ); if( pT ) { name = pT->getName(); } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } XMLexport writer( pT ); if( writer.exportTimer( & file ) ) { statusBar()->showMessage(tr("Package")+name+tr(" saved"), 2000); } } void dlgTriggerEditor::exportAlias( QFile & file ) { QString name; TAlias * pT = 0; QTreeWidgetItem * pItem = treeWidget_alias->currentItem(); if( pItem ) { int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); pT = mpHost->getAliasUnit()->getAlias( triggerID ); if( pT ) { name = pT->getName(); } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } XMLexport writer( pT ); if( writer.exportAlias( & file ) ) { statusBar()->showMessage(tr("Package ")+name+tr(" saved"), 2000); } } void dlgTriggerEditor::exportAction( QFile & file ) { QString name; TAction * pT = 0; QTreeWidgetItem * pItem = treeWidget_actions->currentItem(); if( pItem ) { int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); pT = mpHost->getActionUnit()->getAction( triggerID ); if( pT ) { name = pT->getName(); } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } XMLexport writer( pT ); if( writer.exportAction( & file ) ) { statusBar()->showMessage(tr("Package ")+name+tr(" saved"), 2000); } } void dlgTriggerEditor::exportScript( QFile & file ) { QString name; TScript * pT = 0; QTreeWidgetItem * pItem = treeWidget_scripts->currentItem(); if( pItem ) { int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); pT = mpHost->getScriptUnit()->getScript( triggerID ); if( pT ) { name = pT->getName(); } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } XMLexport writer( pT ); if( writer.exportScript( & file ) ) { statusBar()->showMessage(tr("Package ")+name+tr(" saved"), 2000); } } void dlgTriggerEditor::exportKey( QFile & file ) { QString name; TKey * pT = 0; QTreeWidgetItem * pItem = treeWidget_keys->currentItem(); if( pItem ) { int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); pT = mpHost->getKeyUnit()->getKey( triggerID ); if( pT ) { name = pT->getName(); } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } } else { QMessageBox::warning(this, tr("Export Package:"), tr("You have to chose an item for export first. Please select a tree item and then click on export again.")); return; } XMLexport writer( pT ); if( writer.exportKey( & file ) ) { statusBar()->showMessage(tr("Package ")+name+tr(" saved"), 2000); } } void dlgTriggerEditor::slot_export() { QString fileName = QFileDialog::getSaveFileName(this, tr("Export Triggers"), QDir::currentPath(), tr("Mudlet packages (*.xml)")); if(fileName.isEmpty()) return; fileName.append(".xml"); QFile file(fileName); if( ! file.open(QFile::WriteOnly | QFile::Text) ) { QMessageBox::warning(this, tr("export package:"), tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } switch( mCurrentView ) { case cmTriggerView: exportTrigger( file ); break; case cmTimerView: exportTimer( file ); break; case cmAliasView: exportAlias( file ); break; case cmScriptView: exportScript( file ); break; case cmActionView: exportAction( file ); break; case cmKeysView: exportKey( file ); break; }; } void dlgTriggerEditor::slot_import() { if( mCurrentView ) { switch( mCurrentView ) { case cmTriggerView: saveTrigger(); break; case cmTimerView: saveTimer(); break; case cmAliasView: saveAlias(); break; case cmScriptView: saveScript(); break; case cmActionView: saveAction(); break; case cmKeysView: saveKey(); break; }; } QString fileName = QFileDialog::getOpenFileName(this, tr("Import Mudlet Package"), QDir::currentPath()); if( fileName.isEmpty() ) return; QFile file(fileName); if( ! file.open(QFile::ReadOnly | QFile::Text) ) { QMessageBox::warning(this, tr("Import Mudlet Package:"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } QString packageName = fileName.section("/",-1 ); packageName.replace( ".zip" , "" ); packageName.replace( "trigger", "" ); packageName.replace( "xml", "" ); packageName.replace( ".mpackage" , "" ); packageName.replace( '/' , "" ); packageName.replace( '\\' , "" ); packageName.replace( '.' , "" ); if( mpHost->mInstalledPackages.contains( packageName ) ) { QMessageBox::information(this, tr("Import Mudlet Package:"), tr("Package %1 is already installed.").arg(packageName)); return; } QFile file2; if( fileName.endsWith(".zip") || fileName.endsWith(".mpackage") ) { QString _home = QDir::homePath(); _home.append( "/.config/mudlet/profiles/" ); _home.append( mpHost->getName() ); QString _dest = QString( "%1/%2/").arg( _home ).arg( packageName ); QDir _tmpDir; _tmpDir.mkpath(_dest); QString _script = QString( "unzip([[%1]], [[%2]])" ).arg( fileName ).arg( _dest ); mpHost->mLuaInterpreter.compileAndExecuteScript( _script ); // requirements for zip packages: // - packages must be compressed in zip format // - file extension should be .mpackage (though .zip is accepted) // - there can only be a single xml file per package // - the xml file must be located in the root directory of the zip package. example: myPack.zip contains: the folder images and the file myPack.xml QDir _dir( _dest ); QStringList _filterList; _filterList << "*.xml" << "*.trigger"; QFileInfoList entries = _dir.entryInfoList( _filterList, QDir::Files ); if( entries.size() > 0 ) { file2.setFileName( entries[0].absoluteFilePath() ); } } else { file2.setFileName( fileName ); } file2.open(QFile::ReadOnly | QFile::Text); mpHost->mInstalledPackages.append( packageName ); QString profileName = mpHost->getName(); QString login = mpHost->getLogin(); QString pass = mpHost->getPass(); treeWidget->clear(); treeWidget_alias->clear(); treeWidget_actions->clear(); treeWidget_timers->clear(); treeWidget_keys->clear(); treeWidget_scripts->clear(); XMLimport reader( mpHost ); reader.importPackage( & file2, packageName ); mpHost->setName( profileName ); mpHost->setLogin( login ); mpHost->setPass( pass ); slot_profileSaveAction(); fillout_form(); mCurrentTrigger = 0; mCurrentTimer = 0; mCurrentAlias = 0; mCurrentScript = 0; mCurrentAction = 0; mCurrentKey = 0; slot_show_triggers(); } void dlgTriggerEditor::doCleanReset() { if( mCurrentView ) { switch( mCurrentView ) { case cmTriggerView: saveTrigger(); break; case cmTimerView: saveTimer(); break; case cmAliasView: saveAlias(); break; case cmScriptView: saveScript(); break; case cmActionView: saveAction(); break; case cmKeysView: saveKey(); break; }; } treeWidget->clear(); treeWidget_alias->clear(); treeWidget_actions->clear(); treeWidget_timers->clear(); treeWidget_keys->clear(); treeWidget_scripts->clear(); fillout_form(); mCurrentTrigger = 0; mCurrentTimer = 0; mCurrentAlias = 0; mCurrentScript = 0; mCurrentAction = 0; mCurrentKey = 0; slot_show_triggers(); } void dlgTriggerEditor::slot_profileSaveAction() { QString directory_xml = QDir::homePath()+"/.config/mudlet/profiles/"+mpHost->getName()+"/current"; QString filename_xml = directory_xml + "/"+QDateTime::currentDateTime().toString("dd-MM-yyyy#hh-mm-ss")+".xml"; QDir dir_xml; if( ! dir_xml.exists( directory_xml ) ) { dir_xml.mkpath( directory_xml ); } QFile file_xml( filename_xml ); if ( file_xml.open( QIODevice::WriteOnly ) ) { XMLexport writer( mpHost ); writer.exportHost( & file_xml ); file_xml.close(); qDebug()<<"saving modules"; mpHost->saveModules(1); } else { QMessageBox::critical( this, "Profile Save Failed", "Failed to save "+mpHost->getName()+" to location "+filename_xml+" because of the following error: "+file_xml.errorString() ); } } void dlgTriggerEditor::slot_profileSaveAsAction() { QString fileName = QFileDialog::getSaveFileName(this, tr("Backup Profile"), QDir::homePath(), tr("trigger files (*.trigger *.xml)")); if(fileName.isEmpty()) return; fileName.append(".xml"); QFile file(fileName); if( ! file.open(QFile::WriteOnly | QFile::Text) ) { QMessageBox::warning(this, tr("Backup Profile:"), tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } qDebug()<<"generic export"; XMLexport writer( mpHost, true );//just export a generic package without host element //writer.exportHost( & file ); writer.exportGenericPackage( & file ); file.close(); } bool dlgTriggerEditor::event( QEvent * event ) { if( mIsGrabKey ) { if( event->type() == QEvent::KeyPress ) { QKeyEvent * ke = static_cast( event ); switch( ke->key() ) { case 0x01000000: mIsGrabKey = false; ke->accept(); return true; case 0x01000020: case 0x01000021: case 0x01000022: case 0x01000023: case 0x01001103: break; default: grab_key_callback( ke->key(), ke->modifiers() ); mIsGrabKey = false; ke->accept(); return true; } } } return QMainWindow::event( event ); } void dlgTriggerEditor::slot_grab_key() { mIsGrabKey = true; } void dlgTriggerEditor::grab_key_callback( int key, int modifier ) { KeyUnit * pKeyUnit = mpHost->getKeyUnit(); if( ! pKeyUnit ) return; QString keyName = pKeyUnit->getKeyName( key, modifier ); QString name = keyName; mpKeysMainArea->lineEdit_key->setText( name ); QTreeWidgetItem * pItem = treeWidget_keys->currentItem(); if( pItem ) { int triggerID = pItem->data(0, Qt::UserRole).toInt(); TKey * pT = mpHost->getKeyUnit()->getKey( triggerID ); if( pT ) { pT->setKeyCode( key ); pT->setKeyModifiers( modifier ); } } } void dlgTriggerEditor::slot_chose_action_icon() { QString fileName = QFileDialog::getOpenFileName(this, tr("Seclect Icon"), QDir::homePath(), tr("Images (*.png *.xpm *.jpg)")); mpActionsMainArea->lineEdit_action_icon->setText( fileName ); } void dlgTriggerEditor::slot_colorizeTriggerSetFgColor() { QTreeWidgetItem * pItem = mCurrentTrigger; if( ! pItem ) return; if( ! pItem->parent() ) return; int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); TTrigger * pT = mpHost->getTriggerUnit()->getTrigger( triggerID ); QColor color = QColorDialog::getColor( mpTriggersMainArea->pushButtonFgColor->palette().color( QPalette::Button ), this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color: ")+color.name()+QString(";}"); mpTriggersMainArea->pushButtonFgColor->setStyleSheet( styleSheet ); mpTriggersMainArea->pushButtonFgColor->setPalette( palette ); } } void dlgTriggerEditor::slot_colorizeTriggerSetBgColor() { QTreeWidgetItem * pItem = mCurrentTrigger; if( ! pItem ) return; if( ! pItem->parent() ) return; int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); TTrigger * pT = mpHost->getTriggerUnit()->getTrigger( triggerID ); QColor color = QColorDialog::getColor( mpTriggersMainArea->pushButtonBgColor->palette().color( QPalette::Button ), this ); if ( color.isValid() ) { QPalette palette; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); mpTriggersMainArea->pushButtonBgColor->setStyleSheet( styleSheet ); mpTriggersMainArea->pushButtonBgColor->setPalette( palette ); } } void dlgTriggerEditor::slot_soundTrigger() { QString fileName = QFileDialog::getOpenFileName(this, tr("chose sound file"), QDir::homePath(), tr("*")); mpTriggersMainArea->lineEdit_soundFile->setText( fileName ); } void dlgTriggerEditor::slot_color_trigger_fg() { QTreeWidgetItem * pItem = mCurrentTrigger; if( ! pItem ) { return; } int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); TTrigger * pT = mpHost->getTriggerUnit()->getTrigger( triggerID ); if( ! pT ) return; QPushButton * pB = (QPushButton *) sender(); int row = ((dlgTriggerPatternEdit*)pB->parent())->mRow; dlgTriggerPatternEdit * pI = mTriggerPatternEdit[row]; if( ! pI ) return; QString pattern = pI->lineEdit->text(); QRegExp regex = QRegExp("FG(\\d+)BG(\\d+)"); int _pos = regex.indexIn( pattern ); int ansiFg, ansiBg; if( _pos == -1 ) { //setup default colors ansiFg = 0; ansiBg = 0; } else { // use user defined colors ansiFg = regex.cap(1).toInt(); ansiBg = regex.cap(2).toInt(); } pT->mColorTriggerFgAnsi = ansiFg; pT->mColorTriggerBgAnsi = ansiBg; dlgColorTrigger * pD = new dlgColorTrigger(this, pT, 0 ); pD->setModal( true ); pD->setWindowModality( Qt::ApplicationModal ); pD->exec(); QPalette palette; QColor color = pT->mColorTriggerFgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); if( ! pB ) return; row = ((dlgTriggerPatternEdit*)pB->parent())->mRow; pI = mTriggerPatternEdit[row]; pI->lineEdit->setText(QString("FG%1BG%2").arg(pT->mColorTriggerFgAnsi).arg(pT->mColorTriggerBgAnsi) ); pB->setStyleSheet( styleSheet ); } void dlgTriggerEditor::slot_color_trigger_bg() { QTreeWidgetItem * pItem = mCurrentTrigger; if( ! pItem ) { return; } int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); TTrigger * pT = mpHost->getTriggerUnit()->getTrigger( triggerID ); if( ! pT ) return; QPushButton * pB = (QPushButton *) sender(); int row = ((dlgTriggerPatternEdit*)pB->parent())->mRow; dlgTriggerPatternEdit * pI = mTriggerPatternEdit[row]; if( ! pI ) return; QString pattern = pI->lineEdit->text(); QRegExp regex = QRegExp("FG(\\d+)BG(\\d+)"); int _pos = regex.indexIn( pattern ); int ansiFg, ansiBg; if( _pos == -1 ) { //setup default colors ansiFg = 0; ansiBg = 0; } else { // use user defined colors ansiFg = regex.cap(1).toInt(); ansiBg = regex.cap(2).toInt(); } pT->mColorTriggerFgAnsi = ansiFg; pT->mColorTriggerBgAnsi = ansiBg; dlgColorTrigger * pD = new dlgColorTrigger(this, pT, 1 ); pD->setModal( true ); pD->setWindowModality( Qt::ApplicationModal ); pD->exec(); QPalette palette; QColor color = pT->mColorTriggerBgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); if( ! pB ) return; row = ((dlgTriggerPatternEdit*)pB->parent())->mRow; pI = mTriggerPatternEdit[row]; if( ! pI ) return; pI->lineEdit->setText(QString("FG%1BG%2").arg(pT->mColorTriggerFgAnsi).arg(pT->mColorTriggerBgAnsi) ); pB->setStyleSheet( styleSheet ); /*QTreeWidgetItem * pItem = mCurrentTrigger; if( ! pItem ) { return; } int triggerID = pItem->data( 0, Qt::UserRole ).toInt(); TTrigger * pT = mpHost->getTriggerUnit()->getTrigger( triggerID ); if( ! pT ) return; dlgColorTrigger * pD = new dlgColorTrigger(this, pT, 1 ); pD->exec(); QPalette palette; QColor color = pT->mColorTriggerBgColor; palette.setColor( QPalette::Button, color ); QString styleSheet = QString("QPushButton{background-color:")+color.name()+QString(";}"); QPushButton * pB = (QPushButton *) sender(); if( ! pB ) return; int row = ((dlgTriggerPatternEdit*)pB->parent())->mRow; dlgTriggerPatternEdit * pI = (dlgTriggerPatternEdit*)mpTriggersMainArea->listWidget_regex_list->cellWidget( row, 0 ); if( ! pI ) return; pI->lineEdit->setText(QString("FG%1BG%2").arg(pT->mColorTriggerFgAnsi).arg(pT->mColorTriggerBgAnsi) ); pB->setStyleSheet( styleSheet );*/ } void dlgTriggerEditor::slot_cursorPositionChanged() { int _line = (mpSourceEditorArea->editor->textCursor()).blockNumber(); int _maxLines = mpSourceEditorArea->editor->blockCount(); QString line; if( mCurrentView == cmScriptView ) { line = QString("current line number: %1/%2").arg( _line + 1 ).arg( _maxLines ); } else { line = QString("current line number: %1/%2").arg( _line + 2 ).arg( _maxLines + 1 ); } QMainWindow::statusBar()->showMessage( line ); } mudlet-2.1/src/TKey.cpp0000644000175000017500000001422512070466512014334 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include "TKey.h" #include "Host.h" #include "HostManager.h" #include #include "TDebug.h" #include "mudlet.h" using namespace std; TKey::TKey( TKey * parent, Host * pHost ) : Tree( parent ) , mpHost( pHost ) , mModuleMember(false) , mModuleMasterFolder(false) , mNeedsToBeCompiled( true ) , exportItem(true) { } TKey::TKey( QString name, Host * pHost ) : Tree(0) , mName( name ) , mpHost( pHost ) , mModuleMember(false) , mModuleMasterFolder(false) , mNeedsToBeCompiled( true ) , exportItem(true) { } TKey::~TKey() { if( ! mpHost ) { return; } mpHost->getKeyUnit()->unregisterKey(this); } bool TKey::match( int key, int modifier ) { if( isActive() ) { if( ! mIsFolder ) { if( ( mKeyCode == key ) && ( mKeyModifier == modifier ) ) { execute(); return true; } } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TKey * pChild = *it; if( pChild->match( key, modifier ) ) return true; } } return false; } bool TKey::registerKey() { if( ! mpHost ) { qDebug() << "ERROR: TAlias::registerTrigger() pHost=0"; return false; } return mpHost->getKeyUnit()->registerKey( this ); } void TKey::enableKey( QString & name ) { if( mName == name ) { setIsActive( true ); } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TKey * pChild = *it; pChild->enableKey( name ); } } void TKey::disableKey( QString & name ) { if( mName == name ) { setIsActive( false ); } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TKey * pChild = *it; pChild->disableKey( name ); } } void TKey::compileAll() { mNeedsToBeCompiled = true; if( ! compileScript() ) { if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::red))<<"ERROR: Lua compile error. compiling script of key binding:"<>0;} mOK_code = false; } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TKey * pChild = *it; pChild->compileAll(); } } void TKey::compile() { if( mNeedsToBeCompiled ) { if( ! compileScript() ) { if( mudlet::debugMode ) {TDebug(QColor(Qt::white),QColor(Qt::red))<<"ERROR: Lua compile error. compiling script of key binding:"<>0;} mOK_code = false; } } typedef list::const_iterator I; for( I it = mpMyChildrenList->begin(); it != mpMyChildrenList->end(); it++) { TKey * pChild = *it; pChild->compile(); } } bool TKey::setScript( QString & script ) { mScript = script; mNeedsToBeCompiled = true; mOK_code = compileScript(); return mOK_code; } bool TKey::compileScript() { mFuncName = QString("Key")+QString::number( mID ); QString code = QString("function ")+ mFuncName + QString("()\n") + mScript + QString("\nend\n"); QString error; if( mpHost->mLuaInterpreter.compile( code, error ) ) { mNeedsToBeCompiled = false; mOK_code = true; return true; } else { mOK_code = false; setError( error ); return false; } } void TKey::execute() { if( mCommand.size() > 0 ) { mpHost->send( mCommand ); } if( mNeedsToBeCompiled ) { if( ! compileScript() ) { return; } } mpHost->mLuaInterpreter.call( mFuncName, mName ); } TKey& TKey::clone(const TKey& b) { mName = b.mName; mCommand = b.mCommand; mKeyCode = b.mKeyCode; mKeyModifier = b.mKeyModifier; mRegexCode = b.mRegexCode; mRegex = b.mRegex; mScript = b.mScript; mIsFolder = b.mIsFolder; mpHost = b.mpHost; mNeedsToBeCompiled = b.mNeedsToBeCompiled; return *this; } bool TKey::isClone(TKey &b) const { return( mName == b.mName && mCommand == b.mCommand && mKeyCode == b.mKeyCode && mKeyModifier == b.mKeyModifier && mRegexCode == b.mRegexCode && mRegex == b.mRegex && mScript == b.mScript && mIsFolder == b.mIsFolder && mpHost == b.mpHost && mNeedsToBeCompiled == b.mNeedsToBeCompiled ); } mudlet-2.1/src/ScriptUnit.cpp0000644000175000017500000001422312020507606015555 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include // NULL #include #include #include #include #include "Host.h" #include "TLuaInterpreter.h" #include #include "ScriptUnit.h" using namespace std; void ScriptUnit::_uninstall( TScript * pChild, QString packageName ) { typedef list::const_iterator I; list * childrenList = pChild->mpMyChildrenList; for( I it2 = childrenList->begin(); it2 != childrenList->end(); it2++) { TScript * pT = *it2; _uninstall( pT, packageName ); uninstallList.append( pT ); } } void ScriptUnit::uninstall( QString packageName ) { typedef std::list::iterator IT; for( IT it = mScriptRootNodeList.begin(); it != mScriptRootNodeList.end(); it ++ ) { TScript * pT = *it; if( pT->mPackageName == packageName ) { _uninstall( pT, packageName ); uninstallList.append( pT ); } } for( int i=0; i::const_iterator I; for( I it = mScriptRootNodeList.begin(); it != mScriptRootNodeList.end(); it++) { TScript * pChild = *it; pChild->setIsActive( false ); } } void ScriptUnit::addScriptRootNode( TScript * pT, int parentPosition, int childPosition ) { if( ! pT ) return; if( ! pT->getID() ) { pT->setID( getNewID() ); } if( ( parentPosition == -1 ) || ( childPosition >= static_cast(mScriptRootNodeList.size()) ) ) { mScriptRootNodeList.push_back( pT ); } else { // insert item at proper position int cnt = 0; typedef std::list::iterator IT; for( IT it = mScriptRootNodeList.begin(); it != mScriptRootNodeList.end(); it ++ ) { if( cnt >= childPosition ) { mScriptRootNodeList.insert( it, pT ); break; } cnt++; } } mScriptMap.insert( pT->getID(), pT ); } void ScriptUnit::reParentScript( int childID, int oldParentID, int newParentID, int parentPosition, int childPosition ) { TScript * pOldParent = getScriptPrivate( oldParentID ); TScript * pNewParent = getScriptPrivate( newParentID ); TScript * pChild = getScriptPrivate( childID ); if( ! pChild ) { return; } if( pOldParent ) { pOldParent->popChild( pChild ); } if( ! pOldParent ) { removeScriptRootNode( pChild ); } if( pNewParent ) { pNewParent->addChild( pChild, parentPosition, childPosition ); if( pChild ) pChild->setParent( pNewParent ); //cout << "dumping family of newParent:"<Dump(); } else { pChild->Tree::setParent( 0 ); addScriptRootNode( pChild, parentPosition, childPosition ); } } void ScriptUnit::removeScriptRootNode( TScript * pT ) { if( ! pT ) return; mScriptRootNodeList.remove( pT ); } TScript * ScriptUnit::getScript( int id ) { QMutexLocker locker(& mScriptUnitLock); if( mScriptMap.find( id ) != mScriptMap.end() ) { return mScriptMap.value( id ); } else { return 0; } } TScript * ScriptUnit::getScriptPrivate( int id ) { if( mScriptMap.find( id ) != mScriptMap.end() ) { return mScriptMap.value( id ); } else { return 0; } } bool ScriptUnit::registerScript( TScript * pT ) { if( ! pT ) return false; if( pT->getParent() ) { addScript( pT ); return true; } else { addScriptRootNode( pT ); return true; } } void ScriptUnit::unregisterScript( TScript * pT ) { if( ! pT ) return; if( pT->getParent() ) { removeScript( pT ); return; } else { removeScriptRootNode( pT ); return; } } void ScriptUnit::addScript( TScript * pT ) { if( ! pT ) return; QMutexLocker locker(& mScriptUnitLock); if( ! pT->getID() ) { pT->setID( getNewID() ); } mScriptMap.insert( pT->getID(), pT ); } void ScriptUnit::removeScript( TScript * pT ) { if( ! pT ) return; mScriptMap.remove(pT->getID()); } qint64 ScriptUnit::getNewID() { return ++mMaxID; } void ScriptUnit::compileAll() { typedef list::const_iterator I; for( I it = mScriptRootNodeList.begin(); it != mScriptRootNodeList.end(); it++) { TScript * pChild = *it; if( pChild->isActive() ) { pChild->compileAll(); } } } mudlet-2.1/src/TSplitterHandle.h0000644000175000017500000000051611513237311016163 0ustar csmallcsmall#ifndef TSPLITTERHANDLE_H #define TSPLITTERHANDLE_H #include #include "TSplitter.h" class TSplitter; class TSplitterHandle : public QSplitterHandle { //Q_OBJECT public: TSplitterHandle(Qt::Orientation orientation, TSplitter * parent ); void paintEvent( QPaintEvent * ); }; #endif // TSPLITTERHANDLE_H mudlet-2.1/src/exitstreewidget.cpp0000644000175000017500000000437112020507607016675 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2012 by Vadim Peretokin * * vadim.peretokin@mudlet.org * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "exitstreewidget.h" #include #include "Host.h" #include "HostManager.h" #include "TDebug.h" ExitsTreeWidget::ExitsTreeWidget( QWidget * pW ) : QTreeWidget( pW ) { setSelectionMode(QAbstractItemView::ExtendedSelection); setUniformRowHeights(true); } void ExitsTreeWidget::keyPressEvent ( QKeyEvent * event ) { if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { closePersistentEditor( currentItem(), 1 ); closePersistentEditor( currentItem(), 2 ); } if (event->key() == Qt::Key_Delete && hasFocus() ) { QList selection = selectedItems(); foreach(QTreeWidgetItem *item, selection) { takeTopLevelItem(indexOfTopLevelItem(item)); } } } mudlet-2.1/src/dlgPackageExporter.cpp0000644000175000017500000004264412076170616017244 0ustar csmallcsmall#include "dlgPackageExporter.h" #include "ui_dlgPackageExporter.h" #include "Host.h" #include #include #include "XMLexport.h" #ifdef Q_OS_WIN #include "quazip.h" #include "JlCompress.h" #endif #include dlgPackageExporter::dlgPackageExporter(QWidget *parent) : QDialog(parent), ui(new Ui::dlgPackageExporter) { ui->setupUi(this); } dlgPackageExporter::dlgPackageExporter(QWidget *parent, Host* host) : QDialog(parent), ui(new Ui::dlgPackageExporter) { mpHost = host; ui->setupUi(this); treeWidget = ui->treeWidget; closeButton = ui->buttonBox->addButton (QDialogButtonBox::Close); exportButton = new QPushButton(tr("&Export")); // //HEIKO: added ability to make fully fledged Mudlet packages including a package // name config file and arbitray additional package content selection. // However, this feature is currently restricted to windows only // until quazip is part of the other Mudlet builds #ifdef Q_OS_WIN ui->browseButton->hide(); ui->filePath->hide(); ui->textLabel1->hide(); packageName = QInputDialog::getText(0,"Package Name", "Package Name"); QString packagePath = QFileDialog::getExistingDirectory(0,"Where do you want to save the package?","Where do you want to save the package?"); tempDir = QDir::homePath()+"/.config/mudlet/profiles/"+mpHost->getName()+"/tmp/"; packagePath.replace("\\", "/"); tempDir = tempDir + "/" + packageName; QDir packageDir = QDir(tempDir); if ( !packageDir.exists() ){ packageDir.mkpath(tempDir); } zip = packagePath + "/" + packageName + ".zip"; filePath = tempDir + "/" + packageName + ".xml"; QString luaConfig = tempDir + "/config.lua"; QFile configFile(luaConfig); QStringList strings; if (configFile.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&configFile); out << "mpackage = \"" << packageName << "\"\n"; out.flush(); configFile.close(); } connect(ui->addFiles, SIGNAL(clicked()), this, SLOT(slot_addFiles())); #else ui->addFiles->hide(); ui->textLabel1_2->hide(); connect(ui->browseButton, SIGNAL(clicked()), this, SLOT(slot_browse_button())); exportButton->setDisabled(true); // disabled by default until the user selects a location #endif ui->buttonBox->addButton(exportButton, QDialogButtonBox::ResetRole); connect(exportButton, SIGNAL(clicked()), this, SLOT(slot_export_package())); listTriggers(); listAliases(); listKeys(); listScripts(); listActions(); listTimers(); } dlgPackageExporter::~dlgPackageExporter() { delete ui; } void dlgPackageExporter::recurseTree(QTreeWidgetItem * pItem, QList &treeList){ treeList.append(pItem); for(int i=0;ichildCount();++i) recurseTree(pItem->child(i), treeList); } void dlgPackageExporter::slot_export_package(){ #ifndef Q_OS_WIN filePath = ui->filePath->text(); #endif QFile file_xml( filePath ); if( file_xml.open( QIODevice::WriteOnly ) ) { XMLexport writer( mpHost ); //write trigs QList items = treeWidget->findItems(QString("Triggers"), Qt::MatchExactly, 0); QTreeWidgetItem * top = items.first(); QList trigList; recurseTree(top,trigList); for (int i=0;icheckState(0) == Qt::Unchecked && triggerMap.contains(item)){ triggerMap[item]->exportItem = false; } } items = treeWidget->findItems(QString("Timers"), Qt::MatchExactly, 0); top = items.first(); QList timerList; recurseTree(top,timerList); for (int i=0;icheckState(0) == Qt::Unchecked && timerMap.contains(item)){ timerMap[item]->exportItem = false; } } items = treeWidget->findItems(QString("Aliases"), Qt::MatchExactly, 0); top = items.first(); QList aliasList; recurseTree(top,aliasList); for (int i=0;icheckState(0) == Qt::Unchecked && aliasMap.contains(item)){ aliasMap[item]->exportItem = false; } } items = treeWidget->findItems(QString("Buttons"), Qt::MatchExactly, 0); top = items.first(); QList actionList; recurseTree(top,actionList); for (int i=0;icheckState(0) == Qt::Unchecked && actionMap.contains(item)){ actionMap[item]->exportItem = false; } } items = treeWidget->findItems(QString("Scripts"), Qt::MatchExactly, 0); top = items.first(); QList scriptList; recurseTree(top,scriptList); for (int i=0;icheckState(0) == Qt::Unchecked && scriptMap.contains(item)){ qDebug()<<"not writing"<getName(); scriptMap[item]->exportItem = false; } } items = treeWidget->findItems(QString("Keys"), Qt::MatchExactly, 0); top = items.first(); QList keyList; recurseTree(top,keyList); for (int i=0;icheckState(0) == Qt::Unchecked && keyMap.contains(item)){ keyMap[item]->exportItem = false; } } writer.exportGenericPackage(&file_xml); file_xml.close(); //now fix all the stuff we weren't exporting //trigger, timer, alias,action,script, keys for (int i=0;iexportItem = true; } } for (int i=0;iexportItem = true; } } for (int i=0;iexportItem = true; } } for (int i=0;iexportItem = true; } } for (int i=0;iexportItem = true; } } for (int i=0;iexportItem = true; } } #ifdef Q_OS_WIN JlCompress::compressDir(zip, tempDir ); #else ui->infoLabel->setText("Exported package to "+filePath); #endif } else { ui->infoLabel->setText("Failed to export - couldn't open "+filePath+" for writing in. Do you have the necessary permissions to write to that folder?"); } close(); } void dlgPackageExporter::slot_addFiles(){ QString _pn = "file:///"+tempDir; QDesktopServices::openUrl(QUrl(_pn, QUrl::TolerantMode)); } void dlgPackageExporter::slot_browse_button(){ QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter(tr("Mudlet Packages (*.xml)")); dialog.setViewMode(QFileDialog::Detail); QString fileName; if (dialog.exec()) { fileName = dialog.selectedFiles().first(); if (!fileName.endsWith(".xml")) fileName.append(".xml"); ui->filePath->setText(fileName); exportButton->setDisabled(false); } } void dlgPackageExporter::recurseTriggers(TTrigger* trig, QTreeWidgetItem* qTrig){ list * childList = trig->getChildrenList(); if (!childList->size()) return; list::iterator it; for(it=childList->begin(); it!=childList->end();it++){ TTrigger * pChild = *it; if (pChild->isTempTrigger()) continue; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); triggerMap.insert(pItem, pChild); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); qTrig->addChild(pItem); recurseTriggers(pChild, pItem); } } void dlgPackageExporter::listTriggers() { TriggerUnit* tu = mpHost->getTriggerUnit(); list::const_iterator it; std::list tList = tu->getTriggerRootNodeList(); QList items = treeWidget->findItems(QString("Triggers"), Qt::MatchExactly, 0); QTreeWidgetItem * top = items.first(); for(it = tList.begin(); it != tList.end(); it++) { TTrigger * pChild = *it; if( pChild->isTempTrigger() ) continue; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); top->addChild(pItem); triggerMap.insert(pItem, pChild); recurseTriggers(pChild, pItem); } } void dlgPackageExporter::recurseAliases(TAlias* item, QTreeWidgetItem* qItem){ list * childList = item->getChildrenList(); if (!childList->size()) return; list::iterator it; for(it=childList->begin(); it!=childList->end();it++){ TAlias * pChild = *it; if (pChild->isTempAlias()) continue; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); qItem->addChild(pItem); aliasMap.insert(pItem, pChild); recurseAliases(pChild, pItem); } } void dlgPackageExporter::listAliases() { AliasUnit* tu = mpHost->getAliasUnit(); list::const_iterator it; std::list tList = tu->getAliasRootNodeList(); QList items = treeWidget->findItems(QString("Aliases"), Qt::MatchExactly, 0); QTreeWidgetItem * top = items.first(); for(it = tList.begin(); it != tList.end(); it++) { TAlias * pChild = *it; if (pChild->isTempAlias()) continue; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); top->addChild(pItem); aliasMap.insert(pItem, pChild); recurseAliases(pChild, pItem); } } void dlgPackageExporter::recurseScripts(TScript* item, QTreeWidgetItem* qItem){ list * childList = item->getChildrenList(); if (!childList->size()) return; list::iterator it; for(it=childList->begin(); it!=childList->end();it++){ TScript * pChild = *it; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); scriptMap.insert(pItem, pChild); qItem->addChild(pItem); recurseScripts(pChild, pItem); } } void dlgPackageExporter::listScripts() { ScriptUnit* tu = mpHost->getScriptUnit(); list::const_iterator it; std::list tList = tu->getScriptRootNodeList(); QList items = treeWidget->findItems(QString("Scripts"), Qt::MatchExactly, 0); QTreeWidgetItem * top = items.first(); for(it = tList.begin(); it != tList.end(); it++) { TScript * pChild = *it; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); scriptMap.insert(pItem, pChild); top->addChild(pItem); recurseScripts(pChild, pItem); } } void dlgPackageExporter::recurseKeys(TKey* item, QTreeWidgetItem* qItem){ list * childList = item->getChildrenList(); if (!childList->size()) return; list::iterator it; for(it=childList->begin(); it!=childList->end();it++){ TKey * pChild = *it; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); keyMap.insert(pItem, pChild); qItem->addChild(pItem); recurseKeys(pChild, pItem); } } void dlgPackageExporter::listKeys() { KeyUnit* tu = mpHost->getKeyUnit(); list::const_iterator it; std::list tList = tu->getKeyRootNodeList(); QList items = treeWidget->findItems(QString("Keys"), Qt::MatchExactly, 0); QTreeWidgetItem * top = items.first(); for(it = tList.begin(); it != tList.end(); it++) { TKey * pChild = *it; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); keyMap.insert(pItem, pChild); top->addChild(pItem); recurseKeys(pChild, pItem); } } void dlgPackageExporter::recurseActions(TAction* item, QTreeWidgetItem* qItem){ list * childList = item->getChildrenList(); if (!childList->size()) return; list::iterator it; for(it=childList->begin(); it!=childList->end();it++){ TAction * pChild = *it; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); actionMap.insert(pItem, pChild); qItem->addChild(pItem); recurseActions(pChild, pItem); } } void dlgPackageExporter::listActions() { ActionUnit* tu = mpHost->getActionUnit(); list::const_iterator it; std::list tList = tu->getActionRootNodeList(); QList items = treeWidget->findItems(QString("Buttons"), Qt::MatchExactly, 0); QTreeWidgetItem * top = items.first(); for(it = tList.begin(); it != tList.end(); it++) { TAction * pChild = *it; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); actionMap.insert(pItem, pChild); top->addChild(pItem); recurseActions(pChild, pItem); } } void dlgPackageExporter::recurseTimers(TTimer* item, QTreeWidgetItem* qItem){ list * childList = item->getChildrenList(); if (!childList->size()) return; list::iterator it; for(it=childList->begin(); it!=childList->end();it++){ TTimer * pChild = *it; if (pChild->isTempTimer()) continue; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); timerMap.insert(pItem, pChild); qItem->addChild(pItem); recurseTimers(pChild, pItem); } } void dlgPackageExporter::listTimers() { TimerUnit* tu = mpHost->getTimerUnit(); list::const_iterator it; std::list tList = tu->getTimerRootNodeList(); QList items = treeWidget->findItems(QString("Timers"), Qt::MatchExactly, 0); QTreeWidgetItem * top = items.first(); for(it = tList.begin(); it != tList.end(); it++) { TTimer * pChild = *it; if (pChild->isTempTimer()) continue; QStringList sl; sl << pChild->getName(); QTreeWidgetItem * pItem = new QTreeWidgetItem(sl); pItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsTristate|Qt::ItemIsEnabled|Qt::ItemIsSelectable); pItem->setCheckState(0, Qt::Unchecked); timerMap.insert(pItem, pChild); top->addChild(pItem); recurseTimers(pChild, pItem); } } mudlet-2.1/src/Doxyfile0000755000175000017500000002601511513237311014457 0ustar csmallcsmall# Doxyfile 1.5.5-KDevelop #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = mdev PROJECT_NUMBER = 1 OUTPUT_DIRECTORY = CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = /home/heiko/ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO DETAILS_AT_TOP = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES TYPEDEF_HIDES_STRUCT = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = NO SHOW_FILES = YES SHOW_NAMESPACES = YES FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = /home/heiko/git/mudlet/prealpha1/mudlet/src INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.py \ *.f90 \ *.f \ *.vhd \ *.vhdl \ *.C \ *.CC \ *.C++ \ *.II \ *.I++ \ *.H \ *.HH \ *.H++ \ *.CS \ *.PHP \ *.PHP3 \ *.M \ *.MM \ *.PY \ *.F90 \ *.F \ *.VHD \ *.VHDL \ *.C \ *.H \ *.tlh \ *.diff \ *.patch \ *.moc \ *.xpm \ *.dox RECURSIVE = yes EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXCLUDE_SYMBOLS = EXAMPLE_PATH = EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = NO INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO REFERENCES_LINK_SOURCE = YES USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project HTML_DYNAMIC_SECTIONS = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NONE TREEVIEW_WIDTH = 250 FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = YES LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = yes XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = mdev.tag ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES MSCGEN_PATH = HIDE_UNDOC_RELATIONS = YES HAVE_DOT = NO DOT_FONTNAME = FreeSans DOT_FONTPATH = CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = YES DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO mudlet-2.1/src/TCommandLine.cpp0000644000175000017500000005662412070466512016003 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2011 by Heiko Koehn (KoehnHeiko@googlemail.com) * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "TCommandLine.h" #include #include "TConsole.h" #include "TTextEdit.h" #include #include "TSplitter.h" #include TCommandLine::TCommandLine( Host * pHost, TConsole * pConsole, QWidget * parent ) : QPlainTextEdit( parent ) , mpHost( pHost ) , mpConsole( pConsole ) , mSelectedText( "" ) , mSelectionStart( 0 ) { QString path; #ifdef Q_OS_LINUX path = "/usr/share/hunspell/"; #else path = "./"; #endif QString spell_aff = path + pHost->mSpellDic + ".aff"; QString spell_dic = path + pHost->mSpellDic + ".dic"; mpHunspell = Hunspell_create( spell_aff.toLatin1().data(), spell_dic.toLatin1().data() );//"en_US.aff", "en_US.dic"); mpKeyUnit = mpHost->getKeyUnit(); setAutoFillBackground(true); setFocusPolicy(Qt::StrongFocus); QFont font = mpHost->mDisplayFont; setFont(font); mRegularPalette.setColor(QPalette::Text, mpHost->mCommandLineFgColor );//QColor(0,0,192)); mRegularPalette.setColor(QPalette::Highlight,QColor(0,0,192)); mRegularPalette.setColor(QPalette::HighlightedText, QColor(255,255,255)); mRegularPalette.setColor(QPalette::Base,mpHost->mCommandLineBgColor);//QColor(255,255,225)); setPalette( mRegularPalette ); mTabCompletionPalette.setColor(QPalette::Text,QColor(0,0,192)); mTabCompletionPalette.setColor(QPalette::Highlight,QColor(0,0,192)); mTabCompletionPalette.setColor(QPalette::HighlightedText, QColor(255,255,255)); mTabCompletionPalette.setColor(QPalette::Base,QColor(235,255,235)); mAutoCompletionPalette.setColor(QPalette::Text,QColor(0,0,192)); mAutoCompletionPalette.setColor(QPalette::Highlight,QColor(0,0,192)); mAutoCompletionPalette.setColor(QPalette::HighlightedText, QColor(255,255,255)); mAutoCompletionPalette.setColor(QPalette::Base,QColor(255,235,235)); mHistoryBuffer = 0; mAutoCompletion = false; setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); setCenterOnScroll( false ); setWordWrapMode( QTextOption::WrapAnywhere ); // setMaximumBlockCount(1); setContentsMargins(0,0,0,0); } void TCommandLine::slot_textChanged( const QString & text ) { } bool TCommandLine::event( QEvent * event ) { if( event->type() == QEvent::KeyPress ) { QKeyEvent *ke = static_cast( event ); //qDebug()<<"modifier="<modifiers()<<" key="<key(); switch( ke->key() ) { case Qt::Key_Space: mTabCompletionCount = -1; mAutoCompletionCount = -1; mTabCompletionTyped = ""; mAutoCompletionTyped = ""; if( mpHost->mAutoClearCommandLineAfterSend ) mHistoryBuffer = -1; else mHistoryBuffer = 0; mLastCompletion = ""; break; case Qt::Key_Backtab: if( ke->modifiers() & Qt::ControlModifier ) { int currentIndex = mudlet::self()->mpTabBar->currentIndex(); int count = mudlet::self()->mpTabBar->count(); if( currentIndex-1 < 0 ) mudlet::self()->mpTabBar->setCurrentIndex(count-1); else mudlet::self()->mpTabBar->setCurrentIndex(currentIndex-1); } else { handleTabCompletion( false ); adjustHeight(); } ke->accept(); return true; break; case Qt::Key_Tab: if( ke->modifiers() & Qt::ControlModifier ) { int currentIndex = mudlet::self()->mpTabBar->currentIndex(); int count = mudlet::self()->mpTabBar->count(); if( currentIndex+1 < count ) mudlet::self()->mpTabBar->setCurrentIndex(currentIndex+1); else mudlet::self()->mpTabBar->setCurrentIndex(0); } else handleTabCompletion( true ); ke->accept(); return true; break; // case Qt::Key_Backtab: // handleTabCompletion( false ); // ke->accept(); // adjustHeight(); // return true; // break; // case Qt::Key_Tab: // handleTabCompletion( true ); // ke->accept(); // return true; // break; case Qt::Key_unknown: qWarning()<<"ERROR: key unknown!"; break; case Qt::Key_Backspace: if( mpHost->mAutoClearCommandLineAfterSend ) mHistoryBuffer = -1; else mHistoryBuffer = 0; if( mTabCompletionTyped.size() >= 1 ) { mTabCompletionTyped.chop(1); mAutoCompletionTyped.chop(1); mTabCompletionCount = -1; mAutoCompletionCount = -1; mLastCompletion = ""; } else { mTabCompletionCount = -1; mAutoCompletionCount = -1; mLastCompletion = ""; } QPlainTextEdit::event(event); adjustHeight(); return true; case Qt::Key_Delete: if( mpHost->mAutoClearCommandLineAfterSend ) mHistoryBuffer = -1; else mHistoryBuffer = 0; if( mTabCompletionTyped.size() >= 1 ) { mTabCompletionTyped.chop(1); mAutoCompletionTyped.chop(1); mTabCompletionCount = -1; mAutoCompletionCount = -1; mLastCompletion = ""; } else { mTabCompletionCount = -1; mAutoCompletionCount = -1; mLastCompletion = ""; mTabCompletionTyped = ""; mAutoCompletionTyped = ""; mUserKeptOnTyping = false; mTabCompletionCount = -1; mAutoCompletionCount = -1; } QPlainTextEdit::event(event); adjustHeight(); return true; break; case Qt::Key_Return: if( ke->modifiers() & Qt::ControlModifier ) { mpConsole->console2->mCursorY = mpConsole->buffer.size();// mpConsole->console2->hide(); mpConsole->buffer.mCursorY = mpConsole->buffer.size(); mpConsole->console->mCursorY = mpConsole->buffer.size();// mpConsole->console->mIsTailMode = true; mpConsole->console->updateScreenView(); mpConsole->console->forceUpdate(); ke->accept(); return true; } else if( ke->modifiers() & Qt::ShiftModifier ) { textCursor().insertBlock(); /*if( ! textCursor().movePosition(QTextCursor::Down, QTextCursor::KeepAnchor) ) { textCursor().insertBlock(); }*/ ke->accept(); return true; } else { enterCommand(ke); mTabCompletionCount = -1; mAutoCompletionCount = -1; mLastCompletion = ""; mTabCompletionTyped = ""; mAutoCompletionTyped = ""; mUserKeptOnTyping = false; mTabCompletionCount = -1; mAutoCompletionCount = -1; if( mpHost->mAutoClearCommandLineAfterSend ) { clear(); mHistoryBuffer = -1; } else mHistoryBuffer = 0; adjustHeight(); ke->accept(); return true; } break; case Qt::Key_Enter: enterCommand(ke); mTabCompletionCount = -1; mAutoCompletionCount = -1; mLastCompletion = ""; mTabCompletionTyped = ""; mAutoCompletionTyped = ""; mUserKeptOnTyping = false; mTabCompletionCount = -1; mAutoCompletionCount = -1; if( mpHost->mAutoClearCommandLineAfterSend ) { clear(); mHistoryBuffer = -1; } else mHistoryBuffer = 0; adjustHeight(); ke->accept(); return true; break; case Qt::Key_Down: if( ke->modifiers() & Qt::ControlModifier ) { moveCursor(QTextCursor::Down, QTextCursor::MoveAnchor); ke->accept(); return true; } else { historyDown(ke); ke->accept(); return true; } break; case Qt::Key_Up: if( ke->modifiers() & Qt::ControlModifier ) { moveCursor(QTextCursor::Up, QTextCursor::MoveAnchor ); ke->accept(); return true; } else { historyUp(ke); ke->accept(); return true; } break; case Qt::Key_Escape: selectAll(); mAutoCompletion = false; mTabCompletion = false; mTabCompletionTyped = ""; mAutoCompletionTyped = ""; mUserKeptOnTyping = false; mTabCompletionCount = -1; mAutoCompletionCount = -1; setPalette( mRegularPalette ); if( mpHost->mAutoClearCommandLineAfterSend ) mHistoryBuffer = -1; else mHistoryBuffer = 0; ke->accept(); return true; break; case Qt::Key_PageUp: mpConsole->scrollUp( mpHost->mScreenHeight ); ke->accept(); return true; break; case Qt::Key_PageDown: mpConsole->scrollDown( mpHost->mScreenHeight ); ke->accept(); return true; break; case Qt::Key_C: if( ke->modifiers() & Qt::ControlModifier ) { if( mpConsole->console->mSelectedRegion != QRegion( 0, 0, 0, 0 ) ) { mpConsole->console->copySelectionToClipboard(); ke->accept(); return true; } } break; default: if( mpKeyUnit->processDataStream( ke->key(), (int)ke->modifiers() ) ) { ke->accept(); return true; } else { QPlainTextEdit::event( event ); adjustHeight(); if( mpHost->mAutoClearCommandLineAfterSend ) mHistoryBuffer = -1; else mHistoryBuffer = 0; if( mTabCompletionOld != toPlainText() )//text() ) { mUserKeptOnTyping = true; mAutoCompletionCount = -1; } else { mUserKeptOnTyping = false; } spellCheck(); return false; } } } return QPlainTextEdit::event( event ); } void TCommandLine::focusInEvent( QFocusEvent * event ) { //setSelection( mSelectionStart, mSelectedText.length() ); textCursor().movePosition(QTextCursor::Start); textCursor().movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, mSelectedText.length() ); mpConsole->console->forceUpdate(); mpConsole->console2->forceUpdate(); QPlainTextEdit::focusInEvent( event ); } void TCommandLine::focusOutEvent( QFocusEvent * event ) { if( textCursor().hasSelection() )//hasSelectedText() ) { mSelectionStart = textCursor().selectionStart(); mSelectedText = textCursor().selectedText(); } else { mSelectionStart = 0; mSelectedText = ""; } QPlainTextEdit::focusOutEvent( event ); } void TCommandLine::adjustHeight() { int lines = document()->size().height(); int fontH = QFontMetrics( mpHost->mDisplayFont ).height(); if( lines < 1 ) lines = 1; if( lines > 10 ) lines = 10; int _baseHeight = fontH * lines; int _height = _baseHeight + fontH; if( _height < mpHost->commandLineMinimumHeight ) _height = mpHost->commandLineMinimumHeight; if( _height > height() || _height < height() ) { mpConsole->layerCommandLine->setMinimumHeight( _height ); mpConsole->layerCommandLine->setMaximumHeight( _height ); int x = mpConsole->width(); int y = mpConsole->height(); QSize s = QSize(x,y); QResizeEvent event(s, s); QApplication::sendEvent( mpConsole, &event); } } void TCommandLine::spellCheck() { if( ! mpHost->mEnableSpellCheck ) return; QTextCursor oldCursor = textCursor(); QTextCharFormat f; QColor cred = QColor(255,0,0); f.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); f.setUnderlineColor(cred); QTextCursor c = textCursor(); c.select(QTextCursor::WordUnderCursor); if( ! Hunspell_spell( mpHunspell, c.selectedText().toLatin1().data()) ) { f.setFontUnderline(true); c.setCharFormat(f); } else { f.setFontUnderline(false); c.setCharFormat(f); } setTextCursor(c); f.setFontUnderline(false); oldCursor.setCharFormat(f); setTextCursor(oldCursor); } void TCommandLine::slot_popupMenu() { QAction * pA = (QAction *)sender(); if( ! pA ) { return; } QString t = pA->text(); QTextCursor c = cursorForPosition( mPopupPosition ); c.select(QTextCursor::WordUnderCursor); c.removeSelectedText(); c.insertText( t ); c.clearSelection(); Hunspell_free_list( mpHunspell, &mpHunspellSuggestionList, mHunspellSuggestionNumber ); } void TCommandLine::mousePressEvent( QMouseEvent * event ) { if( event->button() == Qt::RightButton ) { QTextCursor c = cursorForPosition( event->pos() ); c.select(QTextCursor::WordUnderCursor); if( ! Hunspell_spell( mpHunspell, c.selectedText().toLatin1().data()) ) { char ** sl; mHunspellSuggestionNumber = Hunspell_suggest( mpHunspell, &sl, c.selectedText().toLatin1().data() ); QMenu * popup = new QMenu( this ); for( int i=0; iaddAction( sl[i] ); connect( pA, SIGNAL(triggered()), this, SLOT(slot_popupMenu())); } mpHunspellSuggestionList = sl; mPopupPosition = event->pos(); popup->popup( event->globalPos() ); } event->accept(); return; } QPlainTextEdit::mousePressEvent( event ); } void TCommandLine::enterCommand( QKeyEvent * event ) { QString _t = toPlainText(); mAutoCompletion = false; mTabCompletion = false; mTabCompletionCount = -1; mAutoCompletionCount = -1; mTabCompletionTyped = ""; QStringList _l = _t.split("\n"); for( int i=0; i<_l.size(); i++ ) { mpHost->send( _l[i] ); } if( toPlainText().size() > 0 ) { mHistoryBuffer = 0; setPalette( mRegularPalette ); mHistoryList.removeAll( toPlainText() ); mHistoryList.push_front( toPlainText() ); } if( mpHost->mAutoClearCommandLineAfterSend ) clear(); else { selectAll(); } adjustHeight(); } void TCommandLine::slot_sendCommand(const char * pS) { mpHost->sendRaw( QString(pS) ); } // TAB completion mode gets turned on by the tab key. // This mode tries to find suitable matches for the letters being typed by the user // in the output buffer of data being sent by the MUD. This helps the user // to quickly type complicated names by only having to type the first letters. // You can cycle through all possible matches of the currently typed letters // with by repeatedly pressing tab or shift+tab. ESC-key brings you back into regular mode void TCommandLine::handleTabCompletion( bool direction ) { if( ( mTabCompletionCount < 0 ) || ( mUserKeptOnTyping ) ) { mTabCompletionTyped = toPlainText(); if( mTabCompletionTyped.size() == 0 ) return; mUserKeptOnTyping = false; mTabCompletionCount = -1; } int amount = mpHost->mpConsole->buffer.size(); if( amount > 500 ) amount = 500; QStringList bufferList = mpHost->mpConsole->buffer.getEndLines( amount ); QString buffer = bufferList.join(" "); buffer.replace(QChar( 0x21af ), "\n"); buffer.replace(QChar('\n'), " " ); QStringList wordList = buffer.split( QRegExp("\\b"), QString::SkipEmptyParts ); if( direction ) { mTabCompletionCount++; } else { mTabCompletionCount--; } if( wordList.size() > 0 ) { if( mTabCompletionTyped.endsWith(" ") ) return; QString lastWord; QRegExp reg = QRegExp("\\b(\\w+)$"); int typePosition = reg.indexIn( mTabCompletionTyped ); if( reg.numCaptures() >= 1 ) lastWord = reg.cap( 1 ); else lastWord = ""; QStringList filterList = wordList.filter( QRegExp( "^"+lastWord+"\\w+",Qt::CaseInsensitive ) ); if( filterList.size() < 1 ) return; int offset = 0; for( ; ; ) { QString tmp = filterList.back(); filterList.removeAll( tmp ); filterList.insert( offset, tmp ); ++offset; if( offset >= filterList.size() ) break; } if( filterList.size() > 0 ) { if( mTabCompletionCount >= filterList.size() ) mTabCompletionCount = filterList.size()-1; if( mTabCompletionCount < 0 ) mTabCompletionCount = 0; QString proposal = filterList[mTabCompletionCount]; QString userWords = mTabCompletionTyped.left( typePosition ); setPlainText( QString( userWords + proposal ).trimmed() ); moveCursor( QTextCursor::End, QTextCursor::MoveAnchor ); mTabCompletionOld = toPlainText(); } } } // Hitting the cursor up key gets you in autocompletion mode. // in this mode mudlet tries to find matching substrings in the user's // command history. Repeated usage of the cursur up key cycles through // all possible matches. If the user keeps on typing more letters the // the set of possible matches is getting smaller. The ESC key brings you back to regular mode void TCommandLine::handleAutoCompletion() { QString neu = toPlainText(); neu.chop( textCursor().selectedText().size() ); setPlainText( neu ); mTabCompletionOld = neu; int oldLength = toPlainText().size(); if( mAutoCompletionCount >= mHistoryList.size() ) mAutoCompletionCount = mHistoryList.size()-1; if( mAutoCompletionCount < 0 ) mAutoCompletionCount = 0; for( int i=mAutoCompletionCount; i= mHistoryList.size() ) mHistoryBuffer = mHistoryList.size()-1; if( mHistoryBuffer < 0 ) mHistoryBuffer = 0; setPlainText( mHistoryList[mHistoryBuffer] ); selectAll(); adjustHeight(); } else { mAutoCompletionCount--; handleAutoCompletion(); } } // cursor up: turns on autocompletion mode and cycles through all possible matches // In case nothing has been typed it cycles through the command history in // reverse order compared to cursor down. void TCommandLine::historyUp(QKeyEvent *event) { if( mHistoryList.size() < 1 ) return; if( (textCursor().selectedText().size() == toPlainText().size()) || (toPlainText().size() == 0) ) { if( toPlainText().size() != 0) mHistoryBuffer++; if( mHistoryBuffer >= mHistoryList.size() ) mHistoryBuffer = mHistoryList.size()-1; if( mHistoryBuffer < 0 ) mHistoryBuffer = 0; setPlainText( mHistoryList[mHistoryBuffer] ); selectAll(); adjustHeight(); } else { mAutoCompletionCount++; handleAutoCompletion(); } } mudlet-2.1/src/TToolBar.h0000644000175000017500000000462511513237311014610 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008-2009 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef TTOOLBAR_H #define TTOOLBAR_H #include #include #include #include "TFlipButton.h" #include "TAction.h" class Host; class TFlipButton; class TAction; class TToolBar : public QDockWidget { Q_OBJECT public: TToolBar( TAction *, QString, QWidget * pW = 0 ); void addButton( TFlipButton * pW ); void moveEvent( QMoveEvent * e ); void setVerticalOrientation(){ mVerticalOrientation = true; } void setHorizontalOrientation(){ mVerticalOrientation = false; } void clear(); void finalize(); TAction * mpTAction; void recordMove(){ mRecordMove = true; } //private: bool mVerticalOrientation; QWidget * mpWidget; QString mName; bool mRecordMove; QGridLayout * mpLayout; int mItemCount; signals: public slots: void slot_pressed(); }; #endif mudlet-2.1/src/glwidget.h0000644000175000017500000000664211647202526014741 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2010 by Heiko Koehn ( KoehnHeiko@googlemail.com ) * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef GLWIDGET_H #define GLWIDGET_H class TMap; #include // #include "TMap.h" #include "Host.h" class Host; class GLWidget : public QGLWidget { Q_OBJECT public: GLWidget(QWidget *parent = 0); GLWidget(TMap * pM, QWidget *parent = 0); ~GLWidget(); void wheelEvent ( QWheelEvent * e ); bool is2DView; QSize minimumSizeHint() const; QSize sizeHint() const; int mRID; int mAID; int mOx; int mOy; int mOz; bool mShiftMode; bool mShowInfo; public slots: void showInfo(); void shiftUp(); void shiftDown(); void shiftLeft(); void shiftRight(); void shiftZup(); void shiftZdown(); void showArea(QString); void setXRotation(int angle); void setYRotation(int angle); void setZRotation(int angle); void setXDist(int angle); void setYDist(int angle); void setZDist(int angle); void setScale(int); void goRoom(const QString &); void fullView(); void singleView(); void increaseTop(); void reduceTop(); void increaseBottom(); void reduceBottom(); void defaultView(); void sideView(); void topView(); signals: void xRotationChanged(int angle); void yRotationChanged(int angle); void zRotationChanged(int angle); void xDistChanged(int angle); void yDistChanged(int angle); void zDistChanged(int angle); protected: void initializeGL(); void paintGL(); void resizeGL(int width, int height); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); public: float xRot; float yRot; float zRot; float xDist; float yDist; float zDist; float dehnung; int mShowTopLevels; int mShowBottomLevels; QPoint lastPos; QColor qtGreen; QColor qtPurple; GLfloat rotTri, rotQuad; float mScale; TMap * mpMap; int mTarget; Host * mpHost; QMap mQuads; }; #endif mudlet-2.1/templates/0000755000175000017500000000000011513237311014151 5ustar csmallcsmallmudlet-2.1/templates/h0000644000175000017500000000255411513237311014331 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ mudlet-2.1/templates/cpp0000644000175000017500000000255411513237311014664 0ustar csmallcsmall/*************************************************************************** * Copyright (C) 2008 by Heiko Koehn * * KoehnHeiko@googlemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/